당신의 라이브러리가 학습 데이터에 없으면: AI 에이전트가 이를 잘 사용하도록 만드는 방법
요약
AI 에이전트가 학습 데이터에 없는 내부 라이브러리나 최신 기능을 사용할 때 발생하는 코드 오류 문제를 다룹니다. 모델의 환각을 줄이고 정확도를 높이기 위해, API 문서를 간결하게 핵심 지식으로 분리하고, 타입 시스템과 컴파일러를 활용하여 에이전트의 코드를 검증하는 방법을 제시합니다.
핵심 포인트
- API 문서화는 옵션 이름, 반환값 등 구체적인 시그니처에 집중해야 합니다.
- 긴 문서를 핵심 지식(8KB)과 필요할 때만 로드되는 세부 파일로 분리하여 비용 효율성을 높이세요.
- 공개 API는 반드시 엄격하게 타이핑하고, 에이전트에게 자체 타입 검사를 수행하도록 요청하세요.
모델이 당신의 라이브러리를 모른다고 해서 실패하는 것이 '아무것도 하지 않는 것'은 아닙니다. 오히려 모델이 알고 있는 다른 라이브러리의 코드를 자신 있게 작성하면서 실패합니다.
AI 에이전트에게 Jest 테스트가 포함된 React 컴포넌트를 작성해 달라고 요청하면, 나쁘지 않은 결과물을 얻을 수 있습니다. 그 이유는 학습 데이터에 관련 예시가 수백만 개나 존재하기 때문입니다.
하지만 모델에게 한 번도 본 적 없는 것을 사용하도록 요청한다면 어떨까요?
- 당신 회사의 내부 API 클라이언트;
- 당신의 디자인 시스템;
- 틈새 오픈 소스 라이브러리;
- 모든 것을 바꾼 새로운 주요 버전.
모델은 그럴듯해 보이는 코드를 생성하고, 에이전트의 머릿속에서는 컴파일되는 것처럼 보이지만, 실제로는 작고 자신감 넘치는 방식으로 틀린 코드가 나옵니다. 모델은 무작위로 추측하는 것이 아닙니다. 자신이 아는 것 중 가장 비슷한 것으로 모든 공백을 채웁니다. 유사한 라이브러리의 옵션 이름일 수도 있고, 인기 있는 대안에서 가져온 임포트 구문일 수도 있으며, 가정된 반환 형태일 수도 있습니다.
저는 지난 몇 달 동안 제가 관리하는 테스트 라이브러리인 TWD와 이를 이용해 테스트를 작성하는 Claude Code 플러그인을 가지고 이 문제에 대해 고민했습니다. 이것이 제가 갖추게 된 툴킷입니다. 하지만 이 모든 것이 제 라이브러리에만 국한된 것은 아닙니다.
1. 모델에게 규칙이 아닌 지식을 제공하라
당신이 에이전트에게 무엇을 주든 (기술, AGENTS.md, llms.txt, 문서 페이지 등), 그것만이 모델이 당신의 API를 배울 수 있는 유일한 장소입니다. 그러니 그 공간은 가르치는 것에 집중해야 합니다:
- 옵션 이름까지 완전히 작성된 시그니처: 옵션 이름을 정확하게 명시합니다.
- 무엇을 반환하는지: 특히 모델이 가정할 만한 인기 라이브러리와 다를 경우 더욱 중요합니다.
- 패턴: 어떤 순서로 일이 일어나야 하는지, 모든 파일에 필요한 설정은 무엇인지 등입니다.
- 완벽하고 정확한 예시: 모델에게는 작동하는 단 하나의 예제가 설명 문단 세 개보다 낫습니다.
반대로 채워서는 안 되는 것은 경고문입니다.
Context는 공짜가 아니며, 에이전트는 요청당 바이트마다 비용을 지불합니다. 제가 처음 참고했던 문서는 32 KB였고, 에이전트가 이 전체 내용을 로드하여 세 개의 테스트 파일을 작성했습니다.
이제 분리되었습니다. 대부분의 작업에 필요한 약 8 KB의 핵심 부분과 나머지 내용으로 구성된 두 번째 파일입니다. 이 두 번째 파일은 작업이 필요할 때만 에이전트가 읽습니다. Claude Code skills는 references/ 아래의 파일들이 온디맨드(on demand)로 로드되기 때문에 이를 직접적으로 지원합니다. 다른 어떤 설정이든 원리는 같습니다. 짧은 핵심 부분과 세부 사항으로 연결되는 링크들입니다.
2. 컴파일러가 API를 가르치게 하라
타입이 지정된(typed) API는 누군가가 컴파일러를 실행하는 한 모델이 무시할 수 없는 문서화입니다.
에이전트가 옵션 이름을 잘못 만들거나 인수를 순서대로 전달하지 못했을 때, 타입 검사(type check)는 이를 런타임에서 발견되는 버그 대신 몇 초 만에 오류로 바꿉니다. 따라서:
- 공개 API를 엄격하게 타이핑하세요. 오타가 나면 조용히 무시되는 옵션은 사람과 에이전트 모두에게 함정입니다. 컴파일 오류를 발생시키도록 하세요.
- 에이전트에게 실행하기 전에 자신이 작성한 내용을 타입 검사하도록 지시하세요. 이는 지침(instructions)의 한 줄일 뿐이며, 가장 저렴한 확인 방법입니다.
3. 타입을 볼 수 없는 것을 린팅하라
어떤 실수는 유효한 코드입니다. 누락된 await, 인기 있는 대체 라이브러리에서 가져온 임포트(import), .only 같은 디버깅 잔여물, 또는 API에 대해 항상 정의되지 않는 속성을 읽는 경우 등이 있습니다.
이것이 작고 집중적인 린터(linter)가 존재하는 이유입니다. 제 라이브러리의 경우 네 가지 규칙을 사용합니다. 세 가지 속성이 에이전트와 잘 작동하게 만들었습니다:
- 설정 없음(Zero config). 하나의 명령어만으로, 설정 없이, 모든 프로젝트에서 동일한 결과를 얻습니다. 만약 에이전트가 먼저 린터를 설정해야 한다면, 신뢰성 있게 실행하지 못할 것입니다.
- 안전한 경우 자동 수정(Autofix for the safe cases). 수정이 항상 올바른 경우(비동기 함수 내부에
await추가 등), 그냥 적용하세요. - 무엇을 해야 하는지 말해주는 메시지.
신뢰하기 전에, 찾을 수 있는 모든 실제 프로젝트에 대해 실행해 보세요. 작동하는 코드에서 트리거되는 규칙은 에이전트에게 잘못된 것을 가르칩니다.
4. 두 독자를 위해 출력을 설계하세요
콘솔 로그를 읽는 에이전트는 체크 표시를 검색하고, 줄 수를 세며, 때로는 잘못 이해합니다. 이제 여러분의 CLI에는 두 명의 독자가 있습니다: 사람과 프로그램입니다.
- 보기 좋은 출력 옆에 JSON 보고서를 작성하세요. 제 것에는 결과, 각 실패와 그 오류, 그리고 사람이 찾을 만한 진단 정보가 포함되어 있습니다.
- 문제를 보고하는 모든 명령어에
--format json옵션을 제공하세요. - **종료 코드(exit codes)**를 문서화하고, 의미를 부여하세요: 성공적, 문제 발견, 할 일이 없음.
5. 평가(evals)로 지침을 테스트하세요
지침은 어떤 코드처럼 퇴행합니다. 좋은 의도의 수정이 에이전트가 의존했던 규칙을 조용히 제거할 수 있으며, 아무것도 알려주지 않습니다.
평가는 에이전트를 위한 테스트입니다: 작은 프로젝트를 설정하고, 에이전트에게 작업을 부여한 다음, 그것이 생성한 것을 평가합니다. Claude Code에서는 이것이 claude plugin eval입니다. 케이스는 스캐폴드 스크립트, 프롬프트, 그리고 여러 평가자(graders) 목록을 포함하는 폴더입니다:
prompt: |
todo 페이지에 대한 테스트를 작성하세요: 목록, 빈 상태,
로드 실패, 그리고 todo 추가.
...
이것들을 실행하면서 제가 배운 것들:
- 실제 격차를 발견합니다. 수정 작업을 한 라운드 거치기 전에는, 제 이전 지침이 특정 사례에서 0.50점을 받았습니다. 제가 커버된다고 생각했던 작업임에도 불구하고 절반의 검사 항목이 실패했습니다.
- 결정론적 채점기(deterministic grader)를 선호하세요. 에이전트가 작성한 파일에 대한 정규 표현식(regex)이나 "이 도구를 호출했는지 여부" 같은 것은 매번 동일한 답변을 제공합니다. "이것이 플로우당 하나의 테스트인지, 아니면 요소당 하나의 테스트인지"와 같이 일치시킬 수 없는 부분은 LLM 채점기를 사용하세요.
- 채점 기준을 정확하게 만드세요. 제 채점기는 기준에 "모든 호출(awaits every call)"이라고 명시되어 있었고, 그중 한 호출이 동기식(synchronous)이었기 때문에 올바른 파일을 실패 처리했습니다. 비동기(async) 호출들을 이름으로 나열하는 것만으로 문제가 해결되었습니다.
- 실수를 심어 넣으세요. 제 사례 중 하나는 네 개의 의도적으로 삽입된 오류가 있는 파일에서 시작하여, 에이전트가 린터(linter)를 실행하고 파일을 깨끗하게 유지하는지 확인합니다.
- 모든 PR에 대해 실행하지 마세요. 비용이 발생합니다. 제 다섯 가지 사례의 경우 약 $1.80입니다. 저는 출시 전에 그리고 지침을 변경한 후에만 이를 실행합니다. 모든 PR의 경우, CI는 무료이며 오프라인으로
claude plugin validate --strict를 실행하고, 지침이 참조하는 모든 파일이 존재하는지 확인하는 작은 스크립트를 추가로 실행합니다.
6. 지침을 정직하게 유지하세요 (Keep the instructions honest)
가장 조용한 실패는 '표류(drift)'입니다. 라이브러리가 발전하는데 지침이 따라가지 못할 때 발생합니다.
제 에이전트의 지침과 라이브러리의 문서 및 소스 코드를 비교했을 때, 라이브러리가 무시하는 방식으로 문서화된 옵션 하나와, 역방향으로 명시된 기본값(default)을 발견했습니다. 에이전트는 지침을 충실히 따랐습니다. 문제는 지침 자체가 잘못되었다는 것입니다.
두 가지 습관이 도움이 됩니다:
- 버전 노트에 의존하지 마세요. "1.8에서 수정됨" 또는 "1.9 이상 필요"와 같은 문구는 현재 어떤 버전을 사용하고 있는지 모르는 모델에게 아무 의미가 없습니다. 현재의 동작 방식을 설명하세요.
- 기억이 아닌 소스 코드를 기반으로 주장을 확인하세요. 그리고 지침에 규칙과 이유를 함께 명시했다면, 그 이유가 사실인지 확인하세요. 제 경우 중 하나는 몇 달 동안 그렇지 않았습니다.
체크리스트 (The checklist)
만약 여러분의 라이브러리, SDK 또는 디자인 시스템이 아직 모델들이 알지 못하는 것이라면:
- API를 완전한 예제와 함께 레이어별로 한 번 가르치세요.
- 잘못된 호출이 컴파일되지 않도록 타입을 지정하고, 에이전트가 컴파일러를 실행하게 하세요.
- 설정 없이 누락된 타입을 린팅(Lint)하고, 자동 수정하며, 무엇을 해야 할지 알려주는 메시지를 제공하세요.
- 에이전트에게 로그 대신 JSON과 종료 코드를 주세요.
- 대부분 결정론적인 채점기(grader)로 평가(evals)를 작성하고, 출시 전에 실행하세요.
- 지침(instructions)은 소스에 대해 정직하게 유지하세요.
어쩌면 언젠가 모델들이 React를 아는 것처럼 당신의 라이브러리를 알게 될지도 모릅니다. 그때까지는, 당신의 라이브러리가 모델이 모르는 것을 보완해야 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기