
AI 에이전트에게 전달할 사양서 작성법──거대한 요청을 깨뜨리지 않고 작게 전달하기 제1회
요약
AI 에이전트에게 작업을 요청할 때 프롬프트 문장 자체보다 중요한 것은 명확한 사양(Specification)을 전달하는 방식입니다. 에이전트가 추측으로 인한 오류를 범하지 않도록 작업의 경계를 설정하고, 구현 전 판단 기준을 명확히 하는 사양서 작성법을 제안합니다.
핵심 포인트
- 사양서는 명령문이 아닌 작업의 경계(Boundary)를 설정하는 도구임
- 거대한 요청을 작게 나누어 문맥(Context)의 무게를 조절해야 함
- 목적, 비목적, 배경 등 8가지 요소를 포함하여 에이전트의 추측을 방지함
- 무엇을 만들 것인가보다 어떻게 판단할 것인가를 먼저 정의함
이 기사는 「AI 에이전트를 공정에 넣기」 시리즈의 제1회입니다.
제0회에서는 Claude Code / Codex 시대의 개발 플로우를 Plan, Work, Review, Compound로 나누었습니다.
이번에는 그 입구인 Plan, 즉 AI 에이전트에게 전달할 사양서(Specification) 작성법을 다룹니다.
Claude Code나 Codex에 일을 맡길 때, 처음에 고민되는 것은 프롬프트(Prompt)입니다.
「어떻게 써야 잘 작동할까」
하지만 실무에서 한동안 사용해 보면, 문제는 프롬프트 문장 그 자체가 아니라는 것을 알게 됩니다.
중요한 것은 사양을 전달하는 방식입니다.
똑같은 「검색 기능을 추가해 줘」라도, 전달 방식에 따라 결과는 완전히 달라집니다. 아무 생각 없이 부탁하면, agent는 부족한 전제를 추측으로 채웁니다. 검색 대상, UI, API, 상태 관리(State Management), 테스트 방침, 기존 설계와의 조화. 인간이 결정해야 할 부분까지 agent가 마음대로 결정합니다.
잘 될 때도 있습니다.
하지만 그것은 운이 좋았을 뿐입니다. 추측이 빗나갔을 때, 빠르게 틀립니다.
AI 에이전트에게 전달하는 사양서는 거창한 RFC일 필요는 없습니다. 오히려 처음부터 거대한 사양서를 던지면 문맥(Context)이 무거워져서, agent는 중요한 부분을 놓칩니다.
필요한 것은 agent가 헤매지 않을 정도의 정보를, 작업 가능한 크기로 전달하는 것입니다.
이 기사에서는 사양서를 다음 8가지로 나누어 생각합니다.
1. 목적
2. 비목적
3. 배경
...
이 8가지가 있으면 AI 에이전트는 상당히 다루기 쉬워집니다.
우선, 사양서를 명령문이라고 생각하지 않는 편이 좋습니다.
나쁜 예:
상품 목록에 검색 기능을 추가해 주세요.
이것은 짧고 이해하기 쉬워 보입니다. 하지만 agent에게는 공백투성이입니다.
- 상품명만 검색하는가
- SKU도 검색하는가
- 클라이언트 측에서 필터링하는가
- 서버 측 API를 변경하는가
- 기존의 카테고리 필터와 어떻게 조합하는가
- URL query에 반영하는가
- 테스트는 어디에 추가하는가
- 기존의 디자인 시스템에 맞추는가
- 어떤 파일은 건드려도 되는가
- 어디까지 하면 멈추는가
인간 팀원이라면 도중에 되물을지도 모릅니다.
agent도 되묻는 경우가 있습니다. 하지만 대부분의 경우 「그럴듯한 답」을 만들어 가려고 합니다. 이 점이 위험합니다.
그래서 사양서는 agent에게 명령하는 문장이 아니라, 작업 경계(Boundary)를 만드는 문장이라고 생각합니다.
할 일을 결정한다.
하지 않을 일을 결정한다.
봐도 되는 것을 결정한다.
건드려도 되는 곳을 결정한다.
테스트 조건을 결정한다.
불명확한 점이 나오면 멈출 곳을 결정한다.
이것이 사양서입니다.
사양서를 쓰는 목적은 예쁜 문장을 만드는 것이 아닙니다.
구현 전에 만드는 것의 윤곽을 고정하는 것입니다.
코드를 쓰기 전에, 먼저 다음을 결정합니다.
- 누구의 어떤 상황을 개선하는가
- 입력은 무엇인가
- 출력은 무엇인가
- 정상계(Normal case)는 무엇인가
- 실패계(Failure case)는 무엇인가
- 이번에 하지 않을 것은 무엇인가
- 테스트로 어떻게 확인할 것인가
이 순서로 생각하면 prompt를 쓰는 방식도 바뀝니다.
나쁜 의뢰입니다.
상품 검색을 적당히 좋게 고쳐줘.
좋은 의뢰입니다.
상품 목록에서, 상품명 부분 일치 검색을 추가한다.
대상 사용자:
- 관리 화면에서 상품을 찾는 운영 담당자
...
이 정도까지 쓰면 agent는 구현 전에 상당히 헤매지 않게 됩니다.
사양 주도(Specification-driven)라고 하면 거창하게 들리지만, 실무에서는 이 정도면 충분합니다.
「무엇을 만들 것인가」보다 먼저, 「어떻게 판단할 것인가」를 쓴다.
이것이 효과적입니다.
처음에 구현하게 하지 않는다.
이것은 상당히 효과적입니다.
처음에는 read-only mode로 계획을 세우게 하는 것이 더 안정적입니다. 거대한 사양을 갑자기 던지기보다, 먼저 agent에게 리포지토리(Repository)를 읽게 하여 어디를 건드려야 할지, 무엇이 위험한지를 뽑아내게 합니다.
예를 들어 첫 번째 의뢰는 다음과 같습니다.
아직 구현하지 마세요.
상품 목록에 검색 기능을 추가하고 싶습니다.
먼저 기존 코드를 읽고, 구현 계획만 내주세요.
...
여기서 하고 있는 것은 사양서를 쓰기 전의 사양 만들기입니다.
인간이 모든 것을 알고 있다면 그대로 상세한 사양을 쓸 수 있습니다. 하지만 기존 리포지토리에서는 인간도 잊고 있는 것이 있습니다. 기존의 컴포넌트, 테스트 위치, 오래된 설계 판단, 유사한 구현.
agent에게 먼저 읽게 하면 그것들이 나옵니다.
그리고 나온 계획을 인간이 확인합니다.
「API는 변경하지 않는다」
「SKU 검색은 이번에 불필요」
「카테고리 필터와의 조합만 확인」
「URL 쿼리에 반영하는 것은 다음으로 미룬다」
이렇게 작업을 좁힙니다.
이제부터 실제로 에이전트 (agent)에게 전달할 사양서의 형태로 만듭니다.
목적 (Objective)은 짧게 작성합니다.
나쁜 예:
검색을 적절하게 만든다.
좋은 예:
관리 화면의 상품 목록에서, 상품명 부분 일치 검색이 가능하도록 한다.
목적은 추상도를 너무 높이지 않는 것이 좋습니다.
「검색 경험을 개선한다」라고 하면 범위가 너무 넓습니다. UI, 속도, 검색 정밀도, 저장, 이력, 서제스트 (suggest)까지 포함될 것 같습니다.
이번에 하고 싶은 일이 「상품명 부분 일치」라면, 거기까지 작성합니다.
비목적 (Non-objective)은 사양서 내에서 상당히 중요합니다.
AI 에이전트 (AI agent)는 불필요한 일을 하기 쉽습니다. 친절해 보일 수 있지만, 실무에서는 곤란합니다.
이번에 하지 않는 것:
- SKU 검색
- 서버 측 검색 API 추가
...
이것만으로도 변경 범위가 상당히 타이트해집니다.
특히 기존 리포지토리 (repository)에서는 비목적이 없으면 에이전트 (agent)는 「하는 김에 고치기」를 시작합니다.
하는 김에 타입을 정리한다.
하는 김에 컴포넌트 (component)를 분할한다.
하는 김에 오래된 테스트를 다시 작성한다.
하는 김에 UI 문구를 바꾼다.
사람이 보면 악의가 없다는 것을 알 수 있습니다. 하지만 PR (Pull Request)에서는 노이즈입니다.
비목적은 에이전트 (agent)에게 「이번에는 여기서 멈춰라」라고 전달하기 위해 존재합니다.
배경 (Background)은 왜 이 변경을 하는가입니다.
단, 너무 길게 쓰지 마세요.
배경:
상품 수가 늘어나, 카테고리 필터만으로는 목적의 상품을 찾기 어려워지고 있다.
우선 관리 화면 내에서 상품명 검색만 추가하여, API 변경 없이 개선할 수 있는지 확인하고 싶다.
배경이 있으면 에이전트 (agent)가 판단하기 쉬워집니다.
예를 들어 「API 변경 없이 개선할 수 있는지 확인하고 싶다」라고 적혀 있으면, 서버 측 검색을 마음대로 추가하기 어려워집니다.
배경은 사양의 이유입니다. 이유가 있으면 에이전트 (agent)의 추측 범위가 좁아집니다.
변경 범위에서는 건드려도 좋은 곳과 건드리지 말아야 할 곳을 작성합니다.
건드려도 좋은 곳:
- src/features/products/
- src/components/SearchInput.tsx
...
여기서 「unrelated lint / format」을 넣어두면 차이점 (diff)을 읽기 쉬워집니다.
에이전트 (agent)는 눈치를 보며 포맷을 수정할 때가 있습니다. 그 자체는 나쁘지 않습니다. 하지만 구현 차이점과 섞이면 리뷰 (review)가 번거로워집니다.
AI 에이전트 시대의 PR에서는 차이점을 작게 유지하는 것이 더욱 중요해집니다. 생성 속도가 올라갈수록 리뷰 (review)의 부담이 늘어나기 때문입니다.
에이전트 (agent)는 문맥 (context)이 없으면 찾아 헤맵니다.
찾아주는 것은 편리하지만, 매번 처음부터 찾으면 시간과 문맥을 모두 소모합니다. 게다가 봐야 할 자료를 놓칠 때도 있습니다.
그래서 처음부터 입구를 전달합니다.
먼저 읽을 것:
- AGENTS.md
- src/features/products/ProductList.tsx
...
프로젝트마다 INDEX.md를 가지고, 관련 문서나 채널을 주석과 함께 나열하면 에이전트 (agent)는 훨씬 덜 헤매게 됩니다. 단순한 URL 리스트가 아니라, 「무엇이 들어있고, 언제 읽어야 하는지」를 짧게 덧붙입니다.
이것은 실무에서 매우 유용합니다.
예를 들어, 다음과 같은 INDEX.md를 둡니다.
# Project Index
## Product UI
- `src/features/products/`
...
이렇게 해두면 사양서가 짧아집니다.
사양서에 모든 설명을 쓰는 것이 아니라, 읽어야 할 입구를 전달합니다. 이는 에이전트 (agent)에게도 인간에게도 편한 방식입니다.
여기서 GPS, Walrus Memory, Minimi와 같은 메모리 레이어 (memory layer)가 자연스럽게 들어옵니다. 목적은 「무엇이든 기억하는 것」이 아닙니다. 사양을 쓰기 전에, repo rules, past lessons, 과거의 판단을 Plan으로 되돌리는 것입니다.
수락 조건 (Acceptance Criteria)은 「무엇이 되면 완료인가」입니다.
수락 조건:
- 상품명 부분 일치로 목록을 필터링할 수 있음
- 검색 문자열이 비어 있으면 전체 항목이 표시됨
...
수락 조건이 없으면 에이전트 (agent)는 스스로 완료를 결정합니다.
「동작했습니다」로 끝날지도 모릅니다. 하지만 카테고리 필터와의 조합은 확인하지 않았을 수도 있습니다. 빈 문자열의 동작도 확인하지 않았을 수도 있습니다.
수락 조건은 에이전트 (agent)의 완료 선언을 받아들이기 위한 기준입니다.
테스트 조건은 수락 조건보다 구체적입니다.
추가하거나 확인해야 할 테스트:
- 빈 문자열인 경우, 모든 상품이 표시된다
- 상품명의 부분 일치로 필터링할 수 있다
...
여기서 중요한 것은, "테스트해 줘"라고만 하는 것은 약하다는 점입니다.
어떤 케이스를 볼 것인가.
어떤 커맨드 (command)를 실행할 것인가.
실패하면 어떻게 할 것인가.
여기까지 작성합니다.
테스트가 실패한 경우에는 즉시 수정하지 말고,
먼저 실패 원인을 설명해 주세요.
그 후, 최소한의 수정안을 제시해 주세요.
이 내용을 넣으면, 에이전트 (agent)가 로그를 읽지 않고 임기응변식 수정을 반복하는 것을 방지하기 쉬워집니다.
정지 조건은 더 많이 사용되어야 합니다.
에이전트는 계속 나아가려 합니다. 그러므로 멈추는 조건을 작성합니다.
다음의 경우에는 구현을 멈추고 확인해 주세요:
- API 변경이 필요해 보일 때
- DB 스키마 (schema) 변경이 필요해 보일 때
...
이것이 있으면, 에이전트가 멋대로 큰 판단을 내리기 어려워집니다.
정지 조건은 인간의 판단을 남겨두는 곳입니다.
AI 에이전트를 사용하면 인간의 일이 줄어든다기보다, 판단의 위치가 바뀝니다. 전부를 손으로 쓰는 것이 아니라, 어디서 멈출지를 설계하는 것. 이 부분이 중요합니다.
여기까지를 정리하면 다음과 같습니다.
# 사양: 상품 목록에 상품명 검색 추가
## 목적
관리 화면의 상품 목록에서 상품명의 부분 일치 검색이 가능하도록 한다.
...
이 정도면 충분합니다.
포인트는 너무 상세하지 않게 작성하는 것입니다.
모든 구현 절차를 인간이 작성할 필요는 없습니다. 그 정도로 상세히 적을 거라면 직접 구현하는 것이 더 빠를 때도 있습니다.
사양서에 적어야 할 것은, 에이전트가 멋대로 결정하면 곤란한 사항들입니다.
사양서는 처음부터 완성할 필요가 없습니다.
오히려 에이전트에게 만들게 하고, 인간이 깎아내는 편이 좋을 때가 있습니다.
처음에 이렇게 요청합니다.
아직 구현하지 마세요.
다음 목적에 대하여, 구현용 사양서 초안 (draft)을 작성해 주세요.
목적:
...
에이전트가 초안을 내놓습니다.
인간은 그것을 보고 깎아냅니다.
"이것은 이번에는 하지 않는다"
"이 테스트는 불필요하다"
"API 변경은 금지"
"이 파일은 건드리지 마라"
"이 불명확한 점은 이번에는 고정한다"
사양서를 쓰는 일도 에이전트와 분담할 수 있습니다.
단, 최종 판단은 인간이 가져야 합니다. 특히 비목적, 정지 조건, 수락 조건은 인간이 확인해야 합니다.
이 부분을 에이전트에게 통째로 맡겨버리면, 에이전트는 자신에게 유리한 사양을 만듭니다.
사양서가 너무 길어진다면, 태스크가 너무 클 가능성이 있습니다.
예를 들어, 다음 요청은 큽니다.
상품 목록에 검색, 필터 저장, CSV 내보내기, URL query 반영,
서버 측 검색, 권한별 표시를 추가해 주세요.
이것은 하나의 요청처럼 보이지만, 실제로는 여러 개의 변경 사항입니다.
- 상품명 검색
- 필터 저장
- CSV 내보내기
- URL query 반영
- 서버 측 검색
- 권한별 표시
한꺼번에 전달하면, 에이전트는 방대한 양의 판단을 떠안게 됩니다. 문맥 (context)도 무거워지고, 차분 (diff)도 커지며, 리뷰 (review)가 힘들어집니다.
이렇게 나눕니다.
Step 1: 클라이언트 측의 상품명 검색만 추가한다
Step 2: 카테고리 필터와의 조합을 정리한다
Step 3: URL query 반영을 추가한다
...
에이전트에게 처음부터 전부 시키는 것이 아니라, PR (Pull Request)로 만들 수 있는 단위로 나눕니다.
AI 에이전트는 큰 일도 할 수 있습니다. 하지만 팀 개발에서는 만들 수 있느냐보다 리뷰할 수 있느냐가 중요합니다.
작게 전달하는 것은 에이전트만을 위한 것이 아닙니다. 인간의 리뷰를 위해서이기도 합니다.
사양서와 AGENTS.md를 섞지 않는 것이 좋습니다.
사양서는 이번 태스크를 위한 것입니다.
AGENTS.md는 리포지토리 (repository) 전체에서 반복해서 사용하는 규칙입니다.
예를 들어, 이것은 사양서에 적을 내용입니다.
이번에는 상품명 검색만 추가하고, SKU 검색은 하지 않는다.
이것은 AGENTS.md에 적을 내용입니다.
UI 변경 시에는 기존의 디자인 시스템 (design system) 본체를 변경하지 않는다.
필요해 보이는 경우에도 우선 제안에 그친다.
매번 사용하는 규칙은 AGENTS.md.
이번에만 해당하는 조건은 사양서.
이렇게 나누지 않으면 AGENTS.md가 금방 비대해집니다.
CLAUDE.md
이것이 너무 길어지면 그 자체로 부하가 됩니다. 매번 모든 내용을 읽어 들여야 한다면, 해당 세션에 불필요한 정보까지 문맥 (Context)을 압박하게 됩니다. 따라서 내용이 길어지면 guide나 skill로 나누어, 필요한 때에만 읽는 형태로 만들어야 합니다.
이것은 AGENTS.md도 마찬가지입니다.
짧고, 반복적으로 유효한 것들만 둡니다.
세부적인 절차는 guide로 넘깁니다.
이번에만 해당하는 조건은 사양서 (Specification)에 둡니다.
이렇게 정리되어 있으면 agent의 Plan (계획)이 안정됩니다.
사양서를 작성하는 단계에서도 주변 도구들은 자연스럽게 등장합니다.
단, 주인공은 도구가 아닙니다. 막힌 부분에만 등장해야 합니다.
repo rules, past lessons, 과거의 리뷰 지적 사항이 매번 사라진다면, memory layer (메모리 계층)를 고민해야 할 타이밍입니다.
GPS, Walrus Memory, Minimi와 같은 도구들이 이 위치에 해당합니다.
살펴봐야 할 점은 기억의 양이 아닙니다.
- 오래된 기억을 버릴 수 있는가
- 잘못된 기억을 바로잡을 수 있는가
- repo 단위로 문맥 (Context)을 나눌 수 있는가
- Plan (계획) 이전에 자연스럽게 읽을 수 있는가
사양서 이전에 필요한 전제 조건을 불러올 수 있는가. 이 점을 봅니다.
Slack, Drive, Notion, GitHub, docs가 흩어져 있으면 agent는 매번 찾아 헤맵니다.
이 경우, 우선적으로 필요한 것은 고기능 도구가 아니라 INDEX.md입니다.
어디에 무엇이 있고, 언제 읽어야 하는지를 짧게 적습니다.
그래도 부족하다면 MCP나 검색 도구를 추가합니다.
순서를 반대로 하지 않는 것이 좋습니다. 입구가 정리되지 않은 상태에서 도구만 늘리면, agent는 더 넓은 범위에서 길을 잃게 됩니다.
매주 비슷하게 반복되는 종류의 사양을 작성한다면, 템플릿이나 skill로 만듭니다.
예를 들어, UI 변경, API 변경, migration (마이그레이션), 장애 조사, 라이브러리 업데이트 등이 있습니다. 각각에서 살펴봐야 할 점은 다릅니다.
한 번 성공했던 사양서를 다음 회차의 템플릿으로 만듭니다.
이것이 Compound (복리)입니다.
마지막으로, 나쁜 사양서와 좋은 사양서를 나란히 비교해 보겠습니다.
나쁜 사양서:
상품 목록에 검색을 추가해 주세요.
적당히 잘 부탁드립니다.
테스트도 부탁드립니다.
이것은 짧지만, 거의 모든 것을 agent에게 떠넘기고 있습니다.
조금 더 나은 사양서:
상품 목록에 상품명 검색을 추가해 주세요.
카테고리 필터와 함께 사용할 수 있도록 해주세요.
테스트도 추가해 주세요.
목적은 조금 보입니다. 하지만 변경 범위, 비목적 (Non-goal), 정지 조건이 없습니다.
좋은 사양서:
상품 목록에 상품명의 부분 일치 검색을 추가해 주세요.
이번에는 클라이언트 측에서 필터링합니다.
API 변경, DB schema (스키마) 변경, URL query 반영, SKU 검색은 하지 않습니다.
...
이 정도라면 agent가 상당히 길을 잃지 않게 됩니다.
그리고 인간도 리뷰 (Review)하기 쉽습니다.
사양서는 agent만을 위한 것이 아닙니다. 미래의 자신, 리뷰어 (Reviewer), 그리고 다음에 이 작업을 이어받을 사람을 위해서도 필요합니다.
AI 에이전트에게 전달하는 사양서는 길다고 좋은 것이 아닙니다.
너무 짧으면 agent가 마음대로 결정해 버립니다. 너무 길면 문맥 (Context)이 무거워져 중요한 부분이 누락됩니다.
필요한 것은 작업 경계 (Work Boundary)입니다.
- 목적
- 비목적 (Non-goal)
- 배경
- 변경 범위
- 입력 문맥 (Input Context)
- 수락 조건 (Acceptance Criteria)
- 테스트 조건
- 정지 조건
이 8가지를 작성하면 agent를 상당히 다루기 쉬워집니다.
그리고 처음부터 완벽한 사양서를 쓰려고 애쓰지 않아도 됩니다.
먼저 read-only (읽기 전용)로 읽게 합니다.
계획을 내놓게 합니다.
인간이 깎아냅니다.
작은 작업 단위로 나눕니다.
이번에만 해당하는 조건은 사양서로.
반복되는 규칙은 AGENTS.md나 skill로.
이 흐름이 만들어지면, AI 에이전트는 '어쩌다 한 번 맞히는 코드 생성기'가 아니라, 개발 공정 속에서 다룰 수 있는 작업자에 가까워집니다.
다음 회차에서는 나온 결과물을 어떻게 검품할지를 다룹니다.
사양을 쓸 수 있더라도 리뷰 (Review)가 약하면, 생성량이 그대로 리뷰 부채가 됩니다. 다음은 Trace, Eval, Pre-CI Review에 관한 이야기입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기