AI 구현안을 그대로 채택하여 실패한 경험: 독자적인 구현 전에 공식 기능을 확인하는 방법
요약
개발 과정에서 AI가 제시한 코드를 무비판적으로 채택하여 시간과 노력을 낭비한 경험을 공유합니다. 이 글은 독자적인 구현에 앞서 사용 중인 라이브러리의 공식 기능을 먼저 확인하는 중요성을 강조하며, '어떻게 작성할까?'보다 '애초에 작성할 필요가 있는가?'를 질문해야 한다고 조언합니다.
핵심 포인트
- AI 제안 코드를 맹신하기보다 공식 문서를 우선 확인하세요.
- 구현 전 '필요성' 검토가 가장 중요하며, 이는 시간 절약의 핵심입니다.
- 라이브러리별로 제공하는 공식 기능을 먼저 파악해야 합니다.
AI를 사용하며 개발하고 있습니다.
외부 라이브러리를 이용한 구현 과정에서, AI의 제안을 어디까지 신뢰해야 할지 고민이 됩니다.
AI가 제시한 코드를 '작동할 것 같다'는 이유만으로 채택한 경험이 있습니다.
이에 공식 문서를 확인할 타이밍에 대해 생각해보고자 합니다.
본 글에서는 AI로부터 제안받은 독자적인 구현을 채택했지만, 나중에 라이브러리에 같은 목적의 공식 기능이 있다는 것을 알게 된 경험을 바탕으로 다음 세 가지를 정리합니다.
- AI가 제시한 구현안을 어떻게 다룰 것인가
- 독자적인 구현 전에 무엇을 확인할 것인가
- 구현 방식이 바뀌었을 때, 검증 방법을 어떻게 생각할 것인가
이번 배움을 한마디로 표현하자면,
'어떻게 작성할까?'를 고민하기 전에, '애초에 작성할 필요가 있는가?'를 확인하는 것입니다.
인증 라이브러리가 제공하는 특정 API를 비활성화하는 방법을 구현하고 있을 때, AI로부터 Next.js의 Route Handler에 독자적인 차단 처리를 작성하는 방법이 제안되었습니다.
요건을 단순화하면,
인증 라이브러리가 제공하는 특정 API를 이용할 수 없게 만드는 것입니다.
AI가 제안한 것은 요청 경로를 판별하여, 대상 API라면 Better Auth로 처리하기 전에 404를 반환하는 방법이었습니다. 예를 들면 다음과 같은 이미지를 상상해볼 수 있습니다.
import { auth } from "@/lib/auth";
const disabledPaths = new Set([
"/api/auth/example-a",
...
처리 과정 자체는 이해하기 쉬워 보였습니다.
Request
↓
Route Handler
...
대상 API를 차단한다는 요건도 충족할 수 있을 것 같아, 이 방법으로 구현을 진행했습니다.
하지만 이때 한 가지 중요한 확인 사항이 빠져 있었습니다. 바로 Better Auth 자체에 같은 목적을 위한 공식 기능은 없는지? 라는 확인입니다.
나중에 Better Auth의 공식 문서를 확인해 보니, 특정 인증 경로를 비활성화하기 위한 disabledPaths가 준비되어 있는 것을 알게 되었습니다. 예를 들어 다음과 같이 설정할 수 있습니다.
import { betterAuth } from "better-auth";
export const auth = betterAuth({
disabledPaths: [
...
Next.js와의 연동도 현재 공식 문서에서는 toNextJsHandler를 사용한 방법이 안내되고 있습니다.
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
export const { GET, POST } = toNextJsHandler(auth);
즉, 직접 경로 판별 로직을 가지고 있지 않아도,
Request
↓
Better Auth
...
와 같은 형태가 가능했습니다.
disabledPaths의 존재를 사전에 파악하고, 그것이 요건을 충족한다는 것을 확인했더라면, 독자적인 차단 처리를 작성할 필요가 없었습니다.
이번에 저에게 가장 중요했던 점은 이 부분이었습니다. AI가 제안한 독자적인 구현이 전혀 작동하지 않는 코드는 아니었기 때문입니다. 문제가 되었던 것은,
요건
↓
AI가 구현안을 생성
...
으로 진행해 버렸다는 점이었습니다.
원래는 그 사이에,
요건
↓
사용 중인 라이브러리의 공식 기능을 확인
...
와 같은 조사가 필요했습니다. 즉, 이번 문제의 핵심은 AI가 잘못된 코드를 작성했다는 것이 아니라, AI가 코드를 제안해 주었기 때문에 '애초에 이 코드를 작성할 필요가 있는지'를 확인하지 않았다는 것이었습니다.
AI를 사용하면 구체적인 구현안에 도달하는 시간이 매우 짧아집니다. 그렇기 때문에,
어떻게 구현할까?
↓
AI에게 묻기
...
라는 흐름에 빠지기 쉽습니다.
하지만 외부 라이브러리를 사용하고 있다면, 그 전에 다음을 확인할 필요가 있습니다.
- 공식 설정 항목은 없는가
- 공식 API는 없는가
- 공식의 hook이나 확장 포인트는 없는가
- 이용 중인 버전에서 사용할 수 있는가
- 프로젝트 내에 기존 구현 패턴은 없는가
즉, '어떻게 작성할까?'보다 먼저 '작성할 필요가 있는가?'를 확인하는 것입니다.
물론 공식 기능이 존재한다고 해서 반드시 그것을 사용해야 한다는 이야기는 아닙니다. 요건을 충족하지 못하거나 다른 제약 조건이 있어 독자적인 구현이 적절한 경우도 있습니다.
다만, 독자적인 구현에는 스스로 고민해야 할 부분이 늘어납니다.
이번과 같은 경로 판정(path判定)이라면,
- 어떤 경로를 대상으로 할지
- URL을 어떻게 정규화할지
- 끝에 슬래시(/)를 어떻게 처리할지
- 어떤 응답을 반환할지
- 라이브러리 측의 변경 사항에 어떻게 추종할지
등도 스스로가 유지보수해야 할 대상이 됩니다.
독자 구현
↓
코드가 늘어남
...
그렇기 때문에, 먼저 공식 기능을 확인하고, 그것으로는 요구사항을 충족할 수 없는 이유가 있을 때 독자 구현을 검토하는 순서가 중요하다는 것을 배웠습니다.
이번 경험을 통해 AI가 제시한 코드를,
정답(答え)
이 아니라,
구현 방법의 후보
로 보는ようになりました.
AI가 독자적인 처리를 제안하면,
이 구현으로 요구사항을 충족할 수 있을까?
뿐만 아니라,
왜 이 처리를 우리가 직접 작성해야 할까?
공식 기능은 없을까?
기존 코드에 같은 메커니즘은 없을까?
...
까지 확인합니다.
AI가 생성한 코드의 정확성뿐만 아니라,
그 코드 자체가 존재하는 것이 필요한지
를 보는 것입니다.
그래서 스스로는 다음 순서를 의식하게 되었습니다.
① 요구사항을 이해한다
↓
② 사용하고 있는 라이브러리를 특정한다
...
AI를 조사에 사용하는 것 자체는 유효합니다. 예를 들어,
이 요구사항을 Better Auth의 공식 기능만으로 구현할 수 있는지 조사해 주세요.
관련 공식 문서도 보여주세요.
라고 요청하면, 갑자기 구현 코드를 생성하게 하는 것보다 좋은 출발점이 됩니다.
다만, 최종적으로는 공식 문서를 직접 확인합니다. AI의 답변에는 오래된 버전 정보나 다른 라이브러리와의 혼동, 세세한 이용 조건 누락 등이 포함될 가능성이 있기 때문입니다.
AI
↓
조사를 빠르게 한다
...
이런 역할 분담으로 생각하고 있습니다.
독자 구현에서는 Route Handler 자체에 분기가 있습니다. 따라서, 예를 들어,
expect(response.status).toBe(404);
expect(mockAuthHandler).not.toHaveBeenCalled();
와 같은 Unit Test로, 우리가 작성한 차단 처리를 확인할 수 있습니다.
하지만 공식의 disabledPaths로 변경하면, 차단 처리 자체가 Better Auth 측으로 이동합니다. 여기서 Better Auth의 handler를 mock해 버리면,
Request
↓
mock handler
이 되어 실제 disabledPaths 설정을 거치지 않습니다.
즉, 테스트가 PASS하더라도 이번에 변경한 설정 자체를 확인하지 못했다는 상태가 발생할 수 있습니다.
그래서,
지금까지의 Unit Test를 어떻게 남길 것인가
가 아니라,
이 설정이 실제로 기능하고 있다는 것을 어떤 방법으로 확인할 수 있을까
부터 검증 방법을 다시 생각했습니다.
이번에는 실제 handler를 통과하는 HTTP 요청을 보내, 대상 경로에 대한 요청 결과를 확인했습니다. 예를 들어, 로컬 환경에서 다음과 같이 확인할 수 있습니다.
curl \
-o /dev/null \
-w "%{http_code}\n" \
...
이번에 확인한 환경에서는, 대상 경로에 대해 404가 반환되는 것을 확인했습니다.
HTTP Request
↓
Next.js
...
여기서 확인할 수 있었던 것은,
이번 환경・설정・대상 경로에 대해 기대했던 결과가 나왔다는 것입니다.
모든 HTTP 메서드나 대상 경로, 본인 환경(本番環境), 미래의 Better Auth 버전까지도 이 한 번의 확인으로 보장할 수는 없습니다. 여기서 또 하나의 것을 배웠습니다.
구현 방법이 바뀌면 적절한 검증 방법도 바뀐다는 것입니다. 독자 구현을 위해 만든 Unit Test를 남기는 것 자체를 목적으로 삼는 것이 아니라,
이번에 정말로 확인하고 싶은 것은 무엇인가?
부터 검증 방법을 선택해야 합니다.
공식 기능으로 변경함으로써, 독자 구현을 대상으로 하던 테스트의 일부는 필요 없어집니다. 하지만,
테스트가 많다
=
안전하다
는 아닙니다. 예를 들어,
- mock 자체의 동작만 확인한다.
- 실제 설정이 통과하지 않는다.
- 변경한 코드나 설정과는 다른 경로를 확인하고 있다.
와 같다면, 그 테스트가 PASS하더라도 이번 변경에 대한 보장은 되지 않습니다.
중요한 것은 개수보다,
그 테스트가 무엇을 검증하고 있는가
입니다.
구현 방식이 바뀌었다면, 기존 테스트를 기계적으로 남기는 것이 아니라 변경된 처리 경로에 대해 무엇을 검증해야 할지 다시 생각해야 합니다.
공식 기능으로 변경하면 구현 자체는 상당히 짧아집니다.
export const auth = betterAuth({
disabledPaths: [
"/example-a",
...
하지만 나중에 이 설정을 본 사람에게는,
왜 이 API를 비활성화했는지?
까지는 알 수 없을 수도 있습니다.
필요하다면, '무엇을 하고 있는지'가 아니라 '왜 필요한지'를 주석으로 남깁니다.
export const auth = betterAuth({
// 이 설정이 필요한 이유를 기재한다
disabledPaths: [
...
disabledPaths로 경로를 비활성화했다는 것 자체는 코드에서 읽을 수 있습니다.
주석으로 남기고 싶은 것은,
왜 이 설정이 필요한지
라는 배경입니다.
이번 경험을 통해, 외부 라이브러리와 관련된 구현에서는 코드를 작성하기 전에 다음을 확인하고 싶습니다.
[ ] 무엇을 실현하고 싶은지 정리했는지
[ ] 사용 중인 라이브러리의 공식 문서를 확인했는지
...
AI에게 코드를 작성하게 하기 전에 이 확인 과정을 거치는 것만으로도 불필요한 독자적 구현을 줄일 수 있을 것이라고 생각합니다.
이번에 AI가 제안한 독자적 구현을 채택한 후, 같은 목적의 공식 기능이 준비되어 있다는 것을 알게 되었습니다.
돌아보면 중요했던 것은 고도의 구현 테크닉이 아니라,
독자적 구현을 시작하기 전에 먼저 공식 기능을 확인한다.
라는 기본적인 조사였습니다.
AI는 구현을 가속화해 줍니다.
반면에, 구현안이 바로 손에 들어오기 때문에,
AI가 코드를 출력했다
↓
작동할 것 같다
...
라고 진행하기 쉽습니다.
그 사이에,
AI가 코드를 출력했다
↓
애초에, 이 코드는 필요한가?
...
라는 확인을 넣는 것입니다.
그리고, 구현 방식이 바뀌었다면, 그 구현으로 정말 확인하고 싶은 것에 맞춰 검증 방법도 다시 생각합니다.
이번 경험에서 얻은 판단 기준은 간단합니다.
AI의 제안을 조사의 종착점으로 삼지 않는다.
그리고,
'어떻게 쓸까?'보다 '애초에 쓸 필요가 있을까?'를 확인한다.
AI를 활용한 개발을 계속하는 데 있어, 앞으로도 의식하고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기