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);
  }
}
相关推荐
测试蔡坨坨8 小时前
OpenClaw 快速上手教程:用手机远程指挥电脑,打造你的 24 小时 AI 管家!
ai
方方不听话10 小时前
🦞 重磅!腾讯 QQ 官方接入 OpenClaw“小龙虾”:一键创建机器人,1分钟极速部署!
ai·openclaw·小龙虾
凉年技术2 天前
Claude Code 完整上手指南
ai
Johny_Zhao2 天前
centos7安装部署openclaw
linux·人工智能·信息安全·云计算·yum源·系统运维·openclaw
haibindev2 天前
在 Windows+WSL2 上部署 OpenClaw AI员工的实践与踩坑
linux·wsl2·openclaw
程序员徐公2 天前
OpenClaw 快速入门:10 分钟完成本地安装与配置(附常用命令速查)
openclaw·openclaw 安装·openclaw 最新安装教程
曲幽3 天前
FastAPI流式输出实战与避坑指南:让AI像人一样“边想边说”
python·ai·fastapi·web·stream·chat·async·generator·ollama
后端AI实验室3 天前
用AI写代码,我差点把漏洞发上线:血泪总结的10个教训
java·ai
程序员鱼皮3 天前
67个AI编程必会知识,1.6w字一次讲透!女友:“你要考研啊?!”
ai·程序员·编程·ai编程·vibe coding