Agent에 제약을 건다

01 / 29
CONSTRAINTS
Agent에
제약을 건다
기억하지 못하는 Agent로 앱을 끝까지 만든 방법
02 지난 시간에 살펴본 4가지 한계
상태 없음
조건이 토큰으로만 남음
계획 없음
다음 단계를 매번 새로 판단
자기 참조
자기가 쓴 걸 근거로 삼음
오류 전파
한 번 틀리면 뒤로 번짐
Attention이 선택적이라는 본질에서 파생
오늘 — 4가지를 해결한 구체적 사례 살펴보기
03 "잊지 마"는 제약이 아니다
부탁 = 토큰 뒤로 밀림 약해짐
제약 · CONSTRAINTS
온톨로지에서 차용 — 어기면 성립 불가
"지킬 수도, 안 지킬 수도 있는 건
제약이 아니다"
04 제약은 말이 아니라 구현체다
부탁
"검증 잊지 마"
지킬 수도, 안 지킬 수도
제약
--fail-if-no-match
테스트 0개 → 성공으로 세지 않음
구현체를 하나씩 알아보기
05 오늘 다룰 것
명세 제약
구조 제약
기준 제약
명세 파트 확장
명세를 Agent가 쓰게 만들기
관통 축 2개 — 상태·계획은 JSONL / 검증은 별도 Agent
06 사례 — AI App Factory
문제 한 줄 스토어 출시
11단계 라인
17
스킬
13
에이전트
150+
보일러플레이트 파일
사람은 승인만
07 제약 설계도
제약 거기에 매칭되는 파일
단계 순서 PIPELINE_PHASES · 파이프라인 문서
단계별 할 일 · 쓸 수 있는 도구 .claude/skills/*/SKILL.md
산출물 이름 docs/features/ARTIFACTS.md
상태 · 계획 docs/progress/*.jsonl
다음 단계 결정 .codex/hooks/lib/router.py · Stop hook
역할 분리 .claude/agents/implement-orchestrator.md
완료 정의 apps/server-e2e · apps/mobile-e2e
반복 상한 재시도 3회 · MAX_STALE_REPEATS = 2
거짓 GREEN 차단 --fail-if-no-match
검증 분리 e2e-verify · adb-verify · webview-verify
이 한 장 = 오늘 세션 전체 목차
08 명세 제약 ① 순서 고정
setup start clarify pages wireframes architecture
test-scenarios implement deploy build launch
문서 + 코드 상수
이중 고정
11개 밖은 없음
단계를 새로 만들 여지 제거
계획을 모델이 세우지 않게 만든 첫 장치
09 명세 제약 ② SKILL.md
---
name: implement-feature
allowed-tools: Read, Write, Edit, Glob,
  Grep, Agent, Bash(pnpm *), Skill(deploy)
context: fork
agent: implement-orchestrator
---

### Step 1: Determine Feature Name
### Step 2: Check Document Existence
### Step 3: Handle Missing Documents
### Step 4: Spawn Orchestrator
Step 1..N
단계 안의 순서까지 고정
도구 목록
목록 밖은 호출 불가
사람 매뉴얼과 Agent 프롬프트를 같은 파일로
10 명세 제약 ③ 산출물 이름 · 시작 조건
산출물 만드는 곳 읽는 곳
core-idea.md /start /clarify
data-model.md /clarify /define-pages · db-implement
page-map.md /define-pages /design-wireframes
architecture.md /design-architecture implement 에이전트
test-scenarios.md /write-test-scenarios e2e-verify · adb-verify
계약 밖 파일명
참조 금지 — 새 산출물은 계약부터 수정
스펙 6종 미비
구현 시작 안 됨
11 처음에는 사람이 다 썼다
질문
A. 바텀시트   B. 전체 화면   C. 인라인
D. 모달   E. 기타 (직접 설명)
답변
사람
기록
명세 문서
병목
앱 1개 = 결정 수십 개 → 사람이 병목
전제 — "명세는 사람이 쓰는 것"
12 질문은 그대로, 답하는 쪽만 교체
고정
질문 · 선택지 A~E
교체
사람
답변 전담 Agent
답변 근거
코드베이스 패턴 · 기존 스펙 · 제품 판단
이 Agent의 제약
기타 금지 · 되묻기 금지 · 전 문항 필답 · 읽기 전용
문항 · 선택지 무수정
13 auto mode 개방
// docs/progress/auto-mode.json
{
  "enabled": true,
  "problem": "기프티콘 만료일을 자꾸 놓친다",
  "preferences": { "kakao_login": false }
}
11단계 무인 주행
질문 없이 끝까지
출시 후 자동 종료
스스로 enabled = false
14 ★ 품질은 왜 안 무너졌나
명세에 남은 빈칸 채우기
질문 목록
선택지
디폴트 기준표
= 품질 하한선
"제약을 먼저 만들어두면,
그 안을 채우는 일은 넘길 수 있다"
15 상태 · 계획은 JSONL
pipeline
단계 전환
features
구현 · 검증
deploys
빌드 · 스토어
append-only
지울 수 없음도 제약
모델 밖 파일에 상태를 둔다
16 기록 형식도 제약
// 실제로는 한 줄
{
  "ts": "2026-04-07T17:41:21+0900",
  "iter": "initial",
  "feature": "pushup-session",
  "phase": "implement",
  "agent": "implement-orchestrator",
  "event": "impl_status",
  "detail": { "status": "IN_PROGRESS" }
}
스킬이든 에이전트든 같은 한 줄
형식이 어긋난 기록은 상태로 세지 않음
17 실제 로그
// 표시를 위해 ts · iter · feature · phase 생략
{"event":"static_test","detail":{"tool":"pnpm lint","result":"PASS","warnings":209}}
{"event":"static_test","detail":{"tool":"mobile tsc","result":"PASS"}}
{"event":"adb_result","detail":{"build":"dev","pass":2,"fail":0}}
{"event":"error_logged","detail":{"worker":"mobile-implement","error":"MediaPipe model asset path missing"}}
{"event":"impl_status","detail":{"status":"COMPLETED"}}
이 공장에서 뽑은 앱 1개
실제 이벤트
실패까지 그대로
성공만 남기지 않음
18 /continue — 기억이 아니라 재구성
1
로그 역순 스캔
2
중단 지점 확정
3
다음 스킬 호출
불일치 처리
기록과 실제 파일 어긋남 → 파일 우선 + 보정 이벤트
세션이 끊겨도 이어붙는다
19 구조 제약 ① 보일러플레이트
이미 결정된 것
인증 라우팅 다국어 WebView 브리지 광고 상태 관리
95
mobile
22
webview
16
server
남는 판단 — "어디에 붙일까"뿐
20 구조 제약 ② 다음 단계 결정권 회수
JSONL router.py 계산 Stop hook 호출 다음 스킬 실행
MAX_STALE_REPEATS = 2

for phase in PIPELINE_PHASES:
    if phase not in completed:
        return phase
모델은 판단 안 함
다음 단계는 파이썬이 계산
지문 2회 반복
→ 정지
21 구조 제약 ③ 역할 분리
orchestrator
지시 전담
코드 수정 불가 — 문서 조항
위임
db-implement
server-implement
mobile-implement
리뷰 개선 1건씩 · 적용은 워커 위임
22 기준 제약 ① 통과 조건 먼저
RED
테스트 먼저 작성
구현 전 — 전부 FAIL
구현
GREEN
통과가 완료
워커는 통과시킬 목표를 받음
pnpm --fail-if-no-match --filter ./apps/server-e2e e2e
pnpm --fail-if-no-match --filter ./apps/mobile-e2e e2e
테스트 코드 = 완료의 정의
23 기준 제약 ② 반복 상한
3
워커당 재시도
초과 시
FAILED / BLOCKED 표기 후 중단
막힌 건 표기
나머지 시나리오는 계속 진행
끝나지 않는 루프를 숫자로 끊는다
24 기준 제약 ③ 거짓 GREEN 차단
함정
테스트 0개 실행 = 성공으로 보임
# 워크스페이스 미매칭 → 무매칭 성공(false-GREEN)
pnpm --filter ./apps/server-e2e e2e

# 미매칭이면 실패로 처리
pnpm --fail-if-no-match --filter ./apps/server-e2e e2e
한 줄이 통과 기준을 지킨다
25 검증은 별도 Agent
e2e-verify
adb-verify
webview-verify
리뷰어 2
검증자는 코드 수정 불가
읽기 전용
실패 분류 필수
Server / DB / Config
26 자기 보고를 뒤집은 로그 한 줄
기록
기기 검증 성공
실제 화면
LM:0 DET:0 ERR:0
{"event":"error_logged","detail":{"error":"JSONL reported successful ADB
verification, but resumed device smoke still showed WAIT_POSE LM:0 DET:0,
so live landmark acquisition remains unverified."}}
자기 참조 한계
외부 검증이 끊어냄
그 사실도 로그로
다음 세션이 이어받음
27 4가지 한계 → 무엇으로 넘었나
한계 구현체
상태 없음 JSONL 3파일 + /continue 재구성
계획 없음 11단계 명세 + router.py
자기 참조 검증 Agent 분리 + 지울 수 없는 기록
오류 전파 반복 상한 + BLOCKED 표기 + 레이어 분류
한계를 없앤 게 아니라 제약으로 감쌌다
28 내 업무에 걸 제약 3개
1
순서와 산출물 이름을 문서 한 장으로 고정했는가
2
그 빈칸을 Agent에게 넘길 수 있는가
3
완료 판정 주체 · 기준 · 재시도 횟수
셋 중 하나만 있어도 Agent가 다르게 움직인다
NEXT
다음 시간 —
내 업무에 제약 걸기
명세 1장 · 기록 파일 1개 · 통과 기준 1개부터
To be continued —
← 목록으로