AI가 작성한 코드는 '베타 버전': 설계서부터 구현 및 단위 테스트까지 에이전트에게 맡기는 시스템
요약
AI가 생성한 코드의 신뢰도를 높이기 위해 '설계서 기반 -> AI 작성(베타) -> 사람 리뷰 및 검증'의 5단계 시스템을 소개합니다. 이 시스템은 규칙, 검증 로직, 실행 에이전트를 분리하고, 모든 개발 과정에 사람이 개입하여 품질과 책임 소재를 확보하는 것이 핵심입니다.
핵심 포인트
- AI 생성 코드는 '베타 버전'으로 간주하며, 최종 품질 보장은 사람의 역할임.
- 개발 과정을 5단계(계획-코드-테스트-대조표-PR)로 나누고 단계마다 사람이 리뷰함.
- 규칙과 진실을 `guidelines/`에 모아두어 AI와 사람 모두가 이를 유일한 근거로 삼음.
- 역할별 에이전트(planner, coder, tester 등)를 분리하여 체계적인 개발 워크플로우를 구축함.
AI에 코드를 작성하게 하면 놀라울 정도로 빠르게 결과물이 나옵니다. 한편으로는 '정말로 설계서대로인가?', '테스트는 의미 있는 것을 확인하고 있는가?'와 같은 불안감이 남아있습니다.
이 글에서는 설계서(Markdown)를 기반으로 Spring Boot의 배치 및 API 코드는 물론 단위 테스트까지 AI에게 작성하게 하고, 기계적인 체크와 사람의 리뷰로 품질을 보장하는 시스템을 소개합니다. 실제 구현체는 ai-coding 리포지토리에 공개되어 있습니다. 샘플 업무(회원/주문)와 ID는 모두 가상의 데이터입니다.
전제: AI가 생성한 결과물은 '베타 버전'
이 시스템에서는 처음에 입장을 명확히 했습니다.
AI (GitHub Copilot의 에이전트)는 설계서로부터 베타(β) 버전 소스와 단위 테스트를 만드는 도구입니다. 최종적인 품질 보장은 사람이 담당합니다.
AI를 사용하더라도 결과물에 대한 책임 소재가 바뀌지는 않습니다. 그 위에, 품질 보장의 원칙을 5가지로 정했습니다.
- 실행 지시와 결과물 저장소는 사람이 수행한다. 어떤 설계서로, 어떤 공정을 돌릴지는 사람이 결정합니다. -
- AI 생성물(베타 버전)은 전량 리뷰한다. 그대로 채택하지 않습니다. -
- AI 리뷰는 보조 수단이다. 사람의 리뷰를 대체할 수 없습니다. -
- 과제는 티켓으로 추적한다. 리뷰에서 발견된 수정 사항에 대한 누락을 방지합니다. -
- 설계서에 AI가 필요한 정보를 기재한다. 파라미터 파일명, 메시지 ID, 테이블명 등을 포함합니다.
다섯 번째 원칙은 시리즈의 첫 글에서 다룬 '정보 부족' 문제 그 자체입니다. AI가 추측으로 채우기 쉬운 정보들을 처음부터 설계서에 명시해 둡니다.
전체 개요: 규칙, 검증, 실행을 분리하다
리포지토리에서는 역할별로 위치를 나누었습니다.
| 역할 | 저장소 | 내용 |
|---|---|---|
| 규칙 (유일한 진실) | guidelines/ | 규약, 구성, 품질 게이트, 리뷰 관점, AI 활용 원칙 |
| 검증 | template/, tools/spec-trace, scripts/ | 기계가 판정하는 품질 게이트 |
| 실행 | .github/agents/, .github/prompts/ | 역할별 에이전트와 호출용 프롬프트 |
핵심은 규칙의 진실을 guidelines/라는 한 곳에 모아두었다는 점입니다. AI도 사람도 이곳만을 근거로 삼습니다. 에이전트에 대한 지시에도 '여기에 쓰지 않은 규칙을 만들지 않는다. 막히면 추측하지 말고 확인 사항으로 사람에게 반환한다'고 명시했습니다.
5단계와 사람의 리뷰
개발은 5단계로 진행됩니다. 단계가 바뀔 때마다 사람의 리뷰(RP1~RP5)를 거칩니다.
| 단계 | Copilot Chat으로 | 수행할 작업 | 사람의 리뷰 |
|---|---|---|
| 1 계획 | /ai-plan | 생성할 파일 목록과 요구사항 대응표 작성 | RP1 계획 |
| 2 코드 생성 | /ai-code | 소스 코드를 만들고 기계 체크를 통과시키기 | RP2 코드 |
| 3 테스트 생성 | /ai-test | 단위 테스트와 API 시나리오 테스트 작성 | RP3 테스트 |
| 4 대조표 작성 | /ai-review | 설계서와 코드의 판정표 만들기 | RP4 최종 확인 |
| 5 CI + PR | /ai-pr | 모든 체크를 재실행하고, PR 본문 초안 작성 | RP5 PR |
현재 어느 단계에 있는지 알 수 없을 때는 /ai-status로 확인할 수 있습니다.
에이전트를 역할별로 나누기
.github/agents/에는 역할별 에이전트가 배치되어 있습니다.
- planner: 계획을 세움 -
- coder: 코드를 작성함 (테스트는 작성하지 않음) -
- tester: 테스트를 작성함 -
- reviewer: 설계서와 코드를 대조함 -
- orchestrator: 현재 단계를 판단하고, 다음 담당자와 사람의 리뷰로 인계함 (스스로는 작성하지 않음)
코드를 작성하는 담당과 테스트를 작성하는 담당을 분리한 것이 핵심입니다. 같은 AI가 두 가지 모두를 작성하면, 테스트가 구현에 끌려가기 쉽습니다.
AI의 '완료'를 믿지 않는 시스템
AI는 '구현했습니다', '테스트가 통과했습니다'라고 보고합니다. 하지만 실제로는 함수가 없거나, 테스트가 아무것도 확인하지 못하는 경우가 발생합니다.
그래서 상태를 기계적으로 뒷받침하도록 했습니다. 중심이 되는 것이 바로 요구사항-구현-테스트의 대응표입니다.
spec_id: "FEAT-JOB0001"
source: "samples/design-docs/batch/JOB0001_order-import.md"
source_sha256: "..." # 사람이 승인한 후 spec-trace pin으로 기록
...
요구사항마다 상태가 3단계로 나뉩니다.
| 상태 | 누가 지정하는가 | 조건 (툴이 확인) |
|---|---|---|
| pending | planner | 없음 |
| implemented | coder | implements 파일과 함수가 실제로 존재함 |
| proven | tester | proofs 테스트가 실제로 존재하며, 어설션(assertion)이 있음 |
에이전트가 상태를 올리는 것은 괜찮습니다. 단, 조건을 충족하지 못하면 CI의 spec-trace check가 실패합니다. 단순히 '만들었다'고 적는 것만으로는 통과할 수 없다는 의미입니다.
설계서가 바뀌면 감지 가능
대응표에는 사람이 승인한 시점의 설계서 해시(source_sha256)를 기록합니다. 만약 나중에 설계서가 수정되면, 해시가 일치하지 않게 되어 CI에서 감지됩니다. 차이점을 확인하여 영향을 받는 요구사항을 pending으로 되돌리고 다시 진행합니다.
품질 게이트: 기계로 판별할 수 있는 것은 기계에 맡기기
머지(Merge)하기 전에는, 기계가 판별하는 체크(결정론적 게이트, deterministic gate)를 모두 통과시키는 것이 필수입니다.
| ID | 내용 | ID | 내용 |
|---|---|---|---|
| D1 | 컴파일 (Java 17) | D7 | 테스트의 존재 및 어설션 |
| ... |
N1N6의 AI 리뷰는 어디까지나 보조적인 위치입니다. 명확한 것은 D1D11의 기계 판별에 맡기고, AI와 사람은 내용 판단에 집중합니다.
동일한 판별은 로컬에서도 실행할 수 있습니다.
./scripts/verify-gates.sh --final # Windows: .
pm scripts\verify-gates.ps1 -Final
포함된 샘플은 5단계가 완료된 상태(모든 요구사항이 proven)입니다. template/의 코드를 일부러 조금 망가뜨려서 실행하면, 어느 게이트에서 멈추는지 확인할 수 있습니다.
게이트 '우회'를 금지하다
AI에게 체크 통과를 요청하면, 때로는 체크 자체를 무력화시키는 경우가 발생합니다. 따라서 다음 변경 사항을 명확하게 금지하고 있습니다.
- 테스트의 기대값을 설계서가 아닌 구현에 맞춰 수정하는 것
- 어설션(assertion)을 삭제하거나 약화시키거나 (
assertTrue(true)등), 실행만 하는 테스트로 만드는 것 - Checkstyle 또는 SpotBugs의 제외(
exclusion)나@SuppressWarnings를 이유 없이 추가하는 것 - 테스트나 시나리오를
@Disabled/@ignore로 비활성화하는 것 - 대응표에서 요구사항을 삭제하거나, 근거 없이 상태를 올리는 것
- 커버리지(Coverage) 임계값을 낮추는 것
이 금지 사항은 에이전트에게 주는 지침과 CI 체크 양쪽에 모두 포함되어 있습니다. 지침만으로는 AI가 잊어버릴 수 있기 때문에, 기계적으로도 막는 이중의 장치입니다.
테스트 작성 규칙은 테스트 파일을 수정할 때만 로드되는 지침 파일(.github/instructions/test.instructions.md)에 작성되어 있습니다 (발췌).
---
applyTo: "template/src/test/**"
---
...
자동 수정 루프를 멈추는 방법
에이전트는 체크가 통과되지 않으면 원인을 고쳐서 재실행합니다. 하지만 다음 중 하나에 해당하면 즉시 멈추고 사람에게 돌려주는 것으로 결정했습니다.
- 같은 단계에서 3번을 수정해도 통과하지 못하는 경우
- 같은 오류가 2번 연속으로 발생하는 경우 (수정하지 못하고 있는 경우)
- A → B → A처럼, 동일한 수정을 반복하며 왔다 갔다 하는 경우
- 고칠 때마다 에러가 늘어나는 경우
세 번째 항목은 이 시리즈의 첫 번째 글에서 작성했던 'A일 때는 B, B일 때는 A' 루프입니다. 왔다 갔다 하는 것은 판단에 필요한 전제가 부족하다는 신호였습니다. 따라서 AI에게 계속 시키는 것이 아니라, 사람에게 돌려주어 전제를 채웁니다.
사람에게 돌려줄 때는 '각 회차에서 수정한 내용', '오류의 추이', '수렴하지 않는다고 판단한 이유'를 첨부하도록 합니다. 보고서에는 실행한 명령어와 결과도 반드시 포함하도록 합니다. '실행하지 않은 것을 '확인 완료(confirmed)'라고 적지 않는다'는 것도 규칙에 포함되어 있습니다.
시도해 보는 절차
시도해 보는 절차
-
개발 환경(Java 17 및 Rancher Desktop)과 Python 3.12를 준비합니다. 환경은 dev-environment에서 준비할 수 있습니다.
-
리포지토리를 clone하고, 게이트를 실행합니다.
git clone https://github.com/shoyo-maya-bot/ai-coding.git && cd ai-coding pip install -e tools/spec-trace ./scripts/verify-gates.sh --final
-
모든 게이트가 통과하는지 확인합니다.
-
template/안에 있는 테스트에서 어설션(assertion)을 하나 제거하고, 다시 실행합니다. -
어느 게이트에서 멈추는지 살펴봅니다.
고장 나게 만든 곳을 한 번 살펴보면, '기계가 무엇을 지켜주고 있는지'를 실감할 수 있습니다.
자주 하는 실수
AI의 보고를 그대로 믿는 것
'테스트가 통과했습니다'라고 해도, 실제로 실행되지 않은 경우가 있습니다. 보고서에는 실행한 명령어와 결과를 첨부하도록 하고, 상태는 CI(Continuous Integration)로 검증해야 합니다.
규칙이 여기저기 흩어지는 것
프롬프트, 지시 파일, Wiki에 각각 규칙을 작성하면 내용이 서로 충돌하게 됩니다. 규칙의 정답은 한 곳으로 결정하고, 다른 장소에서는 그곳을 참조하도록 해야 합니다.
체크를 통과하는 것이 목적이 되는 것
에러를 없애기 위해 체크(check) 자체를 느슨하게 만드는 것은 흔한 실수입니다. 금지 사항으로 명문화하고, CI에서도 감지할 수 있도록 해야 합니다.
AI에게 몇 번이고 고치게 하는 것
같은 에러를 반복적으로 주고받는 것은 전제가 부족하다는 신호입니다. 횟수의 상한선을 정하고, 일찍 사람에게 되돌려야 합니다.
요약
AI에게 코드를 작성하게 할 때 중요한 것은, AI를 똑똑하게 만드는 것보다, AI의 출력을 확인하는 시스템을 만드는 것입니다.
- AI가 생성한 결과물은 베타 버전으로 간주하고, 사람이 전량 리뷰합니다.
- '구현했다', '테스트했다'는 대응표와 CI로 검증합니다.
- 체크를 무력화시키는 것을 금지하고, 루프하면 사람에게 되돌립니다.
이 시스템은, 하네스(Harness) 글에서 쓴 생각을 실제 개발 과정에 적용한 것입니다. 모델을 바꾸기 전에, 먼저 확인하는 시스템부터 정비해 보세요.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기