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);
  }
}
相关推荐
SharpCJ1 小时前
在 JetBrains IDE 中接入 OpenCode 并配置自定义模型
ai·aigc
JaydenAI1 小时前
[AG-UI详解-06]AG-UI针对MAF的服务端实现
ai·agent·ag-ui·maf
一包惆怅的辣条2 小时前
谈一下怎么写一个一套可复用的用例改写skill架构
自动化测试·人工智能·ai·skill
俊哥V4 小时前
每日 AI 研究简报 · 2026-07-24
人工智能·ai
大公产经晚间消息4 小时前
“胜算未来·2026戈峻思享会”即将登陆大连
大数据·人工智能·ai
涛思数据(TDengine)5 小时前
WAIC 现场直击|烽台科技与 TDengine 战略签约:工业数据+“AI“,答案是什么?
大数据·人工智能·ai·时序数据库·tdengine·国产数据库
蓝创工坊Blue Foundry6 小时前
批量提取图片中的数字:怎样整理成一张可核对的 Excel
python·ai·ocr·excel·paddlepaddle
神奇霸王龙6 小时前
Claude Code 三层架构Subagent并发优化实战
人工智能·ai·架构·agent·ai编程·并发·claude
安逸sgr7 小时前
Agent经典面试题:Agent 安全问题有哪些?如何防止工具误调用和 Prompt Injection?
人工智能·ai·agent·智能体