--- kind: development title: 에이전트 출력 규약 — 사용자 대면 의사결정 제시 description: AI 에이전트(특히 ATP orchestrator)가 사용자에게 결정/선택을 요청할 때의 제시문 규약. 출력 압축(약어·ID 참조·표 과밀)의 적용 경계를 정한다. status: active created_at: 2026-06-18 source_session: 20260617-174635 --- # 에이전트 출력 규약 — 사용자 대면 의사결정 제시 재사용 규칙. AI 에이전트가 작업 중 사용자와 주고받는 출력의 스타일 경계를 정한다. ## 규칙 1 — 의사결정 제시문에는 출력 압축을 적용하지 않는다 **사용자에게 결정/선택/판정을 요청하는 제시문**(질문, `AskUserQuestion` 옵션 포함)은 항상 풀어 쓴다: 1. **배경** — 왜 묻는지, 무엇에 걸린 결정인지 2. **선택지** — 각 옵션을 ID·약어가 아닌 문장으로 3. **권장** — 있으면 이유와 함께 약어·ID 교차참조·과밀 표는 **보조로만** 병기한다. `AskUserQuestion` 팝업을 쓰더라도 옵션 라벨·설명은 **자기완결적**이어야 한다(외부 표를 봐야 이해되는 라벨 금지). 압축형(요약·약어 위주)은 사용자가 **명시 요청**("요약만", "짧게")했을 때만 쓴다. ### 압축이 허용되는 범위 출력 압축(caveman 류 토큰 다이어트 포함)은 **에이전트 간 내부 산출물·로그·요약**에 한정한다. 거기선 ROI 양수다. 사용자 대면 결정 제시에서는 파악 실패 → 재질의 왕복 비용이 압축 절감을 초과한다. ### Why 토큰을 줄이려는 압축 경향이 *사용자가 답을 줘야 하는* 의사결정 제시문으로 번지면, ID 참조·표는 작성자에겐 자명해도 사용자에겐 "무엇을 묻는지" 자체가 불투명해진다. 압축의 **적용 대상 경계**가 잘못 그어진 것이다. ### 발원 사례 W3 골자 합의 세션(`20260617-174635`)에서 orchestrator 가 W3-1 마무리 질문을 ID 약어(`C3`/`C6`/`(가)`)와 표로 과압축해 제시 → 사용자: "너무 축약적이라 W3-1에 대한 질문이 뭔질 모르겠어". 배경+선택지+권장 풀어쓰기로 전환하니 즉시 매끄럽게 답변. 첫 제시부터 풀어쓰기를 기본값으로 삼았다면 1회 왕복 비용이 없었다. > 관련(다른 레포): ATP 번들의 출력 스타일/압축 규약에 동 예외를 명문화하자는 protocol_feedback 가 세션 회고에 기록됨. 적용 *대상* 축은 다르지만 "압축 적용 경계" 교훈은 `caveman-bundle-compression-roi-ceiling`(번들 정적 압축 ROI 천장)과 같은 계열. ## 규칙 2 — 도구 호출에 넣는 비ASCII(한글 등) 텍스트는 리터럴로 작성, `\u` 수동 이스케이프 금지 `AskUserQuestion` 등 JSON 파라미터에 한글을 넣을 때 `\uXXXX` 코드포인트를 손으로 타이핑하지 않는다. 코드포인트 하나라도 오타 나면 렌더링 시 깨진 문자로 나타나고, 에이전트 자신은 도구 호출 스키마상 오류를 감지하지 못한 채 그대로 사용자에게 전달된다. 사용자에게는 "질문 자체가 뭔지 모르겠다"로 나타나 재질의 왕복이 발생한다. - 항상 실제 UTF-8 문자를 그대로 입력한다(복붙 아님, 정상 타이핑). - 결과물이 의심되면 보내기 전에 스스로 읽어 자연스러운 한글인지 확인한다. ### 발원 사례 세션 `20260701-102212` — `AskUserQuestion` 옵션 라벨/설명에 한글을 `\u` 이스케이프로 수동 작성하다 코드포인트 오타 2회 발생. 사용자: "육각 마범롘 다이었 끝점(궁벀 불망 지겁)..." 같은 깨진 텍스트를 받고 "한글이 죄다깨져서 뭐라하는지 모르겟어 다시 질문해봐"로 지적. 리터럴 문자로 재작성하자 즉시 정상 렌더링. > **재발 확인** — 세션 `20260701-142000`: 동일 실수가 다시 발생, 첫 `AskUserQuestion` 호출이 `InputValidationError`(params type mismatch)로 즉시 거부됐다(다행히 사용자에게 깨진 텍스트가 전달되기 전에 스키마 단계에서 걸림). 원인은 동일 — 질문/옵션 텍스트를 타이핑하는 과정에서 글자가 오염됨. **툴 스키마 오류로 걸리지 않는 경우도 있으므로**(오타가 유효한 JSON 문자열이면 스키마는 통과하고 사용자에게 그대로 전달됨 — 첫 발원 사례가 그 경우), 스키마 통과 여부에 의존하지 말고 발신 전 자체 검토를 실제로 수행한다. ## 규칙 4 — `AskUserQuestion` 옵션에 실린 기술적 전제는 제시 전에 grep/Read로 확인한다 옵션 문구가 "기존 리소스로 대체 가능", "이미 동일한 패턴", "네이밍이 일치" 같은 **사실 주장**을 포함할 때, 그 주장을 검증 없이 제시하면 사용자는 검증된 사실로 오인하고 선택한다. 사용자가 그 옵션을 고른 뒤 구현 착수 시점에야 grep 등으로 전제 오류가 발견되면, 이미 사용자 의사결정이 한 번 소비된 뒤라 재확인 왕복(선택 무효화 → 재질의 → 재선택)이 발생한다. 규칙 1(제시문 풀어쓰기)과는 독립된 결함이다 — 문구가 아무리 풀어써졌어도(규칙 1 충족) 그 안의 사실이 틀렸으면 재질의 왕복은 똑같이 발생한다. 절차: 1. 옵션 문구를 작성하기 전, 그 문구가 의존하는 사실 주장(공유 가능성, 네이밍 일치, 기존 구현 존재 등)을 나열한다. 2. 나열된 주장 각각을 grep/Read로 실제 확인한다 — "~일 것 같다"로 제시하지 않는다. 3. 확인이 안 되거나 시간이 없으면, 옵션 문구에서 그 주장을 빼거나 "미확인, 구현 착수 시 재검증 필요"로 명시한다. ### 발원 사례 세션 `20260701-142000` — game-register.jsp CSS 토큰 정리 범위를 묻는 `AskUserQuestion`에서 orchestrator가 "bibimbap.css 공유 변수로 전환 가능"을 grep 없이 전제로 제시(B안). 사용자가 B안을 선택했으나, 구현 착수 전 grep 확인 결과 `bibimbap.css`(`--color-*` 네이밍)가 game-register.jsp가 쓰는 변수(`--surface/--accent/--text` 등)를 대체하지 못함이 드러나 재확인 라운드가 필요했다. 구현 착수 전 단계에서 걸러져 실제 코드 오염은 없었으나, 발견 시점이 빨랐던 것은 우연이었다. ## 규칙 3 — 사용자 지적에 복수 대상 표현이 있으면 스코프를 임의로 좁히지 말고 대상 목록을 먼저 확인 이미지·스크린샷을 동반한 지적에 "각 그래프", "이것들" 처럼 복수/포괄 표현이 쓰이면, 그 중 하나(가장 먼저 눈에 띄는 요소)로 스코프를 임의 축소해 확인 질문(`AskUserQuestion` 등)을 구성하지 않는다. 확인 질문 자체에 "지적 대상이 A/B/C 중 무엇인지"를 먼저 명시하거나, 최소한 확인 질문의 배경 문장에 전체 후보를 나열해 사용자가 스코프 오판을 즉시 정정할 수 있게 한다. ### 발원 사례 세션 `20260701-102212` — 사용자가 스크린샷과 함께 "각 그래프의 끝이 어떤 점수인지 알 수 없다"고 지적(화면엔 막대 미터바 6개 + 육각 레이더 1개, 즉 "그래프"가 최소 2종류 혼재). orchestrator 가 스코프를 막대 미터바로 좁혀 시각전략 확인 질문을 구성·구현·커밋까지 마쳤으나, 사용자가 "미터바도 좋은데 내가말한건 육각 그래프였어"로 정정. 최초 확인 질문에 "미터바/레이더 둘 다 대상인지, 어느 쪽인지"를 먼저 물었다면 방향 전환 비용(재구현+재검증 사이클)을 피할 수 있었다.