<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>2026 on 猜猜是谁的博客</title><link>https://caifengze.com/zh-cn/post/2026/</link><description>Recent content in 2026 on 猜猜是谁的博客</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 19 Jun 2026 14:28:37 -0400</lastBuildDate><atom:link href="https://caifengze.com/zh-cn/post/2026/index.xml" rel="self" type="application/rss+xml"/><item><title>CodexGo 回忆录：在 Auto Approve 出现前夜</title><link>https://caifengze.com/zh-cn/blog/2026/codexgo-memoir-before-auto-approve/</link><pubDate>Fri, 19 Jun 2026 14:28:37 -0400</pubDate><guid>https://caifengze.com/zh-cn/blog/2026/codexgo-memoir-before-auto-approve/</guid><description>&lt;h2 id="写在前面">写在前面
&lt;/h2>&lt;p>没事看了一下自己的 blog，又是大几个月没更新了，其实脑子里一直都有很多idea，不过陪伴，工作，各种事情充斥着生活，也没多少时间记记想记录的事情。&lt;/p>
&lt;p>一直都觉得&lt;strong>反思&lt;/strong>很重要，不过我好像也没常反思。把标题取做回忆录，既是给这个项目“入坟”的哀悼，也是一个让自己多反思的提点。&lt;/p>
&lt;p>我觉得自己当时应该是有点 &lt;a class="link" href="https://en.wikipedia.org/wiki/Fear_of_missing_out" target="_blank" rel="noopener"
>Fomo&lt;/a> 的。&lt;/p>
&lt;p>codex 的 desktop 横空出世，让我非常的开心，不用再每天盯着“编辑器”在那看代码了。说实在的，按照当时我用 ai 的开发习惯，最集中的注意力其实不是代码本身，而是转移到了项目架构，文件结构，代码规范，测试上。而 cc 和 codex 本质上就是 这种注意力转移的更显化的产品。&lt;/p>
&lt;p>在 cursor 和 codex plugin in VSCode 的时代，AI 写出来的代码，我总会点过去看看，到底长什么样，但我其实也不是一个coding freshman，觉得自己在学习，但也挑不出什么 AI 的毛病，只能反复问：你可以再检查一下自己的代码吗，看看哪里还有问题。一直问到，ai 自己也觉得没有什么问题，然后开始测试的循环了。&lt;/p>
&lt;p>我记得还问过 siwei 老师，到底怎么让 AI 的代码写的好呢？记得当时 siwei 老师应该已经开始大规模的 AI coding 造出了 nowledge-mem了，并且整体的完成度非常高，和我能做出来的玩意儿是在是差距真有点大哈哈哈。 siwei 老师回答大概的意思是，多验证，多测试，好像很简单，但其实这一套范式至今，也是 vibe coding 的非常合理化的手段。&lt;/p>
&lt;p>像前面说的 vibe coding 本质上是把注意力转移到架构上了，你变成指挥的人了，那在你手下干活的 coding agent，本质上也是一个会coding的“人”，你要保证他产出的东西有用，那应该用公司生产的那一套范式，让其他人（agent）去验证开发的对还是不对。&lt;/p>
&lt;p>至此，我觉得，测试，运维其实在这个时代的地位是上升了许多的。&lt;/p>
&lt;p>我想，这些话作为这篇文章的开头语，似乎又有点多了，可能我需要另有一篇来介绍自己对 AI coding 的理解吧。&lt;/p>
&lt;h2 id="正文">正文
&lt;/h2>&lt;h3 id="缘起">缘起
&lt;/h3>&lt;p>为什么我说自己 fomo 的，其实我是真想折腾一点好用的小工具出来，能够让自己有一个 star 基础的（貌似有点功利了）。&lt;/p>
&lt;p>所以我不断找啊找啊找需求。然后看到了 permission 这个问题上。这个问题确实很早就出现了: 在我还在用 vscode 的时候，其实并不放心，所有的 命令 ai 都能操作，但对 ask mode 又很厌烦，动不动2-3s一个 bash 就需要自己 approve，不然整个进度就会卡住。等我看到帖子里的很多人都在说这个问题的时候，codexgo 的 idea 就横空出世了——我需要一个工具就是能自动 approve 执行我觉得不重要的命令，也能为我拦下关键的操作。&lt;/p>
&lt;h3 id="借钩">借钩
&lt;/h3>&lt;p>当然，思路非常简单，就是在 codex 进行 &lt;code>PermissionRequest&lt;/code> 前利用 hook 加了一层判断，像这样&lt;/p>
&lt;pre tabindex="0">&lt;code>Codex PermissionRequest -&amp;gt; codexgo decide -&amp;gt; allow / deny / ask
&lt;/code>&lt;/pre>&lt;p>allow, deny, ask 区分很清楚，所有在 allow 范围里面的，都会直接批准;&lt;code>deny&lt;/code> 表示阻止；&lt;code>ask&lt;/code> 表示不做决定，交还给 Codex 原本的确认弹窗。&lt;/p>
&lt;h3 id="初成">初成
&lt;/h3>&lt;p>就单单这么说，显得项目就很简单了，那怎么能让用户直接就上手呢？&lt;/p>
&lt;p>就直接：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">codexgo init
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>然后你就可以在所有项目里都享受到 codex 的便利啦！&lt;/p>
&lt;p>当然，codexgo 还支持项目级别的配置，即:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">codexgo init --scope project
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>是不是像 &lt;code>git init&lt;/code> 一样简单！&lt;/p>
&lt;h3 id="分野">分野
&lt;/h3>&lt;p>当然，用户级别配置，config 会写在&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">~/.codex/config.toml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">~/.codex/hooks.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">~/.codexgo/policy.json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>如果是 项目级 配置则是出现在&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&amp;lt;repo&amp;gt;/.codex/config.toml
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;repo&amp;gt;/.codex/hooks.json
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;lt;repo&amp;gt;/.codexgo/policy.json
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>并且项目级配置优先于用户级配置。&lt;/p>
&lt;h3 id="立规">立规
&lt;/h3>&lt;p>在 &lt;code>codex init&lt;/code> 后会自动生成一些基本配置，这个是按照正常的需求来的，比如，&lt;code>rm -rf /&lt;/code>、&lt;code>sudo&lt;/code> 等等命令肯定不用说，都是会被deny的；像 &lt;code>pwd&lt;/code>、&lt;code>rg&lt;/code> 、&lt;code>git diff&lt;/code> 等等没有风险的常用命令会被自动包括进去。默认的这些规则我们称其为一个 profile，这个profile 叫做 manual profile，其规则是&lt;/p>
&lt;pre tabindex="0">&lt;code>命中 allow 规则 -&amp;gt; 自动允许
命中 deny 规则 -&amp;gt; 直接拒绝
命中 ask 规则 -&amp;gt; 交给 Codex 弹窗确认
没有命中规则 -&amp;gt; 交给 Codex 弹窗确认
&lt;/code>&lt;/pre>&lt;p>当然，这会在遇到很多其他不常规的命令时，需要你手动添加一些规则才行，添加命令的方式如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">codexgo allow &amp;lt;command&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo ask &amp;lt;command&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo deny &amp;lt;command&amp;gt;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>具体例子就像&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">codexgo allow &lt;span class="s2">&amp;#34;git status&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo deny &lt;span class="s2">&amp;#34;git reset --hard&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo ask &lt;span class="s2">&amp;#34;git push&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>当然，针对项目添加，只用像上面说的带上 &lt;code>--scope&lt;/code> 就好&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">codexgo allow --scope project &lt;span class="s2">&amp;#34;npm run lint&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo ask --scope project &lt;span class="s2">&amp;#34;git push&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo deny --scope project &lt;span class="s2">&amp;#34;rm -rf&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="辨形">辨形
&lt;/h3>&lt;p>不过给的例子都像是非常精准匹配的，但事实上，我们还可以指定匹配方式，例如：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">codexgo allow --scope project --match exact &lt;span class="s2">&amp;#34;npm test&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">codexgo deny --scope project --match contains &lt;span class="s2">&amp;#34;curl | sh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>其中有三种匹配模式：&lt;/p>
&lt;pre tabindex="0">&lt;code>exact 完全匹配
prefix 前缀匹配，默认
contains 包含匹配
&lt;/code>&lt;/pre>&lt;p>这样，就可以在命令上更精细化控制了！&lt;/p>
&lt;h3 id="放行">放行
&lt;/h3>&lt;p>以上，已经是一个比较完善的产品了，但我还是懒，我只想要我明确禁止的命令不做，其他全部 pass 好啦！&lt;/p>
&lt;p>那这个时候就有一个 &lt;code>go profile&lt;/code>。&lt;/p>
&lt;p>默认 manual 模式下，只有命中明确规则的命令才会自动 allow / deny；其它命令都会回到 Codex 弹窗确认。&lt;code>go profile&lt;/code> 则是我只关注需要 deny 和 ask 的 命令，而剩余的命令全部都可以 自动放行，也就是如下逻辑：&lt;/p>
&lt;pre tabindex="0">&lt;code>go profile:
1. 先看 project / user 显式规则里的 deny / ask
2. 再看 go profile 风险规则里的 deny / ask
3. 再看 built-in defaults
4. 如果是复杂 shell / 重定向 / 下载写文件 / 命令替换等 -&amp;gt; ask
5. 如果还没命中，并且不是复杂命令 -&amp;gt; allow
&lt;/code>&lt;/pre>&lt;p>那其实这个产品，就更加便捷了，只用&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">codexgo go --scope project
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>就可以开始用啦！defaults 里面已经把大多数日常危险的命令都 deny 或者 ask 了，剩下的，就是无比丝滑！&lt;/p>
&lt;h3 id="潮来">潮来
&lt;/h3>&lt;p>刚做出来的时候，我自己用的也非常开心，不过没两天，你知道，codex 官方就提供了一个 anto approve for me 的选项，按调研过来看，这是一个小模型的实现。虽然规则不像我们这样严苛，但是解决了大部分问题，甚至逻辑上更加丝滑，不用用户再自己控制一些规则了。&lt;/p>
&lt;p>我自己也是，在用过自己做出来的产品一周后，发现，已经可以被 codex 的这个功能基本完全（不完全是因为我觉得还会有些命令，有用户）替代了。当时应该还是很感叹的：刚出世的小东西，一下子就没了用武之地。&lt;/p>
&lt;h3 id="余响">余响
&lt;/h3>&lt;p>虽然现在来看，觉得自己做的还挺有意义的，只不过在更优秀的产品面前，被淘汰也是很自然的事情。时代洪流裹挟着大家一起往前飘，努力划桨，为的是在前方插下一个属于自己的旗帜，但大海会慢慢涌过它；也许被淹没，也许被看到的人慷慨。&lt;/p>
&lt;p>如果你想看看这个旗帜短暂存在过的样子：&lt;a class="link" href="https://github.com/Fengzdadi/codexgo" target="_blank" rel="noopener"
>Fengzdadi/codexgo&lt;/a>。&lt;/p></description></item><item><title>为什么 OpenClaw 消耗 Token 这么快？</title><link>https://caifengze.com/zh-cn/blog/2026/%E4%B8%BA%E4%BB%80%E4%B9%88-openclaw-%E6%B6%88%E8%80%97-token-%E8%BF%99%E4%B9%88%E5%BF%AB/</link><pubDate>Thu, 05 Feb 2026 21:00:00 -0500</pubDate><guid>https://caifengze.com/zh-cn/blog/2026/%E4%B8%BA%E4%BB%80%E4%B9%88-openclaw-%E6%B6%88%E8%80%97-token-%E8%BF%99%E4%B9%88%E5%BF%AB/</guid><description>&lt;img src="https://caifengze.com/zh-cn/blog/2026/%E4%B8%BA%E4%BB%80%E4%B9%88-openclaw-%E6%B6%88%E8%80%97-token-%E8%BF%99%E4%B9%88%E5%BF%AB/overview.png" alt="Featured image of post 为什么 OpenClaw 消耗 Token 这么快？" />&lt;h1 id="为什么-openclaw-消耗-token-这么快">为什么 OpenClaw 消耗 Token 这么快？
&lt;/h1>&lt;p>这篇文章的第一部分回答一个最基础、但也最关键的问题：&lt;/p>
&lt;h2 id="每次交互openclaw-到底向模型发送了什么">每次交互，OpenClaw 到底向模型发送了什么？
&lt;/h2>&lt;p>当我们说“上下文很大、token 消耗很快”，本质上是在说：每一次调用模型 API 时，OpenClaw 会把一段“完整输入”发送给模型，这段输入往往远超过用户的当前一句话。&lt;/p>
&lt;p>下面是这段输入的组成和来源。&lt;/p>
&lt;p>&lt;strong>1. System Prompt（系统提示词）&lt;/strong>&lt;/p>
&lt;p>系统提示词是 OpenClaw 每次调用模型都会带上的“基础说明书”。它包含了多段固定或半固定内容，核心目的是让模型知道它是什么、有哪些工具、在哪个工作目录、如何处理记忆和渠道消息等。&lt;/p>
&lt;p>System prompt 是一个“大盒子”，内部包含以下子块：&lt;/p>
&lt;ul>
&lt;li>Tooling 段：列出工具清单以及简要说明。&lt;/li>
&lt;li>Safety 段：基础安全与行为约束。&lt;/li>
&lt;li>Skills 段：技能目录提示（可很长，随技能数量增长）。&lt;/li>
&lt;li>Memory 段：记忆检索规范（告诉模型先搜索 MEMORY.md 等）。&lt;/li>
&lt;li>Documentation 段：本地文档路径提示。&lt;/li>
&lt;li>Workspace 段：当前工作目录 + 备注。&lt;/li>
&lt;li>Project Context 段：注入的上下文文件内容（通常是最大头）。&lt;/li>
&lt;li>Messaging/Voice/Reply Tags/Sandbox/Runtime 等辅助段。&lt;/li>
&lt;/ul>
&lt;p>下面的 2～4 小节之所以单独展开，是为了突出这些子块在 token 体积上的“贡献度”，而不是把它们当作 system prompt 之外的独立部分。&lt;/p>
&lt;p>System prompt 的构建逻辑集中在：&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/pi-embedded-runner/system-prompt.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. Project Context（项目上下文注入）&lt;/strong>&lt;/p>
&lt;p>这是 token 消耗最明显的部分之一。OpenClaw 会在每次运行前读取一组 workspace 的“引导文件”，再将它们原文注入到 system prompt 中。&lt;/p>
&lt;p>默认会读取的文件包括：&lt;/p>
&lt;ul>
&lt;li>&lt;code>AGENTS.md&lt;/code>&lt;/li>
&lt;li>&lt;code>SOUL.md&lt;/code>&lt;/li>
&lt;li>&lt;code>TOOLS.md&lt;/code>&lt;/li>
&lt;li>&lt;code>IDENTITY.md&lt;/code>&lt;/li>
&lt;li>&lt;code>USER.md&lt;/code>&lt;/li>
&lt;li>&lt;code>HEARTBEAT.md&lt;/code>&lt;/li>
&lt;li>&lt;code>BOOTSTRAP.md&lt;/code>&lt;/li>
&lt;li>&lt;code>MEMORY.md&lt;/code> 或 &lt;code>memory.md&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>这些文件会被逐个裁剪（单文件上限默认 20,000 chars），然后以如下形式插入：&lt;/p>
&lt;pre tabindex="0">&lt;code># Project Context
## BOOTSTRAP.md
&amp;lt;内容&amp;gt;
&lt;/code>&lt;/pre>&lt;p>逻辑位于：&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/workspace.ts&lt;/code>（读取文件集合）&lt;/li>
&lt;li>&lt;code>src/agents/bootstrap-files.ts&lt;/code>（组装注入）&lt;/li>
&lt;li>&lt;code>src/agents/pi-embedded-helpers/bootstrap.ts&lt;/code>（裁剪）&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>（最终注入）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>3. Skills 列表（技能清单）&lt;/strong>&lt;/p>
&lt;p>如果开启了 skills，OpenClaw 会把全部 skills 编成一个目录段落，注入到 system prompt。这个列表会随技能数量和描述长度线性增长。&lt;/p>
&lt;p>它不是“工具”，而是“工作流程说明”，模型会根据提示去读 SKILL.md。&lt;/p>
&lt;p>相关逻辑：&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/skills/workspace.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>4. Tools 定义（工具清单 + schema）&lt;/strong>&lt;/p>
&lt;p>模型真正能调用的工具列表（如 &lt;code>read&lt;/code>、&lt;code>exec&lt;/code>、&lt;code>message&lt;/code>）会被注入到 system prompt 中，同时工具参数 schema 也会被传入模型。这部分通常不会在 prompt 里完整展示，但仍会占用输入 token。&lt;/p>
&lt;p>相关逻辑：&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/pi-tools.ts&lt;/code>&lt;/li>
&lt;li>&lt;code>src/agents/system-prompt.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>5. 历史对话 + 工具结果&lt;/strong>&lt;/p>
&lt;p>除了 system prompt，OpenClaw 还会把 session 中的历史消息、工具调用结果一起发送给模型。这些历史会不断累积，直到触发 compaction 或 memory flush。&lt;/p>
&lt;p>相关逻辑：&lt;/p>
&lt;ul>
&lt;li>&lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code>（加载历史）&lt;/li>
&lt;li>&lt;code>src/agents/pi-embedded-runner/compact.ts&lt;/code>（压缩）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>6. 当前用户输入&lt;/strong>&lt;/p>
&lt;p>最后才是用户的这一条消息，它会和上面所有内容一起构成“本次 API 调用的完整输入”。&lt;/p>
&lt;p>&lt;strong>总结：一次交互实际上不是“只发你这一句话”。&lt;/strong>&lt;/p>
&lt;p>OpenClaw 每次调用模型，会发送：&lt;/p>
&lt;ul>
&lt;li>system prompt（很长）&lt;/li>
&lt;li>project context（很长）&lt;/li>
&lt;li>skills 列表（可很长）&lt;/li>
&lt;li>工具 schema（可很长）&lt;/li>
&lt;li>历史对话与工具结果（会不断增长）&lt;/li>
&lt;li>当前用户消息&lt;/li>
&lt;/ul>
&lt;p>这就是为什么 token 会增长得很快。&lt;/p>
&lt;p>&lt;img src="https://caifengze.com/zh-cn/blog/2026/%E4%B8%BA%E4%BB%80%E4%B9%88-openclaw-%E6%B6%88%E8%80%97-token-%E8%BF%99%E4%B9%88%E5%BF%AB/overview.png"
width="4284"
height="2112"
srcset="https://caifengze.com/zh-cn/blog/2026/%E4%B8%BA%E4%BB%80%E4%B9%88-openclaw-%E6%B6%88%E8%80%97-token-%E8%BF%99%E4%B9%88%E5%BF%AB/overview_hu_e49c0d2ff66be2e5.png 480w, https://caifengze.com/zh-cn/blog/2026/%E4%B8%BA%E4%BB%80%E4%B9%88-openclaw-%E6%B6%88%E8%80%97-token-%E8%BF%99%E4%B9%88%E5%BF%AB/overview_hu_27464601b4dee01f.png 1024w"
loading="lazy"
alt="OpenClaw token flow overview"
class="gallery-image"
data-flex-grow="202"
data-flex-basis="486px"
>&lt;/p>
&lt;p>&lt;em>图：一次请求中 system prompt、session history、用户输入与子 agent/fallback/compaction 的关系。&lt;/em>&lt;/p>
&lt;p>&lt;strong>代码佐证：系统提示词的“总装配口”&lt;/strong>&lt;/p>
&lt;p>以下是 &lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code> 中的关键片段，能直观看到哪些内容被打包进 system prompt（已做精简）：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// src/agents/pi-embedded-runner/run/attempt.ts
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">appendPrompt&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">buildEmbeddedSystemPrompt&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">skillsPrompt&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Skills 列表
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">contextFiles&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Project Context（BOOTSTRAP 等）
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">tools&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// Tool 列表 + schema
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">docsPath&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// 文档提示
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">runtimeInfo&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// 运行环境信息
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">workspaceNotes&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// workspace 提示
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">sandboxInfo&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// 沙箱信息
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">modelAliasLines&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1">// 模型别名
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="c1">// ... 还有更多辅助信息
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="一次请求可能触发多轮-api工具调用链">一次请求可能触发多轮 API：工具调用链
&lt;/h2>&lt;p>一个“用户请求”不一定只调用一次模型 API。最常见的原因是 &lt;strong>工具调用链&lt;/strong>：&lt;/p>
&lt;ol>
&lt;li>模型看到工具列表后，先发起 tool call（如 &lt;code>read&lt;/code> / &lt;code>exec&lt;/code>）。&lt;/li>
&lt;li>OpenClaw 执行工具，产出 tool result。&lt;/li>
&lt;li>工具结果被写回 session（作为工具消息）。&lt;/li>
&lt;li>模型继续生成，必要时再发起下一次 tool call。&lt;/li>
&lt;/ol>
&lt;p>这意味着一次用户输入可能产生多轮模型交互，从而更快消耗 token。&lt;/p>
&lt;p>对应代码入口（精简路径）：&lt;/p>
&lt;ul>
&lt;li>工具定义：&lt;code>src/agents/pi-tools.ts&lt;/code>&lt;/li>
&lt;li>session 创建 + tools 注入：&lt;code>src/agents/pi-embedded-runner/run/attempt.ts&lt;/code>&lt;/li>
&lt;li>订阅工具事件：&lt;code>src/agents/pi-embedded-subscribe.ts&lt;/code>&lt;/li>
&lt;li>工具执行生命周期处理：&lt;code>src/agents/pi-embedded-subscribe.handlers.tools.ts&lt;/code>&lt;/li>
&lt;/ul>
&lt;h2 id="失败重试--fallback模型回退与重试如何发生">失败重试 / fallback：模型回退与重试如何发生
&lt;/h2>&lt;p>OpenClaw 并不是“遇错就算了”。当模型调用失败（超时、限流、鉴权等），系统会尝试&lt;strong>模型回退&lt;/strong>，继续用候选模型列表中的下一个模型重试。&lt;/p>
&lt;p>核心逻辑在 &lt;code>runWithModelFallback&lt;/code> 中实现：&lt;br>
&lt;code>src/agents/model-fallback.ts&lt;/code>&lt;/p>
&lt;p>它的逻辑非常清晰：&lt;/p>
&lt;ol>
&lt;li>先根据配置生成“候选模型列表”（来自 &lt;code>agents.defaults.model.fallbacks&lt;/code> 或调用时传入的 override）。&lt;/li>
&lt;li>按顺序逐个尝试调用模型。&lt;/li>
&lt;li>只有当错误被判定为 &lt;strong>FailoverError&lt;/strong> 才会进入下一轮回退；否则直接抛错。&lt;/li>
&lt;/ol>
&lt;p>这意味着，&lt;strong>一次用户请求可能因为回退机制而触发多次 API 调用&lt;/strong>。当然，这是好事。&lt;/p>
&lt;h2 id="compaction-与-memory-flush上下文快满时发生了什么">Compaction 与 Memory Flush：上下文快满时发生了什么
&lt;/h2>&lt;p>当上下文快满时，OpenClaw 可能触发&lt;strong>两种不同的额外模型调用&lt;/strong>：&lt;br>
一个是 &lt;strong>Compaction（摘要压缩）&lt;/strong>，一个是 &lt;strong>Memory Flush（记忆写入）&lt;/strong>。两者目的不同、流程也不同。&lt;/p>
&lt;h3 id="1-compaction摘要压缩">1. Compaction（摘要压缩）
&lt;/h3>&lt;p>目标：把历史对话“压缩成更短摘要”，释放上下文空间。&lt;/p>
&lt;p>实现逻辑在：&lt;code>src/agents/compaction.ts&lt;/code>&lt;/p>
&lt;p>关键点：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>不是一次性把全部历史发给模型&lt;/strong>&lt;br>
会先按 token 将历史分块，然后逐块调用模型生成摘要，再合并为一个总摘要。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>如果单条消息太大&lt;/strong>&lt;br>
会走 fallback：只摘要小消息，大消息用占位提示。&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>简化流程：&lt;/p>
&lt;pre tabindex="0">&lt;code>历史消息 → 按 token 分块 → 每块调用模型摘要 → 合并摘要
&lt;/code>&lt;/pre>&lt;h3 id="2-memory-flush记忆写入">2. Memory Flush（记忆写入）
&lt;/h3>&lt;p>目标：在 compaction 之前，把“长期记忆”写入磁盘（&lt;code>memory/YYYY-MM-DD.md&lt;/code>）。&lt;/p>
&lt;p>触发逻辑在：&lt;code>src/auto-reply/reply/agent-runner-memory.ts&lt;/code>&lt;br>
提示与默认文案在：&lt;code>src/auto-reply/reply/memory-flush.ts&lt;/code>&lt;/p>
&lt;p>关键点：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>不是摘要历史&lt;/strong>&lt;br>
而是让模型整理出“值得长期保存的记忆”，写到 &lt;code>memory/&lt;/code> 目录。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>这是一轮额外的模型调用&lt;/strong>&lt;br>
目的在于保存持久记忆，而不是压缩上下文。&lt;/p>
&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="子-agent--sessions_spawn并行与分工如何导致额外调用">子 agent / sessions_spawn：并行与分工如何导致额外调用
&lt;/h2>&lt;p>当任务复杂、耗时或适合并行时，主 agent 可能会调用 &lt;code>sessions_spawn&lt;/code> 工具，把子任务交给子 agent 处理。这会启动一个&lt;strong>全新的子会话&lt;/strong>，它拥有自己的 sessionKey、system prompt 和工具链路，因此会带来额外的模型调用。&lt;/p>
&lt;p>核心入口在：&lt;code>src/agents/tools/sessions-spawn-tool.ts&lt;/code>&lt;/p>
&lt;p>简化流程如下：&lt;/p>
&lt;ol>
&lt;li>主 agent 调用 &lt;code>sessions_spawn&lt;/code>（这是一种模型的工具调用选择）。&lt;/li>
&lt;li>系统生成 &lt;code>childSessionKey&lt;/code>（&lt;code>agent:&amp;lt;id&amp;gt;:subagent:&amp;lt;uuid&amp;gt;&lt;/code>）。&lt;/li>
&lt;li>构造子 agent 的 system prompt（&lt;code>buildSubagentSystemPrompt&lt;/code>）。&lt;/li>
&lt;li>通过 &lt;code>callGateway&lt;/code> 启动子 agent 的独立运行流程。&lt;/li>
&lt;li>子 agent 完成任务后，结果回传主会话。&lt;/li>
&lt;/ol>
&lt;p>简单来说，就是 &lt;strong>子 agent 是“另起一条完整会话”&lt;/strong>。因此它会显著增加整体的 API 调用次数与 token 消耗。&lt;/p></description></item></channel></rss>