首页 / 资讯中心 / 文章详情

OpenClaw 源码解读(18)用日志追踪 Embedded Agent Runner 执行全链路:从配置到验证

OpenClaw 源码解读(18)用日志追踪 Embedded Agent Runner 执行全链路:从配置到验证 ★ FEATURED ARTICLE
1. 一条消息卡在“processing”时日志到底该看哪几行如果你正在读 OpenClaw 源码或者本地跑着一个 Embedded Agent Runner大概率遇到过这种场景Matrix 通道里消息发出去了界面一直显示 processing既没有报错也没有回复。这时候翻日志满屏都是[agent/embedded]、[diagnostic]、[model-fetch]前缀根本不知道从哪一行开始看。这篇就聚焦这件事把 Embedded Agent Runner 从“配置注入”到“SSE 流式返回”的日志链路拆开给你一份可以直接抄的日志配置骨架再配合 TaoToken 的统一 Key/API 通道把本地调试环境跑通。适合两类人一是正在读 OpenClaw 源码、想搞清执行链路关键节点的同学二是本地起了 Agent Runner、但日志级别没配对、看不到关键信息的同学。核心检索词先摆出来OpenClaw 的 Embedded Agent Runner 是内嵌在 Agent 进程里的执行引擎负责把一条入站消息变成一次 LLM 调用日志追踪是它暴露执行链路的主要手段执行链路从 extraParams 注入开始经过 Admission 并发控制、prompt 组装、上下文预检、max_tokens 钳制最后到 provider-transport-fetch 发请求。你要做的是让这条链路的每一段都打出可读日志而不是只看到一句“processing”。我试过在默认配置下直接跑日志里只有 lifecycle 的 start/end中间 prompt 组装和预算检查全是 debug 级别默认不输出。所以第一步不是读代码是把日志级别和输出目标配对。2. 前置TaoToken 统一 Key 与 API 通道接入OpenClaw 的 provider 配置支持自定义 baseUrl这意味着你可以把请求指向一个统一的 API 通道而不是在每个 agent 里分别填不同厂商的 Key。TaoToken 在这里的角色就是这层统一通道一个 Key 覆盖多家模型baseUrl 固定省去在 config.toml 里反复改 provider 段的麻烦。接入动作分三步。第一步在 TaoToken 控制台创建一个 API Key地址是 https://taotoken.net/api-keys 创建后复制出来后面写进环境变量。第二步确认你要用的模型名模型对话页 https://taotoken.net/models 可以看当前可用的模型标识比如 qwen 系列、claude 系列。第三步把 baseUrl 指向 https://taotoken.net/api 注意这个地址不带任何查询参数直接作为 OpenAI 兼容端点使用。这里有个容易踩的坑OpenClaw 的 provider 配置里api字段要写openai-completions而不是openai。因为 Embedded Agent Runner 走的是 completions 传输层日志里你会看到apiopenai-completions如果写成别的transport 层不会触发 SSE 解析日志里就看不到contentTypetext/event-stream。如果你后面要做长期编码或者多 Agent 编排可以考虑 Coding Plan地址 https://taotoken.net/coding-plan 它更适合持续性的 agent 调用场景。但本篇先聚焦单次调试链路的打通。3. 可复制的日志配置骨架OpenClaw 的配置分两层一层是config.toml管 provider、model、agent 的静态配置另一层是settings.json管运行时行为和日志级别。两份都要改缺一个都看不到完整链路。3.1 config.toml 片段[providers.taotoken] api openai-completions baseUrl https://taotoken.net/api apiKeyEnv TAOTOKEN_API_KEY [models.qwen-debug] provider taotoken id qwen3.7-plus contextWindow 150000 maxOutputTokens 128000 [agents.code-analyst] model qwen-debug systemPromptFile ./prompts/code-analyst.md关键点apiKeyEnv指向环境变量不要把 Key 硬编码进 toml。contextWindow和maxOutputTokens这两个值会直接影响后面预检和钳制日志里的数字配错了日志里的contextTokenBudget就对不上。3.2 settings.json 片段{ logging: { level: debug, targets: [stderr, file], file: { path: ./logs/embedded-runner.log, rotate: { maxSizeMb: 64, maxFiles: 5 } }, namespaces: { agent/embedded: debug, diagnostic: debug, openai-transport: debug, provider-transport-fetch: debug, context-diag: debug } }, embeddedRunner: { admission: { maxConcurrentRuns: 4 }, contextBudget: { reserveTokens: 20000, precheckEnabled: true } } }namespaces这一段是重点。OpenClaw 的日志按命名空间分级默认agent/embedded是 info你把它调到 debug 才能看到embedded run prompt start和[context-diag] pre-prompt。provider-transport-fetch调到 debug 才能看到[model-fetch] start和response。3.3 环境变量export TAOTOKEN_API_KEYsk-你的key export OPENCLAW_LOG_LEVELdebug export OPENCLAW_LOG_FILE./logs/embedded-runner.log环境变量优先级高于 settings.json本地调试时用环境变量临时覆盖最方便。4. 逐步验证从启动到看到 SSE 返回配置写完按下面顺序验证每一步都有对应的日志特征对不上就说明那一段没打通。4.1 启动并确认配置加载openclaw run --agent code-analyst --log-level debug启动后先 grep 配置加载日志grep applying extraParams ./logs/embedded-runner.log期望看到类似[agent/embedded] applying extraParams to agent streamFn for taotoken/qwen3.7-plus这行说明 extraParams 注入生效了provider 和 model 解析正确。如果这行没有检查 config.toml 里 provider 名和 model 名是否拼错。4.2 发一条测试消息观察 Admission 登记通过 Matrix 通道或者本地 CLI 发一条消息然后看grep run registered ./logs/embedded-runner.log期望[diagnostic] session state: sessionId... prevprocessing newprocessing reasonrun_started queueDepth1 [diagnostic] run registered: sessionId... totalActive1reasonrun_started说明是首次登记totalActive1说明当前只有一个并发 run。如果同一个 session 连发两条第二条会显示reasonrun_replaced这是 Admission 并发控制在起作用。4.3 确认 prompt 组装与上下文预检grep -E embedded run prompt start|context-diag|context-overflow-precheck ./logs/embedded-runner.log期望看到三行关键日志[agent/embedded] embedded run prompt start: runId... providertaotoken apiopenai-completions endpointcustom routeproxy-like policynone [agent/embedded] [context-diag] pre-prompt: messages6 roleCountsassistant:3,toolResult:1,user:2 systemPromptChars26492 promptChars1711 [agent/embedded] [context-overflow-precheck] routefits estimatedPromptTokens10209 promptBudgetBeforeReserve130000 overflowTokens0routeproxy-like说明 baseUrl 被识别为自定义代理端点这会触发后面的 max_tokens 钳制分支。routefits说明上下文没超不需要压缩。如果这里显示compact_only或truncate_tool_results_only说明你的 contextWindow 配小了或者历史消息太长。4.4 确认 max_tokens 钳制与请求发出grep -E clamp_max_tokens|model-fetch ./logs/embedded-runner.log期望[openai-transport] [completions] clamp_max_tokens providertaotoken apiopenai-completions modelqwen3.7-plus requested128000 output126533 effectiveContext150000 estimatedInput23466 [provider-transport-fetch] [model-fetch] start providertaotoken apiopenai-completions modelqwen3.7-plus methodPOST urlhttps://taotoken.net/api/v1/chat/completions [provider-transport-fetch] [model-fetch] response providertaotoken apiopenai-completions modelqwen3.7-plus status200 elapsedMs1247 contentTypetext/event-stream; charsetutf-8看到status200和contentTypetext/event-stream说明请求成功且是流式返回。elapsedMs是首字节时间如果这个值特别大问题在通道侧不在 OpenClaw 侧。4.5 验证流式内容落盘grep stream chunk ./logs/embedded-runner.log | tail -5期望看到连续的 chunk 日志最后一条带finish_reasonstop。到这里整条链路就通了。5. 本篇常见错排查5.1 日志里只有 lifecycle没有 prompt 组装现象grepembedded run prompt start返回空。原因通常是agent/embedded命名空间还是 info 级别。检查 settings.json 的namespaces段确认agent/embedded是 debug。另外确认环境变量OPENCLAW_LOG_LEVEL没有覆盖成 info。5.2 报 401 或 403但 Key 是对的现象[model-fetch] response status401。先确认 baseUrl 是https://taotoken.net/api不要多加/v1OpenClaw 的 transport 层会自己拼/v1/chat/completions。如果 baseUrl 写成https://taotoken.net/api/v1最终 URL 会变成/api/v1/v1/chat/completions直接 404 或 401。另外确认apiKeyEnv指向的环境变量在当前 shell 里确实 export 了。5.3 预检显示 compact_only但消息并不长现象context-overflow-precheck routecompact_only。检查 config.toml 里的contextWindow如果配成了 32000 而实际模型支持 150000预检会误判溢出。把contextWindow改成模型真实上限reserveTokens保持 20000 左右。5.4 clamp_max_tokens 没出现现象grep 不到clamp_max_tokens。这个分支只在routeproxy-like且clampedMaxTokens有值时触发。如果你的 baseUrl 被识别成非 proxy-like或者maxOutputTokens没配就不会走这个分支。确认 config.toml 里 model 段有maxOutputTokens且 baseUrl 是自定义域名而非官方域名。5.5 流式返回中断日志停在 response 没有 chunk现象看到status200 contentTypetext/event-stream但后面没有 chunk 日志。这通常是 SSE 解析层的问题检查openai-transport命名空间是否 debug。如果确认是 debug 还是没有 chunk可能是通道侧在首字节后断流用 curl 直接打一次同样的请求对比curl -N https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d {model:qwen3.7-plus,stream:true,messages:[{role:user,content:ping}]}如果 curl 能持续收到data:行说明通道没问题问题在 OpenClaw 的 transport 配置。6. 把日志链路固定成调试习惯整条链路跑通之后建议把上面几个 grep 命令写成一个脚本每次调试先跑一遍三十秒内就能定位卡在哪一段。日志追踪的价值不在于日志多而在于每一段都有明确的“通过特征”extraParams 看 provider/model 解析Admission 看 run_startedprompt 组装看 routeproxy-like预检看 routefits钳制看 clamp_max_tokens请求看 status200 text/event-stream。如果你在接入阶段遇到 Key 或 baseUrl 的问题直接去 https://taotoken.net/api-keys 重新生成一个 Key 对比测试排除 Key 本身的问题。模型标识不确定的时候https://taotoken.net/models 可以对照当前可用列表。需要长期跑编码类 agent 的话Coding Plan 页面 https://taotoken.net/coding-plan 有更细的配额说明。接入文档在 https://taotoken.net/doc 里面有针对 OpenAI 兼容端点的完整参数说明配 config.toml 时对着看能少踩几个字段名的坑。
阅读完成 · 觉得有帮助?
咨询建站