에이전트 디스패치 수명주기
디스패치란 무엇인가
섹션 제목: “디스패치란 무엇인가”디스패치는 하나의 대화에서 하나의 어댑터를 통해 이루어지는, 한 에이전트의 한 번의 실행입니다. 디스패치에 관한 모든 일은 cc_server에서 일어납니다. 클라이언트는 메시지를 보낸 뒤 이벤트가 다시 스트리밍되는 것을 지켜봅니다. 어떤 클라이언트에도 디스패치 경로는 없습니다.
에이전트는 여섯 가지 사유로 깨어나며, 실행은 그 사유를 웨이크 컨텍스트로 함께 전달하므로 에이전트는 자신이 왜 깨어 있는지 압니다.
| 웨이크 사유 | 트리거 |
|---|---|
userMessage |
누군가 스페이스에서 메시지를 보냈거나 에이전트를 멘션함 |
assignment |
티켓이 에이전트에 할당됨 |
pipelineStep |
파이프라인 단계가 디스패치함 |
childCompleted |
하위 티켓이 완료됨 |
followUp |
예약된 팔로업 하트비트 |
recovery |
실패 후 복구 경로가 다시 디스패치함 |
웨이크 컨텍스트는 그 사유에 딸린 id들 — 티켓, 스페이스, 메시지, 파이프라인 실행 — 을 함께 담으며, 이것들은 에이전트의 환경과 프롬프트에 주입됩니다.
프롬프트 조립
섹션 제목: “프롬프트 조립”프롬프트는 계층으로 구성되며, 각 계층은 레이블이 붙은 섹션입니다.
- 아이덴티티 — 에이전트 자신의 id, 이름, 워크스페이스 id이며, 이 UUID들을 워크스페이스 범위 도구에 그대로 전달하라는 명시적 지시가 함께 들어갑니다. 워크스페이스는 에이전트에 내재된 것이므로 항상 포함됩니다.
- 도구 카탈로그와 리소스 프로토콜, 그다음 워크스페이스 레이아웃.
- 에이전트에 설정된 경우 시스템 프롬프트 재정의, 그다음 페르소나(역할로 매개변수화됨)와 팀 브리프.
- 스킬 — 에이전트에 지정된 이름들.
- 현재 모드의 실행 계약과 절차.
- 웨이크 컨텍스트와 멘션 컨텍스트: 누가 에이전트를 호출했는지, 그리고 그 주변의 로스터.
- 모드 블록 — 모드의 기능 프로필 과 실제로 구성된 도구 목록 에서 생성되므로, 프롬프트가 실행에 실제로 없는 도구의 이름을 언급하는 일은 결코 없습니다.
- 메모리 컨텍스트 — 작업을 위해 검색된 사실들.
- 대화 컨텍스트 — 최근 스페이스 기록이며, 에이전트에 설정된 컨텍스트 크기와 무관하게 그대로 담기는 창은 50,000자로 제한됩니다. 오래된 기록이 잘려 사라지는 것은 아닙니다. 에이전트는
get_messages로 필요할 때 가져오며, 의미상 관련 있는 오래된 메시지는 여전히 드러납니다.
명령은 두 곳에 나뉘어 처리됩니다. /todo와 /compact는 컴포저에서 가로채며, 메시지로 저장하거나 에이전트에 보내지 않습니다. /compact를 저장하면 압축 기준점이 한 턴 뒤로 밀려 트랜스크립트가 오염되기 때문입니다. /plan은 양쪽에서 처리됩니다. 컴포저가 스페이스의 모드를 전환하며, 이것이 이번 턴과 그 이후 모든 턴에서 도구 표면, 가드 프리셋, 프롬프트를 서로 맞춰 줍니다. /goal, /loop, /skill:<name>은 실행 내부에서, 그것도 내장 하네스에서만 처리됩니다. /goal과 /loop는 비용 예산과 함께 자율 작업을 시작하고, skill: 접두사가 붙은 이름은 스킬로 조회되어 그 SKILL.md 본문이 해당 턴의 지시가 됩니다. 네임스페이스가 두 어휘를 분리해 줍니다. 이름을 스킬로 그대로 해석하던 때에는 plan이나 compact라는 스킬이 내장 명령에 영구히 가려졌습니다. 네임스페이스가 생기기 전에 작성된 메시지를 위해, 내장이 아닌 이름은 접두사 없이도 여전히 해석됩니다. 인식되지 않는 이름은 그냥 일반 텍스트로 처리됩니다.
워크트리 프로비저닝
섹션 제목: “워크트리 프로비저닝”무엇이든 실행되기 전에 대화는 자신만의 작업 루트를 확보하며, 그 아래에 저장소마다 격리된 쓰기 시 복사 워크트리가 놓입니다. 기본값은 워크스페이스에 연결된 모든 저장소입니다. PR 스페이스나 명시적 선택으로 만든 스페이스는 허용 목록에 있는 저장소만 프로비저닝하며, PR 리뷰 대화는 자신의 저장소 하나를 풀 리퀘스트의 head ref에 고정하고 나머지는 각자의 기본 브랜치에 둡니다. 원본 체크아웃은 결코 변경되지 않으며, 스페이스를 삭제하면 대화 디렉터리 전체가 회수됩니다.
쓰기 시 복사는 rift가 제공되는 모든 곳에서 유일한 구현이며, 번들로 포함된 네이티브가 이를 뒷받침합니다. reflink를 할 수 없는 파일 시스템이나, 저장소와 다른 볼륨에 있는 데이터 디렉터리는 폴백으로 넘어가지 않고 프로비저닝을 실패시킵니다. git worktree는 쓰기 시 복사 백엔드를 만들 수 없는 Windows의 백엔드이며, 다른 호스트에서의 조용한 성능 저하가 아닙니다. rift를 제공하는 플랫폼에서 rift가 없다면 설치는 망가진 것입니다. 서버는 조용히 폴백하지 않고 부팅을 거부합니다. 조용한 폴백은 그 고장을 영원히 더 느린 경로 뒤에 숨기기 때문입니다.
아이덴티티와 자격 증명
섹션 제목: “아이덴티티와 자격 증명”프로세스가 시작되기 전에, 실행마다 두 가지 아이덴티티가 결정됩니다.
Git 작성자 표기. 에이전트가 만든 커밋은 에이전트로서 작성됩니다 — GIT_AUTHOR_*와 GIT_COMMITTER_* 모두에서 <Name> (agent) <agentId@agents.control-center.local> 형태이며, 사람을 사칭하지 않습니다. 로컬 파트는 에이전트의 이름 슬러그가 아니라 에이전트의 UUID입니다. 요청한 사람은 Co-Authored-By: 트레일러로 크레딧을 받으며, 이는 환경에 실려 전달되고 시스템 프롬프트에서 지시됩니다. 호출자가 명시적으로 지정한 아이덴티티는 항상 이 둘보다 우선합니다.
코드 호스트 아이덴티티. 실행의 GitHub 자격 증명은 언제나 브로커의 것입니다 — 저장소 범위 App 설치 토큰 또는 그 환경 PAT 폴백 — 요청한 멤버가 저장해 둔 자신의 토큰은 결코 아닙니다. actingUserId는 PAT 폴백의 범위를 제한하므로 서버 소유자가 아닌 멤버가 서버의 영향력을 물려받지 않습니다. 개인 토큰을 에이전트 환경 위에 덧씌우는 것이 아닙니다.
모델 공급자 자격 증명은 정해진 순서로 결정되며 그 순서가 중요합니다.
- 어댑터별 환경 재정의,
- 호출자의 환경,
- 서버의 자격 증명 저장소(만료가 임박한 OAuth 토큰은 갱신),
- 프로세스 환경.
어댑터별 재정의가 가장 먼저이므로, 앱에서 연결한 공급자 계정을 조용히 앞지릅니다. 실행이 엉뚱한 계정으로 과금된다면, 그 재정의가 가장 먼저 살펴볼 곳입니다. 공급자 자격 증명은 호스트 전역이며, 설치된 모든 워크스페이스가 공유합니다.
실행의 GitHub 토큰은 자격 증명 브로커에서 나옵니다. 워크트리 저장소 범위의 읽기 전용 토큰입니다. 푸시는 에이전트 실행 게이트웨이를 거치며, 게이트웨이는 전달하기 전에 리모트에 푸시 규칙에 묻습니다. 티켓팅 키는 주입되지 않습니다. 샌드박스와 보안을 참고하세요.
실행은 자신의 워크트리를 작업 디렉터리로 삼아 생성되며, Claude Code의 경우 에이전트가 Control Center의 도구 표면에 닿을 수 있도록 생성된 MCP 구성도 함께 받습니다. ACP와 하네스 bash에는 정리된 환경이 주어지고, NoSandboxAdapter를 거치는 Claude Code는 호스트 환경을 물려받습니다.
스트리밍
섹션 제목: “스트리밍”실행은 타입이 지정된 이벤트 시퀀스를 다시 스트리밍하며, 스트림 프로세서는 이를 메시지 델타로 저장하고, 트랜스크립트 세그먼트로 접어 넣고, 메시징 이벤트로 바꿉니다.
| 이벤트 | 담기는 내용 |
|---|---|
thinking |
추론 출력, 인라인으로 렌더링됨 |
text |
표시되는 출력 |
toolCall |
도구 호출, 그 id와 구조화된 인수 포함 |
toolResult |
대응하는 결과, 오류가 발생했거나 부분 스트림인 경우 표시됨 |
usage |
측정 구간의 토큰 수와 비용 |
error |
오류, 어댑터가 보고한 경우 그 구조화된 코드 포함 |
sandboxViolation |
OS가 시스템 호출을 거부함. 샌드박스가 실제로 프로세스를 감싸는 곳에서만 발생합니다 — 위의 참고를 보세요 |
debug |
런타임 진단(시작 표시자, 가드 결정, 계약 넛지) |
done |
실행 종료 |
실행을 제한하는 요소
섹션 제목: “실행을 제한하는 요소”어디에도 턴 상한이 없다는 것은 의도된 설계입니다. 하드 반복 횟수는 정당한 장기 작업(마이그레이션, 팬아웃 정리)을 죽이면서, 아래 가드들이 더 일찍 잡아내는 것은 아무것도 잡지 못합니다. 실행은 다음 경우에 끝납니다.
- 모델이 스스로 멈출 때;
- 사람이 멈출 때, 또는 대화를 넘겨받을 때(내장 하네스는 다음의 깨끗한 턴 경계에서 일시 중지됩니다. 안전한 경계가 없는 Claude Code 실행은 대신 중지됩니다);
- 무응답 감시 타이머가 발동할 때. 임계 시간 동안 출력이 없으면
silentRun실패와 함께 세션이 종료됩니다. 기본값은 15분이며, 읽기 위주 모드(리뷰와 플랜)에서는 10분으로 줄어듭니다. 에이전트는 1분에서 240분 사이에서 이 값을 재정의할 수 있습니다. 감시 타이머는 자식 프로세스가 PID를 보고할 때 무장되므로 Claude Code CLI를 포괄합니다 — 아무것도 생성하지 않는 내장 하네스는 포괄하지 않습니다; - 비용 상한이 걸릴 때 — 다만 자율 명령에서만 그렇습니다.
둠 루프 가드는 종료 장치가 아닙니다. 동일한 도구 호출이 세 번 연속 이어지면, 루프는 에이전트가 접근 방식을 바꾸도록 _스티어링_합니다.
종합하면, 내장 하네스에서 평범한 대화형 턴은 턴 상한도, 비용 상한도, 무응답 감시 타이머도 없습니다. 모델이 멈추거나 사용자가 멈출 때 끝납니다. 이는 의도된 절충입니다 — 대안들은 모두 정당한 장기 작업을 죽입니다 — 다만 무인 대화형 실행은 모델 자신의 판단 외에는 아무것도 그것을 제한하지 않는다는 뜻이기도 합니다.
실행 중에, 실행 중인 에이전트에게 보낸 메시지는 스티어링으로 대기열에 들어가 다음 턴 경계에서 소진되므로, 실행을 죽이지 않고도 방향을 조정할 수 있습니다. 스티어링, 일시 중지, 서브에이전트, 완료 계약은 내장 하네스의 기능이며, Claude Code에는 이 중 어느 것도 없습니다.
실행이 기록되는 방식
섹션 제목: “실행이 기록되는 방식”모든 디스패치는 AgentRunLog를 기록합니다. 시작과 종료 시각, 요약, 토큰 수와 추정 비용(서브에이전트에서 합산된 비용 포함), 어댑터와 모델, 프로세스 id와 로그 경로, 대화 및 소속된 티켓이나 파이프라인 실행, 그리고 진실의 대부분을 담는 두 가지 분류 필드입니다.
- 상태는 거칩니다:
pending,running,completed,error. - 활성 상태는 더 세밀한 판독입니다:
alive,productive,completed,blocked,empty,looping,failed,stalled,dead. - 오류 계열은 실패를 유용하게 묶습니다:
transientUpstream,sandboxInfrastructure,budgetExceeded,processLost,silentRun,unknown.
실행을 닫으면 AgentRunCompleted가 발행되며, 여기에 많은 것이 매달려 있습니다. 파이프라인 비용 합산, 실행을 기다리던 파이프라인 단계 재개, 배후 티켓 완료, 오케스트레이션을 종료 상태로 매핑, 목표 감독자의 계속·중지 결정, 체커 역할, 그리고 실행 후 예산 평가입니다. 프레즌스 로스터는 이벤트가 아니라 최근 실행 로그를 지켜보는 별도의 경로로 따라옵니다. “에이전트 완료” 알림은 이 목록에 없습니다. 이 이벤트는 프로세스 스트림이 끝날 때, 즉 답장이 기록되기 전에 발생하므로, 알림은 메시지가 영속화된 뒤 발행되는 해당 턴의 MessageReceived입니다.
예산, 사후 반영
섹션 제목: “예산, 사후 반영”예산 집행은 게이트가 아니라 반응 입니다. 실행이 완료되면 평가자가 에이전트의 월 누적 지출을 유효 상한(연결된 예산 정책이 있으면 그것, 없으면 에이전트 자체의 월 한도이며 0은 무제한을 뜻합니다)과 비교합니다. 소프트 임계값을 넘으면 경고 인시던트가 기록되고, 예산을 모두 소진하면 심각 인시던트가 기록되며, 조직도에서 에이전트의 수명주기 상태가 paused로 바뀝니다. 디스패치는 그 에이전트의 작업을 여전히 받아들입니다. BudgetThresholdCrossed 파이프라인 트리거는 같은 이벤트에서 후속 작업을 시작할 수 있습니다.
재시도 계보
섹션 제목: “재시도 계보”모든 실행 로그는 재시도 계보를 담을 수 있습니다 — 부모 실행 id, 시도 횟수 카운터, 이어받기 요약입니다. 대화 실행 트리는 시도 횟수가 0이 아닐 때 그 번호를 렌더링합니다. 채팅에서의 “다시 시도”는 새 실행 로그를 가진 새로운 디스패치입니다.