Agent Loop (OpenClaw)

Agentic 루프는 agent의 완전한 "실제" 실행입니다: 수신 → 컨텍스트 조립 → model 추론 → tool 실행 → 스트리밍 응답 → 지속성. 이는 메시지를 액션 및 최종 응답으로 전환하면서 session state를 일관되게 유지하는 권위 있는 경로입니다.

OpenClaw에서 루프는 model이 생각하고, tool을 호출하고, 출력을 스트리밍할 때 생명주기 및 스트림 event를 발행하는 session당 단일 직렬화된 실행입니다. 이 문서는 이 진정한 루프가 end-to-end로 어떻게 연결되는지 설명합니다.

진입점

  • Gateway RPC: agentagent.wait.
  • CLI: agent 명령.

작동 방식 (상위 레벨)

  1. agent RPC는 매개변수를 검증하고, session(sessionKey/sessionId)을 해결하고, session 메타데이터를 지속하고, { runId, acceptedAt }를 즉시 반환합니다.
  2. agentCommand는 agent를 실행합니다:
    • model + thinking/verbose 기본값 해결
    • skill 스냅샷 로드
    • runEmbeddedPiAgent 호출 (pi-agent-core 런타임)
    • 임베디드 루프가 발행하지 않으면 생명주기 end/error 발행
  3. runEmbeddedPiAgent:
    • session별 + 전역 queue를 통해 실행 직렬화
    • model + auth profile 해결 및 pi session 빌드
    • pi event를 구독하고 assistant/tool delta 스트리밍
    • timeout 강제 -> 초과 시 실행 중단
    • payload + 사용량 메타데이터 반환
  4. subscribeEmbeddedPiSession은 pi-agent-core event를 OpenClaw agent 스트림으로 브리징합니다:
    • tool event => stream: "tool"
    • assistant delta => stream: "assistant"
    • 생명주기 event => stream: "lifecycle" (phase: "start" | "end" | "error")
  5. agent.waitwaitForAgentJob를 사용합니다:
    • runId에 대한 생명주기 end/error 대기
    • { status: ok|error|timeout, startedAt, endedAt, error? } 반환

큐잉 + 동시성

  • 실행은 session key(session lane)당 직렬화되며 선택적으로 전역 lane을 통해 직렬화됩니다.
  • 이를 통해 tool/session 경쟁을 방지하고 session 기록을 일관되게 유지합니다.
  • 메시징 channel은 이 lane 시스템에 공급하는 queue mode(collect/steer/followup)를 선택할 수 있습니다. Command Queue 참조.

Session + workspace 준비

  • Workspace가 해결되고 생성됩니다; 샌드박스 실행은 샌드박스 workspace root로 리디렉션될 수 있습니다.
  • Skill이 로드되고 (또는 스냅샷에서 재사용) env 및 프롬프트에 주입됩니다.
  • Bootstrap/context 파일이 해결되고 시스템 프롬프트 보고서에 주입됩니다.
  • Session 쓰기 잠금이 획득됩니다; SessionManager가 스트리밍 전에 열리고 준비됩니다.

프롬프트 조립 + 시스템 프롬프트

  • 시스템 프롬프트는 OpenClaw의 기본 프롬프트, skill 프롬프트, bootstrap 컨텍스트 및 실행별 재정의로 빌드됩니다.
  • Model별 제한 및 compaction 예약 토큰이 강제됩니다.
  • model이 보는 내용은 System prompt 참조.

Hook 지점 (가로챌 수 있는 곳)

OpenClaw에는 두 가지 hook 시스템이 있습니다:

  • 내부 hook (Gateway hook): 명령 및 생명주기 event를 위한 event 기반 스크립트.
  • Plugin hook: agent/tool 생명주기 및 gateway 파이프라인 내부의 확장 지점.

