
「AI 에이전트가 폭주했다」고 보였던 54분의 정체는, 사양서의 사실 미검증이었다
요약
AI 에이전트 기반의 spec-to-pr 파이프라인에서 발생한 중단(ABORT) 사례를 분석합니다. 에이전트의 성능 저하가 아닌, 사양서에 명시된 전제 조건이 실제 코드베이스와 일치하지 않아 발생한 문제임을 밝힙니다.
핵심 포인트
- AI 에이전트의 반복적인 오류는 모델 성능보다 사양서의 사실 검증 미흡이 원인일 수 있음
- takt와 같은 워크플로우 엔진을 활용한 선언적 에이전트 제어 방식 소개
- 에이전트가 스스로 판단하여 작업을 중단(ABORT)하는 예외 처리 메커니즘의 중요성
- 사양서와 실제 코드베이스 간의 정합성 유지가 에이전트 워크플로우의 핵심
안녕하세요, 엔도(@shoma_ai)입니다.
평소에는 중소기업을 대상으로 한 AI 도입 지원 및 시스템 개발을 하고 있습니다.
얼마 전, 사양서로부터 PR을 자동 생성하는 파이프라인(spec-to-pr)이 같은 날에 두 번이나 ABORT(자동 중단)되어, 합계로 54분 정도를 허비했습니다.
처음에는 "또 AI가 이상한 동작을 하고 있구나"라고 생각했습니다. 하지만 나중에 주간 회고(harness-review라고 부르고 있습니다)에서 로그를 다시 살펴보니, 원인은 그 반대였다는 것을 깨달았습니다.
이 기사에서는 전제가 되는 메커니즘부터 경위, 결국 어디를 수정했는지까지 작성합니다. AI 에이전트의 반복(리뷰와 수정의 왕복)이나 ABORT가 서서히 늘어나면서 "구현 정밀도가 떨어졌나?"라고 느끼고 있는 분들은, 로그를 뒤져보기 전에 어디를 봐야 하는지 알 수 있을 것입니다.
전제: 어떤 메커니즘으로 돌리고 있는가
저는 로컬에서 takt라는 OSS의 CLI를 사용하여, 여러 AI 에이전트를 연결한 파이프라인을 돌리고 있습니다.
takt는 각 단계의 역할·전이 규칙·리뷰 루프·인간의 개입 포인트를 YAML로 선언적으로 정의할 수 있는 워크플로우 엔진(Workflow Engine)입니다.
spec-to-pr은 그 위에서 실행하고 있는 워크플로우 중 하나입니다. 인간이 사양서(무엇을·어떻게 고칠지를 적은 Markdown)를 투입하면 다음과 같은 흐름으로 진행됩니다.
- planner: 사양서와 코드베이스를 읽고 구현 계획을 세움
- implement: 계획에 따라 코드를 작성함
- 리뷰: 작성된 코드를 여러 리뷰용 단계(안티 패턴·아키텍처·자기 리뷰(self-review) 3종)가 확인하고, 지적이 있으면 수정 단계로 되돌림
- PR 생성: 리뷰를 통과하면 PR을 생성함 (머지는 인간이 수행함)
포인트는 각 단계에 분기 규칙이 있다는 점입니다. "요건이 불명확함", "사양서의 전제가 실제와 다름"이라고 판단하면, 에이전트는 앞으로 나아가지 않고 ABORT, 즉 중단하여 인간에게 되돌려 보냅니다. 또한, review→fix와 같은 왕복이 3회 연속 이어져도 진척이 없는 경우에는 루프 모니터링이 "비생산적"이라고 판단하여 이 또한 ABORT 됩니다.
전체 모습을 그림으로 나타내면 다음과 같습니다.

