CCAR-F · CHAPTER 01 · D1 AGENTIC ARCHITECTURE & ORCHESTRATION · 27%
스스로 판단하는 에이전트의 뼈대 — 루프·조율·세션 설계
이 도메인은 CCAR-F 전체 배점의 27%를 차지하는 가장 큰 축입니다. 에이전트가 한 번의 응답으로 끝나지 않고 도구를 쓰며 판단을 이어가는 반복 구조, 그리고 여러 에이전트를 코디네이터가 조율하는 설계가 여기에 담깁니다. 설계자가 이 뼈대를 정확히 이해하지 못하면 이후 도메인의 거의 모든 결정이 흔들립니다.
1.1 에이전틱 루프의 생명주기 (agentic loop lifecycle)
에이전트는 한 번의 응답으로 끝나지 않고, 모델과 실행 환경이 번갈아 오가는 반복 구조로 돌아갑니다. 설계자는 매 반복마다 모델 응답의 stop_reason(중단 사유) 값을 확인합니다. 값이 tool_use(도구 호출 요청)이면 모델이 요청한 도구를 실제로 실행하고, 그 결과를 대화 이력(conversation history, 지금까지 오간 메시지 묶음)의 뒤에 이어 붙여 다음 요청으로 모델에 되돌립니다. 값이 end_turn(발화 종료)이면 모델이 스스로 할 일을 마쳤다는 뜻이므로 루프를 끝냅니다. 실행 결과가 다시 문맥으로 들어가야, 모델이 방금 무슨 일이 일어났는지 알고 그다음 행동을 고를 수 있습니다.
실무 예시
고객지원 에이전트를 설계하는 테크리드가 '주문 조회 → 환불 가능 여부 판단 → 환불 실행'을 하나의 루프로 엮습니다. 모델이 첫 응답에서 주문 조회 도구를 tool_use로 요청하면, 조회 결과를 이력에 붙여 다시 넘기고, 모델은 그 결과를 보고 환불 도구를 부를지 담당자에게 넘길지를 다음 반복에서 판단합니다.
1.2 종료는 모델이 정한다 — 결정 트리가 아니라 (model-driven control)
에이전트 제어의 핵심 원칙은 다음 행동과 종료 시점을 모델이 정하게 두는 것입니다. 과거 자동화처럼 설계자가 미리 그린 결정 트리(decision tree, 조건 분기를 고정한 흐름도)에 가두면, 예상 못 한 상황에서 에이전트가 굳어 버립니다. 특히 두 안티패턴을 피해야 합니다. 하나는 모델이 내놓은 자연어 문장('완료했습니다' 같은)을 파싱해 종료를 판단하는 것 — 표현이 조금만 달라져도 무너집니다. 다른 하나는 '반복 5회를 넘으면 무조건 멈춤' 같은 임의의 횟수 상한으로 종료를 거는 것입니다. 종료의 단일 근거는 언제나 구조화된 stop_reason 값이어야 합니다. 횟수 상한은 폭주를 막는 안전장치일 뿐, 정상 종료의 기준이 될 수 없습니다.
실무 예시
코드리뷰 자동화 에이전트를 만드는 아키텍트가 처음엔 '리뷰 끝'이라는 문장이 나오면 멈추도록 짰다가, 모델이 '리뷰를 마무리하겠습니다'라고 답하는 순간 종료를 놓칩니다. stop_reason이 end_turn인지를 보도록 고치면, 표현이 어떻게 바뀌어도 정확한 지점에서 끝납니다.
1.3 코디네이터와 서브에이전트 — 허브 앤 스포크 조율 (coordinator orchestration)
규모가 커지면 한 에이전트가 모든 일을 감당하기 어렵습니다. 이때 코디네이터(coordinator, 조율자) 하나가 중심에 서고 여러 서브에이전트(subagent, 하위 에이전트)가 바퀴살처럼 붙는 허브 앤 스포크(hub-and-spoke) 구조를 씁니다. 코디네이터의 책임은 작업을 잘게 나누고, 각 조각을 알맞은 서브에이전트에 맡기고, 돌아온 결과를 하나로 합치는 것입니다. 어떤 서브에이전트를 부를지는 상황을 보고 그때그때 고릅니다. 핵심 전제는 서브에이전트가 격리된 문맥(isolated context)에서 작동하며 부모의 대화 이력을 자동으로 물려받지 않는다는 점입니다 — 필요한 정보는 코디네이터가 명시적으로 건네야 합니다. 반대로 작업을 지나치게 좁게 쪼개면 서브에이전트가 맥락을 잃고 합치는 비용만 늘어납니다.
실무 예시
멀티에이전트 리서치 플랫폼을 설계하는 아키텍트가 코디네이터에게 '시장 조사'를 맡기면, 코디네이터가 이를 경쟁사·규제·가격 조사로 나눠 서브에이전트 셋에 각각 위임하고 세 보고를 하나의 요약으로 합칩니다. 각 서브에이전트는 자기 몫의 문맥만 받으므로, 코디네이터가 조사 범위와 기준을 처음에 분명히 넘겨야 합니다.
1.4 서브에이전트를 실제로 띄우는 법 — Task 도구와 AgentDefinition
서브에이전트는 개념만으로 뜨지 않습니다. 코디네이터가 서브에이전트를 띄우려면 Task 도구(Task tool)를 호출해야 하고, 그러려면 코디네이터의 허용 도구 목록(allowedTools)에 Task가 반드시 들어 있어야 합니다 — 없으면 위임 자체가 불가능합니다. 서브에이전트의 성격은 AgentDefinition이라는 설정 묶음으로 정의하는데, 여기에 그 에이전트의 역할, 쓸 수 있는 도구, 지시문을 담습니다. 앞서 말했듯 문맥은 상속되지 않으므로, 서브에이전트가 일할 때 필요한 배경은 호출하는 쪽에서 명시적으로 넘깁니다. 성능이 중요하면 한 번의 응답에서 여러 서브에이전트를 동시에 띄워 병렬로 진행할 수 있고, 갈래를 나눠야 할 때는 세션을 분기(fork)해 각자의 흐름으로 이어갑니다.
실무 예시
고객지원 플랫폼의 아키텍트가 주문·배송·환불 세 도메인을 각각 다루는 서브에이전트를 AgentDefinition으로 정의해 두고, 문의가 들어오면 코디네이터가 한 응답에서 관련 서브에이전트만 골라 병렬로 띄웁니다. 이때 코디네이터의 allowedTools에 Task가 빠져 있으면 위임이 겉으로 드러나지 않은 채 실패하므로, 설계 단계에서 먼저 확인해야 합니다.
1.5 지시가 아니라 강제 — 훅과 사전 관문 (programmatic enforcement)
프롬프트로 '신원을 먼저 확인하라'고 지시하는 것과, 시스템이 그것을 강제하는 것은 다릅니다. 모델의 지시 따르기는 확률적이라, 규정 준수가 반드시 지켜져야 하는 지점에는 지시가 아니라 결정론적 강제가 필요합니다. 이때 쓰는 장치가 훅(hook, 특정 시점에 자동으로 끼어드는 코드)과 사전 관문(prerequisite gate)입니다. 가령 환불·송금 같은 금융 작업을 실행하기 전에 신원 확인이 끝났는지를 관문에서 검사해, 통과하지 못하면 도구 실행 자체를 막습니다. Agent SDK의 훅은 도구 호출을 가로채(PostToolUse) 결과 형식을 표준으로 다듬거나 규정 위반을 걸러내는 데도 쓰입니다. 에이전트가 감당하기 어려운 상황은 사람에게 넘기되, 고객 정보·근본 원인·권장 조치를 정해진 형식으로 함께 전하는 구조화된 인계(handoff)를 설계해 둡니다.
실무 예시
환불 에이전트를 설계하는 테크리드가 '금액이 크면 본인 확인을 하라'를 프롬프트에만 적어 두면, 모델이 급한 맥락에서 이 단계를 건너뛸 수 있습니다. 대신 환불 실행 도구 앞에 신원 확인 완료를 요구하는 관문을 두면, 확인이 없는 한 도구가 실행되지 않습니다. 확인이 어려운 분쟁 건은 원인과 권장 조치를 정리해 상담 담당자에게 구조화된 형식으로 인계합니다.
1.6 고정 파이프라인과 적응형 분해, 그리고 세션 관리
작업을 나누는 방식에는 두 갈래가 있습니다. 순서가 늘 같은 일은 고정된 파이프라인, 곧 프롬프트 체이닝(prompt chaining, 앞 단계 출력이 다음 단계 입력이 되는 사슬)으로 단순하게 엮습니다. 반대로 무엇을 할지가 입력에 따라 달라지는 일은 상황을 보며 분해를 바꾸는 적응형(dynamic) 방식이 맞습니다. 둘을 혼동하면 유연해야 할 일을 굳은 사슬에 가두거나, 단순한 일을 과하게 복잡하게 만듭니다. 세션 관리도 설계 대상입니다. 이름 붙인 세션은 나중에 --resume으로 이어서 재개할 수 있고, 흐름을 갈래로 나눠야 하면 fork_session으로 분기합니다. 다만 재개한 세션이 이전에 본 파일이 그새 바뀌었다면, 바뀐 내용을 세션에 먼저 알려 주어야 합니다. 오래된 결과를 그대로 믿고 이어가기보다 깨끗하게 새로 시작하는 편이 나은 경우도 분명히 있습니다.
실무 예시
코드리뷰 자동화를 설계하는 아키텍트가 '정적 검사 → 스타일 검사 → 요약'처럼 순서가 고정된 부분은 프롬프트 체이닝으로 엮고, '어떤 파일을 깊게 볼지'는 변경 내용에 따라 달라지므로 적응형 분해에 맡깁니다. 어제 멈춘 리뷰를 --resume으로 재개할 때는 그사이 새로 커밋된 파일을 세션에 먼저 알려, 낡은 판단을 이어가지 않게 합니다.
! 흔한 함정
- 종료 조건을 임의의 반복 횟수 상한으로 거는 것 — 정상 종료의 기준은 stop_reason이고, 횟수 상한은 폭주를 막는 안전장치일 뿐입니다.
- 모델이 답한 자연어 문장을 파싱해 다음 행동이나 종료를 판단하는 것 — 표현이 조금만 달라져도 무너집니다. 구조화된 신호(stop_reason·tool_use)를 근거로 삼아야 합니다.
- 서브에이전트가 부모의 대화 이력을 자동으로 물려받는다고 가정하는 것 — 서브에이전트는 격리된 문맥에서 시작하므로, 필요한 배경은 코디네이터가 명시적으로 건네야 합니다.
- 결정론적 준수가 필요한 규칙(금융 작업 전 신원 확인 등)을 프롬프트 지시로만 처리하는 것 — 반드시 지켜져야 하는 규정은 훅이나 사전 관문으로 강제해야 합니다.
HANDS-ON 에이전트 조율·서브에이전트·훅·세션 재개(--resume)를 실제 코드로 익히려면 byteforce learn의 '4-claude-code' 코스가 가장 가깝고, 루프와 stop_reason의 바탕 개념은 '2-claude-api' 코스에서 다집니다. learn으로 →
Q 확인 퀴즈
고객지원 에이전트를 처음 설계하는 테크리드가 모델 응답을 받은 뒤 다음에 무엇을 해야 할지 판단하는 반복 구조를 짜고 있습니다.
에이전틱 루프(agentic loop, 모델과 실행 환경이 번갈아 오가는 반복 구조)에서 모델 응답의 stop_reason(중단 사유) 값이 tool_use(도구 호출 요청)로 돌아왔습니다. 설계자가 그다음에 해야 할 일로 가장 올바른 것은 무엇입니까?