당신의 프롬프트 템플릿은 도구 호출(Tool Calls)입니다: AskUserQuestion의 4개 옵션 제한이 저를 세 번이나 괴롭힌 방법
요약
Claude Code의 AskUserQuestion 도구가 가진 4개 옵션 제한으로 인해 발생하는 프롬프트 템플릿 오류와 그로 인한 실행 턴 낭비 문제를 다룹니다. 메뉴 옵션이 제한을 초과할 때 발생하는 유효성 검사 오류와 옵션이 누락되는 심각한 실패 모드를 분석합니다.
핵심 포인트
- Claude Code의 AskUserQuestion 도구는 옵션을 최대 4개로 제한함
- 프롬프트 템플릿에 5개 이상의 옵션이 포함될 경우 유효성 검사 오류 발생
- 옵션 초과 시 모델이 임의로 옵션을 삭제하여 '중단(Abort)' 기능이 사라지는 위험 존재
- 오케스트레이터 설계 시 메뉴 크기 확장에 따른 스키마 제한 고려 필요
동일한 버그가 제대로 수정하기 전까지 세 번의 별도 세션에서 저를 괴롭혔습니다. 매번 제 오케스트레이터(orchestrator)는 결정 지점에 도달하여 메뉴를 제시하려고 시도했지만, 질문 대신 유효성 검사 오류(validation error)로 인해 한 턴을 허비했습니다:
InputValidationError: {
"code": "too_big",
"maximum": 4,
...
Claude Code의 AskUserQuestion 도구는 모든 질문의 옵션을 4개로 제한합니다. 제 메뉴에는 5개가 있었습니다.
첫 번째 타격: 실행 종료 메뉴. 두 번째 타격: 차단 해제 복구(blocker-recovery) 메뉴. 세 번째 타격: 문제를 해결했다고 생각한 2주 후, 동일한 복구 메뉴에서 발생했습니다. 이 반복이 바로 이 이야기의 핵심입니다.
왜 이 문제가 계속 반복되는가
일회성 유효성 검사 오류는 블로그 포스트를 쓸 가치가 없습니다. 이 글을 쓸 가치가 있는 이유는 이 문제가 왜 재발했는가에 있습니다. 원인은 오타가 아니었습니다. 바로 템플릿(template)이었습니다.
제 Claude Code 오케스트레이터인 Suhail은 마크다운 프롬프트 파일들의 집합이며, 그 메뉴들은 해당 파일 안에 리터럴 옵션 목록(literal option lists)으로 존재합니다. 즉, 템플릿이 제시할 내용을 정확히 명시하면 모델이 이를 그대로 제시하는 구조입니다. 5개의 옵션이 하나의 AskUserQuestion 호출로 들어가면, 스키마(schema)가 이를 거부하고 모델과의 왕복(round-trip) 과정이 낭비됩니다. 제 실행 과정에서 모델은 그 후 4개의 옵션으로 재시도하여 계속 진행되었고, 이 때문에 처음 두 번은 재시도가 이루어지는 것을 해결된 것으로 간주했습니다.
복구 비용이 너무 저렴해서 이 버그는 결함이 아닌 단순한 일시적 오류(hiccup)처럼 보입니다.
하지만 결정 메뉴(decision menus)는 모든 오케스트레이터의 자연스러운 축적 지점입니다. 새로운 기능이 추가될 때마다 계속하기(continue), 커밋(commit), 건너뛰기(skip), 재시도(retry), 중단(abort), 상태 표시(show status)와 같은 슬롯을 원하게 됩니다. 메뉴는 계속해서 커집니다. 5개 옵션의 템플릿은 한 번 실패하고 끝나는 것이 아니라, 해당 지점에 도달하는 모든 실행에서 매번 한 턴씩 낭비하며 템플릿을 수정할 때까지 계속 실패합니다.
오류보다 더 나쁜 실패 모드
낭비된 턴은 양호한 버전의 실패입니다. Suhail의 공개 변경 로그(changelog)에는 더 악성인 사례가 기록되어 있습니다. 대화형 완료 핸들러(interactive complete-handler) 메뉴가 제한 범위를 초과했을 때, 오류를 발생시키는 대신 제시된 메뉴에서 마지막 옵션이 그냥 사라져 버린 것입니다. 손이 닿지 않는 곳으로 밀려나 사라진 옵션은 바로 Abort(중단)였습니다.
⚠️ [IMG:N] 형식 토큰은 이미지 placeholder 입니다. 번역하지 말고 원래 위치에 그대로 유지하세요.
Abort 옵션이 인터랙티브 완성 핸들러에서 접근 가능하게 되었습니다. 이전에 메뉴가 4개 옵션 제한을 초과하여 Abort를 손이 닿지 않는 곳으로 밀어냈지만, 이제는 메뉴가 분리되어 Abort가 항상 선택 가능합니다.
이는 Suhail's CHANGELOG v0.13.0에 나온 내용입니다. 모델이 너무 큰 메뉴를 스키마에 맞게 압축할 때, 무엇을 제거할지 결정하는데, 이때 탈출구(escape hatch)가 빠진 것입니다. 그 메뉴를 보고 있는 사용자는 실행을 중단할 방법이 없었습니다. 오류 메시지는 어디에도 나타나지 않았습니다.
스키마가 실제로 허용하는 것들
2026년 7월의 실시간 도구 스키마를 기준으로 검증한 내용입니다:
- 질문당 2개에서 4개의 옵션. 5개 이상의 옵션은 위에서 언급된
too_big오류가 발생하며, 단일 옵션도 유효하지 않습니다. 이것은 프롬프트로 우회할 수 있는 모델 동작이 아니라 스키마 검증입니다. - 호출당 최대 4개의 질문. 큰 메뉴를 하나의 호출에서 두 개의 질문으로 그룹화하는 것은 합법적이며, Suhail's 완성 핸들러 메뉴가 수정된 방식이 바로 이것입니다.
- **
- 모든 메뉴 옆에 템플릿 내부에 제한 사항을 구워 넣으세요 (Bake the cap into the template). Suhail의 완성 핸들러(complete-handler)는 이제 메뉴가 정의된 바로 그 위치에 "하나의 호출에 두 개의 질문을 클러스터링함 (질문당 4개 옵션 제한)"이라고 명시합니다. 이 주석은 메뉴와 함께 이동하므로, 제가 다음에 추가할 기능은 런타임(runtime)이 아닌 편집 시점에 이 제한 사항에 걸리게 됩니다.
- 무료로 제공되는 탈출구(escape hatch)에 슬롯을 낭비하지 마세요. "기타 (Other)" 옵션은 자동으로 제공됩니다. 모든 것을 포괄하는 옵션(catch-all options)은 템플릿에서 완전히 제외하십시오.
- 드롭 순서(drop order)를 런타임이 아닌 템플릿에서 결정하세요. 메뉴에 다섯 번째 옵션이 필요할 때, 작성자가 직접 삭제하거나 분할해야 합니다. 모델에게 이를 맡기면, 삭제되는 항목이
중단 (Abort)이 될 수도 있습니다.
메뉴는 계속 누적되기 때문에, 주석은 모든 메뉴에 있어야 합니다. 이 포스트의 사실 관계를 확인하기 위해 Suhail의 메인 브랜치를 검색(grep)해 본 결과, 이미 5개의 옵션을 가진 메뉴 두 개를 더 발견했으며, 도구가 이미 제공하고 있는 "기타 (Other)" 옵션을 추가하라고 모델에게 지시하는 명령어도 발견했습니다. 이 정리 작업은 이 포스트가 초안 상태일 때 v1.1.1로 배포되었습니다. 누적은 결코 멈추지 않습니다. 제한 사항은 메뉴가 작성되는 방식의 일부가 되어야 합니다.
핵심 요약 (The takeaway)
모델이 당신의 프롬프트 파일로부터 도구 호출(tool calls)을 생성할 때, 해당 파일에 있는 모든 정형화된 목록(canonical list)은 검증을 기다리는 도구 호출입니다. 실패의 결과는 턴(turn)을 낭비하거나, 더 나쁜 경우 중요한 옵션이 사라진 채 메뉴가 조용히 잘려 나가는 것입니다. 모델은 당신의 문서(doc)를 검증기(validator)로 직행하도록 글자 그대로 따를 것이므로, 템플릿이 공급하는 도구의 제한 사항에 맞춰 템플릿을 린트(Lint)하세요.
결국 스키마(schema)가 승리할 것입니다.
여기서 반복적으로 등장하는 메뉴는 제가 매일 프로덕션 Expo/Supabase 리포지토리에 사용하는 오케스트레이터인 Suhail의 것입니다. 도구 제한 사항은 2026년 7월 기준 Claude Code의 라이브 AskUserQuestion 스키마(v2.1.216) 및 문서를 통해 확인되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기