내부 hook (Gateway hook)

  • agent:bootstrap: 시스템 프롬프트가 최종화되기 전에 bootstrap 파일을 빌드하는 동안 실행됩니다. bootstrap 컨텍스트 파일을 추가/제거하는 데 사용합니다.
  • 명령 hook: /new, /reset, /stop 및 기타 명령 event (Hook 문서 참조).

설정 및 예제는 Hooks 참조.

Plugin hook (agent + gateway 생명주기)

agent 루프 또는 gateway 파이프라인 내부에서 실행됩니다:

  • before_agent_start: 실행이 시작되기 전에 컨텍스트를 주입하거나 시스템 프롬프트를 재정의합니다.
  • agent_end: 완료 후 최종 메시지 목록 및 실행 메타데이터를 검사합니다.
  • before_compaction / after_compaction: compaction 주기를 관찰하거나 주석을 답니다.
  • before_tool_call / after_tool_call: tool 매개변수/결과를 가로챕니다.
  • tool_result_persist: session transcript에 쓰기 전에 tool 결과를 동기적으로 변환합니다.
  • message_received / message_sending / message_sent: 인바운드 + 아웃바운드 메시지 hook.
  • session_start / session_end: session 생명주기 경계.
  • gateway_start / gateway_stop: gateway 생명주기 event.

hook API 및 등록 세부 정보는 Plugins 참조.

스트리밍 + 부분 응답

  • Assistant delta는 pi-agent-core에서 스트리밍되고 assistant event로 발행됩니다.
  • Block 스트리밍은 text_end 또는 message_end에서 부분 응답을 발행할 수 있습니다.
  • Reasoning 스트리밍은 별도의 스트림 또는 block 응답으로 발행될 수 있습니다.
  • 청크 및 block 응답 동작은 Streaming 참조.

Tool 실행 + 메시징 tool

  • Tool start/update/end event는 tool 스트림에서 발행됩니다.
  • Tool 결과는 로깅/발행 전에 크기 및 이미지 payload에 대해 정리됩니다.
  • 메시징 tool 전송은 중복 assistant 확인을 억제하기 위해 추적됩니다.

응답 형성 + 억제

  • 최종 payload는 다음에서 조립됩니다:
    • assistant 텍스트 (및 선택적 reasoning)
    • 인라인 tool 요약 (verbose + 허용된 경우)
    • model 오류 시 assistant 오류 텍스트
  • NO_REPLY는 무음 token으로 처리되고 나가는 payload에서 필터링됩니다.
  • 메시징 tool 중복은 최종 payload 목록에서 제거됩니다.
  • 렌더링 가능한 payload가 남지 않고 tool이 오류를 발생시킨 경우, 대체 tool 오류 응답이 발행됩니다 (메시징 tool이 이미 사용자에게 표시되는 응답을 보내지 않은 경우).

Compaction + 재시도

  • 자동 compaction은 compaction 스트림 event를 발행하고 재시도를 트리거할 수 있습니다.
  • 재시도 시, 인메모리 버퍼 및 tool 요약은 중복 출력을 방지하기 위해 재설정됩니다.
  • compaction 파이프라인은 Compaction 참조.

Event 스트림 (현재)

  • lifecycle: subscribeEmbeddedPiSession에 의해 발행됨 (그리고 agentCommand에 의해 대체로 발행됨)
  • assistant: pi-agent-core에서 스트리밍된 delta
  • tool: pi-agent-core에서 스트리밍된 tool event

Chat channel 처리

  • Assistant delta는 chat delta 메시지로 버퍼링됩니다.
  • Chat final생명주기 end/error에서 발행됩니다.

Timeout

  • agent.wait 기본값: 30초 (대기만). timeoutMs 매개변수가 재정의합니다.
  • Agent 런타임: agents.defaults.timeoutSeconds 기본값 600초; runEmbeddedPiAgent 중단 타이머에서 강제됩니다.

조기 종료 가능한 곳

  • Agent timeout (중단)
  • AbortSignal (취소)
  • Gateway 연결 해제 또는 RPC timeout
  • agent.wait timeout (대기만, agent 중지하지 않음)