이 ABORT로 향하는 화살표 2개가 이번 이야기의 주인공입니다. 당시의 워크플로우 정의에서 해당 규칙을 인용합니다 (일부 생략).
steps:
- name: plan
persona: planner
...
이후에 나오는 "반복 횟수"는 단계의 실행이 하나의 태스크에서 몇 번 일어났는지를 나타내는 숫자입니다 (리뷰와 수정의 왕복이 늘어날수록 쌓입니다). 실행 로그는 자동으로 집계 다이제스트(Digest)에 기록되어 있으며, 주간 회고에서 평균 반복 횟수 등을 다시 살펴보고 있습니다.
무슨 일이 일어났는가
먼저, 당일 실행 로그의 집계(자동 생성하고 있는 다이제스트) 실물은 이것입니다.
| 시작 | workflow | status | 반복 | 소요 |
|---|---|---|---|---|
| 2026-07-16 14:49 | spec-to-pr | completed | 20 | 65m18s |
| ... |
aborted된 2개를 더하면 53분 38초. 이것이 서두에서 말한 "54분"입니다.
1회차(12:38)는 planner가 반복 1회·8분 만에 스스로 ABORT했습니다. 그때 planner가 남긴 실제 리포트에서 발췌합니다 (3건 중 2건, 일부 생략).
조사를 완료했습니다. 사양서는 상세하지만,
실제 구현 착수 전에 인간의 판단이 필요한 사실 오인·사양 결락을 3건 검출했으므로, 운용 전제(무인) 규칙에 따라 ABORT 합니다.
1. 【최중요】
admin_action_logs의 타입이 생성되지 않아 npm run verify가 반드시 실패함
supabase gen types는 원격 DB를 읽기 때문에, 관리자가 마이그레이션(Migration)을 적용할 때까지 admin_action_logs는 타입에 나타나지 않습니다 (현재 database.types.ts에 0건). 타입이 없으면 .from('admin_action_logs')도 .rpc()도 타입 에러 → npm run build 실패 → 완료 게이트를 통과할 수 없습니다.
3.
content_categories는 이미 존재하지 않음 (사양서의 사실 오인)
20251223000000_drop_content_categories.sql:8에서 DROP 완료됨. database.types.ts에도 0건.
사양서에는 "이 테이블의 이 컬럼을 사용하여 로직을 작성하라"고 적혀 있었습니다. 하지만 실제 DB에는 테이블을 생성하는 마이그레이션 (Migration)이 적용되지 않아, 타입 정의 (Type definition)에 테이블이 존재하지 않았습니다. 게다가 사양서에서 "확인할 것"이라고 지정했던 다른 테이블은 이미 반년 전에 DROP된 상태였습니다.
2회차(12:53)에는 리뷰 공정의 마지막 단계인 셀프 리뷰 (self-review)가 동일한 지적을 3번 반복했습니다. 이를 받은 수정 (fix) 단계가 "수정을 진행할 수 없음" 분기에 해당하여, 이 역시 스스로 ABORT했습니다. 3회차 셀프 리뷰는 다음과 같이 응답했습니다 (일부 생략).
[Self-Review: Rejected]
계속되는 finding:
VAL-NEW-spec-incomplete-L336
: 사양 전체의 주요 기능이 미구현
VAL-NEW-data-deletion-hitl-L438
: 데이터 삭제·인증 경로의 인간 승인(Human approval) 없음
동일한 상태가 3회 지속되었으며, 코드 수정으로는 해결할 수 없습니다. 인간에 의한 마이그레이션 (migration) 승인 및 적용 후, 타입 재생성(Type regeneration)과 후속 구현이 필요합니다.
사양서에 적힌 범위와 코드 수정으로 해결할 수 있는 범위가 어긋나 있었고, AI는 충실하게 "이 지적은 코드로 고칠 수 없지 않습니까"라고 계속 말하고 있었던 것입니다.
집계 테이블의 상태만 보면 둘 다 "aborted"이며, 2회차는 "반복 13"입니다. "AI 에이전트가 멈췄다" 혹은 "폭주하고 있다"처럼 보입니다. 실제로 직후의 제 반응도 "또 리트라이 (retry) 횟수 조정이 필요한가"였습니다.
오독했던 포인트
하지만 침착하게 내용을 읽어보니, 이것은 "기계적인 고장"이 아니었습니다. 1회차에서는 사양서의 사실 오인을, 2회차에서는 사양서의 스코프 (Scope)와 하나의 PR로 구현할 수 있는 범위 사이의 괴리를 AI가 검출하여 멈춘 것이었습니다. 오히려 정상적으로 기능하고 있었습니다.
이상했던 것은 입력(사양서) 측이었지, AI의 구현력 측이 아니었습니다.
그리고 그 사양서는 DB의 실체를 확인하지 않은 채 제가 투입한 것이었습니다. "AI가 이상한 거동을 하고 있다"라고 처음에 오독한 것을 포함하여, 잘못은 AI가 아니라 저에게 있었습니다.
이 부분은 최근 주간 리뷰에서도 수치로 나타나고 있는데, 평균 반복 횟수가 전주 3회에서 이번 주 11.3회까지 증가했습니다. 동일한 다이제스트에는 워크플로우 (workflow)별 요약도 나와 있습니다.
| workflow | 실행 | completed | 실패/중단 | 평균 반복 | 평균 소요 |
|---|---|---|---|---|---|
| spec-to-pr | 3 | 1 | 2 | 11.3 | 39m38s |
여기서도 우선 "구현 정밀도가 떨어졌나?"라고 의심했습니다. 하지만 내용을 보니 구현 실수로 리트라이를 반복하고 있었던 것이 아니었습니다.
ABORT된 2건(반복은 총 14회)은 사양 측의 문제를 검출하여 멈추기까지의 반복입니다. 완주한 3번째 건의 반복 20회에는 통상적인 리뷰·수정 왕복도 포함되어 있지만, 이 건은 최종적으로 PR까지 도달했습니다.
무엇을 고쳤는가
리트라이 횟수의 임계값 (Threshold)을 건드리는 방향으로는 가지 않았습니다. 그렇게 하면 이번에는 진짜 사실 오인이 있는 사양서인 채로 그대로 돌진해 버릴 리스크가 있기 때문입니다.
고친 곳은 두 군데입니다.
첫 번째는 사양서 측입니다. 1회차 ABORT 직후, DROP된 테이블을 전제로 한 기술을 정정하여, "마이그레이션만 선행하여 PR화하고, 코드 구현은 그 이후로 분리한다"는 단계적 분할 방식으로 재구성했습니다. 다만, 2회차 실행은 이 수정된 사양서에서도 ABORT되었습니다. 단계적으로 분할된 사양서와 "사양서의 모든 요구사항이 구현되었는가"를 확인하는 셀프 리뷰 게이트 (self-review gate)가 맞물리지 않았기 때문입니다. 최종적으로는 태스크 지시 자체를 후반 스테이지(코드 구현 측)의 일부만을 구현하는 내용으로 직접 좁혔습니다. 그렇게 던진 3회차 실행(위 표의 14:49)이 반복 20회를 거치면서도 완주하여 PR 생성까지 도달했습니다.
두 번째는 워크플로우 정의 측입니다. 다음 날, 플래너 (planner)의 ABORT 조건을 세분화하여 다시 설정했습니다. 1회차 ABORT 이유였던 "마이그레이션 미적용으로 타입이 없음"은 다시 생각해보면 사양서의 사실 오인이 아니라, 관리자가 마이그레이션을 적용하기 전까지 발생하는 기지의 타임랙 (Time lag)입니다. 이를 진짜 사실 오인과 동일하게 취급하여 멈추는 것을 그만두고, 잠정 타입 파일 (Provisional type file)로 구현을 계속하는 패턴을 추가했습니다. 해당 커밋 (2026-07-17 "마이그레이션 미적용 테이블에 대한 잠정 타입 패턴을 spec-to-pr 워크플로우에 추가함")의 차분(diff)을 첨부합니다 (변경되지 않은 행은 일부 생략).
rules:
- - condition: 요건이 명확하고 구현 가능함 (신규 또는 기존 WIP/PR에 대한 차분 추가 포함)
+ - condition: 요건이 명확하고 구현 가능함 (신규 또는 기존 WIP/PR에 대한 차분 추가 포함. 미적용 마이그레이션(unapplied migration)에 대한 대응은 Pending Migration Types 패턴으로 구현 가능하므로 "명확함"에 포함)
...
implement 단계에도 동일한 취지의 규칙을 추가했습니다 (발췌).
+ - 대상 테이블·컬럼이 마이그레이션 미적용 상태이며 `database.types.ts`에 존재하지 않을 경우, `.agents/skills/supabase/service-usage.md` §6의 Pending Migration Types 패턴에 따라 `src/types/database.types.pending.ts`를 추가하여 구현을 계속한다. 타입이 없다는 이유로 구현을 중단하거나 ABORT 하지 않는다.
즉 "진짜 사실 오인은 이전과 같이 중단시킨다. 이미 알고 있는 지연(lag) 때문에 중단하지는 않는다"라는 구분을 규칙에 명시했습니다. planner가 "타입이 없다"라고 말할 때마다 제가 당황하며 확인해야 했던 흐름을 없애고 싶었기 때문입니다.
결론
반복 횟수가 늘어날 때, 무심코 "AI의 구현 능력이 떨어졌다"라고 읽고 싶어집니다. 하지만 이번에 의심했어야 했던 것은 AI 측이 아니라, 인간이 전달한 사양서의 사실 정확도였습니다.
AI 에이전트에게 사양서 기반으로 구현을 맡기는 운영을 하고 있는 분들이라면 아마 흔히 겪는 일이라고 생각합니다. 반복 횟수나 ABORT율이 증가하기 시작한다면, 에이전트 측의 설정을 건드리기 전에 사양서와 DB(또는 실제 코드) 사이의 괴리를 의심해 보세요. 미미해 보이지만, 이 방법이 가장 효과적이었습니다.
Discussion

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