
도해로 해설! Claude Certified Architect (CCAR-F) 시험 가이드
요약
Claude Certified Architect (CCA-F) 시험 범위를 바탕으로 Claude API를 활용한 에이전트 구현 핵심 원리를 설명합니다. 특히 에이전트 루프(Agentic Loop)의 작동 방식과 stop_reason에 따른 제어 흐름을 상세히 다룹니다.
핵심 포인트
- 에이전트 루프는 Claude가 도구 실행 결과를 바탕으로 다음 행동을 자율적으로 추론하는 메커니즘임
- 도구 실행 결과는 반드시 대화 기록(Conversation History)에 추가되어 컨텍스트로 활용되어야 함
- stop_reason이 'tool_use'인 경우 루프를 지속하고, 'end_turn'인 경우 루프를 종료함
- max_tokens, refusal 등 다양한 stop_reason에 따른 적절한 예외 처리가 필요함
Claude Certified Architect – Foundations (CCA-F)의 시험 범위에 대해, 필자가 개인적인 학습의 일환으로 이해를 정리하고 공유하는 것을 목적으로 집필한 것입니다.
기재된 내용은 공개된 시험 가이드 (Version 0.2 Last Updated: June 30 2026) 및 공식 문서를 참고하여, 필자 자신의 해석과 경험을 섞어 해설한 것입니다. 따라서 시험의 출제 내용이나 Anthropic의 공식 견해를 보증하는 것은 아닙니다.
인증 시험을 응시하시는 분은 반드시 최신 공식 문서와 시험 가이드를 확인해 주시기 바랍니다. 또한, 본 기사에 오류나 개선점 등이 있다면 댓글 등으로 지적해 주시면 감사하겠습니다.
【보충】 평소에는 OpenAI API (GPT)를 사용한 서비스 개발을 하고 있으며, Claude는 Cowork를 검증용으로 조금 다뤄본 정도이지만, 이 학습용 메모를 몇 번이고 반복해서 복습하고, 이와 함께 Anthropic의 공식 Exam Guide 영문도 반복해서 숙독함으로써 (영어가 서툰 필자임에도) 무사히 단번에 합격(800점대 초반)할 수 있었습니다.
Claude API를 이용하여 에이전트를 구현할 경우, 가장 중요한 사고방식 중 하나가 Agentic Loop (에이전트 루프) 입니다.
Agentic Loop란, Claude가 상황에 따라 도구(Tool)를 호출하고, 그 실행 결과를 바탕으로 다음 행동을 자율적으로 판단하며 태스크를 진행하는 메커니즘입니다. 기존의 '정해진 순서대로 도구를 실행하는 워크플로우'와 달리, Claude 스스로가 다음에 무엇을 해야 할지를 추론한다는 점이 큰 특징입니다.
Agentic Loop는 다음 흐름으로 반복 실행됩니다.
포인트는 Tool의 실행 결과를 Conversation History (대화 기록)에 추가한 뒤, Claude에게 다시 요청을 보내는 것입니다. Claude는 대화 기록 전체를 컨텍스트 (Context)로 하여 추론하기 때문에, 새로 얻은 Tool의 실행 결과를 대화 기록에 추가하지 않으면 다음 판단에 이용할 수 없습니다.
Agentic Loop의 종료 조건은 Claude가 반환하는 stop_reason만으로 판단합니다.
| stop_reason | 의미 | 다음 처리 |
|---|---|---|
| tool_use | Tool 실행이 필요 | Tool을 실행하고, 결과를 Conversation History에 추가하여 루프 지속 |
| end_turn | Claude의 처리가 완료 | 루프를 종료하고 사용자에게 답변을 반환 |
즉, stop_reason == "tool_use"라면 루프를 계속하고, stop_reason == "end_turn"이라면 종료합니다.
그 외에 stop_reason에는 다음과 같은 5가지 종류가 있습니다.
| stop_reason | 의미 | 대응 |
|---|---|---|
| max_tokens | 지정한 max_tokens에 도달함 | max_tokens를 늘리거나 다음 내용을 생성함 |
| stop_sequence | 지정한 stop_sequences와 일치 | 정지한 시퀀스를 확인함 |
| pause_turn | 서버 도구 (Web 검색 등)의 반복 상한에 도달함 | Assistant 응답을 그대로 다시 보내 다음 내용을 실행함 |
| refusal | Claude가 안전상의 이유 등으로 응답을 거부 | stop_details를 확인하고 필요 시 폴백 (Fallback) 수행 |
| model_context_window_exceeded | 모델의 컨텍스트 윈도우 (Context Window) 상한에 도달함 | 컨텍스트를 축소 또는 요약하여 재실행 |
예를 들어, 사용자가 "오늘의 도쿄 날씨를 알려줘"라고 질문하고 Claude가 Weather Tool을 호출했을 때의 실행 결과가,
{
"temperature": 31,
"condition": "Sunny"
}
였다면, 이 결과를 Conversation History에 추가한 뒤 다시 Claude에게 전달하면, Claude는 "도쿄는 현재 31℃이며 맑습니다."라고 자연스러운 문장을 생성할 수 있습니다. 만약 Tool의 실행 결과를 Conversation History에 추가하지 않으면, Claude는 Tool의 결과를 알지 못하기 때문에 적절한 답변을 생성할 수 없습니다.
Agentic Loop의 특징은 Claude 스스로가 다음 행동을 판단한다는 것입니다.
예를 들어,
주소 취득
↓
우편번호 취득
↓
배송일 계산
이러한 순서는 프로그램 측에서 고정하는 것이 아닙니다.
Claude가,
- 필요한 Tool
- 호출 순서
- 필요하다면 추가적인 Tool
을 상황에 따라 결정합니다. 즉, 개발자는 "루프 (Loop)"를 구현하고, Claude는 "의사결정 (Decision Making)"을 담당합니다.
Agentic Loop에서는 루프 종료 판단을 stop_reason 이외에 의존해서는 안 됩니다.
| 안티패턴 (Anti-pattern) | 문제점 | 권장 방법 |
|---|---|---|
| "I've completed the task" 등 자연어를 해석하여 종료 판정함 | 모델의 표현은 매번 달라지므로 오판정할 가능성이 있음 | stop_reason을 이용함 |
| Assistant의 답변 내용을 보고 종료를 판단함 | Tool 호출 전에 완료된 듯한 문장을 반환하는 경우가 있음 | stop_reason을 이용함 |
| 최대 루프 횟수를 주요 종료 조건으로 설정함 | 정상적인 처리 중에도 중간에 종료될 수 있음 | stop_reason을 이용하고, 최대 횟수는 안전장치로만 이용함 |
| 미리 Tool의 실행 순서를 고정함 | Claude의 추론 능력을 활용할 수 없음 | Claude에게 Tool 선택을 맡김 |
포인트는 다음과 같습니다.
- Agentic Loop는 Claude → Tool → Claude를 반복하는 제어 구조이다.
- 루프의 지속 및 종료는
stop_reason만으로 판단한다. - Tool의 실행 결과는 **Conversation History (대화 기록)**에 추가한 후, Claude에게 다시 전달한다. Claude는 대화 기록 전체를 이용하여 다음 행동을 추론한다.
- 개발자는 루프 제어를 구현하고, Claude는 다음에 실행해야 할 Tool을 자율적으로 판단한다.
- 자연어 해석이나 고정적인 종료 조건에 의존하는 구현은 안티패턴이다.
Agentic Loop를 올바르게 구현함으로써, Claude는 Tool의 실행 결과에 기반하여 자율적으로 추론을 지속하며, 유연하고 확장성이 높은 AI 에이전트 (Agent)를 실현할 수 있습니다.
대규모 조사나 복잡한 태스크에서는 하나의 에이전트가 모든 것을 처리하는 것보다, 여러 에이전트가 역할을 분담하는 것이 더 효율적입니다. Claude Code나 Agent SDK에서는 이러한 구성을 Coordinator-Subagent Pattern (코디네이터-서브에이전트 패턴)이라고 부릅니다.
멀티 에이전트 (Multi-agent) 환경에서는 Coordinator (코디네이터)가 중심이 되어 모든 서브에이전트를 관리합니다.
중요한 점은 서브에이전트끼리는 직접 통신하지 않는다는 것입니다. 모든 통신은 Coordinator를 경유합니다. Coordinator는 다음을 담당합니다.
- 태스크 분해
- 에이전트 선택
- 결과 집약
- 에러 핸들링 (Error Handling)
- 정보 라우팅 (Information Routing)
서브에이전트는 Coordinator의 Conversation History를 자동으로 승계하지 않습니다. 즉, 각 서브에이전트는 독립된 컨텍스트 (Isolated Context)에서 실행됩니다.
따라서 Coordinator는 필요한 정보만 서브에이전트에게 전달하고, 돌아온 결과를 다시 통합하는 역할을 가집니다.
훌륭한 Coordinator는 매번 모든 서브에이전트를 호출하지 않습니다. 예를 들어,
"도쿄의 AI 활용 사례를 조사해 주세요"
라는 요청이라면,
- Search Agent
- Summarization Agent
만으로도 충분할 수 있습니다. 반면,
"이 Python 코드의 설계를 개선해 주세요"
라면,
- Code Agent
하나만 기동해도 충분합니다. 즉, Coordinator는 질의 내용을 분석하여 필요한 서브에이전트만을 동적으로 선택합니다.
여러 개의 Search Agent를 이용하는 경우라도, 모두에게 "OpenAI에 대해 조사해 주세요"라고 요청하면 거의 동일한 결과가 나옵니다. 좋은 설계에서는 역할을 나눕니다.
| Agent | 담당 |
|---|---|
| Search Agent A | 공식 문서 |
| ... |
이와 같이 함으로써 중복을 줄이고 망라성 (Comprehensiveness)을 높일 수 있습니다.
Coordinator는 서브에이전트의 결과를 정리하는 것으로 끝내지 않습니다. 결과를 평가하고, 부족한 정보가 있다면 추가 조사를 지시합니다.
이러한 반복 개선 루프를 통해 더욱 품질 높은 답변을 얻을 수 있습니다.
모든 커뮤니케이션을 Coordinator를 경유함으로써 다음과 같은 이점이 있습니다.
| 이점 | 내용 |
|---|---|
| 가관측성 (Observability) | 모든 커뮤니케이션 이력을 추적할 수 있음 |
| ... | ... |
Coordinator는 태스크를 너무 세밀하게 분할해서도 안 됩니다. 예를 들어,
AI 시장에 대해 조사
를,
- OpenAI
- Anthropic
- Microsoft
- NVIDIA
- AWS
- Azure
…
와 같이 너무 잘게 나누면 시장 전체를 조망하는 능력을 잃고 중요한 정보를 놓칠 가능성이 있습니다. 태스크 분해는 포괄성과 효율성 사이의 균형이 중요합니다.
포인트는 다음과 같습니다.
- Coordinator가 Hub가 되는 Hub-and-Spoke 아키텍처를 채택한다
- 서브 에이전트 (Sub-agent)는 독립된 컨텍스트에서 동작하며, 대화 이력 (Conversation History)은 자동으로 공유되지 않는다
- Coordinator는 질의 내용을 분석하여 필요한 서브 에이전트만 동적으로 기동한다
- 조사 범위를 적절히 분담하여 중복을 최소화한다
- Coordinator는 결과를 통합할 뿐만 아니라, 부족한 정보를 평가하고 필요에 따라 반복 개선 루프를 실행한다
- 모든 통신을 Coordinator를 경유함으로써 가관측성, 에러 핸들링 (Error handling), 정보 관리, 제어성을 실현할 수 있다
Coordinator-Subagent 패턴은 Claude Code나 Agent SDK에서의 대표적인 멀티 에이전트 구성입니다. Coordinator가 전체를 제어하고 각 서브 에이전트가 전문 분야에 집중함으로써, 고품질이며 확장성이 높은 AI 에이전트 시스템을 구축할 수 있습니다.
전 장 1.2에서는 Coordinator와 SubAgent에 의한 멀티 에이전트 구성에 대해 설명했습니다. 본 장에서는 실제로 서브 에이전트를 어떻게 기동하고 필요한 정보를 전달하는지에 대해 설명합니다.
Claude Code나 Agent SDK를 이용하는 데 있어 가장 중요한 노하우 중 하나입니다.
Claude Code에서는 서브 에이전트가 Task Tool에 의해 생성 (Spawn)됩니다. 또한, Coordinator가 서브 에이전트를 기동하려면 allowedTools에 Task를 포함해야 합니다.
Task Tool을 이용할 수 없다면 Coordinator는 SubAgent를 기동할 수 없습니다.
각 서브 에이전트는 AgentDefinition에 의해 정의됩니다. 대표적인 설정 항목은 다음과 같습니다.
| 항목 | 설명 |
|---|---|
| Description | 에이전트의 역할 |
| ... | ... |
예를 들어, Search Agent는,
AgentDefinition
Description:
Search official documentation
...
Analysis Agent는,
AgentDefinition
Description:
Analyze collected documents
...
와 같이 역할마다 설정을 나눕니다.
중요한 점은 서브 에이전트가 Coordinator의 대화 이력 (Conversation History)을 자동으로 공유하지 않는다는 점입니다.
필요한 정보는 매번 프롬프트 (Prompt)에 포함하여 전달해야 합니다.
예를 들어, Search Agent가
- 웹 검색
- PDF 분석
을 실시했다고 가정해 봅시다.
그 결과를 Coordinator가 Synthesis Agent에게 전달합니다.
이때 단순히 "요약해 주세요"가 아니라, 검색 결과나 분석 결과를 그대로 프롬프트에 포함하는 것이 권장됩니다.
에이전트 간에 정보를 전달할 때는 문장만 전달하는 것이 아니라 구조화된 데이터 (Structured data)를 이용합니다.
예:
{
"content":
"Claude Code supports Task Tool.",
...
이렇게 함으로써,
- 출처
- URL
- 페이지 번호
등의 속성 정보 (Attribution)를 유지할 수 있습니다.
Coordinator는 여러 턴에 걸쳐 태스크 (Task)를 실행하는 것이 아니라, 1회의 응답으로 여러 개의 Task Tool을 반환합니다.
이를 통해 병렬 실행이 가능해져 처리 시간을 단축할 수 있습니다.
나쁜 예로서,
① 검색해 주세요
② 분석해 주세요
③ 요약해 주세요
와 같이, 단계를 너무 세세하게 작성하는 것입니다.
반면 좋은 예는,
목적:
OpenAI API의 최신 사양을 정리해 주세요.
품질 기준:
・공식 정보 우선
・중복 제거
・출처 유지
・중요한 변경 사항 추출
과 같이, 조사 목표와 품질 기준(Quality Criteria)만 지정하는 것입니다. 이렇게 하면 서브 에이전트(Sub-agent)가 상황에 따라 최적의 방법을 판단할 수 있습니다.
Fork는 현재의 분석 결과를 기준으로 다른 접근 방식을 시도하는 메커니즘입니다.
flowchart TD
Base[Current Analysis]
Base --> A[Approach A]
Base --> B[Approach B]
Base --> C[Approach C]
예를 들어, 어떤 설계에 대해,
- 성능 중시
- 유지보수성 중시
- 보안 중시
라는 세 가지 방향성을 동일한 분석 결과로부터 병렬로 검토할 수 있습니다. Fork를 통해 원래의 세션을 해치지 않고 여러 안을 비교할 수 있습니다.
포인트는 다음과 같습니다.
- 서브 에이전트는 Task Tool에 의해 기동됨
- Coordinator가 서브 에이전트를 기동하려면
allowedTools에 Task가 필요함 - AgentDefinition에는 Description·System Prompt·allowedTools를 정의함
- 서브 에이전트는 부모 에이전트의 대화 기록(Conversation History)을 공유하지 않으므로, 필요한 정보는 매번 프롬프트에 명시적으로 전달해야 함
- 에이전트(Agent) 간에는 구조화된 데이터(Structured Data)를 이용하며, 콘텐츠와 메타데이터(URL·문서명·페이지 번호 등)를 분리함으로써 출처 정보를 유지할 수 있음
- Coordinator는 한 번의 응답으로 여러 개의 Task Tool을 반환하여 서브 에이전트를 병렬로 기동함
- Coordinator는 세세한 절차가 아니라 조사 목표와 품질 기준을 지시함으로써 서브 에이전트의 자율성을 활용할 수 있음
- Fork 기반의 세션 관리를 이용함으로써 동일한 분석 결과로부터 여러 접근 방식을 안전하게 비교·검토할 수 있음
Task Tool, AgentDefinition, Context Passing는 Claude Code의 멀티 에이전트 설계의 핵심이 되는 개념입니다. 이것들을 올바르게 이해함으로써 유연하고 확장성이 높은 멀티 에이전트 시스템을 구축할 수 있습니다.
AI 에이전트는 유연하게 추론할 수 있지만, "반드시 지켜야 하는 절차"까지 LLM의 판단에 맡겨서는 안 됩니다.
예를 들어,
- 본인 확인이 끝나기 전에 환불해서는 안 됨
- 권한 확인 전에 개인 정보를 표시해서는 안 됨
- 승인 전에 송금해서는 안 됨
이러한 처리는 프로그램 측에서 반드시 보장(Enforcement)해야 합니다.
본 장에서는 멀티 스텝 워크플로우(Multi-step Workflow)에서의 Enforcement와 Human Handoff 설계에 대해 설명합니다.
LLM에게 "본인 확인을 수행한 후 환불해 주세요"라고 지시할 수는 있습니다. 하지만 LLM은 확률적으로 동작하기 때문에, 프롬프트만으로는 실패할 가능성을 제로로 만들 수 없습니다. 반면, 프로그래밍적 강제(Programmatic Enforcement)를 통해서는 애플리케이션 측에서 반드시 조건을 충족하는지 확인합니다.
중요한 것은 워크플로우의 제어는 프로그램이 담당하고, Claude는 추론을 담당한다는 역할 분담입니다.
예를 들어, 환불 처리에서,
get_customer
↓
본인 확인
↓
process_refund
라는 순서를 지켜야 한다고 가정해 봅시다. 이를 Claude의 판단에만 맡기는 것이 아니라, 프로그램 측에서 제어합니다.
예를 들어,
customer = get_customer()
if not customer.verified:
raise PermissionError()
...
와 같이, 후속 처리를 실행하기 전에 반드시 전제 조건을 확인합니다. 이러한 메커니즘을 선결 게이트(Prerequisite Gate)라고 부릅니다.
사용자로부터 "주문이 도착하지 않았고 청구 금액도 이상하니 환불해 주세요"라는 문의가 왔다고 가정해 봅시다. 이는,
- 배송 상황(Shipping)
- 청구 내용(Billing)
- 환불 조건(Refund)
이라는 여러 문제를 포함하고 있습니다. Coordinator는 이것들을 개별적으로 조사합니다.
각각을 병렬로 조사한 후에, Coordinator가 통합된 답변을 작성합니다.
모든 문제를 LLM이 해결할 수 있는 것은 아닙니다. 예를 들어,
- 법적 판단
- 특별 환불
- 클레임 대응
등은 사람에게 인계해야 합니다. 이때 담당자는 LLM의 대화 이력을 볼 수 없는 경우도 있습니다. 따라서 LLM은 구조화된 인계 정보 (Structured Handoff Information)를 작성합니다.
인계 내용에는 다음과 같은 정보를 포함합니다.
| 항목 | 내용 |
|---|---|
| Customer ID | 고객 ID |
| ... | ... |
{
"customer_id": "12345",
"root_cause": "Duplicate charge",
...
이와 같이 구조화된 데이터로 만듦으로써, 인간 담당자는 대화 이력을 보지 않고도 상황을 이해할 수 있습니다.
자연어만으로는 중요한 정보가 누락되거나 담당자에 따라 해석이 달라질 가능성도 있습니다. 반면, 구조화된 데이터라면,
- 필요 항목의 누락 방지
- 시스템 간 연계
- 티켓 시스템(Ticket System) 등록
- CRM과의 연계
등이 용이해집니다. 따라서 Human Handoff에서는 구조화된 데이터 형식이 권장됩니다.
포인트는 다음과 같습니다.
- Prompt를 통한 지시만으로는 반드시 지켜야 할 처리 순서를 보장할 수 없음
- 사람 확인이나 권한 확인 등의 전제 조건은 Programmatic Enforcement (프로그램에 의한 강제 실행)로 보장함
- Prerequisite Gate를 통해 전제 조건을 충족할 때까지 후속 처리를 실행하지 않음
- 여러 문의는 개별적으로 분해하고, 공유 컨텍스트 (Shared Context)를 이용해 병렬로 조사한 후, Coordinator가 통합함
- 사람에게 에스컬레이션 (Escalation)할 때는 Customer ID, Root Cause, Refund Amount, Recommended Action 등을 포함하는 구조화된 Handoff Summary를 작성함
AI 에이전트의 유연한 추론 능력은 매우 강력하지만, 금융·의료·행정 등 높은 신뢰성이 요구되는 시스템에서는 'LLM에 맡기는 부분'과 '프로그램으로 반드시 보장하는 부분'을 적절히 분리하는 것이 안전하고 신뢰성 높은 워크플로우 설계의 핵심입니다.
AI 에이전트에서는 Claude가 Tool을 선택하여 외부 시스템으로부터 정보를 가져오거나 업무 처리를 실행합니다. 하지만 실무에서는 다음과 같은 제어가 필요합니다.
- 500달러를 초과하는 환불을 자동으로 실행하지 않음
- 서로 다른 MCP Tool로부터 반환되는 일시 형식(Datetime Format)을 통일함
- 수치 형태의 상태 코드(Status Code)를 의미를 알 수 있는 문자열로 변환함
- Tool의 실행 결과에서 불필요한 정보나 기밀 정보를 제거함
이러한 처리를 실현하는 메커니즘이 Hooks입니다. Claude Code의 Hooks는 Claude Code의 라이프사이클 상 특정 타이밍에 자동으로 실행되는 사용자 정의 명령이나 HTTP 엔드포인트 등입니다. LLM이 자율적으로 규칙을 지키는 것에 의존하지 않고, 정해진 처리를 확실하게 실행하기 위해 이용할 수 있습니다.
Hook은 Claude Code의 처리 도중에 개입하여 Tool의 입력이나 출력을 검사·변환하는 메커니즘입니다. 특히 중요한 것은 다음 두 종류입니다.
| Hook | 실행 타이밍 | 주요 용도 |
|---|---|---|
PreToolUse | Tool이 실행되기 전 | Tool 호출의 허가·거부·입력 변경 |
PostToolUse | Tool이 정상 종료된 직후 | Tool 실행 결과의 검사·변환·정규화 |
Exam Guide에 있는 tool call interception hooks는 Claude Code에서는 주로 PreToolUse에 해당합니다.
PreToolUse는 Claude가 Tool의 인자(Argument)를 생성한 후, 실제로 Tool이 실행되기 전에 호출됩니다. Tool의 이름이나 입력값을 검사하여 다음과 같은 처리를 실시할 수 있습니다.
- 허가함
- 거부함
- 사용자에게 확인을 요청함
- Tool의 입력값을 변경함
- 비대화형 모드(Non-interactive mode)에서 Tool 호출을 일시 보류함
공식 레퍼런스에서는 PreToolUse가 Tool 실행 전에 호출되며, allow, deny, ask, defer 등의 판단을 반환할 수 있다고 설명합니다.
PreToolUse는 실행 전에 처리를 중단할 수 있기 때문에 환불, 송금, 데이터 삭제 등 실행 후에 취소하기 어려운 처리의 제어에 적합합니다.
예를 들어, Claude가 다음 Tool을 호출하는 시스템을 생각해 봅시다.
{
"tool_name": "mcp__billing__process_refund",
"tool_input": {
...
여기서 업무 규칙이 다음과 같이 정의되어 있다고 가정해 봅시다.
500달러를 초과하는 환불은 AI 에이전트가 자동으로 실행하지 않고, 인간 담당자에게 인계한다.
이 규칙은 프롬프트만으로 지시하는 것이 아니라, PreToolUse Hook을 통해 강제합니다.
{
"hooks": {
"PreToolUse": [
...
여기서 matcher는 어떤 Tool에 대해 Hook을 실행할지 범위를 좁히기 위해 사용합니다.
Claude Code의 Hook은 사용자 설정인 ~/.claude/settings.json, 프로젝트 설정인 .claude/settings.json, 로컬 설정인 .claude/settings.local.json 등에 정의할 수 있습니다. 설정된 Hooks는 /hooks 명령어로 확인할 수 있습니다.
#!/usr/bin/env python3
import json
import sys
...
PreToolUse의 구조화된 판단은 hookSpecificOutput 내의 permissionDecision으로 반환됩니다. 현재 공식 형식에서는 allow, deny, ask, defer가 사용되며, 이전의 최상위 레벨(top-level)이었던 decision과 reason은 PreToolUse에서 권장되지 않습니다 (deprecated).
단순히 Tool을 거부하는 것만으로는 사용자의 문제가 해결되지 않습니다. 환불을 차단한 후에는 Claude가 예를 들어 다음과 같은 행동을 취하도록 합니다.
- 환불 Tool 실행을 거부한다
- 거부 이유를 Claude에게 전달한다
- 사람에게 인계할 정보를 작성한다
- Handoff Tool이나 티켓 생성 Tool을 호출한다
이 설계 예시에서는 Hook이 업무 규칙을 강제하고, Claude가 대안을 판단합니다. 즉, 역할 분담은 다음과 같습니다.
| 담당 | 역할 |
|---|---|
| Hook | 500달러 초과 환불을 확실히 차단한다 |
| ... |
PostToolUse는 Tool이 정상적으로 종료된 직후에 호출됩니다. Hook에는 다음과 같은 정보가 전달됩니다.
tool_nametool_inputtool_responsetool_use_id- 세션 정보
공식 레퍼런스에서는 PostToolUse의 입력에 Tool로 전달된 인자인 tool_input과 Tool이 반환한 결과인 tool_response가 모두 포함된다고 설명합니다.
중요한 점은 Claude가 Tool 결과를 추론에 사용하기 전에 데이터 형식을 통일할 수 있다는 것입니다.
여러 개의 MCP Tool을 이용하면 동일한 의미의 데이터라도 형식이 다를 수 있습니다. 예를 들어, 주문 일시가 다음과 같이 반환될 수 있습니다.
● Tool A
{
"created_at": 1784341800
}
● Tool B
{
"created_at": "2026-07-18T10:30:00+09:00"
}
● Tool C
{
"created_date": "2026/07/18 10:30:00"
}
또한, 상태(status) 값도 Tool에 따라 다를 수 있습니다.
{
"status": 2
}
{
"status": "completed"
}
이 상태 그대로 Claude에게 전달하면 매번 다른 형식을 해석해야 합니다. PostToolUse Hook을 사용하면 예를 들어 다음과 같은 형식으로 통일할 수 있습니다.
{
"created_at": "2026-07-18T10:30:00+09:00",
"status": "completed"
}
{
"hooks": {
"PostToolUse": [
...
#!/usr/bin/env python3
import json
import sys
...
PostToolUse에서는 updatedToolOutput
를 반환함으로써, Claude가 받는 Tool 결과를 교체할 수 있습니다. 단, Tool은 이미 실행된 상태이며, 교체되는 것은 Claude에게 보이는 결과뿐입니다. 파일 쓰기, 명령 실행, 네트워크 전송 등의 부작용(Side effect)을 취소할 수는 없습니다.
PostToolUse에서는 Tool 결과에 대한 보충 정보를 Claude에게 전달하는 여러 가지 방법이 있습니다.
| 출력 | 용도 |
|---|---|
additionalContext | 원래의 Tool 결과는 남겨두고, 보충 설명을 추가함 |
updatedToolOutput | Claude가 받는 Tool 결과 그 자체를 교체함 |
decision: "block" | Tool 실행 후에 문제점을 Claude에게 전달함 |
데이터 형식의 정규화(Normalization)에는 기본적으로 updatedToolOutput이 적합합니다.
반면, "이 상태값은 잠정적인 값이며, 확정된 정보가 아니다"와 같은 주의 사항을 추가하는 것뿐이라면 additionalContext가 적합합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기