OpenClaw Agent Loop 机制源码深度分析(一)

OpenClaw Agent Loop 机制源码深度分析

基于源码的全面解析,帮助你深入理解 OpenClaw 的 Agent 循环执行机制

目录


概述

OpenClaw 的 Agent Loop(代理循环) 是系统的核心执行引擎,负责接收消息、构建上下文、调用 LLM、执行工具、处理响应,形成一个完整的对话循环。

核心特性

支持功能
流式响应
上下文窗口管理
工具策略控制
错误恢复
Agent Loop
是
否
接收消息
构建上下文
调用 LLM
有工具调用?
执行工具
返回结果
压缩上下文

循环流程

有
无
是
否
开始
接收消息
构建系统提示词
加载会话历史
调用 LLM
工具调用?
执行工具
生成回复
压缩会话
继续?
结束


架构设计

模块结构

复制代码
src/agents/pi-embedded-runner/
├── run.ts                          # 主运行入口
├── run/
│   ├── params.ts                  # 运行参数
│   ├── attempt.ts                 # 单次执行尝试
│   ├── payloads.ts                # 载荷构建
│   └── images.ts                  # 图片处理
├── compact.ts                      # 会话压缩
├── runs.ts                         # 运行状态管理
├── history.ts                      # 历史管理
├── lanes.ts                        # 执行队列通道
├── system-prompt.ts               # 系统提示词构建
├── tool-split.ts                  # 工具拆分
├── tool-result-truncation.ts      # 工具结果截断
├── types.ts                       # 类型定义
└── utils.ts                       # 工具函数

核心类型定义

typescript 复制代码
// types.ts

export type EmbeddedPiRunResult = {
  success: boolean;
  reply?: string;
  usage?: Usage;
  error?: string;
};

export type EmbeddedPiAgentMeta = {
  runId: string;
  sessionId: string;
  provider: string;
  modelId: string;
  thinkLevel: ThinkLevel;
};

// 运行状态
export type EmbeddedPiRunStatus =
  | { status: "idle" }
  | { status: "streaming" }
  | { status: "compacting" }
  | { status: "completed" }
  | { status: "error"; error: string };

核心组件

运行器入口

文件 : run.ts

主入口函数,处理整个运行生命周期。

typescript 复制代码
export async function runEmbeddedPiAgent(
  params: RunEmbeddedPiAgentParams,
): Promise<EmbeddedPiRunResult> {
  const sessionLane = resolveSessionLane(params.sessionKey || params.sessionId);
  
  return enqueueSession(() =>
    enqueueGlobal(async () => {
      // 1. 准备工作区
      const workspaceResolution = resolveRunWorkspaceDir({...});
      const resolvedWorkspace = workspaceResolution.workspaceDir;
      
      // 2. 解析模型配置
      const { model, error, authStorage } = resolveModel(
        provider, modelId, agentDir, params.config
      );
      
      if (!model) {
        throw new Error(error ?? `Unknown model: ${provider}/${modelId}`);
      }
      
      // 3. 检查上下文窗口
      const ctxInfo = resolveContextWindowInfo({...});
      const ctxGuard = evaluateContextWindowGuard({...});
      
      // 4. 执行循环
      const result = await runEmbeddedAttempt({
        ...params,
        model,
        authStorage,
        workspaceDir: resolvedWorkspace,
        sessionId: redactedSessionId,
      });
      
      return result;
    })
  );
}

参数定义:

typescript 复制代码
type RunEmbeddedPiAgentParams = {
  message: string;              // 用户消息
  sessionId: string;            // 会话 ID
  sessionKey?: string;         // 会话 Key
  agentId?: string;            // Agent ID
  provider?: string;           // 模型提供商
  model?: string;             // 模型名称
  workspaceDir?: string;      // 工作区目录
  config?: OpenClawConfig;    // 配置
  messageChannel?: string;   // 消息通道
  messageProvider?: string;   // 消息提供商
  // ... 更多参数
};

执行尝试

文件 : run/attempt.ts

单个执行尝试,包含完整的 LLM 调用和工具执行循环。

typescript 复制代码
export async function runEmbeddedAttempt(
  params: EmbeddedRunAttemptParams,
): Promise<EmbeddedRunAttemptResult> {
  const workspace = resolveUserPath(params.workspaceDir);
  
  // 1. 解析沙箱配置
  const sandbox = await resolveSandboxContext({
    config: params.config,
    sessionKey: params.sessionKey || params.sessionId,
    workspaceDir: workspace,
  });
  
  // 2. 加载 Skills
  const skillEntries = loadWorkspaceSkillEntries(workspace);
  const skillsPrompt = resolveSkillsPromptForRun({...});
  
  // 3. 构建系统提示词
  const { systemPrompt, snapshot } = buildEmbeddedSystemPrompt({...});
  
  // 4. 准备会话管理器
  const sessionManager = await prepareSessionManagerForRun({
    sessionId: params.sessionId,
    sessionKey: params.sessionKey,
    systemPrompt,
    workspaceDir: workspace,
    config: params.config,
  });
  
  // 5. 构建工具定义
  const tools = await toClientToolDefinitions({
    config: params.config,
    sessionManager,
    sandbox,
  });
  
  // 6. 注册运行状态
  const handle = registerRun({
    sessionId: params.sessionId,
    sessionManager,
  });
  
  try {
    // 7. 发送用户消息
    await sessionManager.appendUserMessage(params.message);
    
    // 8. 执行主循环
    while (true) {
      // 调用 LLM
      const response = await sessionManager.complete({
        model: params.modelId,
        tools,
        thinking: params.thinkLevel,
      });
      
      // 检查是否有工具调用
      if (response.tool_calls?.length > 0) {
        // 执行工具
        for (const toolCall of response.tool_calls) {
          const result = await executeTool(toolCall);
          await sessionManager.appendToolResult(toolCall.id, toolCall.name, result);
        }
        continue;  // 继续循环
      }
      
      // 没有工具调用,返回结果
      return {
        success: true,
        reply: response.content,
        usage: response.usage,
      };
    }
  } finally {
    unregisterRun(params.sessionId);
  }
}
相关推荐
感谢地心引力4 天前
我用 Doubao-Seed-2.1-pro 做了一个深度融入 AI 功能的本地知识库软件
ai·开源·seed·markdown·豆包
阿昌喜欢吃黄桃4 天前
提示词工程:User Prompt 与 System Prompt
ai·prompt·提示词·提示词工程
AI产品测评官4 天前
海内外AI招聘工具分赛道横向对比:五大品类的技术路线与选型参考
人工智能·ai·求职招聘
俊哥V4 天前
每日 AI 研究简报 · 2026-09-21
人工智能·ai
omenkk74 天前
上下文工程:优化系统提示词,利用 KV Cache 降低 Token 成本
ai
代码方舟4 天前
零信任架构实战:基于天远手机在网状态V即时版构建自动化通信分发网关
人工智能·ai·工具分享
MicrosoftReactor4 天前
技术速递|GitHub Copilot App 入门指南:使用 Diff、终端和浏览器
ai·copilot·agent
TechEdu2026064 天前
[人工智能]人工智能时代的零日漏洞与零日攻击
人工智能·网络安全·ai·信息安全
程序员无隅4 天前
Pi Agent Loop 完整流程源码解析:从 Agent.prompt() 到 agent_end
ai