Sub-agent
Sub-agent는 기존 agent 실행에서 spawn되는 백그라운드 agent 실행입니다. 이들은 자체 세션(agent:<agentId>:subagent:<uuid>)에서 실행되며, 완료되면 결과를 요청자 채팅 채널에 다시 알립니다. 각 sub-agent 실행은 백그라운드 작업으로 추적됩니다.
Slash command
현재 세션의 sub-agent 실행을 확인하거나 제어하려면/subagents를 사용하세요.
/subagents list/subagents kill <id|#|all>/subagents log <id|#> [limit] [tools]/subagents info <id|#>/subagents send <id|#> <message>/subagents steer <id|#> <message>/subagents spawn <agentId> <task> [--model <model>] [--thinking <level>]
/focus <subagent-label|session-key|session-id|session-label>/unfocus/agents/session idle <duration|off>/session max-age <duration|off>
/subagents info는 실행 메타데이터(상태, 타임스탬프, session id, transcript 경로, cleanup)를 표시합니다.
범위가 제한되고 안전 필터링된 회상 뷰에는 sessions_history를 사용하고,
원시 전체 transcript가 필요할 때는 디스크의 transcript 경로를 확인하세요.
Spawn 동작
/subagents spawn은 백그라운드 sub-agent를 내부 relay가 아닌 사용자 command로 시작하며, 실행이 끝나면 요청자 채팅으로 최종 완료 업데이트 하나를 전송합니다.
- spawn command는 non-blocking입니다. 즉시 run id를 반환합니다.
- 완료 시 sub-agent는 요청자 채팅 채널에 요약/결과 메시지를 알립니다.
- 완료는 push 기반입니다. 한 번 spawn한 뒤에는 완료를 기다리기 위해
/subagents list,sessions_list,sessions_history를 반복 호출하거나 루프를 돌리지 마세요. 상태 확인은 디버깅이나 개입이 필요할 때만 수행하세요. - 완료 시 OpenClaw는 최선의 노력으로 해당 sub-agent 세션이 연 추적된 브라우저 탭/프로세스를 닫은 뒤 announce cleanup 흐름을 계속합니다.
- 수동 spawn의 경우 전달은 복원력이 있습니다.
- OpenClaw는 먼저 안정적인 멱등성 키를 사용해 직접
agent전달을 시도합니다. - 직접 전달이 실패하면 queue 라우팅으로 fallback합니다.
- queue 라우팅도 불가능하면 최종 포기 전 짧은 지수 백오프로 announce를 재시도합니다.
- OpenClaw는 먼저 안정적인 멱등성 키를 사용해 직접
- 완료 전달은 resolve된 요청자 경로를 유지합니다.
- 가능하면 thread 바인딩 또는 conversation 바인딩 완료 경로가 우선합니다
- 완료 origin이 채널만 제공하는 경우, OpenClaw는 요청자 세션의 resolve된 경로(
lastChannel/lastTo/lastAccountId)에서 누락된 target/account를 채워 직접 전달이 계속 동작하도록 합니다
- 요청자 세션으로의 완료 handoff는 런타임이 생성한 내부 컨텍스트이며(사용자 작성 텍스트 아님), 다음을 포함합니다.
Result(가장 최신의 보이는assistant답변 텍스트, 없으면 정리된 최신 tool/toolResult 텍스트)Status(completed successfully/failed/timed out/unknown)- 간결한 런타임/토큰 통계
- 원시 내부 메타데이터를 그대로 전달하지 말고 일반 assistant 음성으로 다시 작성하라는 전달 지시
--model과--thinking은 해당 실행에 대해서만 기본값을 override합니다.- 완료 후 세부 정보와 출력을 확인하려면
info/log를 사용하세요. /subagents spawn은 일회성 모드(mode: "run")입니다. 지속적인 thread 바인딩 세션에는thread: true및mode: "session"으로sessions_spawn을 사용하세요.- ACP harness 세션(Codex, Claude Code, Gemini CLI)에는
runtime: "acp"로sessions_spawn을 사용하고 ACP agent를 참고하세요.
- 메인 실행을 막지 않고 “조사 / 장기 작업 / 느린 tool” 작업을 병렬화합니다.
- 기본적으로 sub-agent를 격리 상태로 유지합니다(세션 분리 + 선택적 샌드박싱).
- tool surface를 오용하기 어렵게 유지합니다: sub-agent는 기본적으로 session tool을 받지 않습니다.
- orchestrator 패턴을 위한 설정 가능한 중첩 깊이를 지원합니다.
agents.defaults.subagents.model 또는 agent별 override로 설정할 수 있습니다.
Tool
sessions_spawn 사용:
- sub-agent 실행 시작 (
deliver: false, 전역 lane:subagent) - 그런 다음 announce 단계를 실행하고 announce 답변을 요청자 채팅 채널에 게시
- 기본 모델:
agents.defaults.subagents.model(또는 agent별agents.list[].subagents.model)을 설정하지 않으면 호출자를 상속합니다. 명시적인sessions_spawn.model은 여전히 우선합니다. - 기본 thinking:
agents.defaults.subagents.thinking(또는 agent별agents.list[].subagents.thinking)을 설정하지 않으면 호출자를 상속합니다. 명시적인sessions_spawn.thinking은 여전히 우선합니다. - 기본 실행 timeout:
sessions_spawn.runTimeoutSeconds가 생략되면, 설정된 경우 OpenClaw는agents.defaults.subagents.runTimeoutSeconds를 사용하고, 그렇지 않으면0(timeout 없음)으로 fallback합니다.
task(필수)label?(선택 사항)agentId?(선택 사항; 허용되는 경우 다른 agent id 아래에서 spawn)model?(선택 사항; sub-agent 모델 override; 잘못된 값은 건너뛰고 tool 결과에 경고를 남긴 채 기본 모델로 sub-agent가 실행됨)thinking?(선택 사항; sub-agent 실행의 thinking 레벨 override)runTimeoutSeconds?(설정된 경우 기본값은agents.defaults.subagents.runTimeoutSeconds, 그렇지 않으면0; 설정 시 sub-agent 실행은 N초 후 중단됨)thread?(기본값false;true이면 이 sub-agent 세션에 대한 채널 thread 바인딩 요청)mode?(run|session)- 기본값은
run thread: true이고mode가 생략되면 기본값은sessionmode: "session"에는thread: true가 필요함
- 기본값은
cleanup?(delete|keep, 기본값keep)sandbox?(inherit|require, 기본값inherit;require는 대상 자식 런타임이 샌드박스 상태가 아니면 spawn을 거부)sessions_spawn은 채널 전달 파라미터(target,channel,to,threadId,replyTo,transport)를 받지 않습니다. 전달은 spawn된 실행에서message/sessions_send를 사용하세요.
thread에 바인딩된 세션
채널에서 thread 바인딩이 활성화되어 있으면, sub-agent는 thread에 바인딩된 상태로 유지될 수 있어 해당 thread의 후속 사용자 메시지가 같은 sub-agent 세션으로 계속 라우팅됩니다.thread를 지원하는 채널
- Discord(현재 유일한 지원 채널): 지속적인 thread 바인딩 subagent 세션(
thread: true인sessions_spawn), 수동 thread 제어(/_focus,/unfocus,/agents,/session idle,/session max-age), 그리고 adapter keychannels.discord.threadBindings.enabled,channels.discord.threadBindings.idleHours,channels.discord.threadBindings.maxAgeHours,channels.discord.threadBindings.spawnSubagentSessions를 지원합니다.
thread: true(및 선택적으로mode: "session")로sessions_spawn을 사용해 spawn합니다.- OpenClaw가 활성 채널에서 thread를 만들거나 그 세션 대상에 바인딩합니다.
- 해당 thread의 답변과 후속 메시지는 바인딩된 세션으로 라우팅됩니다.
/session idle을 사용해 비활성 자동 unfocus를 확인/업데이트하고,/session max-age로 하드 제한을 제어합니다.- 수동으로 분리하려면
/unfocus를 사용합니다.
/focus <target>은 현재 thread를 sub-agent/session 대상에 바인딩합니다(또는 thread를 생성)./unfocus는 현재 바인딩된 thread의 바인딩을 제거합니다./agents는 활성 실행과 바인딩 상태(thread:<id>또는unbound)를 나열합니다./session idle과/session max-age는 포커스된 바인딩 thread에서만 동작합니다.
- 전역 기본값:
session.threadBindings.enabled,session.threadBindings.idleHours,session.threadBindings.maxAgeHours - 채널 override 및 spawn 자동 바인딩 key는 adapter별입니다. 위의 thread를 지원하는 채널을 참고하세요.
agents.list[].subagents.allowAgents:agentId를 통해 대상으로 지정할 수 있는 agent id 목록(["*"]는 모든 agent 허용). 기본값: 요청자 agent만.agents.defaults.subagents.allowAgents: 요청자 agent가 자체subagents.allowAgents를 설정하지 않았을 때 사용하는 기본 대상-agent allowlist.- 샌드박스 상속 가드: 요청자 세션이 샌드박스 상태면
sessions_spawn은 샌드박스 없이 실행될 대상을 거부합니다. agents.defaults.subagents.requireAgentId/agents.list[].subagents.requireAgentId: true일 때agentId를 생략한sessions_spawn호출을 차단합니다(명시적 profile 선택 강제). 기본값: false.
- 현재
sessions_spawn에 허용된 agent id를 보려면agents_list를 사용하세요.
- sub-agent 세션은
agents.defaults.subagents.archiveAfterMinutes후 자동 보관됩니다(기본값: 60). - 보관은
sessions.delete를 사용하고 transcript를*.deleted.<timestamp>로 이름 변경합니다(같은 폴더). cleanup: "delete"는 announce 직후 즉시 보관합니다(여전히 transcript는 이름 변경을 통해 유지).- 자동 보관은 최선의 노력이며, gateway가 재시작되면 보류 중인 타이머는 사라집니다.
runTimeoutSeconds는 자동 보관하지 않습니다. 실행만 중지합니다. 세션은 자동 보관까지 유지됩니다.- 자동 보관은 depth-1과 depth-2 세션에 동일하게 적용됩니다.
- 브라우저 cleanup은 보관 cleanup과 별개입니다. transcript/session 레코드가 유지되더라도, 실행이 끝나면 추적된 브라우저 탭/프로세스를 최선의 노력으로 닫습니다.
중첩 Sub-agent
기본적으로 sub-agent는 자신의 sub-agent를 spawn할 수 없습니다(maxSpawnDepth: 1). maxSpawnDepth: 2를 설정하면 한 단계의 중첩을 활성화할 수 있으며, 이는 orchestrator 패턴을 허용합니다: main → orchestrator sub-agent → worker sub-sub-agent.
활성화 방법
깊이 수준
| Depth | Session key 형태 | 역할 | spawn 가능 여부 |
|---|---|---|---|
| 0 | agent:<id>:main | 메인 agent | 항상 가능 |
| 1 | agent:<id>:subagent:<uuid> | Sub-agent (depth 2 허용 시 orchestrator) | maxSpawnDepth >= 2일 때만 |
| 2 | agent:<id>:subagent:<uuid>:subagent:<uuid> | Sub-sub-agent(leaf worker) | 불가 |
알림 체인
결과는 체인을 따라 상위로 전달됩니다.- depth-2 worker 완료 → 부모(depth-1 orchestrator)에게 알림
- depth-1 orchestrator가 알림을 수신하고 결과를 종합한 뒤 완료 → main에 알림
- main agent가 알림을 수신하고 사용자에게 전달
- 자식 작업은 한 번 시작하고,
sessions_list,sessions_history,/subagents list, 또는execsleep command를 중심으로 poll 루프를 만들지 말고 완료 이벤트를 기다리세요. - 자식 완료 이벤트가 최종 답변을 이미 보낸 뒤 도착했다면,
올바른 후속 동작은 정확히
NO_REPLY/no_reply라는 무음 토큰입니다.
깊이별 tool 정책
- 역할과 제어 범위는 spawn 시점에 세션 메타데이터에 기록됩니다. 이렇게 하면 평면화되었거나 복원된 session key가 의도치 않게 orchestrator 권한을 되찾는 일을 막을 수 있습니다.
- Depth 1 (
maxSpawnDepth >= 2일 때 orchestrator): 자식을 관리할 수 있도록sessions_spawn,subagents,sessions_list,sessions_history를 받습니다. 다른 session/system tool은 계속 거부됩니다. - Depth 1 (
maxSpawnDepth == 1일 때 leaf): session tool 없음(현재 기본 동작). - Depth 2 (leaf worker): session tool 없음 — depth 2에서는
sessions_spawn이 항상 거부됩니다. 더 깊은 자식을 spawn할 수 없습니다.
agent별 spawn 제한
각 agent 세션(어떤 depth이든)은 동시에 최대maxChildrenPerAgent(기본값: 5)개의 활성 자식을 가질 수 있습니다. 이는 단일 orchestrator로부터의 과도한 fan-out을 방지합니다.
연쇄 중지
depth-1 orchestrator를 중지하면 모든 depth-2 자식도 자동으로 중지됩니다.- 메인 채팅에서
/stop을 실행하면 모든 depth-1 agent가 중지되고 해당 depth-2 자식에도 연쇄 적용됩니다. /subagents kill <id>는 특정 sub-agent를 중지하고 그 자식에게도 연쇄 적용됩니다./subagents kill all은 요청자의 모든 sub-agent를 중지하고 연쇄 적용됩니다.
인증
sub-agent 인증은 세션 타입이 아니라 agent id를 기준으로 resolve됩니다.- sub-agent session key는
agent:<agentId>:subagent:<uuid>입니다. - auth 저장소는 해당 agent의
agentDir에서 로드됩니다. - 메인 agent의 auth profile은 fallback으로 병합되며, 충돌 시 agent profile이 main profile을 override합니다.
announce
sub-agent는 announce 단계를 통해 결과를 보고합니다.- announce 단계는 요청자 세션이 아니라 sub-agent 세션 내부에서 실행됩니다.
- sub-agent가 정확히
ANNOUNCE_SKIP로 답하면 아무것도 게시되지 않습니다. - 최신 assistant 텍스트가 정확히
NO_REPLY/no_reply라는 무음 토큰이면, 이전에 보이는 진행 상황이 있었더라도 announce 출력은 억제됩니다. - 그 외에는 요청자 depth에 따라 전달이 달라집니다.
- 최상위 요청자 세션은 외부 전달(
deliver=true)이 있는 후속agent호출을 사용합니다 - 중첩된 요청자 subagent 세션은 orchestrator가 세션 내에서 자식 결과를 종합할 수 있도록 내부 후속 주입(
deliver=false)을 받습니다 - 중첩된 요청자 subagent 세션이 사라졌다면, 가능하면 OpenClaw는 해당 세션의 요청자로 fallback합니다
- 최상위 요청자 세션은 외부 전달(
- 최상위 요청자 세션의 경우, completion 모드 직접 전달은 먼저 바인딩된 conversation/thread 경로와 hook override를 resolve한 뒤, 요청자 세션에 저장된 경로에서 누락된 채널 대상 필드를 채웁니다. 이렇게 하면 완료 origin이 채널만 식별하더라도 올바른 chat/topic에서 완료 전달이 유지됩니다.
- 중첩된 완료 결과를 구성할 때 자식 완료 집계는 현재 요청자 실행 범위로 제한되므로, 이전 실행의 오래된 자식 출력이 현재 announce에 섞이지 않습니다.
- 채널 adapter에서 가능할 경우 announce 답변은 thread/topic 라우팅을 유지합니다.
- announce 컨텍스트는 안정적인 내부 이벤트 블록으로 정규화됩니다.
- source (
subagent또는cron) - 자식 session key/id
- announce 타입 + task label
- 런타임 결과(
success,error,timeout,unknown)에서 파생된 status 라인 - 가장 최신의 보이는 assistant 텍스트에서 선택한 결과 콘텐츠, 없으면 정리된 최신 tool/toolResult 텍스트
- 언제 답해야 하고 언제 조용히 있어야 하는지 설명하는 후속 지시
- source (
Status는 모델 출력에서 추론되지 않습니다. 런타임 결과 신호에서 가져옵니다.- timeout 시 자식이 tool 호출까지만 진행했다면, announce는 원시 tool 출력을 재생하는 대신 그 히스토리를 짧은 부분 진행 요약으로 축약할 수 있습니다.
- Runtime (예:
runtime 5m12s) - 토큰 사용량(input/output/total)
- 모델 가격이 설정된 경우 예상 비용(
models.providers.*.models[].cost) sessionKey,sessionId, transcript 경로(따라서 main agent가sessions_history로 히스토리를 가져오거나 디스크 파일을 직접 확인할 수 있음)- 내부 메타데이터는 오케스트레이션 전용입니다. 사용자 대상 답변은 일반 assistant 음성으로 다시 작성해야 합니다.
sessions_history는 더 안전한 오케스트레이션 경로입니다.
- assistant 회상은 먼저 정규화됩니다.
- thinking tag는 제거됩니다
<relevant-memories>/<relevant_memories>scaffold 블록은 제거됩니다<tool_call>...</tool_call>,<function_call>...</function_call>,<tool_calls>...</tool_calls>,<function_calls>...</function_calls>같은 일반 텍스트 tool-call XML payload 블록은 제거되며, 정상적으로 닫히지 않은 잘린 payload도 포함됩니다- 강등된 tool-call/result scaffold 및 historical-context marker는 제거됩니다
<|assistant|>같은 누출된 모델 제어 토큰, 기타 ASCII<|...|>토큰, 전체 폭<|...|>변형은 제거됩니다- 잘못된 MiniMax tool-call XML은 제거됩니다
- credential/token 유사 텍스트는 redaction됩니다
- 긴 블록은 잘릴 수 있습니다
- 매우 큰 히스토리는 오래된 row를 제거하거나 큰 row 하나를
[sessions_history omitted: message too large]로 대체할 수 있습니다 - 전체 바이트 단위 transcript가 필요하면 원시 디스크 transcript 확인이 fallback입니다
Tool 정책(sub-agent tool)
기본적으로 sub-agent는 session tool과 system tool을 제외한 모든 tool을 받습니다.sessions_listsessions_historysessions_sendsessions_spawn
sessions_history는 범위가 제한되고 정리된 회상 뷰이며,
원시 transcript 덤프가 아닙니다.
maxSpawnDepth >= 2일 때 depth-1 orchestrator sub-agent는 자식을 관리할 수 있도록 추가로 sessions_spawn, subagents, sessions_list, sessions_history를 받습니다.
config를 통한 override:
동시성
sub-agent는 전용 in-process queue lane을 사용합니다.- Lane 이름:
subagent - 동시성:
agents.defaults.subagents.maxConcurrent(기본값8)
중지
- 요청자 채팅에
/stop을 보내면 요청자 세션이 중단되고, 여기서 spawn된 활성 sub-agent 실행도 중첩된 자식까지 연쇄적으로 중지됩니다. /subagents kill <id>는 특정 sub-agent를 중지하고 그 자식에게도 연쇄 적용됩니다.
제한 사항
- sub-agent announce는 best-effort입니다. gateway가 재시작되면 대기 중인 “결과 알림” 작업은 사라집니다.
- sub-agent는 여전히 동일한 gateway 프로세스 리소스를 공유하므로
maxConcurrent를 안전 밸브로 취급하세요. sessions_spawn은 항상 non-blocking입니다. 즉시{ status: "accepted", runId, childSessionKey }를 반환합니다.- sub-agent 컨텍스트는
AGENTS.md+TOOLS.md만 주입합니다(SOUL.md,IDENTITY.md,USER.md,HEARTBEAT.md,BOOTSTRAP.md는 없음). - 최대 중첩 깊이는 5입니다(
maxSpawnDepth범위: 1–5). 대부분의 사용 사례에는 depth 2를 권장합니다. maxChildrenPerAgent는 세션당 활성 자식 수를 제한합니다(기본값: 5, 범위: 1–20).