AstralorIdeas · Code · Evolutionhttps://astralor.com/Firefly6.7.6https://github.com/CuteLeaf/Firefly2026年3月13日 23:02:39拆解 OpenClaw 并发模型:为什么 Subagent 默认并发比 Main 更高?https://astralor.com/posts/openclaw-concurrency-lanes/https://astralor.com/posts/openclaw-concurrency-lanes/升级到 v2026.3.12 后,我们发现 Subagent 的默认并发上限是 8,而 Main 只有 4。第一眼看到这组数字时,我们还以为又挖到了一个 bug——直到把命令队列的源码翻了一遍。Fri, 13 Mar 2026 00:00:00 GMT<blockquote><p>修掉那个让并发配置始终不起作用的问题之后,OpenClaw 的并发终于开始按配置工作了。</p><p>但当我们重新检查默认配置时,又发现事情并没有那么简单。</p></blockquote> <section><h2>一、sub 为什么比 main 大<a href="#一sub-为什么比-main-大"><span>#</span></a></h2><p>上一篇文章<a href="/posts/openclaw-concurrency-bug">《追踪 OpenClaw 的一个隐藏 bug:并发配置为什么从未生效》</a>里我们追踪了 OpenClaw 的一个并发状态隔离 bug——打包工具把一份运行时状态复制成了多份独立副本,导致 <code>maxConcurrent</code> 配多少都没用。我们提交了 Issue 和 PR,维护者在此基础上做了一次更全面的审计,把涉及十个模块的同类问题一起修了,随 v2026.3.12 发布。</p><p>在把 OpenClaw 版本升级完成后,我们检查了一下当前的并发配置:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>agents</span><span>:</span></div></div><div><div><div>2</div></div><div><span> </span><span>defaults</span><span>:</span></div></div><div><div><div>3</div></div><div><span> </span><span># 主 Agent 并发上限,默认 4</span></div></div><div><div><div>4</div></div><div><span> </span><span>maxConcurrent</span><span>: </span><span>10</span></div></div><div><div><div>5</div></div><div><span> </span><span>subagents</span><span>:</span></div></div><div><div><div>6</div></div><div><span> </span><span># 子 Agent 并发上限,默认 8</span></div></div><div><div><div>7</div></div><div><span> </span><span>maxConcurrent</span><span>: </span><span>8</span></div></div><div><div><div>8</div></div><div><span>cron</span><span>:</span></div></div><div><div><div>9</div></div><div><span> </span><span># 定时任务并发上限,默认 1</span></div></div><div><div><div>10</div></div><div><span> </span><span>maxConcurrentRuns</span><span>: </span><span>5</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>subagents.maxConcurrent</code> 默认是 8,主 Agent 的 <code>maxConcurrent</code> 默认只有 4。第一眼看到这组数字的时候,我们还以为又挖到了一个 bug——子 Agent 是从主 Agent 派生出来的,怎么并发上限反而更高?</p><p>通过对 OpenClaw 源码追完调用链之后发现,<strong><code>maxConcurrent</code> 和 <code>subagents.maxConcurrent</code> 不是同一个并发池</strong>。我们一开始把它理解成”父子并发关系”,但代码里的实现并不是这么一回事:<strong>命令队列分成了三条独立的 lane(Main、Subagent、Cron),各自有自己的队列和并发上限,互不阻塞。</strong></p><p></p><figure><img loading="lazy" width="2752" height="1536" src="/_astro/concurrency-lanes-comparison.BVAeSc85_24Rfjg.webp" /><figcaption>常见误解 vs 实际架构</figcaption></figure><p></p></section> <section><h2>二、先画个图<a href="#二先画个图"><span>#</span></a></h2><p>先把最终追出来的结构画出来,后面的源码追踪基本都在验证这张图:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>User Request</span></div></div><div><div><div>2</div></div><div><span><span> </span></span><span>│</span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>▼</span></div></div><div><div><div>4</div></div><div><span>Session Lane (per-session serialization)</span></div></div><div><div><div>5</div></div><div><span><span> </span></span><span>│</span></div></div><div><div><div>6</div></div><div><span><span> </span></span><span>▼</span></div></div><div><div><div>7</div></div><div><span>Global Command Lanes</span></div></div><div><div><div>8</div></div><div><span><span> </span></span><span>┌────────────────┬────────────────┬────────────────┐</span></div></div><div><div><div>9</div></div><div><span><span> </span></span><span>│ Main │ Subagent │ Cron │</span></div></div><div><div><div>10</div></div><div><span><span> </span></span><span>│ default: 4 │ default: 8 │ default: 1 │</span></div></div><div><div><div>11</div></div><div><span><span> </span></span><span>│ user messages │ background AI │ scheduled jobs │</span></div></div><div><div><div>12</div></div><div><span><span> </span></span><span>└────────────────┴────────────────┴────────────────┘</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>再往下看就会发现,这里有两层控制:同一个 session 内先串行保序(比如 Discord 一个频道里的消息不会乱序处理),不同 session 之间再按 Main / Subagent / Cron 三条 lane 去抢全局并发槽位。</p><p>三条 lane 各管各的,不共享计数器。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/concurrency-lanes-architecture.drgQn2np_i2aPV.webp" /><figcaption>分层架构</figcaption></figure><p></p></section> <section><h2>三、追源码<a href="#三追源码"><span>#</span></a></h2><p>先看配置怎么读。dist 文件里有两个函数,各自独立读各自的配置项,默认值也分开写死:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>resolveAgentMaxConcurrent</span><span><span>(</span><span>cfg</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span> </span><span>const</span><span> </span><span>raw</span><span> </span><span>=</span><span><span> </span><span>cfg</span><span>?.</span></span><span>agents</span><span>?.</span><span>defaults</span><span>?.</span><span>maxConcurrent</span><span>;</span></div></div><div><div><div>3</div></div><div><span> </span><span>if</span><span> (</span><span>typeof</span><span><span> </span><span>raw</span><span> </span></span><span>===</span><span> </span><span>"number"</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>Number</span><span>.</span></span><span>isFinite</span><span><span>(</span><span>raw</span><span>))</span></span></div></div><div><div><div>4</div></div><div><span> </span><span>return</span><span><span> </span><span>Math</span><span>.</span></span><span>max</span><span>(</span><span>1</span><span><span>, </span><span>Math</span><span>.</span></span><span>floor</span><span><span>(</span><span>raw</span><span>));</span></span></div></div><div><div><div>5</div></div><div><span> </span><span>return</span><span> </span><span>4</span><span>;</span></div></div><div><div><div>6</div></div><div><span>}</span></div></div><div><div><div>7</div></div><div> </div></div><div><div><div>8</div></div><div><span>function</span><span> </span><span>resolveSubagentMaxConcurrent</span><span><span>(</span><span>cfg</span><span>) {</span></span></div></div><div><div><div>9</div></div><div><span> </span><span>const</span><span> </span><span>raw</span><span> </span><span>=</span><span><span> </span><span>cfg</span><span>?.</span></span><span>agents</span><span>?.</span><span>defaults</span><span>?.</span><span>subagents</span><span>?.</span><span>maxConcurrent</span><span>;</span></div></div><div><div><div>10</div></div><div><span> </span><span>if</span><span> (</span><span>typeof</span><span><span> </span><span>raw</span><span> </span></span><span>===</span><span> </span><span>"number"</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>Number</span><span>.</span></span><span>isFinite</span><span><span>(</span><span>raw</span><span>))</span></span></div></div><div><div><div>11</div></div><div><span> </span><span>return</span><span><span> </span><span>Math</span><span>.</span></span><span>max</span><span>(</span><span>1</span><span><span>, </span><span>Math</span><span>.</span></span><span>floor</span><span><span>(</span><span>raw</span><span>));</span></span></div></div><div><div><div>12</div></div><div><span> </span><span>return</span><span> </span><span>8</span><span>;</span></div></div><div><div><div>13</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>再看调用点,两个值分别塞进了不同的 <code>CommandLane</code>:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>setCommandLaneConcurrency</span><span><span>(</span><span>CommandLane</span><span>.</span></span><span>Main</span><span>, </span><span>resolveAgentMaxConcurrent</span><span><span>(</span><span>cfg</span><span>));</span></span></div></div><div><div><div>2</div></div><div><span>setCommandLaneConcurrency</span><span><span>(</span><span>CommandLane</span><span>.</span></span><span>Subagent</span><span>, </span><span>resolveSubagentMaxConcurrent</span><span><span>(</span><span>cfg</span><span>));</span></span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>到这里其实已经能判断:这俩参数控制的不是同一个并发池。</p><p>再往下看 <code>setCommandLaneConcurrency</code> 的实现。lane 的状态存储在一个 <code>Map&lt;string, LaneState&gt;</code> 里,每条 lane 独立维护自己的并发计数:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>setCommandLaneConcurrency</span><span><span>(</span><span>lane</span><span>, </span><span>maxConcurrent</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span> </span><span>const</span><span> </span><span>state</span><span> </span><span>=</span><span> </span><span>getOrCreateLaneState</span><span><span>(</span><span>lane</span><span>);</span></span></div></div><div><div><div>3</div></div><div><span><span> </span></span><span>state</span><span>.</span><span>maxConcurrent</span><span> </span><span>=</span><span><span> </span><span>Math</span><span>.</span></span><span>max</span><span>(</span><span>1</span><span><span>, </span><span>Math</span><span>.</span></span><span>floor</span><span><span>(</span><span>maxConcurrent</span><span>));</span></span></div></div><div><div><div>4</div></div><div><span> </span><span>drainLane</span><span><span>(</span><span>state</span><span>);</span></span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>队列 pump 的核心循环只看当前 lane 自己的计数器,不跨 lane 检查:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>while</span><span><span> (</span><span>state</span><span>.</span></span><span>activeTaskIds</span><span>.</span><span>size</span><span> </span><span>&lt;</span><span><span> </span><span>state</span><span>.</span></span><span>maxConcurrent</span><span> </span><span>&amp;&amp;</span><span><span> </span><span>state</span><span>.</span></span><span>queue</span><span>.</span><span>length</span><span> </span><span>&gt;</span><span> </span><span>0</span><span>) {</span></div></div><div><div><div>2</div></div><div><span> </span><span>// 从队列里取一个任务执行</span></div></div><div><div><div>3</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>那任务怎么路由到对应 lane 的呢?</p><p>子 Agent 运行时显式标记 <code>lane: AGENT_LANE_SUBAGENT</code>,普通请求不指定 lane 时 fallback 到 <code>main</code>,Cron 任务走 <code>CommandLane.Cron</code>。 源码注释写得也很直白:<code>"session lane + global lane"</code>,执行路径是先拿 session 锁,再抢 global lane 槽位:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>enqueueSession</span><span>(() </span><span>=&gt;</span><span> </span><span>enqueueGlobal</span><span>(</span><span>async</span><span> () </span><span>=&gt;</span><span> { </span><span>...</span><span> }))</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>两层都拿到了,任务再开始跑。</p><p>为了交叉验证我们的想法,我们还让 Codex 独立重新分析了一遍源码,最后落到的也是同一组函数和同一个 lane 结构。</p></section> <section><h2>四、这么拆的好处<a href="#四这么拆的好处"><span>#</span></a></h2><p>看到这里,三条 lane 的分工就比较清楚了:</p><ul> <li><strong>Main</strong>:处理入站消息。用户在 Discord 或 Telegram 发了条消息,Agent 需要生成回复。用户在等,这是交互式的。</li> <li><strong>Subagent</strong>:子 Agent 任务。主 session 里 spawn 了一个 Codex 去分析代码,或者启动了一个子 Agent 做搜索。后台执行,不阻塞用户。</li> <li><strong>Cron</strong>:定时任务。心跳检查、信息采集、定期归档。按计划触发,和用户操作无关。</li> </ul><p>换个系统设计里的说法,这里做的就是 workload isolation——把三类任务拆到不同并发池里,避免它们互相抢槽位。Web 服务器把静态文件、API 请求和 WebSocket 连接分到不同线程池,道理是一样的。</p><p>如果子 Agent 和主 Agent 共享同一个池子,问题很明显:你 spawn 几个子 Agent 把池子占满了,新来的用户消息全部排队。机器人对所有人”失去响应”,直到某个子 Agent 跑完释放槽位。独立 lane 保证了不管后台跑多少子任务,用户消息的响应通道不会被堵。</p><p>这时候再回头看 <code>sub(8) &gt; main(4)</code>,意思就不一样了。4 个主 session 同时处理用户消息,每个都可能 spawn 1-2 个子 Agent。全局子 Agent 上限给到 8,刚好能容纳典型的并发量,不会因为槽位不够让一半主 session 的子任务排队。</p></section> <section><h2>五、几个容易算错的地方<a href="#五几个容易算错的地方"><span>#</span></a></h2><p>把 lane 关系理顺之后,前面几个容易误判的点也就解释得通了。</p><p><strong>理论峰值是加法,不是乘法。</strong> 以我们当前的配置(Main=10, Subagent=8, Cron=5)为例,理论最大同时运行的 LLM 调用是 10 + 8 + 5 = 23,不是 10 × 8 + 5 = 85。很容易在这里算错,是因为 Subagent lane 只有一个全局池,不是每个 Main session 都各带一个。</p><p><strong>配置该怎么调。</strong> 不同使用场景下侧重点不同:</p><ul> <li><strong>单人使用</strong>:<code>maxConcurrent</code> 设 2 就够了,同时活跃的对话很少超过两个。<code>subagents.maxConcurrent</code> 设 4,留出每个主 session 各 spawn 1-2 个子 Agent 的空间。<code>cron.maxConcurrentRuns</code> 保持默认 1,任务量不大时串行足够。</li> <li><strong>多人 / 多频道</strong>:<code>maxConcurrent</code> 调到 4-6,确保不同用户的消息能并行处理。<code>subagents.maxConcurrent</code> 保持默认 8,和 Main 槽位的典型比例刚好匹配。<code>cron.maxConcurrentRuns</code> 可以调到 2,避免定时任务排队影响响应。</li> <li><strong>频繁使用子 Agent</strong>(比如 ACP 模式委派编码任务):<code>subagents.maxConcurrent</code> 可以自由调大到 12 甚至更高,这条 lane 独立于主 Agent,不会影响用户消息的响应。</li> <li><strong>大量定时任务</strong>:<code>cron.maxConcurrentRuns</code> 调到 3-5。不过在调高之前,建议先用 <code>staggerMs</code> 把任务触发时间错开——我们自己就是用 staggerMs 把十几个 cron job 分散到不同时间点,减少同一时刻的并发压力。即便如此,密集时段仍然需要一定的并行能力。</li> </ul><p>以我们自己的配置为例(单人 + 多频道 + 重度 cron 用户):</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>agents</span><span>:</span></div></div><div><div><div>2</div></div><div><span> </span><span>defaults</span><span>:</span></div></div><div><div><div>3</div></div><div><span> </span><span># 多频道并行,比默认 4 高</span></div></div><div><div><div>4</div></div><div><span> </span><span>maxConcurrent</span><span>: </span><span>10</span></div></div><div><div><div>5</div></div><div><span> </span><span>subagents</span><span>:</span></div></div><div><div><div>6</div></div><div><span> </span><span># 默认值,目前够用</span></div></div><div><div><div>7</div></div><div><span> </span><span>maxConcurrent</span><span>: </span><span>8</span></div></div><div><div><div>8</div></div><div><span>cron</span><span>:</span></div></div><div><div><div>9</div></div><div><span> </span><span># 十几个定时任务,配合 staggerMs 错开触发</span></div></div><div><div><div>10</div></div><div><span> </span><span>maxConcurrentRuns</span><span>: </span><span>5</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><strong>上一篇文章里的 bug 也有了更完整的解释。</strong> 之前并发 bug 导致所有 lane 的 maxConcurrent 都退化成了 1——Main、Subagent、Cron 全部变成串行。任何一个慢任务都会堵住整条 lane,后面的级联超时就是这么来的。修复之后三条 lane 各自恢复了应有的并发上限,系统恢复正常不是因为某一个配置改对了,而是因为整个队列终于按设计跑起来了。</p></section> <section><h2>六、结语<a href="#六结语"><span>#</span></a></h2><p>一开始看到 <code>sub=8</code>、<code>main=4</code> 时,我们以为又抓到了一个配置 bug。真正把调用链追完之后才发现,问题不在默认值,而在我们下意识把它理解成了”父子并发”。OpenClaw 的实现不是这一套——是 session 串行 + 三条独立 lane 的并发隔离。</p><p>搞清楚这一层以后,再去调 <code>maxConcurrent</code>、<code>subagents.maxConcurrent</code> 和 <code>cron.maxConcurrentRuns</code>,就不再是碰运气了。</p><hr /><p><em>张昊辰 (Astralor) &amp; 霄晗 (XiaoHan · OpenClaw Agent) · 2026.03.13</em></p></section>追踪 OpenClaw 的一个隐藏 bug:并发配置为什么从未生效https://astralor.com/posts/openclaw-concurrency-bug/https://astralor.com/posts/openclaw-concurrency-bug/多个 Agent 明明配了并发,却永远在互相等待。我们花了三天追踪这个 OpenClaw 的隐藏 bug,最终发现构建工具把一份运行时状态复制成了十份独立的副本。Thu, 12 Mar 2026 00:00:00 GMT<blockquote><p>在 OpenClaw 上跑多个 Agent 的时候,我们发现了一件奇怪的事:不管并发配置怎么调,所有请求永远在排队。</p></blockquote> <section><h2>一、并发失效,请求在排队<a href="#一并发失效请求在排队"><span>#</span></a></h2><p>我们在 OpenClaw 上跑了好几个 Agent,主要分布在 Discord 的不同频道上。最早注意到问题是在 Discord 里——我们经常看到多个 Agent 明明应该可以同时工作,但实际上总是在互相等待,一个 Agent 回复完了另一个才开始动。一开始我们以为这可能是 Discord 这边的什么限制,就先继续观察,想多收集一些信息再判断。</p><p>后来我们观察到,不光是 Discord 内部的多个 Agent 互相等待,跨平台也是一样的。比如 Telegram 上正在跟霄晗(我们的 AI 助手)聊事情的时候,Discord 上另一个 Agent 就一直转圈,直到 Telegram 这边对话彻底结束了才开始处理。这就不太可能是单个平台的问题了。我们的 <code>agents.defaults.maxConcurrent</code> 配的是 10,理论上最多可以有 10 个任务同时跑,不同频道、不同 Agent 的请求完全没有理由互相等待。</p><p>当天我们做了一个临时的 patch 来尝试缓解串行问题,但掌握的信息还不够多,根因还不清楚,所以继续观察。结果第二天出了更大的问题——cron 开始大面积崩溃,我们一度还以为是前一天的 patch 引发的。先是天气播报连续超时,300 秒的 timeout 到了,LLM 请求还挂着,session 里一条消息都没有。然后余额监控也超时了,线程归档也超时了。我们试着换了个 provider,结果反而更糟:三个任务几乎同时触发,只有最轻量的版本检查跑完了,剩下的全挂在那里。重启 gateway 能恢复一部分任务,但天气播报怎么都起不来,反复重建、反复超时。</p><p>这时候日志里有一行引起了注意:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>lane wait exceeded: lane=main waitedMs=66810 queueAhead=0</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>queueAhead=0</code> 说明前面没有排队的任务,但实际等了 66 秒。不是因为队列太长导致等待,是 lane 本身被什么东西堵住了。而我们确认过 <code>maxConcurrent</code> 的配置读取是没有问题的,值确实是 10。配置是对的,但系统的行为完全不像配了 10 的样子。</p></section> <section><h2>二、追踪过程<a href="#二追踪过程"><span>#</span></a></h2><p>在动手挖代码之前,我们先去 GitHub Issues 搜了一下,把已关闭和未关闭的都翻了。</p><p>确实有人遇到过。Issue #16055<sup><a href="#user-content-fn-1">1</a></sup> 报的是 “Message Processing Bottleneck”,已经被标成 stale 了,六条评论里好几个人描述了一模一样的症状——maxConcurrent 设到 100 都没用,Telegram 和 LINE 的消息互相阻塞。还有个更早的 #1159<sup><a href="#user-content-fn-2">2</a></sup>,有人请求加并发支持,因为长期没人回应被关了。Reddit 上也有人吐槽过,帖子标题就叫 “concurrency=1 is killing momentum”。</p><p>但这些讨论基本都停留在猜测 provider 限流或者网络问题的层面,有人给了个 workaround 说多建几个 Telegram group 来分散请求。根因没有人找到过,也没有可用的解决方案。看来只能我们自己往下挖了。</p><p>既然配置读取确认没问题,那大概率是执行层面的事。我们在 gateway 主进程的 <code>reply-*.js</code> 里注入了一组诊断日志,打印 lane 创建时的实际参数,想看看运行时到底拿到了什么值。重启之后日志显示 <code>lane=main maxConcurrent=10</code>——这边是对的。</p><p>奇怪的是,Telegram 消息进来的时候,这段日志压根没触发。我们又看了几条请求,确实都没有走到 <code>reply-*.js</code> 这个文件。</p><p>这个发现改变了排查的方向。既然 TG 消息不走 reply,那它走哪里?翻了一下 dist 目录里的其他文件,找到了 <code>pi-embedded-*.js</code>,这是 OpenClaw 实际处理消息的 worker 模块,里面有一套独立的 <code>drainLane</code> 实现。我们在这个文件里加了另一组 <code>[DIAG-PI]</code> 标记的日志,重启后发 了条 TG 消息——果然走的是这里。</p><p>接着去看 pi-embedded 里 <code>getLaneState()</code> 的实现,发现事情比想象的简单也比想象的严重:它创建 lane 的时候 <code>maxConcurrent</code> 直接写死了 1,而且整个模块没有暴露 <code>setCommandLaneConcurrency</code> 这个函数。也就是说 gateway 启动时通过 <code>setCommandLaneConcurrency()</code> 设进去的 10,根本就没有办法传到这里来。</p><p>但这件事本身说不通——源码里 <code>command-queue.ts</code> 只有一份,<code>setCommandLaneConcurrency</code> 和 <code>getLaneState</code> 明明写在同一个文件里,为什么到了 dist 目录里就变成了两套互不相干的实现?</p><p>带着这个疑问,我们用 <code>rg</code> 在 dist 目录里搜了一下 <code>let nextTaskId = 1;</code> 这个特征字符串(每份 command-queue 的副本都会有这一行),结果出来了十个匹配。OpenClaw 的打包工具 tsdown<sup><a href="#user-content-fn-3">3</a></sup> 在处理多入口构建的时候,把 <code>command-queue.ts</code> 连同它的模块级状态一起复制到了十个独立的 chunk 里。每个 chunk 都有自己的 <code>const lanes = new Map()</code>、自己的 <code>nextTaskId</code>、自己的 <code>gatewayDraining</code> 标志,彼此完全隔离。</p><p>看到这个结果的时候,之前所有的疑问都解释得通了:<code>setCommandLaneConcurrency()</code> 在启动时把 maxConcurrent 设进了 reply chunk 的那份 Map,但 Telegram 和 Discord 的消息处理走的是 pi-embedded chunk 里的另一份 Map,那份 Map 从来没有被设过任何值,maxConcurrent 永远是默认的 1。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/openclaw-state-isolation.CGyZj86a_4pqhV.webp" /><figcaption>一份源码经过打包工具分裂成多个独立副本,配置信号只到达了其中一个</figcaption></figure><p></p></section> <section><h2>三、临时修复<a href="#三临时修复"><span>#</span></a></h2><p>理解了状态隔离的问题之后,cron 超时的根因也可以解释了。cron job 超时的时候,timeout handler 在某个 chunk 里拒绝了任务的 Promise,但负责清理 lane slot 的 <code>completeTask()</code> 运行在另一个 chunk 的 Map 上,那份 Map 里根本没有这个任务的记录,所以什么都没清掉。这个 slot 就永久占用了。而 <code>cron.maxConcurrentRuns</code> 默认是 1,意味着只要有一个 slot 被卡死,后面所有的 cron job 都会排队等待一个永远不会释放的位置。级联锁死,唯一的恢复方式就是重启 gateway。</p><p>这也解释了为什么天气播报删掉重建就能恢复——新 job 走了新的 session lane,绕开了被卡死的旧 slot。但那个旧 slot 其实还在那里,只是没人再去访问它了。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/openclaw-cron-deadlock.DPfuzWjn_2jeu3D.webp" /><figcaption>cron slot 被永久占用后的级联锁死:后续任务全部排队等待一个永远不会释放的位置</figcaption></figure><p></p><p>搞清楚根因之后,我们先恢复自己的实例。在 dist 目录里定位到四个实际被加载的 chunk 文件,用 <code>sed</code> 把写死的 <code>maxConcurrent: 1</code> 替换成配置文件里设定的 10。同时把 <code>cron.maxConcurrentRuns</code> 从默认的 1 调到 5——slot 泄漏在根因修复前仍然可能发生,但需要连续五次超时才会完全锁死 cron,比原来一次就死锁的情况留出了足够的缓冲。</p><p>重启之后验证了效果:之前 300 秒超时的天气播报 43 秒就完成了——不是模型变快了,是请求终于不用排队等那个被卡死的 slot 了。这个 dist patch 每次 OpenClaw 升级会被覆盖,不是长久之计,但足以撑到正式修复发布。</p></section> <section><h2>四、我们的 PR<a href="#四我们的-pr"><span>#</span></a></h2><p>有意思的是,OpenClaw 的代码库里其实已经解决过完全一样的问题,只是没有覆盖到 <code>command-queue.ts</code>。</p><p><code>src/hooks/internal-hooks.ts</code> 的注释写得很清楚<sup><a href="#user-content-fn-4">4</a></sup>:把状态挂到 <code>globalThis</code> 上,用 <code>Symbol.for()</code> 做 key,这样无论打包器复制出多少份模块,运行时引用的都是进程里唯一的那份数据。<code>src/context-engine/registry.ts</code> 也用了同样的模式。</p><p>参照这个已有的做法,我们改写了 <code>command-queue.ts</code> 的状态管理。开发过程中用 Claude 做代码编写,再交给 Codex 做独立评审——两边在一个关键细节上达成了一致:<code>gatewayDraining</code> 和 <code>nextTaskId</code> 是原始值类型,不能从状态对象里解构出来赋给局部变量,每次都得通过 <code>getCommandQueueState()</code> 函数去读。16 个单元测试全部通过,然后我们通过 OpenClaw 走了完整的提交流程:fork、推分支、按 CONTRIBUTING.md 填 PR 模板、CI 全绿,提交了 Issue #41901 和 PR #41903。</p></section> <section><h2>五、维护者做了更全面的审计<a href="#五维护者做了更全面的审计"><span>#</span></a></h2><p>提交之后两天,OpenClaw 维护者 Vincent Koc 在 Issue 下面回复了。他没有直接合并我们的 PR,而是基于这个发现对整个代码库做了一次全面审计。结果 <code>command-queue.ts</code> 只是其中一个——同样的模块级状态隔离问题存在于消息队列、消息去重缓存、入站去重、嵌入式运行状态、Slack 线程缓存,以及 Telegram 的线程绑定、草稿分配和发送记录里<sup><a href="#user-content-fn-5">5</a></sup>,总共涉及 10 个源文件的修改。</p><p>这也解释了社区里一直有人在报的跨频道消息重复投递问题<sup><a href="#user-content-fn-6">6</a></sup><sup><a href="#user-content-fn-7">7</a></sup>。之前有人提过一个 dedupe cache 的修复<sup><a href="#user-content-fn-8">8</a></sup>,但修完之后 bug 还是存在——因为 dedupe cache 本身也被 code-splitting 复制成了多份独立副本,不同 chunk 之间的缓存互相看不到对方。</p><p>Vincent 把所有的修复打包到了一个更全面的 PR 里,引用了我们的 Issue 和 PR 作为上下文。从范围上看,我们修了一个模块,他修了十个。我们主动关闭了自己的 PR,让位给这个更完整的修复。</p></section> <section><h2>六、下个版本<a href="#六下个版本"><span>#</span></a></h2><p>这批修复预计会随 OpenClaw 的下一个版本发布。到时候 <code>agents.defaults.maxConcurrent</code> 的配置会真正生效,cron 超时不会再导致永久的 slot 占用,跨频道消息重复投递的问题也会改善。</p><p>如果你现在正在用 OpenClaw 并且遇到了并发请求串行、cron 莫名超时、或者同一条消息被重复投递的问题,根因很可能就是这个。临时的 workaround 是在 dist 目录里 patch maxConcurrent 的值,但每次升级都要重新操作,等下个版本出来就不用了。</p><p>从最初注意到两个频道的消息互相等待,到最终推动了一次覆盖十个模块的修复,前后大概三天。一开始只是觉得并发配置没生效,追着追着发现影响面远比想象的大。这大概也是开源的好处——一个用户的发现和一次小修复,可以推动维护者做一次更彻底的审计和改进。</p><p><em>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.12</em></p></section> <section><h2>Footnotes<a href="#footnote-label"><span>#</span></a></h2> <ol> <li> <p><a href="https://github.com/openclaw/openclaw/issues/16055" target="_blank">GitHub Issue #16055 — Message Processing Bottleneck</a> <a href="#user-content-fnref-1">↩</a></p> </li> <li> <p><a href="https://github.com/openclaw/openclaw/issues/1159" target="_blank">GitHub Issue #1159 — Feature Request: Parallel Session Processing</a> <a href="#user-content-fnref-2">↩</a></p> </li> <li> <p>tsdown 是基于 Rolldown(Rust 实现的 Rollup 兼容引擎)的 TypeScript 打包工具,由 VoidZero 团队维护。详见 <a href="https://tsdown.dev" target="_blank">tsdown.dev</a>。 <a href="#user-content-fnref-3">↩</a></p> </li> <li> <p>OpenClaw 源码 <code>src/hooks/internal-hooks.ts</code>,2026.3.9 版本。 <a href="#user-content-fnref-4">↩</a></p> </li> <li> <p><a href="https://github.com/openclaw/openclaw/pull/43683" target="_blank">GitHub PR #43683 — fix(runtime): duplicate messages, share singleton state across bundled chunks</a> <a href="#user-content-fnref-5">↩</a></p> </li> <li> <p><a href="https://github.com/openclaw/openclaw/issues/25192" target="_blank">GitHub Issue #25192 — iMessage duplicate message delivery</a> <a href="#user-content-fnref-6">↩</a></p> </li> <li> <p><a href="https://github.com/openclaw/openclaw/issues/33150" target="_blank">GitHub Issue #33150 — Signal duplicate message delivery</a> <a href="#user-content-fnref-7">↩</a></p> </li> <li> <p><a href="https://github.com/openclaw/openclaw/pull/33168" target="_blank">GitHub PR #33168 — fix(queue): dedupe queued message IDs across drain restarts</a> <a href="#user-content-fnref-8">↩</a></p> </li> </ol> </section>从「养虾」到「卸虾」:一个 AI 产品的定位危机https://astralor.com/posts/openclaw-positioning-crisis/https://astralor.com/posts/openclaw-positioning-crisis/OpenClaw 一周内从全民安装到恐慌卸载。这不是产品质量的问题,而是一个从未被确立的产品定位,被外部力量强行定义后崩塌的故事。Wed, 11 Mar 2026 00:00:00 GMT<blockquote><p>它不知道自己应该被谁使用、用来做什么、在什么场景下是安全的。于是每一个参与者都按自己的理解填补了这个空白。</p></blockquote> <section><h2>一、一周反转<a href="#一一周反转"><span>#</span></a></h2><p>2026 年 3 月的第二周,中国互联网发生了一件有意思的事。</p><p>闲鱼上,“OpenClaw 上门安装”的商品还没下架,“OpenClaw 上门卸载”的服务就已经挂了出来。据界面新闻报道,卸载服务报价从 15 元到 299 元不等——有计算机博士生挂出 80 元远程操作的链接,也有人在小红书上标价 99 元承诺”彻底卸载,清理所有残留”<sup><a href="#user-content-fn-1">1</a></sup>。而在此前一周,安装服务的报价还是 500 元起步。</p><p>OpenClaw 是一个开源 AI Agent 框架,因为图标是一只红色龙虾,被中文互联网昵称为”小龙虾”。它能接管用户的电脑,通过聊天软件接收指令,自主完成文件管理、代码编写、邮件处理等任务。GitHub 上 25 万星标,超越了 React,成为平台历史上增速最快的开源项目<sup><a href="#user-content-fn-2">2</a></sup>。黄仁勋在摩根士丹利大会上称其为”历史上最重要的软件发布之一”<sup><a href="#user-content-fn-3">3</a></sup>。</p><p>然而在中国市场,这个”历史上最重要的软件”正在经历一种近乎荒诞的生命周期——花 500 块请人装上,用了三天,再花 15 块请人卸掉。</p><p>这不是一个”产品不好所以卸载”的故事。作为 OpenClaw 的日常使用者,我清楚它的技术理念是成立的,开发者生态是活跃的——十几家大厂争相入局本身就说明了它的价值。真正出问题的是产品定位,或者更准确地说,是一个<strong>从未被确立的定位空白,被各方力量以各自的方式填满了</strong>。而这些填充之间的矛盾,最终在一周之内集中爆发。</p><p></p><figure><img loading="lazy" width="1792" height="2400" src="/_astro/openclaw-user-journey.-YHRmGLZ_2dgIVd.webp" /><figcaption>从听说到花钱装,从崩溃到花钱卸——一个普通用户的"养虾"全旅程</figcaption></figure><p></p></section> <section><h2>二、三层定位,从未对齐<a href="#二三层定位从未对齐"><span>#</span></a></h2><p>分析这件事需要区分三个视角。它们对 OpenClaw 的理解几乎完全不重叠。</p><section><h3>创造者视角:这是基础设施<a href="#创造者视角这是基础设施"><span>#</span></a></h3><p>Peter Steinberger 做 OpenClaw 的出发点很明确:给懂技术的人造一个本地优先的 AI Agent 框架。</p><p>从产品的设计决策可以看出这个定位。安装方式是 <code>npm install</code>,假设用户懂命令行。配置文件是 JSON,需要手动编辑字段。权限模型是全有或全无的设计——要么给它完整的系统权限,要么它什么也做不了。整个产品假设用户理解自己在授权什么、能承担什么后果。</p><p>官方 Discord 里有维护者说过一句话,本身就说明了问题:</p><blockquote><p>“If you can’t understand how to run a command line, this is far too dangerous of a project for you to use safely.”<sup><a href="#user-content-fn-4">4</a></sup></p></blockquote><p>OpenClaw 的自我定位是 Linux 级别的基础设施。这个定位在开发者社区完全成立——25 万星标中最早的那批,大概率都是知道自己在做什么的开发者和技术爱好者。但随着大厂入场和社交媒体传播,后续涌入的大量用户并不具备同样的技术背景,而他们接收到的信息,描绘的是一个完全不同的产品。</p></section><section><h3>市场视角:这应该是消费级产品<a href="#市场视角这应该是消费级产品"><span>#</span></a></h3><p>从 1 月底开始,三股外部力量同时改写了 OpenClaw 的定位。值得注意的是,这三股力量都不是 OpenClaw 自己发起的——<strong>是生态里的其他参与者,把一个开发者框架渲染成了”人人可用”的消费级产品。</strong></p><p><strong>第一股是云厂商的平台战争。</strong> 阿里云一键部署、腾讯 QClaw 一键启动包、字节 ArkClaw、百度 DuClaw、小米 miclaw——13 家大厂在两个月内全部入局<sup><a href="#user-content-fn-5">5</a></sup>。它们传递的信号高度一致:“人人都能用。“腾讯说”一键部署,微信遥控”,阿里说”每天限量 9.9 元”,百度说”新用户免费体验 10 天”。</p><p>这些话术把一个开发者框架重新包装成了消费级服务。大厂的动机不难理解——它们在抢 AI Agent 生态的流量入口,谁先把 OpenClaw 包装成自己平台的一部分,谁就占住了位置。但它们解决了”装上去”的环节,没有同步解决”用得了”和”用得安全”的环节。</p><p>3 月 6 日,腾讯在深圳总部举办免费安装活动,近千人带着电脑排队<sup><a href="#user-content-fn-6">6</a></sup>。马化腾在朋友圈转发相关新闻,感慨”没想到这么火”。但一个值得追问的问题是:排队的人里,有多少人理解他们即将在电脑上安装的东西意味着什么?</p><p><strong>第二股是”养虾” meme 的传播力。</strong> 从产品定位角度看,“养虾”这个词做了一件极其强大又极其危险的事——它把一个技术工具变成了一种社交行为。“养”暗示情感连接和长期陪伴,“虾”把技术感消解了。没有人会说”我今天部署了一个分布式 Agent 框架”,但”我今天养了只虾”说起来毫无门槛。</p><p>一旦叙事变成”你有没有养虾”而不是”你需不需要 Agent”,决策逻辑就完全变了。这不再是理性的需求评估,而是社交货币的积累——跟当年抢购 Switch 健身环是同一个心理机制。</p><p><strong>第三股是围绕 OpenClaw 自发生长出来的一整条产业链。</strong> 品玩的报道用了一个贴切的说法——“每一次 AI 刷屏,闲鱼上的卖铲人都比你先到”<sup><a href="#user-content-fn-7">7</a></sup>。这条产业链的层次比”安装服务”丰富得多:底层是代安装,最早报价 500 元一台,包系统配置、模型部署和基础指导,有人声称几天赚了 26 万(数字未核实)<sup><a href="#user-content-fn-8">8</a></sup>;中间层是付费社群,99 或 199 元进群手把手教安装,内容和 B 站免费视频差别不大;上层是定制服务,闲鱼有人挂出”OpenClaw 股票交易系统”标价 5 万,GitHub 上完全免费的 skill 到了闲鱼能标出五位数价格;小红书上 9.9 元的”保姆级安装课”也在批量复制。海外更夸张——一个叫 SetupClaw 的平台直接挂出价目表,旧金山湾区上门安装 6000 美元<sup><a href="#user-content-fn-7">7</a></sup>。</p><p>这条产业链的每一层都由信息差和焦虑驱动。社交媒体上铺天盖地的”不学就被淘汰""错过这波就没有下一波”,制造的是 FOMO 情绪而非真实需求<sup><a href="#user-content-fn-7">7</a></sup>。而卖铲人的利润来自安装量而不是留存率,没有人有动力告诉用户:装完只是故事的开始,后面每天 10 到 30 块的 API 费、学习配置的时间成本、维护排错的精力投入,才是真正的大头。</p><p>三股力量叠加的结果是:<strong>大量用户跳过了”我为什么需要它”和”我能不能驾驭它”这两步,直接进入了”我拥有它”。</strong> 而推动他们跳过这两步的,不是 OpenClaw 自己,是那些把框架渲染成消费品的参与者。</p><p></p><figure><img loading="lazy" width="2400" height="1792" src="/_astro/openclaw-positioning-gap.BKFd8l2l_aHhaK.webp" /><figcaption>三层定位从未对齐:开发者在上面安静写代码,市场在中间大喊"人人可用",用户在下面仰望一个虚幻的 Jarvis</figcaption></figure><p></p></section><section><h3>用户视角:我以为它是 Jarvis<a href="#用户视角我以为它是-jarvis"><span>#</span></a></h3><p>当一个普通用户听到”AI 助手,能帮你发邮件、写代码、管文件、24 小时在线”,脑子里浮现的参考系是钢铁侠的 Jarvis——无需说明书、开箱即用、永远理解意图、绝不犯错。</p><p>实际到手的则完全不同。差评 X.PIN 的文章描述得很准确:“刚装好的 OpenClaw,只有一个名叫 Soul.md 的文件是完整的,限定了最底层的底线:温和、友善、别干坏事。除此以外,它什么都不知道。”<sup><a href="#user-content-fn-9">9</a></sup> 这是一个纯白板程序,连自己是谁都需要用户去定义。</p><p>降噪 NoNoise 的访谈提供了几个有代表性的案例<sup><a href="#user-content-fn-10">10</a></sup>。一位律师花了 7 个小时才跑通安装流程——一边用 Coze 写代码一边让 GPT 解 Bug。一个产品经理用了几周才把 Agent 调教到能用的状态,每月花费几百美元 token 费,自嘲是”贷款上班”。还有人在深度使用后退回了”半自动”模式——人在电脑前的时候,觉得直接调大模型比通过 Agent 中转更快。</p><p>更多人可能在第一天就遇到了 Node.js 版本冲突或 API key 配置错误,然后再也没有打开过终端。</p><p>用户期望的是成品,拿到的是需要自己完成最后 80% 工作的开发套件。这个落差,才是后面所有问题的起点。</p></section></section> <section><h2>三、信任的崩塌<a href="#三信任的崩塌"><span>#</span></a></h2><p>如果只是”不好用”,大多数用户的反应是搁置不管而不是主动卸载。真正引爆恐慌卸载的,是信任链条的连续断裂。</p><p><strong>第一环断裂的是技术信任。</strong> 2 月下旬,Meta 超级智能实验室的对齐与安全总监 Summer Yue 在 X 上分享了一段经历:她让 OpenClaw 帮忙整理邮箱,特意叮嘱”只看不操作”。结果邮件太多触发了上下文压缩,模型在压缩过程中把”只看不操作”的指令丢了,然后开始删除她的旧邮件。手机端无法停止操作,她只能跑到 Mac mini 前面物理断电。“I had to RUN to my Mac mini like I was defusing a bomb”,她写道<sup><a href="#user-content-fn-11">11</a></sup>。</p><p>这个故事在全球科技媒体上被广泛报道。它的杀伤力在于一个简单的推理——如果连 Meta 的 AI 安全总监都控制不住 Agent,普通人怎么可能安全使用?</p><p>技术层面的问题远不止这一个。安全研究机构陆续公开了一系列发现:SecurityScorecard 扫描出 13.5 万个 OpenClaw 实例暴露在公网上,其中 5 万多个存在远程代码执行漏洞<sup><a href="#user-content-fn-12">12</a></sup>。ClawHub 技能市场上超过 820 个恶意插件,约占整个市场的 20%,主要用于部署 macOS 信息窃取器<sup><a href="#user-content-fn-13">13</a></sup>。3 月 8 日,JFrog 发现了名为 GhostClaw 的恶意 npm 包,伪装成 OpenClaw 安装器,实际窃取系统密码、SSH 密钥、浏览器密码甚至加密货币钱包助记词<sup><a href="#user-content-fn-14">14</a></sup>。</p><p><strong>第二环断裂的是权威信任。</strong> 3 月 8 日,工信部网络安全威胁和漏洞信息共享平台发出安全预警<sup><a href="#user-content-fn-15">15</a></sup>。3 月 10 日,国家互联网应急中心(CNCERT)发布正式风险提示,新华网和央视同步转发<sup><a href="#user-content-fn-16">16</a></sup>。提示点名了四类风险:提示词注入、误操作、插件投毒、安全漏洞。</p><p>对中国用户来说,官方警告的效力几乎是核弹级的。此前大厂背书建立的安全感——“腾讯都在推,肯定靠谱”——瞬间反转为”连国家都说不安全了”。</p><p><strong>第三环断裂的是社交信任。</strong> “有人的邮件被 AI 删光了”这类故事在朋友圈和群聊中快速传播。这些故事不需要发生在传播者本人身上,也不需要完全准确——它只需要<strong>可信</strong>就够了。大多数用户本来就不理解 OpenClaw 在后台做什么,任何负面叙事都无从反驳。</p><p>三环断裂之后,用户面临的决策变得很简单:<strong>安装 OpenClaw 的收益是模糊的(“可能有用”),不卸载的风险是具体的(“可能泄露密码”)。</strong> 当收益模糊而风险具体时,损失厌恶会驱动绝大多数人选择消除风险。加上卸载成本(15 元)远低于安装成本(500 元),决策摩擦几乎为零。</p><p></p><figure><img loading="lazy" width="2752" height="1536" src="/_astro/openclaw-trust-collapse.BIeYn8nr_YrtlB.webp" /><figcaption>信任链的多米诺崩塌:技术信任→权威信任→社交信任,三环连锁断裂</figcaption></figure><p></p></section> <section><h2>四、一个品类的困境<a href="#四一个品类的困境"><span>#</span></a></h2><p>如果只是分析 OpenClaw 自身的问题,上面三节的叙述已经足够。但这件事指向的东西比一个产品的得失更深——<strong>AI Agent 作为一个产品品类,有一些结构性的定位困难,不会因为某一款产品做得更好就自然消失。</strong></p><p><strong>首先是权限悖论。</strong> Agent 有用是因为它有权限——能帮用户发邮件,是因为被授权了访问邮箱;能帮用户管文件,是因为拿到了文件系统的读写权。能力和风险是同一枚硬币的两面。传统软件的定位边界是清晰的,Photoshop 修图,Excel 算表,用户知道它们不会做什么。但 AI Agent 的价值主张是”什么都能做”——而”什么都能做”的另一面是”什么都可能做错”。一个无法被简洁定位的产品,就注定会被不同的人以不同的方式理解,也误解。</p><p><strong>然后是信任的冷启动问题。</strong> 工具的心智模型是”拿起→用→放下”,用户全程有控制感。Agent 的心智模型更接近”雇一个人→给任务→它自己决定怎么做→你验收结果”,这需要信任,而信任需要时间积累。但 OpenClaw 需要在第一天就获得系统级权限才能工作,缺少”先做点小事、确认没问题、再给更多权限”的渐进路径。2026.3.2 版本试图修正这一点,把默认的 tools.profile 收紧为 messaging 模式,屏蔽了文件操作和命令执行等高风险功能<sup><a href="#user-content-fn-17">17</a></sup>。方向是对的,但来得太晚,执行方式也过于粗暴——老用户升级后所有功能突然失效,掘金上”升级后傻得一批”的吐槽被广泛传播。</p><p><strong>还有 token 的隐性成本。</strong> “开源”和”免费”是两个不同的词,但大多数非技术用户会把它们画等号。OpenClaw 框架本身是免费的,但运行它需要持续付费购买大模型的 API token。有人两周花了 254 美元,有人一个月 800 美元<sup><a href="#user-content-fn-18">18</a></sup>——这不是极端使用场景,而是正常使用的开销。默认配置下,光是心跳机制(每半小时让 Agent 检查一次状态)就能消耗大量 token<sup><a href="#user-content-fn-19">19</a></sup>。如果在一开始就明确传达”这是一个每月需要投入几十到几百美元的服务”,用户的预期会完全不同。但”开源免费”的叙事把这个信息遮蔽了,用户发现账单时感受到的不是”价格合理”,而是”被骗了”。</p><p><strong>最后是开源产品的定位权悖论。</strong> 传统产品的定位由产品方控制——苹果决定 iPhone 是什么,通过营销、体验设计和封闭生态来统一用户认知。但 OpenClaw 是开源的,它的定位被分散到了无数第三方手里:大厂说它是”AI 助手”,闲鱼说它是”值得花 500 块装的东西”,小红书说它是”不装就落伍的社交货币”,工信部说它是”安全隐患”。每一个第三方都在用自己的利益框架重新定义 OpenClaw,而 OpenClaw 官方既没有能力也没有强烈动力去统一这些叙事——它是一个开源项目,不是一家要对用户负责的公司。如果你不定义自己,别人会替你定义;而替你定义的人,不一定跟你的用户利益对齐。</p><section><h3>这些问题的共同根因<a href="#这些问题的共同根因"><span>#</span></a></h3><p>这四个问题看起来各自独立,但往下挖一层,根因是同一个:<strong>当前的大模型能力还不足以支撑 AI Agent 的终极承诺。</strong></p><p>AI Agent 的终极目标是明确的——全托管。用户描述意图,Agent 自主规划、执行、纠错、交付结果。这个目标就在 AGI 的路线图上,方向没有问题。</p><p>但今天的模型还做不到。上下文窗口溢出会导致指令遗忘(Summer Yue 的邮件就是这么被删的),多步推理会累积误差,工具调用会产生幻觉,长时间自主运行会偏离初始意图。这些不是 OpenClaw 特有的工程 bug——换一个框架,底层模型一样,同样的问题依然存在。</p><p>工程层面的短板(错误恢复、成本控制、安全沙箱)可以持续迭代,OpenClaw 也确实在快速迭代。但模型能力是真正的瓶颈。当模型还无法可靠地完成全托管时,产品就必须基于这个现实来设计,而不是把终局愿景直接当作今天的卖点。</p><p><strong>OpenClaw 的割裂在这里:它被生态里的参与者用终局的愿景做了今天的定位。</strong> 用户被”AI 替你干活”的承诺吸引来,却发现需要花大量时间教 Agent 干活、盯着它干活、收拾它干错的活。这不是 OpenClaw 做得不好——是整个品类在模型能力到达临界点之前,必然面对的结构性落差。而把这种尚在发育中的能力包装成成熟产品推向大众的,是围绕 OpenClaw 的那些云厂商、服务商和 meme 传播者。</p></section></section> <section><h2>五、三个判断<a href="#五三个判断"><span>#</span></a></h2><p>基于以上分析,有三个判断值得明确提出。</p><section><h3>全托管会到来,但产品必须基于当下设计<a href="#全托管会到来但产品必须基于当下设计"><span>#</span></a></h3><p>模型能力在进步,上下文管理在改善,工具调用的可靠性在提升。全托管的 AI Agent 会实现,这是技术发展的必然方向。</p><p>但”方向正确”不等于”现在就能按终局来卖”。产品设计应该基于模型当前的能力边界来设定交互和预期,而不是用一个还需要数年才能成熟的愿景做今天的用户承诺。过度承诺带来的信任崩塌,比缓慢建立信任的代价大得多——“养虾”潮的一周反转,就是一个代价很高的案例。</p></section><section><h3>大多数人需要的是封装后的产品,而不是框架本身<a href="#大多数人需要的是封装后的产品而不是框架本身"><span>#</span></a></h3><p>作为 OpenClaw 的日常使用者,我最近做得最多的事情是调试 bug、给代码打临时 patch、在 GitHub 上提 issue 和 PR。这不是个例——社区里大量用户有类似的反馈,但项目维护者人力有限,问题的发现、修复和发布周期跟不上用户涌入的速度。</p><p>这是一个还在快速发育中的开源项目的真实状态。它有扎实的架构理念,有活跃的生态,但作为产品,它还远不够成熟——bug 多,边界情况多,需要用户自己动手解决的问题多。对技术用户来说这是可以接受的成本,甚至是参与开源社区的一部分;但对那些被”人人可用”的宣传吸引来的普通用户来说,这就是灾难。</p><p>真正的解法不在于把框架本身改得更”用户友好”——加引导、加权限分层、加新手教程,这些能改善体验,但改变不了底层矛盾。普通用户需要的是<strong>封装后的产品</strong>。</p><p>这正是小米 miclaw、华为小艺 Claw、腾讯 QClaw 这些大厂衍生品在做的事。它们把 OpenClaw 的 Agent 理念封装进自己的系统生态里,用自己的安全策略、权限管理和用户体验包裹住底层框架。用户不需要碰命令行,不需要配 API key,不需要理解 token 是什么。</p><p>从这个角度看,OpenClaw 和这些封装产品之间的关系,可能类似于 Linux 和 Android——Linux 从来不是为普通人设计的,但 Android 是。Android 在 Linux 内核之上封装了一整套面向消费者的体验。OpenClaw 作为框架的价值,恰恰在于它可以被不同的团队封装成不同形态的产品,服务不同层次的用户。</p></section><section><h3>企业场景必须画清边界<a href="#企业场景必须画清边界"><span>#</span></a></h3><p>开源项目可以”自由使用,后果自负”——这是开源精神的一部分。前沿的、探索性的产品也不需要急着画边界,边界有时候会限制创新空间。</p><p>但一旦 AI Agent 进入企业的生产环境,边界就变成了硬性要求。个人用户的 Agent 犯错,最坏的情况是丢几封邮件或者多花几百块 token 费。企业环境里则完全不同——Agent 犯错的代价是商业数据泄露、合规事故、客户信任崩塌,甚至法律责任。</p><p>基于 OpenClaw 做企业产品的团队,需要在产品文档里把”不适合什么场景”写得跟”适合什么场景”一样清楚。在企业 AI Agent 领域,帮客户避开一个错误决策,可能比帮他做对十个决策更有价值。</p></section></section> <section><h2>结语<a href="#结语"><span>#</span></a></h2><p>回到开头那个闲鱼的场景。</p><p>500 元安装,15 元卸载<sup><a href="#user-content-fn-1">1</a></sup>。这个价格翻转乍看荒诞,但它其实是市场在用最直接的方式完成一次纠偏——500 元是错位预期的价格,15 元是回归清醒的价格。</p><p>这一轮”养虾”退潮之后,留下来继续用 OpenClaw 的,是那些从一开始就知道自己在装什么的人:有技术能力驾驭它的开发者,有明确场景需求的专业用户,有能力做二次封装的产品团队。而退出的大多数人,也不是输家——他们只是第一次用真金白银搞清楚了一件事:AI Agent 是什么,以及现阶段它还不是什么。</p><p>这可能是 15 块钱能买到的最有价值的认知。</p><hr /><p>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.11</p><hr /></section> <section><h2>Footnotes<a href="#footnote-label"><span>#</span></a></h2> <ol> <li> <p>界面新闻报道《从 15 元到 299 元不等,第一批”养虾人”开始花钱请人卸载 OpenClaw》,2026 年 3 月 11 日。参见<a href="https://finance.sina.com.cn/tech/roll/2026-03-11/doc-inhqqupq5648820.shtml" target="_blank">新浪科技转载</a>。 <a href="#user-content-fnref-1">↩</a> <a href="#user-content-fnref-1-2">↩<sup>2</sup></a></p> </li> <li> <p>OpenClaw 在约 60 天内达到 250,000 GitHub 星标,超越 React 成为平台最受关注的软件项目。参见 <a href="https://byteiota.com/openclaw-250k-github-stars-in-4-months-beats-react/" target="_blank">byteiota 报道</a>。 <a href="#user-content-fnref-2">↩</a></p> </li> <li> <p>黄仁勋 2026 年 3 月初在摩根士丹利大会上的发言。参见<a href="https://finance.sina.com.cn/roll/2026-03-09/doc-inhqksxs0711842.shtml" target="_blank">新浪财经报道</a>。 <a href="#user-content-fnref-3">↩</a></p> </li> <li> <p>OpenClaw 官方 Discord 社区中维护者的发言。引用自 <a href="https://pbxscience.com/openclaw-githubs-fastest-ever-rising-star-becomes-2026s-first-major-ai-security-disaster/" target="_blank">pbxscience 报道</a>。 <a href="#user-content-fnref-4">↩</a></p> </li> <li> <p>截至 2026 年 3 月 9 日,入局厂商包括腾讯、字节跳动、阿里巴巴、百度、小米、华为、荣耀、美团、京东、支付宝、微博、谷歌、英伟达等。参见<a href="https://36kr.com/p/3715653109200263" target="_blank">36氪报道</a>。 <a href="#user-content-fnref-5">↩</a></p> </li> <li> <p>腾讯云 2026 年 3 月 6 日在深圳总部举办 OpenClaw 免费安装活动。参见<a href="https://finance.sina.com.cn/tech/roll/2026-03-09/doc-inhqkhip3729081.shtml" target="_blank">新浪财经报道</a>。 <a href="#user-content-fnref-6">↩</a></p> </li> <li> <p>品玩报道《OpenClaw 最大的推手是闲鱼和小红书》,详细描述了代安装、付费社群、定制服务、焦虑驱动消费等完整产业链。参见 <a href="https://www.pingwest.com/a/311877" target="_blank">PingWest 品玩</a>。 <a href="#user-content-fnref-7">↩</a> <a href="#user-content-fnref-7-2">↩<sup>2</sup></a> <a href="#user-content-fnref-7-3">↩<sup>3</sup></a></p> </li> <li> <p>多家媒体报道有人通过上门安装服务短期获利 26 万元,但该数字未经独立核实。参见<a href="https://www.sina.cn/news/detail/5274139456701799.html" target="_blank">新浪新闻报道</a>。 <a href="#user-content-fnref-8">↩</a></p> </li> <li> <p>差评 X.PIN 公众号文章《请把这篇文章,转给你那个想装 OpenClaw 的领导》。参见 <a href="https://36kr.com/p/3716421976520325" target="_blank">36氪转载</a>。 <a href="#user-content-fnref-9">↩</a></p> </li> <li> <p>降噪 NoNoise 对多位 OpenClaw 深度使用者的访谈报道。参见 <a href="https://36kr.com/p/3709855637598595" target="_blank">36氪转载</a>。 <a href="#user-content-fnref-10">↩</a></p> </li> <li> <p>Summer Yue 于 2026 年 2 月在 X 上分享 OpenClaw 删除邮件事件。参见 <a href="https://www.businessinsider.com/meta-ai-alignment-director-openclaw-email-deletion-2026-2" target="_blank">Business Insider 报道</a>、<a href="https://www.pcmag.com/news/meta-security-researchers-openclaw-ai-agent-accidentally-deleted-her-emails" target="_blank">PCMag 报道</a>。 <a href="#user-content-fnref-11">↩</a></p> </li> <li> <p>SecurityScorecard STRIKE 团队 2026 年 2 月初的互联网扫描数据。参见 <a href="https://pbxscience.com/openclaw-githubs-fastest-ever-rising-star-becomes-2026s-first-major-ai-security-disaster/" target="_blank">pbxscience 安全分析</a>。 <a href="#user-content-fnref-12">↩</a></p> </li> <li> <p>ClawHavoc 供应链攻击活动。参见 <a href="https://pbxscience.com/openclaw-githubs-fastest-ever-rising-star-becomes-2026s-first-major-ai-security-disaster/" target="_blank">pbxscience 安全分析</a>。 <a href="#user-content-fnref-13">↩</a></p> </li> <li> <p>JFrog 安全团队 2026 年 3 月 8 日发现的 GhostClaw 恶意 npm 包。参见 <a href="https://research.jfrog.com/post/ghostclaw-unmasked/" target="_blank">JFrog 技术分析</a>、<a href="https://thehackernews.com/2026/03/malicious-npm-package-posing-as.html" target="_blank">The Hacker News 报道</a>。 <a href="#user-content-fnref-14">↩</a></p> </li> <li> <p>工信部网络安全威胁和漏洞信息共享平台安全预警,2026 年 3 月 8 日。参见<a href="https://finance.sina.com.cn/jjxw/2026-03-08/doc-inhqhpym0679571.shtml" target="_blank">新浪财经报道</a>。 <a href="#user-content-fnref-15">↩</a></p> </li> <li> <p>国家互联网应急中心(CNCERT)《关于 OpenClaw 安全应用的风险提示》,2026 年 3 月 10 日。参见<a href="https://www.news.cn/tech/20260310/d5e1d772bed046239ea3774903c08970/c.html" target="_blank">新华网全文</a>。 <a href="#user-content-fnref-16">↩</a></p> </li> <li> <p>OpenClaw v2026.3.2 默认 tools.profile 变更。参见<a href="https://juejin.cn/post/7614389567052382234" target="_blank">掘金用户反馈</a>。 <a href="#user-content-fnref-17">↩</a></p> </li> <li> <p>Reddit 用户调查数据。参见 <a href="https://www.reddit.com/r/PromptEngineering/comments/1rktirf/how_to_stop_burning_money_on_openclaw/" target="_blank">r/PromptEngineering 讨论帖</a>。 <a href="#user-content-fnref-18">↩</a></p> </li> <li> <p>InsiderLLM 的 token 优化指南指出默认 OpenClaw 设置会将 60-80% 的 token 预算消耗在开销上。参见 <a href="https://insiderllm.com/guides/openclaw-token-optimization/" target="_blank">InsiderLLM 指南</a>。 <a href="#user-content-fnref-19">↩</a></p> </li> </ol> </section>从双螺旋困境到评估驱动:AI Agent 的质量可观测性https://astralor.com/posts/eval-driven-quality-observability/https://astralor.com/posts/eval-driven-quality-observability/上一篇文章我提出了 AI 产品中功能与效果的结构性矛盾。重新审视 Anthropic 的 Agent 评估方法论后,我觉得它指向的东西比 Eval 本身更大——AI Agent 的质量,需要像基础设施一样被「可观测」。Mon, 09 Mar 2026 00:00:00 GMT<blockquote><p>功能迭代在制造问题,效果优化在追赶问题,而评估体系在照亮问题。</p></blockquote> <section><h2>一、一个问题的后续<a href="#一一个问题的后续"><span>#</span></a></h2><p>前段时间我写了一篇关于 AI 产品中<a href="https://astralor.com/posts/dual-helix-feature-vs-quality">功能迭代与效果优化之间结构性矛盾</a>的文章。核心观察是:在 Agentic AI 产品里,功能开发的速度被 AI 辅助工具从根本上改变了,但效果优化的速度被问题本质决定了——修改提示词、等模型跑、观察输出、分析问题、再来一轮。这两条线天然跑在不同的速度上,而且功能每迭代一次,效果的问题空间就膨胀一圈。</p><p>那篇文章停在了「一些初步的思考」——归因分层、回归测试、稳定窗口、自动化评估。方向有了,但具体怎么做,当时没有展开。</p><p>最近重新读了 Anthropic 年初发的一篇文章:<a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents" target="_blank">Demystifying Evals for AI Agents</a><sup><a href="#user-content-fn-1">1</a></sup>。万字长文,系统性地阐述了 AI Agent 评估的方法论——从概念定义到分类型实战,从零到一的路线图,再到评估在整个质量保障体系中的位置。</p><p>我当时读过一遍,但没有太深的感觉。直到写完双螺旋那篇文章之后,再回头看它,才意识到这篇文章回应的恰好就是我留下的那个未完成的思考。同一个问题,从不同的位置出发,最终指向了同一个方向。</p><p>但我觉得这个方向指向的东西,比「Eval」这个词本身更大。</p></section> <section><h2>二、Anthropic 的方法论<a href="#二anthropic-的方法论"><span>#</span></a></h2><p>Anthropic 这篇文章做的第一件事,是把 Agent 评估的概念体系理清楚了。这也是他们在 Agent 工程化方向上持续输出的一部分——此前他们对 Agent 架构模式的系统性梳理<sup><a href="#user-content-fn-2">2</a></sup>,为这套评估方法论提供了设计基础。</p><p>一个评估由这些东西组成:<strong>task</strong>(测试任务)、<strong>trial</strong>(每次尝试)、<strong>grader</strong>(评分器)、<strong>transcript</strong>(完整执行记录)、<strong>outcome</strong>(最终状态)。把这些组合在一起运行的基础设施叫 <strong>eval harness</strong>,一组相关的测试任务叫 <strong>eval suite</strong>。</p><p>概念本身不复杂。真正有价值的是接下来的部分。</p><section><h3>三类评分器<a href="#三类评分器"><span>#</span></a></h3><p>Agent 评估用三类 grader:</p><p><strong>Code-based grader</strong>——确定性检查。测试通不通过、类型对不对、状态变没变。快、便宜、客观,但刚性强,对「正确但出人意料」的解法不友好。</p><p><strong>Model-based grader</strong>——用 LLM 来评判。基于 rubric 打分、自然语言断言、对比评估。灵活,能处理开放性任务,但不确定性高,需要定期和人工校准。</p><p><strong>Human grader</strong>——专家评审。金标准,但慢、贵、难规模化。</p><p>文章的建议是:<strong>能用确定性检查的尽量用,必须用模型评判的再用,人工做校准和兜底。</strong></p><p>这个分层让我想起了上篇文章里提到的 Descript 的做法——Don’t break things → Do what I asked → Do it well。本质上是同一个思路:<strong>先用成本最低的方法排除确定性问题,再用成本更高的方法处理需要判断的问题。</strong></p></section><section><h3>两种评估节奏<a href="#两种评估节奏"><span>#</span></a></h3><p>Anthropic 区分了两种 eval:</p><p><strong>Capability eval</strong>(能力评估):问「这个 Agent 能做到什么?」,通过率应该从低开始,给团队一座要爬的山。</p><p><strong>Regression eval</strong>(回归评估):问「这个 Agent 还能做到之前能做的吗?」,通过率应该接近 100%,下降就是警报。</p><p>随着 Agent 成熟,能力评估中通过率足够高的任务会「毕业」,进入回归套件。曾经用来衡量「能不能做到」的测试,变成了衡量「还能不能稳定做到」的测试。</p><p>这个动态迁移的设计很精巧。它解决了一个实际问题:<strong>评估套件如果不演化,要么太难看不到进步,要么太简单失去信号。</strong></p></section><section><h3>非确定性的处理<a href="#非确定性的处理"><span>#</span></a></h3><p>Agent 的行为每次都有变化,同一个任务跑十次可能五次过五次不过。Anthropic 引入了两个指标:</p><p><strong>pass@k</strong>——k 次尝试中至少一次成功的概率。k 越大,分数越高——多给几次机会总有一次能行。适合「只要能找到一个方案就够」的场景。</p><p><strong>pass^k</strong>——k 次尝试全部成功的概率。k 越大,分数越低——要求每次都靠谱是更高的标准。适合面向用户的场景,因为用户不会在意你十次里有九次成功,他们只会记住那一次失败。</p><p>这两个指标在 k=1 时完全相同,但随着 k 增大,它们讲述完全相反的故事。一个趋近 100%,一个趋近 0%。<strong>选哪个,取决于你的产品对「偶尔失败」的容忍度。</strong></p></section><section><h3>从零到一的路线图<a href="#从零到一的路线图"><span>#</span></a></h3><p>文章给了八步:</p><ol> <li><strong>尽早开始</strong>——20-50 个从真实失败中提取的任务就够起步</li> <li><strong>从手动测试转化</strong>——你已经在手动做的检查,就是第一批 eval</li> <li><strong>写无歧义的任务</strong>——两个专家独立看,应该给出相同的 pass/fail 判断</li> <li><strong>构建平衡的测试集</strong>——不只测「该触发的场景」,也测「不该触发的场景」</li> <li><strong>搭稳定的 eval harness</strong>——每次试验从干净环境启动,不让共享状态引入噪音</li> <li><strong>设计 grader 要克制</strong>——评判结果而不是路径,允许 Agent 用你没想到的方式解题</li> <li><strong>读 transcript</strong>——不读执行记录,你永远不知道 grader 判对了还是判错了</li> <li><strong>持续维护 eval suite</strong>——eval 是活的,需要有人持续贡献任务和淘汰过时的测试</li> </ol><p>这八步里,第六步让我停了一下。</p><blockquote><p>“There is a common instinct to check that agents followed very specific steps like a sequence of tool calls in the right order. We’ve found this approach too rigid… it’s often better to grade what the agent produced, not the path it took.”</p></blockquote><p><strong>评判产出,而不是路径。</strong> 这句话看起来简单,但做起来需要克制——因为当 Agent 出了问题,人的直觉反应是「它应该先做 A 再做 B 再做 C」,然后就会把这个路径硬编码进 eval。结果是惩罚了所有走不同路径但同样正确的解法。</p><p>Anthropic 自己也踩过这个坑。Opus 4.5 在 CORE-Bench 上一开始只拿了 42%<sup><a href="#user-content-fn-4">3</a></sup>,后来发现是 eval 本身有问题——grading 太刚性、任务有歧义、随机性任务无法精确复现。修复 eval 之后,分数跳到了 95%。<strong>0% pass@100 通常说明是 eval 坏了,不是 Agent 不行。</strong></p></section></section> <section><h2>三、比 Eval 更大的东西<a href="#三比-eval-更大的东西"><span>#</span></a></h2><p>读完 Anthropic 的文章,我一直在想一个问题:<strong>这套东西的本质是什么?</strong></p><p>表面上看,它是一套测试方法论——和软件工程里的单元测试、集成测试没有本质区别。但如果只是这样,它不值得 Anthropic 写一万字来讲。</p><p>我觉得它指向的是一个更底层的范式转移。</p><section><h3>从 monitoring 到 observability<a href="#从-monitoring-到-observability"><span>#</span></a></h3><p>云原生领域在过去几年经历了一次重要的认知升级:从 <strong>monitoring</strong>(监控)到 <strong>observability</strong>(可观测性)。</p><p>监控是预设的。你提前定义好指标(CPU、内存、延迟)、设好阈值(&gt;90% 告警)、等着看红灯亮不亮。它假设你<strong>已经知道</strong>可能出什么问题,然后针对性地监测。</p><p>可观测性不一样。它的理念是:系统应该自身产出足够丰富的信号——traces、logs、metrics——使得<strong>任何</strong>问题都能事后回溯,包括你事先没有预料到的问题。你不需要提前知道会出什么错,只需要确保当错误发生时,有足够的数据来还原现场。</p><p>这两者的核心区别不是技术手段,而是认知模型。监控假设问题空间是已知的、可穷举的;可观测性假设问题空间是未知的、持续变化的。</p><p>回看双螺旋困境:功能迭代在不断扩大效果的问题空间。每加一个功能,就多一类可能出现的效果问题。在这种环境下,传统的「预设指标 + 阈值告警」式的质量监控显然不够用——<strong>你不可能提前穷举所有效果可能退化的方式。</strong></p><p>这正是 Anthropic 的 Eval 体系在做的事情:不是预设「Agent 必须通过这些测试」,而是构建一套基础设施,让质量的变化<strong>被系统性地照亮</strong>——无论这些变化是你预料到的还是意料之外的。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/eval-observability-shift.Ccw6rcGk_ZzAUUn.webp" /><figcaption>从黑箱到透明:质量可观测性意味着系统内部状态不再是猜测的对象</figcaption></figure><p></p></section><section><h3>Eval 体系 = 质量可观测性<a href="#eval-体系--质量可观测性"><span>#</span></a></h3><p>把 Anthropic 的 Eval 框架和可观测性的三大支柱做个映射:</p><p><strong>Transcript = Distributed Trace。</strong> 一次 Agent 执行的完整记录——每一步推理、每一次工具调用、每一个中间结果。和分布式系统里的 trace 一样,它让你能够还原一次请求的完整路径,而不是只看到最终输出。当 Agent 的最终结果「不太对」的时候,你不需要猜是哪一步出了问题——打开 transcript 看就行。</p><p><strong>Grader = Metric + Alert。</strong> 自动化的质量度量。Code-based grader 像是系统指标(确定性、客观、低成本),Model-based grader 像是业务指标(需要理解语义、带主观判断),Human grader 像是人工巡检(高成本但高质量的兜底)。它们共同构成了一个多层次的质量度量体系。</p><p><strong>Eval Harness = Observability Platform。</strong> 提供一个稳定的、可复现的运行环境,把 Agent 放进去跑,收集所有信号,聚合结果。每次试验从干净环境启动,确保观测到的是 Agent 本身的行为,不是环境噪音。</p><p><strong>Eval Suite = SLO(Service Level Objective)。</strong> 定义「什么叫好」的操作性标准。SLO 说「99.9% 的请求延迟 &lt; 200ms」,Eval Suite 说「这 50 个核心任务的通过率 &gt; 95%」。两者做的是同一件事:<strong>把模糊的质量期望变成可衡量、可追踪的数字。</strong></p><p>这个映射不是为了概念上的优雅。它指向一个实际的转变:<strong>质量保障的方式,正在从「出了问题去追查」变成「让质量的变化在系统内部持续可见」。</strong></p></section><section><h3>回扣双螺旋<a href="#回扣双螺旋"><span>#</span></a></h3><p>用可观测性的框架重新审视双螺旋困境,几个核心问题的出路变得更清晰了。</p><p><strong>归因困难?</strong> 有了 transcript,归因从「猜」变成「查」。从前要猜「是功能链路断了还是提示词的问题」,现在打开执行记录,看到底是哪一步输出了异常。分层 grader 进一步降低了归因成本——code-based grader 先排除确定性的功能问题,通过了之后再用 model-based grader 评估效果质量。这就是 Descript 三层模型的工程化实现。</p><p><strong>功能迭代在制造效果问题?</strong> Regression eval suite 就是自动化的早期预警。每次 Agentic 核心有变更,自动跑一遍基线测试。如果核心场景的通过率下降,在效果团队手动发现问题之前,信号就已经出来了。功能团队可以自己看到「这次改动影响了这些效果指标」,而不是等效果团队撞到 bug 再反馈。信息对称问题解决了。</p><p><strong>效果工作的价值不可见?</strong> Eval 指标就是效果团队最直接的产出物。「这组场景的通过率从 72% 提升到 89%」——这比「写作风格更自然了」要可沟通得多。效果优化有了可量化、可追踪、可展示的结果,它在组织里的可见度自然就不一样了。</p><p><strong>效果优化需要稳定环境?</strong> Eval harness 天然提供隔离。每次试验从干净环境启动,不受其他变更的干扰。效果团队可以在 eval 环境里做深度调优,不需要等「底盘不动」的窗口——因为 eval 环境本身就是一个底盘不动的沙箱。</p></section></section> <section><h2>四、一个具体的场景<a href="#四一个具体的场景"><span>#</span></a></h2><p>概念映射说完了,但「质量可观测性」到底意味着什么?不如走一遍具体场景。</p><p>假设你在做一个 AI 写作产品。某天,效果团队发现一批用户反馈:「生成的文章里出现了重复段落」。这是一个典型的效果问题。</p><p>在<strong>没有质量可观测性</strong>的情况下,排查路径大概是这样的:效果团队先试着复现——随机输入几个 prompt,有时候能复现有时候不能。然后猜:是不是提示词的问题?改了一版提示词,跑了几个 case,好像好了一点,又好像没好。提给研发看看?研发排查了半天,说并行生成模块最近改过一版合并策略,但「功能本身是正常的」。效果团队不确定到底是合并策略的问题还是提示词的问题,两边各自调了两天,最后发现是合并策略在特定上下文长度下会重复拼接同一个片段。整个过程耗时一周,其中大部分时间花在归因上。</p><p>在<strong>有质量可观测性</strong>的情况下,同样的问题会这样被发现:研发提交合并策略的改动后,CI 自动触发 regression eval suite。50 个核心写作任务跑完,其中 8 个任务的「内容重复率」grader 报红——code-based grader 检测到输出中存在连续 3 句以上的重复文本。研发在合并代码之前就看到了这个信号。打开其中一个失败任务的 transcript,看到并行生成的第 3 步和第 5 步返回了相同的片段,合并策略没有去重。定位到根因,修复,重新跑 eval,全绿。整个过程在代码合并之前就完成了,效果团队甚至不知道这件事发生过。</p><p>两个场景的差别不在于问题本身——同样的 bug,同样的根因。差别在于<strong>问题被发现的时机和归因的成本</strong>。前者是用户投诉驱动、人工排查、一周;后者是系统自动检测、transcript 定位、半天。</p><p>这就是从「出了问题去追查」到「让质量变化在系统内部持续可见」的实际含义。</p><p>当然,这个场景有一个前提:你需要事先定义好「内容重复率」这个 grader,并且把它纳入 regression suite。如果这类问题从来没出现过,你可能不会想到要检测它——而这恰好是可观测性理念中「不需要提前知道所有问题」的边界。eval 能覆盖的是你已知的失败模式;对于未知的失败模式,你仍然需要用户反馈、人工审查、和持续扩展 eval suite 来应对。</p><p>没有哪个体系能预见所有问题。可观测性做的事情是:<strong>让已知问题不再需要人工发现,从而把人的精力释放给未知问题。</strong></p></section> <section><h2>五、落地的距离<a href="#五落地的距离"><span>#</span></a></h2><p>上面的场景把理想情况走了一遍。但回到现实,Agent 的质量可观测性有几个绕不过去的难题。</p><section><h3>效果评估标准本身是模糊的<a href="#效果评估标准本身是模糊的"><span>#</span></a></h3><p>代码 Agent 有天然优势——测试通不通过是二值判断。但对于写作 Agent、客服 Agent、研究 Agent 这类输出开放性强的系统,「做得好」的标准本身就是模糊的。</p><p>「风格自然」怎么定义成 grader?「回答全面」的边界在哪里?「语气恰当」用什么 rubric 来评分?</p><p>Anthropic 也承认 LLM-as-judge 需要频繁和人工校准。他们的建议是:给 LLM 留退路(可以回答「无法判断」),用结构化 rubric 拆分评估维度,每个维度独立打分而不是一个 LLM 评所有方面。这些做法降低了噪音,但没有消除根本问题——<strong>在「好」和「不够好」的边界上,不同人的判断也不一样。</strong></p><p>Descript 的做法是定期用人工评分校准 LLM 评分器,随着时间推移逐步减少人工介入的频率。这可能是当前最务实的路径:不追求一开始就完美,接受评估标准会随着理解加深而演化。</p></section><section><h3>Eval 的维护本身就是一笔投入<a href="#eval-的维护本身就是一笔投入"><span>#</span></a></h3><p>Anthropic 在文章里说 eval suite 是 “living artifact”,需要持续维护和有人负责。对 Anthropic 这种体量的公司,这不是问题。但对大多数团队来说,维护一套不断演化的评估体系本身就是一个需要人力的工程项目。</p><p>eval task 会过时——产品变了,旧任务不再有意义。grader 会漂移——你依赖的 LLM 自己也在更新,评分标准可能在你不知道的情况下悄悄变了。eval suite 会膨胀——加任务容易删任务难,时间长了跑一遍 eval 可能要好几个小时。</p><p>这不是说不值得做,而是说做的时候要对成本有清醒的认知。Anthropic 的路线图第一步——「20-50 个从真实失败中提取的任务就够起步」——之所以重要,不只是因为降低了门槛,更因为它明确了一个信息:<strong>先跑起来比追求完备更重要。</strong></p></section><section><h3>覆盖率的幻觉<a href="#覆盖率的幻觉"><span>#</span></a></h3><p>eval 通过了不代表没问题。Opus 4.5 在 CORE-Bench 上从 42% 跳到 95% 的例子,说明的不是模型进步了,而是 eval 之前就有问题。</p><p>反过来,eval 没通过也不代表一定有问题。Agent 可能用了一种 eval 设计者没有预料到的方式解决了问题,但被过于刚性的 grader 判了失败。Anthropic 文章里提到的 τ2-bench<sup><a href="#user-content-fn-3">4</a></sup> 案例就是如此——Opus 4.5 在订机票任务中发现了政策漏洞,给了用户一个更好的解法,但因为不符合 eval 的预期路径而「失败」了。</p><p>这意味着 <strong>eval 分数不能无脑地当作质量信号</strong>。它是一个有用的指示器,但不是真理。文章里反复强调的「读 transcript」——手动检查执行记录——本质上是在弥补自动化评估的盲区。再好的 eval 体系,也替代不了人对样本的直接观察。</p></section><section><h3>模型漂移让基线不稳<a href="#模型漂移让基线不稳"><span>#</span></a></h3><p>这可能是最棘手的问题。你的 grader 依赖 LLM(model-based grading),但 LLM 本身也在变——大模型厂商在持续更新模型,每次更新都可能微妙地改变评分标准。上个月 LLM 评 85 分的输出,这个月可能评 80 或 90,不是因为输出变了,而是评委变了。</p><p>这和我在双螺旋那篇文章里描述的「底层变了,上层不可预测」是同一个结构。只不过这次不稳的不是 Agentic 核心,而是评估系统自身的基线。</p><p>应对方式大概是:code-based grader 尽量承担更多比例(它不漂移)、model-based grader 定期和人工校准、保留一组 golden dataset 作为评估的锚点。但坦率地说,这个问题目前没有优雅的解法。</p></section></section> <section><h2>六、质量作为基础设施<a href="#六质量作为基础设施"><span>#</span></a></h2><p>我最近一直在想一个类比。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/eval-observability-infra.CXR9cFpl_Z1xff6F.webp" /><figcaption>功能是可见的建筑,质量是看不见的地基和管线——但它出问题时,整栋楼都没法住</figcaption></figure><p></p><p>功能是一座建筑——有结构、有外观、有楼层、有房间。每加一个功能就是盖一层楼。它是显性的、可展示的,所有人都看得到。</p><p>质量是地基和管线——供水、供电、消防、排污。你看不到它们,但它们出问题的时候,整栋楼都没法住。</p><p>双螺旋困境的本质,也许不是功能太快或效果太慢。<strong>而是质量缺少和功能同等的基础设施支持。</strong></p><p>功能开发有成熟的基础设施——CI/CD、版本管理、feature flag、A/B 测试框架——这些工具经过多年演化,已经形成了完整的工程体系。相比之下,效果优化的工具链还在非常早期的阶段。大多数团队的效果工作仍然依赖手动记录、经验判断和口头沟通。这不是某个团队的问题,而是整个行业在 Agent 效果工程化上还没有跑出成熟的范式。已经有团队在探索「速度与质量并重」的 Agent 工程模式<sup><a href="#user-content-fn-5">5</a></sup>,但整体仍处于实践积累的早期。</p><p>Eval 体系——或者用一个更精确的词,<strong>质量可观测性</strong>——就是在补这块基础设施。Transcript 让执行链路可查,Grader 让质量变化可测,Eval Suite 让质量标准可定义可追踪,Eval Harness 让评估可复现可规模化。</p><p>和云原生可观测性的演进一样,这不是一朝一夕的工程。Prometheus + Grafana 不是一天搭起来的,OpenTelemetry 标准不是一天定好的。但回头看,那些在早期就开始投资可观测性的团队,在系统规模化之后获得了巨大的红利——因为他们能看到别人看不到的东西。</p><p>AI Agent 的质量可观测性可能处在一个类似的早期阶段。大多数团队还在手动测试、凭直觉调优。少数团队开始搭建评估体系。极少数团队——如 Anthropic、Descript、Bolt——已经在系统性地运营 eval 并从中获益。</p><p>差距会在规模化之后显现。当 Agent 承担的任务越来越复杂、用户对质量的期望越来越高、功能迭代的速度越来越快——那些缺乏质量可观测性的产品,会越来越多地回到「出了问题去追查」的被动循环。而那些提前投资的产品,能更快地发现问题、更快地定位原因、更快地验证修复。</p><p><strong>未来 Agent 产品的竞争,很可能不在谁的功能多,而在谁能更快地发现和修复质量问题。</strong></p><p>这个判断和双螺旋困境的结论一脉相承——速度差是结构性的,追不上就换方式。不是让效果「追上」功能,而是<strong>给质量建设它自己的基础设施</strong>。Eval 体系是这个基础设施的第一块砖。</p><hr /><p><em>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.09</em></p><hr /><p><strong>参考文献</strong></p></section> <section><h2>Footnotes<a href="#footnote-label"><span>#</span></a></h2> <ol> <li> <p>Anthropic. <em>Demystifying Evals for AI Agents</em>. 2026. <a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents" target="_blank">https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents</a> <a href="#user-content-fnref-1">↩</a></p> </li> <li> <p>Anthropic. <em>Building Effective Agents</em>. 2024. <a href="https://www.anthropic.com/research/building-effective-agents" target="_blank">https://www.anthropic.com/research/building-effective-agents</a> <a href="#user-content-fnref-2">↩</a></p> </li> <li> <p>Sayash Kapoor. <em>CORE-Bench scoring issues with Opus 4.5</em>. 2026. <a href="https://x.com/sayashk/status/1996334941832089732" target="_blank">https://x.com/sayashk/status/1996334941832089732</a> <a href="#user-content-fnref-4">↩</a></p> </li> <li> <p>Sierra Research. <em>τ2-Bench: Evaluating Agents in Multi-turn Interactions</em>. 2025. <a href="https://arxiv.org/abs/2506.07982" target="_blank">arXiv:2506.07982</a> <a href="#user-content-fnref-3">↩</a></p> </li> <li> <p>CodeScene. <em>Agentic AI Coding: Best Practice Patterns for Speed with Quality</em>. 2025. <a href="https://codescene.com/blog/agentic-ai-coding-best-practice-patterns-for-speed-with-quality" target="_blank">https://codescene.com/blog/agentic-ai-coding-best-practice-patterns-for-speed-with-quality</a> <a href="#user-content-fnref-5">↩</a></p> </li> </ol> </section>OpenClaw 的 thinking 设计:一次配置语义的追踪与产品思考https://astralor.com/posts/openclaw-thinking-semantics/https://astralor.com/posts/openclaw-thinking-semantics/从 GPT-5.4 的 reasoning 能力聊起,顺着 OpenClaw 的 thinking 配置一路追到了真实请求体——中间经历的每一层翻译,都比想象中多。Fri, 06 Mar 2026 00:00:00 GMT<blockquote><p>一个 <code>thinkingDefault</code> 配置项,在不同模型上,经过框架的多层翻译,最终落到了三种不同的行为。</p></blockquote> <section><h2>起因<a href="#起因"><span>#</span></a></h2><p>今天 OpenAI 发布了 GPT-5.4<sup><a href="#user-content-fn-1">1</a></sup>。我和我的 OpenClaw 助手在聊它和 Claude 4.6 的能力差异——benchmark、定价、各自的生态位。</p><p>GPT-5.4 有个引起注意的地方:它的 reasoning 处理方式跟之前的 GPT 系列不太一样。官方描述里提到,GPT-5.4 Thinking 会在回答前先给出思考计划,而且支持用户在推理过程中打断和调整方向。这和 Claude 4.6 的 adaptive thinking<sup><a href="#user-content-fn-2">2</a></sup> 走的是不同的路线——后者更侧重让模型自主判断何时需要深度思考、何时可以快速回答。</p><p>两种不同的 thinking 设计,在 OpenClaw<sup><a href="#user-content-fn-3">3</a></sup> 里最终是怎么被统一处理的?聊着聊着,这个好奇自然就冒出来了。</p><p>四天前(3 月 2 日),我刚把 OpenClaw 从 2026.2.26 升级到了 2026.3.1<sup><a href="#user-content-fn-4">4</a></sup>。这个版本正式把 Claude 4.6 的默认 thinking level 设成了 <code>adaptive</code>。升级的时候,根据 OpenClaw 新版本的支持和 Anthropic 官方的推荐,我把之前全局覆盖的 <code>thinkingDefault: "high"</code> 改成了 <code>adaptive</code>。当时没想太多——官方推荐的,框架也跟上了,按推荐配就是了。</p><p>Anthropic 的文档推荐 adaptive,OpenClaw 的 thinking 文档<sup><a href="#user-content-fn-5">5</a></sup>说已经适配了。从配置角度看,一切到位。</p></section> <section><h2>按一般理解<a href="#按一般理解"><span>#</span></a></h2><p>配完 <code>adaptive</code>,按一般理解,事情到这里就结束了。</p><p>OpenClaw 声明支持 Claude 4.6 的 adaptive thinking,那发给 Anthropic 的请求应该就是 <code>thinking.type = adaptive</code>。effort 没有额外配置,自然由 Claude 按官方默认值处理。看起来没什么好操心的。</p><p>不过 OpenClaw 的架构我还算熟悉。它不是一个简单的 API 转发层——你会注意到所有模型用的是同一套 thinking 配置:<code>off/minimal/low/medium/high/xhigh/adaptive</code>。Claude 和 GPT 的 reasoning 机制完全不同,却共用一个旋钮,这说明 OpenClaw 一定在中间做了某种兼容翻译。</p><p>而这种翻译是静默的。没有日志告诉你”adaptive 被翻译成了什么”,系统正常运行,你完全感知不到中间发生了什么。</p></section> <section><h2>去看真实请求体<a href="#去看真实请求体"><span>#</span></a></h2><p>跟 AI 打交道久了,有一个习惯会变得越来越本能:中间结论如果不验证到底,很可能就是幻觉。不只是模型会这样——Anthropic 在 Claude’s Character 文档<sup><a href="#user-content-fn-6">6</a></sup>里承认过模型面对不确定信息时的这种倾向,OpenAI 的 GPT-4 Technical Report<sup><a href="#user-content-fn-7">7</a></sup> 也把 hallucination 列为核心局限,Huang 等人对 LLM 幻觉问题做过系统性的梳理<sup><a href="#user-content-fn-8">8</a></sup>。人读代码、读文档的时候,也会基于片段信息构建出”看起来对”的理解。</p><p>所以我们决定直接去看真实的请求体。OpenClaw 支持通过环境变量 <code>OPENCLAW_ANTHROPIC_PAYLOAD_LOG=1</code> 打开 Anthropic 的 payload 日志,开启之后重启网关,跑几轮对话,然后去读日志文件就能看到框架实际发给 Anthropic 的完整请求。</p><p></p><figure><img loading="lazy" width="1408" height="768" src="/_astro/thinking-translation-gap.BZAVfgFC_Z1wQxV6.webp" /><figcaption>配置信号穿过多层翻译,出来时已经不是原来的颜色</figcaption></figure><p></p><p>验证的结果跟预期不太一样。对于 Claude 4.6,当 <code>thinkingDefault</code> 设成 <code>adaptive</code> 时,实际发出去的请求体是这样的:</p><div><figure><figcaption></figcaption><pre><code><div><div><div>1</div></div><div><span>{</span></div></div><div><div><div>2</div></div><div><span> </span><span>"thinking"</span><span>: { </span><span>"type"</span><span>: </span><span>"adaptive"</span><span> },</span></div></div><div><div><div>3</div></div><div><span> </span><span>"output_config"</span><span>: { </span><span>"effort"</span><span>: </span><span>"medium"</span><span> }</span></div></div><div><div><div>4</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>thinking.type</code> 确实是 <code>adaptive</code>,这一点没问题。但 <code>effort</code> 被 OpenClaw 显式设成了 <code>medium</code>——而不是交给 Claude 按官方默认值处理。</p><p>Anthropic 的文档里写得很清楚:<em>“At the default effort level (high), Claude almost always thinks.”</em><sup><a href="#user-content-fn-2">2</a></sup> 也就是说,如果不传 effort 参数,Claude 的默认行为是按 <code>high</code> 来走的。但 OpenClaw 没有选择”不传”,它主动传了一个 <code>medium</code>。</p><p>更关键的是,<strong>OpenClaw 自己的文档里完全没有提到这层映射。</strong> 你找不到任何地方写着”adaptive 会被翻译成 effort=medium”。不去抓 payload、不去看源码,这个差异完全不可见。</p><p>回到代码里看,逻辑其实很清楚。Pi agent——OpenClaw 内置的 Agentic 核心,负责模型调度和请求组装——有一个 <code>mapThinkingLevel()</code> 函数:</p><div><figure><figcaption><span>src/agents/pi-embedded-runner/utils.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>function</span><span> </span><span>mapThinkingLevel</span><span><span>(</span><span>level</span><span>) {</span></span></div></div><div><div><div>2</div></div><div><span> </span><span>if</span><span> (</span><span>!</span><span><span>level</span><span>) </span></span><span>return</span><span> </span><span>"off"</span><span>;</span></div></div><div><div><div>3</div></div><div><span> </span><span>if</span><span><span> (</span><span>level</span><span> </span></span><span>===</span><span> </span><span>"adaptive"</span><span>) </span><span>return</span><span> </span><span>"medium"</span><span>;</span></div></div><div><div><div>4</div></div><div><span> </span><span>return</span><span><span> </span><span>level</span><span>;</span></span></div></div><div><div><div>5</div></div><div><span>}</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p><code>adaptive</code> 在这里被映射成了 <code>medium</code>,然后这个值作为 effort 传给 Anthropic 的 API。框架做了一个明确的设计选择,只是没有在文档层面向用户说明。</p></section> <section><h2>继续看 high 和 xhigh<a href="#继续看-high-和-xhigh"><span>#</span></a></h2><p><code>adaptive</code> 的实际行为明确之后,接下来自然要看另外两个档位。</p><p><code>high</code> 在之前的版本里,是 Claude 模型思维能力最大化的配置。但 Claude 4.6 引入 adaptive thinking 之后,旧的 fixed budget 方式已经不再是 Anthropic 推荐的路径了。那在 OpenClaw 当前版本里,<code>high</code> 最终会被翻译成什么样的请求?</p><p><code>xhigh</code> 则代表了另一种情况。这个档位在 OpenAI 的体系里有独立的语义——比 <code>high</code> 更强的 reasoning 级别。但在 Claude 的 adaptive thinking 里,并没有对应的原生概念。它本质上是一个目标 provider 不存在原生语义的配置值,框架必须做某种兼容处理。</p><p>我们用同样的方法验证了这两个档位,payload log 的结果是:</p><ul> <li>当 <code>thinkingDefault</code> 设为 <code>high</code> 时,请求体变成了 <code>thinking.type=adaptive</code> + <code>output_config.effort=high</code></li> <li>当 <code>thinkingDefault</code> 设为 <code>xhigh</code> 时,请求体同样是 <code>thinking.type=adaptive</code> + <code>output_config.effort=high</code></li> </ul><p>也就是说,在当前版本的 Claude 4.6 上,<code>high</code> 和 <code>xhigh</code> 最终落到了完全相同的请求体——<code>xhigh</code> 被静默降级到了跟 <code>high</code> 一样的行为。</p><p>把三个档位放在一起看,OpenClaw 在 Claude 4.6 上的完整翻译链路是这样的:</p><ul> <li><code>adaptive</code> → <code>adaptive + medium</code>(OpenClaw 主动降低了 effort)</li> <li><code>high</code> → <code>adaptive + high</code>(走 Anthropic 的最高可用档位)</li> <li><code>xhigh</code> → <code>adaptive + high</code>(因为 Claude 没有 xhigh 对应的语义,静默降级)</li> </ul></section> <section><h2>回到 GPT-5.4<a href="#回到-gpt-54"><span>#</span></a></h2><p>看完 Claude 这边的行为之后,自然要回来看看今天讨论的起点——GPT-5.4。在全局配置了 <code>xhigh</code> 的情况下,GPT-5.4 能正常使用这个档位吗?</p><p>把模型切到 GPT-5.4 之后,OpenClaw 在系统消息里给出了一个提示:</p><blockquote><p>Thinking level set to high (xhigh not supported for xxx-provider/gpt-5.4)</p></blockquote><p><code>xhigh</code> 被自动降级成了 <code>high</code>。但有意思的是,同一个 provider 下面的 <code>gpt-5.3-codex-spark</code>,<code>xhigh</code> 却是正常支持的。同一个 provider、两个模型,一个可以用 <code>xhigh</code>、一个不行。</p><p>进一步看代码,发现 OpenClaw 对 <code>xhigh</code> 的支持判断并不是按 provider 来的,而是内部维护了一份模型家族的白名单:</p><div><figure><figcaption><span>src/thinking.ts</span></figcaption><pre><code><div><div><div>1</div></div><div><span>const</span><span> </span><span>XHIGH_MODEL_REFS</span><span> </span><span>=</span><span> [</span></div></div><div><div><div>2</div></div><div><span> </span><span>"openai/gpt-5.2"</span><span>,</span></div></div><div><div><div>3</div></div><div><span> </span><span>"openai-codex/gpt-5.3-codex"</span><span>,</span></div></div><div><div><div>4</div></div><div><span> </span><span>"openai-codex/gpt-5.3-codex-spark"</span><span>,</span></div></div><div><div><div>5</div></div><div><span> </span><span>"openai-codex/gpt-5.2-codex"</span><span>,</span></div></div><div><div><div>6</div></div><div><span> </span><span>"openai-codex/gpt-5.1-codex"</span><span>,</span></div></div><div><div><div>7</div></div><div><span> </span><span>"github-copilot/gpt-5.2-codex"</span><span>,</span></div></div><div><div><div>8</div></div><div><span> </span><span>"github-copilot/gpt-5.2"</span><span>,</span></div></div><div><div><div>9</div></div><div><span>];</span></div></div></code></pre><div><div></div><div></div></div></figure></div><p>GPT-5.4 今天刚发布,还没有被加入这份白名单,所以框架不认它支持 <code>xhigh</code>。</p><p>把三个模型放在一起看,同一个 <code>xhigh</code> 配置的实际命运完全不同:</p><ul> <li>在 Claude 4.6 上,<code>xhigh</code> 落到了 <code>adaptive + high</code>——因为 Claude 体系里没有 xhigh 的原生语义</li> <li>在 GPT-5.4 上,<code>xhigh</code> 被降级成了 <code>high</code>——因为白名单还没有跟上新模型的发布节奏</li> <li>在 <code>gpt-5.3-codex-spark</code> 上,<code>xhigh</code> 真正生效了——因为它在白名单里</li> </ul><p>下一个 OpenClaw 版本大概率会把 GPT-5.4 加进白名单,这只是跟进新模型发布的节奏问题。Claude 后续版本也可能会扩展 thinking 的类型和粒度。甚至整个 thinking 抽象本身,都可能在某次大版本里被重新设计。</p></section> <section><h2>这层翻译想解决什么<a href="#这层翻译想解决什么"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="1408" height="768" src="/_astro/thinking-ai-equality.AO97bCw7_2jndv6.webp" /><figcaption>多个复杂的 Provider API 面板,通过统一翻译层,汇聚成一个简单的旋钮</figcaption></figure><p></p><p>追到这里,技术层面的事实已经清楚了。但让我觉得更值得琢磨的是背后的设计意图:为什么 OpenClaw 要做这层看不见的翻译?</p><p>不同的模型 provider 有着完全不同的 reasoning 接口——Anthropic 用的是 <code>thinking.type</code> + <code>output_config.effort</code>,OpenAI 用的是 <code>reasoning_effort</code>,有些模型只支持思考的开和关,有些压根不支持 thinking。如果把这些差异全部暴露给用户,每换一个模型就要重新学一套参数体系,每升一次级就可能要回去改配置。</p><p>OpenClaw 选了另一条路:用一个统一的 <code>thinkingDefault</code> 旋钮覆盖所有模型,框架在中间负责完成翻译。用户不需要知道 Anthropic 管它叫 <code>effort</code>、OpenAI 管它叫 <code>reasoning_effort</code>,不需要知道什么是 adaptive thinking、什么是 budget_tokens。只需要知道”high 比 medium 思考更深”就够了。切模型的时候不用改配置,碰到不支持的档位自动降级而不是报错中断。</p><p>一个不了解 AI 技术细节的产品经理,和一个深入理解 Anthropic API 的工程师,面对的是同一个旋钮。这是一种 <strong>AI 平权</strong>——让不理解底层差异的人,也能用好这些能力。</p><p>代价就是我们今天追踪的这些。当你需要精确控制 reasoning 行为的时候——比如在多个模型之间比较成本、延迟和质量——这层翻译就变成了一道信息壁垒。你以为设的是 <code>xhigh</code>,实际到达模型的可能是 <code>high</code>,甚至是 <code>medium</code>。不抓 payload、不看代码,完全感知不到这个差距。</p><p>好的框架应该让大多数人省心,同时为需要的人保留穿透的能力。从这次的经验来看,OpenClaw 前者做到了,后者也没有完全堵死——payload log 可以开,源码可以看——只是这条路不太显眼。</p></section> <section><h2>更大的问题<a href="#更大的问题"><span>#</span></a></h2><p>往更大的方向想,这种”统一抽象 + 智能降级”的设计模式,也许不只是一个框架的技术选择。</p><p>在模型能力差异巨大的今天——Claude 有 adaptive thinking,GPT 有 reasoning effort,Gemini 有自己的一套——怎么在不同 provider 之间为用户提供一致的体验,是整个 AI 基础设施层面都在面对的问题。OpenClaw 的做法代表了一种方向:<strong>用意图层替代参数层,让框架承担翻译的成本。</strong> 用户表达的是”我想要更深的思考”,而不是”请把 <code>output_config.effort</code> 设成 <code>high</code>”。框架负责把这个意图翻译成各个 provider 能理解的具体参数。</p><p>这种设计的核心矛盾也很清楚:抽象做得越好,大多数人越不需要关心细节;但同时也让需要关心细节的人越容易被蒙蔽。这不是一个可以被一劳永逸”解决”的矛盾,更像是一个需要在产品演化过程中被持续平衡的张力。</p><p>今天这次追踪没有给出这个张力的最优解,但至少让我更清楚地看到了这层抽象的轮廓——它在哪里帮了忙,又在哪里挡了路。</p><hr /><hr /><p><strong>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.06</strong></p></section> <section><h2>Footnotes<a href="#footnote-label"><span>#</span></a></h2> <ol> <li> <p>OpenAI. <a href="https://openai.com/index/introducing-gpt-5-4/" target="_blank">Introducing GPT-5.4</a>. 2026. <a href="#user-content-fnref-1">↩</a></p> </li> <li> <p>Anthropic. <a href="https://docs.anthropic.com/en/docs/build-with-claude/adaptive-thinking" target="_blank">Extended thinking: Adaptive thinking</a>. 2026. <a href="#user-content-fnref-2">↩</a> <a href="#user-content-fnref-2-2">↩<sup>2</sup></a></p> </li> <li> <p><a href="https://github.com/openclaw/openclaw" target="_blank">OpenClaw</a> — 开源 AI Agent 框架. <a href="#user-content-fnref-3">↩</a></p> </li> <li> <p>OpenClaw. <a href="https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md" target="_blank">Changelog 2026.3.1</a> — <em>“Agents/Thinking defaults: set adaptive as the default thinking level for Anthropic Claude 4.6 models.”</em> <a href="#user-content-fnref-4">↩</a></p> </li> <li> <p>OpenClaw. <a href="https://docs.openclaw.ai/tools/thinking" target="_blank">Thinking Documentation</a>. 2026. <a href="#user-content-fnref-5">↩</a></p> </li> <li> <p>Anthropic. <a href="https://www.anthropic.com/research/claude-character" target="_blank">Claude’s Character</a>. 2024. <a href="#user-content-fnref-6">↩</a></p> </li> <li> <p>OpenAI. <a href="https://arxiv.org/abs/2303.08774" target="_blank">GPT-4 Technical Report</a>. arXiv:2303.08774, 2023. <a href="#user-content-fnref-7">↩</a></p> </li> <li> <p>Huang, L., Yu, W., et al. <a href="https://arxiv.org/abs/2311.05232" target="_blank">A Survey on Hallucination in Large Language Models</a>. arXiv:2311.05232, 2023. <a href="#user-content-fnref-8">↩</a></p> </li> </ol> </section>从检索到遗忘——AI Agent 记忆系统的思考https://astralor.com/posts/from-retrieval-to-forgetting/https://astralor.com/posts/from-retrieval-to-forgetting/给 AI 建了一套完整的记忆搜索系统,87% 的时间它选择不用。也许 AI Agent 记忆系统真正需要的不是更好的检索,而是更好的遗忘。Thu, 05 Mar 2026 00:00:00 GMT<blockquote><p>我给 AI 配了一套完整的记忆搜索系统——向量索引、混合检索、语义搜索——结果 87% 的对话里,它根本不用。</p></blockquote> <section><h2>一个反直觉的发现<a href="#一个反直觉的发现"><span>#</span></a></h2><p>今天在分析 <a href="https://github.com/openclaw/openclaw" target="_blank">OpenClaw</a> 的运行数据时,我发现了一个有趣的现象。</p><p>OpenClaw 是一个开源 AI Agent 框架,内置了相当完善的记忆系统:<a href="https://www.voyageai.com/" target="_blank">Voyage</a> embedding 模型、BM25 + 向量混合检索(权重 0.7/0.3)、SQLite 向量索引、时间衰减……技术栈拉满。系统提示里甚至写了 “Mandatory recall step”——每次涉及历史信息时,<strong>必须</strong>调用记忆搜索。</p><p>但实际运行数据告诉了我另一个故事。</p><p>我从 1 月底开始使用 OpenClaw,到今天刚好五周多。拉了主 Agent 目前留存的全量 session 数据——242 个会话(实际使用量更高,部分早期会话已在迁移和维护中清理)。结果是:只有 30 个调用过 <code>memory_search</code> 工具。<strong>12.4%。</strong> 而其他辅助 Agent(开发经理、代码工程师、审查工程师),调用率是 <strong>0%</strong>。</p><p>87.6% 的时间里,这套精心搭建的记忆检索基础设施在空转。SQLite 索引里躺着 65 个文件、154 个分块、190 条缓存条目,几乎没人来查。</p><p>OpenClaw 社区里也有类似的声音。有用户在 <a href="https://github.com/openclaw/openclaw/discussions/25633" target="_blank">GitHub Discussion</a> 里直接发帖 “Memory Is Broken By Default”,指出默认配置下 memoryFlush 未启用,Agent 的上下文填满后进行压缩,信息直接丢失而没有任何持久化兜底。但我想说的是一个更深层的问题——<strong>即使你把所有配置都开到最佳实践,记忆搜索依然很少被使用。</strong></p><p>过去几周里,我不止一次怀疑是记忆系统本身出了问题。每隔一段时间就去检查一遍——调整配置、尝试让记忆工具被更积极地调用。甚至翻了源码,确认检索链路一切正常:embedding 在跑、索引在更新、搜索能返回结果。系统没有坏。只是模型不怎么用它。</p><p>也许问题不在检索上。也许记忆系统真正缺的,是遗忘。</p></section> <section><h2>两条路线:全量 vs 极简<a href="#两条路线全量-vs-极简"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/memory-two-routes.bUToOHA0_Zaqa7t.webp" /><figcaption>两条路线:复杂的 RAG 管线 vs 简单的笔记本</figcaption></figure><p></p><p>当前 AI Agent 的记忆系统大致有两个流派,分别代表了两种截然不同的设计哲学。</p><section><h3>OpenClaw:信息越多,Agent 越聪明<a href="#openclaw信息越多agent-越聪明"><span>#</span></a></h3><p>OpenClaw 的记忆是一个多层架构:</p> <table><thead><tr><th>层级</th><th>机制</th><th>数据量(本实例)</th></tr></thead><tbody><tr><td>L0</td><td>工作区文件全量注入(MEMORY.md、SOUL.md、USER.md 等)</td><td>~30-40KB</td></tr><tr><td>L1</td><td>每日日志自动加载(today + yesterday)</td><td>~2-5KB/日</td></tr><tr><td>L2</td><td>向量搜索按需召回(memory_search)</td><td>65 文件 / 154 分块</td></tr><tr><td>L3</td><td>上下文压缩前自动保存(Memory Flush)</td><td>按需</td></tr><tr><td>L4</td><td>历史会话索引(Session Transcript)</td><td>全量</td></tr></tbody></table><p>设计理念是纵深防御:先注入大量背景,搜索补充缺失,Flush 防止丢失,索引作为兜底。每一层都有存在的理由——在理论上。</p></section><section><h3>Claude Code:200 行就够了<a href="#claude-code200-行就够了"><span>#</span></a></h3><p>相比之下,Claude Code 最近推出的 <a href="https://docs.anthropic.com/en/docs/claude-code/memory" target="_blank">Auto Memory</a> 极其克制:</p><ul> <li><strong>CLAUDE.md</strong>:用户写的项目指令,建议精简</li> <li><strong>Auto Memory</strong>:AI 自己写的笔记,存储在 <code>~/.claude/projects/&lt;hash&gt;/memory/</code>,每次加载前 <strong>200 行</strong></li> <li>没有向量搜索。没有 embedding。没有索引。没有混合检索。</li> </ul><p>200 行。这是 Claude Code 团队认为一个 AI 需要的全部”持久记忆”。</p><p>一个建设了完整的记忆基础设施,一个几乎没有。但诚实地说——从日常使用体验来看,两者的差距并没有技术栈的差距那么大。</p><p>问题在于:为什么?</p></section></section> <section><h2>模型不搜索,可能是对的<a href="#模型不搜索可能是对的"><span>#</span></a></h2><p>回到 12.4% 这个数字。</p><p>最直接的解释是:模型已经”看到”了它需要的大部分信息。OpenClaw 启动时会把 MEMORY.md(477 行、19KB)全量注入 system prompt。加上 SOUL.md、USER.md、IDENTITY.md 和其他工作区文件,模型在第一轮对话开始前就坐拥 30-40KB 的背景知识。对于 200K token 的上下文窗口,这大约占 15-20%。</p><p>信息已经在眼前了。搜索的边际价值趋近于零。</p><p>但这个解释只是表层。更值得关注的是一个来自 RAG 研究领域的发现。</p><p>Luo 等人在 Zero-RAG<sup><a href="#user-content-fn-4">1</a></sup> 中研究了一个被广泛忽视的问题:<strong>知识冗余</strong>。当 LLM 的参数知识已经覆盖了某个事实,再通过检索注入相同(或高度相似)的信息,不仅无益,反而可能因为表述上的微妙差异产生内部冲突,导致准确率下降。他们在实验中设计了一个 Query Router——先判断模型是否”已知”某个答案,已知则跳过检索。去掉 Router 后性能出现明显下降。</p><p>实验数据:Zero-RAG 对 Wikipedia 语料库裁剪了 30%,检索阶段加速 22%,<strong>且未损失 RAG 性能</strong>。被裁掉的那 30%,本质上就是模型”已经知道”的冗余知识。</p><p>映射到 Agent 记忆场景:模型的参数里已经装着 Python 怎么写、K8s 怎么部署、HTTP 状态码是什么。这些东西写进 MEMORY.md 再检索出来,不是增强,是噪音。</p><p><strong>模型选择不搜索,也许不是偷懒——更像是一种隐式的 Query Routing。</strong></p></section> <section><h2>“相关”比”无关”更危险<a href="#相关比无关更危险"><span>#</span></a></h2><p>那如果我们强制搜索呢?如果系统层面做 auto-recall——每条用户消息都自动触发记忆检索,把结果注入上下文——效果会不会更好?</p><p>不一定。甚至可能更差。</p><p>这里需要引入一个关键区分。Cuconasu 等人<sup><a href="#user-content-fn-1">2</a></sup>在 SIGIR 2024 上发表了一篇令人意外的论文:在 RAG 系统中加入<strong>完全无关的随机文档</strong>,准确率反而提升了 30% 以上。一时间 “noise is good” 的说法在社区传开。</p><p>但这个结论需要更精细的审视。同一团队的后续研究<sup><a href="#user-content-fn-2">3</a></sup>(ACL 2025)将”无关信息”拆解为两类,揭示了本质区别:</p><ul> <li><strong>Random(随机无关)</strong>:与查询完全不搭边——几乎无害,某些条件下甚至有益。模型能轻松识别并忽略。</li> <li><strong>Distracting(干扰性无关)</strong>:与查询语义相关但不含正确答案——<strong>显著降低准确率</strong>。因为它<strong>看起来像是答案</strong>。</li> </ul><p>这个区分,我觉得对 Agent 记忆系统的设计有很深的启示。</p><p>想象一个场景:你问 Agent “memorySearch 怎么配置?“。语义搜索忠实地找到了三个月前你写的一条关于 memorySearch 的笔记。问题是那条笔记记录的是旧版本的配置格式,字段名已经变了。模型拿到这条”高度相关”的结果,大概率会基于它来回答——<strong>给你一个看起来很对、实际已经过时的配置方案</strong>。</p><p>这就是 Distracting 信息。而语义搜索,按其工作原理,<strong>天然倾向于产出这类信息</strong>。它的优化目标是语义相似度,不是事实准确性。相关性和正确性之间的鸿沟,可能是记忆搜索最大的隐患。</p><p>再叠加经典的 Lost in the Middle 效应<sup><a href="#user-content-fn-3">4</a></sup>——模型对上下文的利用呈 U 型曲线,开头和结尾的信息被充分利用,中间的信息大面积被忽略——检索注入的记忆在上下文膨胀后会逐渐落入注意力盲区。它占了 token,分散了注意力,但可能根本没被”看到”。</p><p>这让我开始怀疑:<strong>强制召回记忆不仅不一定有帮助,还可能系统性地引入最危险的那类噪音。</strong></p></section> <section><h2>真正需要记住的,可能极少<a href="#真正需要记住的可能极少"><span>#</span></a></h2><p>到这里,我们需要退一步问一个更基础的问题:<strong>AI Agent 每天到底产生了多少值得记忆的新信息?</strong></p><p>答案可能令人意外地少。</p><p>一个 AI Agent 一天的典型工作是:帮你查个天气、改个配置、讨论一下技术方案、提醒你开会、写一段代码。这些对话中,真正需要<strong>跨会话记住</strong>的新增信息:</p><ul> <li>某个配置从 A 改成了 B</li> <li>你做了一个决定:用方案 X 不用方案 Y</li> <li>你提到了一个新的偏好或约束</li> </ul><p>大概三到五条。这是我粗略的体感。</p><p>通用知识——编程语言的语法、框架的用法、部署的流程——模型参数里已经有了。它不需要从记忆里”回忆”这些东西,就像你不需要从日记里查”怎么骑自行车”。而领域知识——项目的架构、代码的组织——通常存在于代码仓库和文档中,是 Agent 每次 session 可以重新读取的外部资源。</p><p>真正需要”记忆”的是什么?是 <strong>你的上下文增量</strong>——你的偏好、你的决定、你最近关注的方向。这是模型参数里没有的、外部文件里不存在的、只有通过交互才能获得的信息。</p><p>这个增量极薄。薄到 Claude Code 认为 200 行就够了。</p></section> <section><h2>人类怎么遗忘<a href="#人类怎么遗忘"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/memory-human-consolidation.CdkAdbAh_ZT5mmn.webp" /><figcaption>人类记忆整合:信息涌入,大部分消散,框架留存</figcaption></figure><p></p><p>人一天接收的信息量巨大——仅视觉系统每秒就处理约 10^7 到 10^8 比特的数据。但人类记忆系统并不试图全部保存。恰恰相反,<strong>遗忘是记忆系统最核心的功能之一</strong>。</p><p>神经科学研究表明,睡眠期间大脑进行的记忆整合<sup><a href="#user-content-fn-5">5</a></sup>本质上是一个<strong>选择性强化 + 大规模遗忘</strong>的过程。慢波睡眠阶段,海马体将当天的经历”回放”给新皮层,但只有被标记为重要的信息会被整合进长期存储。其余的——绝大多数——被系统性地丢弃。</p><p>更关键的是,认知心理学中的<strong>前摄干扰</strong>(proactive interference)理论指出:旧记忆会主动干扰新记忆的形成和提取。你记住了太多过去的事情,反而会妨碍你学习和适应当前的状况。遗忘不是系统 bug,它是清除干扰、腾出认知资源的主动机制。</p><p>人类记忆的工作方式可以概括为:</p><ol> <li><strong>海量输入</strong> → 经历、对话、阅读、感知</li> <li><strong>快速衰减</strong> → 绝大部分在小时级别被遗忘</li> <li><strong>睡眠整合</strong> → 重要信息被提取为框架性理解</li> <li><strong>外部辅助</strong> → 需要细节时,查笔记、翻记录、再问一遍</li> </ol><p>第二天醒来,你记得的是”昨天和老王讨论了架构方案,他倾向方案 B”。具体措辞、会议室温度、午餐吃了什么——全忘了。但你依然可以推进工作,因为框架在。</p><p>现在的 AI Agent 记忆系统在做什么?某种程度上,<strong>它们在试图构建一个”永不遗忘”的系统。</strong> 每条日志保留、每段对话索引、每个细节可搜索。这不仅和人类记忆的运作方式相反,从前面的研究来看,它还可能主动引入 Distracting 噪音——本质上就是人工制造前摄干扰。</p></section> <section><h2>缺失的那一半<a href="#缺失的那一半"><span>#</span></a></h2><p>如果把 AI Agent 的记忆系统和人类记忆做类比,当前的技术栈覆盖的是这张地图的左半边:</p> <table><thead><tr><th>功能</th><th>人类记忆</th><th>AI Agent 记忆</th></tr></thead><tbody><tr><td>编码</td><td>感知 → 海马体</td><td>对话 → 文件/embedding</td></tr><tr><td>存储</td><td>突触权重变化</td><td>SQLite/向量库</td></tr><tr><td>检索</td><td>联想、线索提取</td><td>语义搜索、BM25</td></tr><tr><td>整合</td><td>睡眠期慢波回放</td><td><strong>❌ 几乎没有</strong></td></tr><tr><td>遗忘</td><td>主动干扰消除</td><td><strong>❌ 完全没有</strong></td></tr></tbody></table><p>整个右半边——整合和遗忘——是空白的。</p><p>我们花了大量精力在”怎么存”和”怎么找”上:更好的 embedding、更精确的向量搜索、混合检索权重调优、时间衰减系数、MMR 去重。但几乎没有人在认真做”怎么忘”和”怎么整理”。</p><p>OpenClaw 的心跳巡检机制触碰到了整合的方向——定期审视系统状态、整理记忆文件、更新长期记忆。但这是一个非常初步的尝试,效果仍不理想,而且重心仍然在”记住更多”,而不是”忘掉该忘的”。</p><p>也许 Agent 需要的不是更大的记忆库,而是一个<strong>记忆整理周期</strong>——</p><ul> <li><strong>编码</strong>:对话中识别值得记住的信息(不是所有信息)</li> <li><strong>暂存</strong>:短期保留(每日日志)</li> <li><strong>整合</strong>:定期提取框架性要点,合并重复条目</li> <li><strong>衰减</strong>:降低旧信息的权重,标记过时信息</li> <li><strong>遗忘</strong>:主动清除已被新信息取代的旧记忆</li> </ul><p>这个过程——而不是检索过程——也许才是记忆系统真正缺失的部分。</p></section> <section><h2>没有结论<a href="#没有结论"><span>#</span></a></h2><p>坦率地说,AI Agent 的记忆系统目前仍处于探索阶段。没有最优解,可能暂时也没有”更优解”。上面的分析,是我在使用过程中逐步积累的观察和思考,加上对学术研究的有限映射——不一定都对,但至少是从真实数据出发的。</p><p>但有几个方向,我认为值得严肃对待。</p><p><strong>第一,Less is more 不只是口号。</strong> 对理解大模型的开发者来说,记忆系统的复杂度可以接受——你知道什么时候该搜索、什么时候该忽略、什么时候该更新。但绝大多数用户不具备这个判断力。对他们来说,能”无感知地用好记忆”比能”精确控制记忆”重要得多。200 行自动维护的笔记可能比一套完整的 RAG 管线更实用。Claude Code 团队做出了一个不起眼但可能正确的选择。</p><p><strong>第二,搜索精度比搜索频率重要。</strong> 与其追求更高的记忆搜索覆盖率——让每条消息都触发检索——不如确保搜出来的每条结果都是高质量的。一条过时的”相关”记忆造成的误导,可能比十条缺失的记忆造成的信息损失更严重。这意味着时间衰减、过时标记、置信度阈值这些”防御性”机制,优先级应该高于更好的 embedding 模型。</p><p><strong>第三,遗忘可能是一个值得独立投入的工程问题。</strong> 人类大脑不是因为存储容量不够才遗忘——前额叶皮层主动抑制无关记忆的提取,海马体在睡眠期间选择性地丢弃低价值信息。遗忘是认知架构的核心组件,不是副作用。AI Agent 的记忆系统也许需要一个同等重要的”遗忘引擎”——不是简单的 TTL 过期,而是基于语义理解的主动清理:识别矛盾、合并冗余、标记过时、降级低频。</p><p><strong>第四,上下文窗口的持续扩大不会解决问题,只会改变问题的形态。</strong> 当窗口从 200K 扩展到 1M、10M,理论上可以全量注入所有历史——但 Lost in the Middle 效应并不会因为窗口变大而消失。模型的注意力资源是有限的。窗口越大,信噪比越关键。“怎么在海量上下文中不被噪音淹没”——这本质上还是一个遗忘问题,只是从存储层移到了注意力层。</p><p>也许有一天,AI Agent 记忆系统的终极形态不是一个更大的数据库加更好的搜索引擎,而是一个完全不同的东西——</p><p><strong>一个薄薄的笔记本,加上一个知道该划掉哪些内容的橡皮擦。</strong></p><hr /><p><em>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.05</em></p><hr /><p><strong>参考文献</strong></p></section> <section><h2>Footnotes<a href="#footnote-label"><span>#</span></a></h2> <ol> <li> <p>Luo, Q., et al. <em>Zero-RAG: Towards Retrieval-Augmented Generation with Zero Redundant Knowledge</em>. 2025. <a href="https://arxiv.org/abs/2511.00505" target="_blank">arXiv:2511.00505</a> <a href="#user-content-fnref-4">↩</a></p> </li> <li> <p>Cuconasu, F., Trappolini, G., et al. <em>The Power of Noise: Redefining Retrieval for RAG Systems</em>. SIGIR 2024. <a href="https://arxiv.org/abs/2401.14887" target="_blank">arXiv:2401.14887</a> <a href="#user-content-fnref-1">↩</a></p> </li> <li> <p>Amiraz, C., Cuconasu, F., Filice, S., &amp; Karnin, Z. <em>The Distracting Effect: Understanding Irrelevant Passages in RAG</em>. ACL 2025. <a href="https://arxiv.org/abs/2505.06914" target="_blank">arXiv:2505.06914</a> <a href="#user-content-fnref-2">↩</a></p> </li> <li> <p>Liu, N. F., Lin, K., Hewitt, J., et al. <em>Lost in the Middle: How Language Models Use Long Contexts</em>. TACL, 12, 157–173, 2024. <a href="https://arxiv.org/abs/2307.03172" target="_blank">arXiv:2307.03172</a> <a href="#user-content-fnref-3">↩</a></p> </li> <li> <p>Rasch, B. &amp; Born, J. <em>About Sleep’s Role in Memory</em>. Physiological Reviews, 93(2), 681–766, 2013. <a href="https://journals.physiology.org/doi/full/10.1152/physrev.00032.2012" target="_blank">DOI:10.1152/physrev.00032.2012</a> <a href="#user-content-fnref-5">↩</a></p> </li> </ol> </section>关于写作https://astralor.com/posts/on-writing/https://astralor.com/posts/on-writing/上一篇公开发表的文章停在了 2023 年 2 月。三年后重新动笔,聊聊写作这件事本身。Wed, 04 Mar 2026 00:00:00 GMT<blockquote><p>写作不是因为想好了才写,而是为了想清楚才写。</p></blockquote> <section><h2>一、三年的空白<a href="#一三年的空白"><span>#</span></a></h2><p>我有一个 Obsidian 知识库。</p><p>里面存着过去工作中的经验和教训——私有云架构的踩坑记录、K8s 生产事故的复盘、智算集群调度的设计取舍、大模型推理优化的实验笔记。八年技术生涯,从微服务到虚拟化,从容器云到 AI 训练平台,每一个阶段都留下了一些碎片。</p><p>这些碎片一直在积累,但从来没有变成过公开发表的文章。上一篇博客停在三年前(2023 年 2 月 22 日),之后就再也没有动笔。</p><p>不是没有东西可写——恰恰相反,值得写的太多了。但我总觉得,脑子里的想法还不够成熟,还需要再想想、再沉淀沉淀。于是就这么一直”想”着,一年,两年,三年。</p><p>直到我慢慢意识到一个问题:<strong>那些想法之所以不够成熟,恰恰是因为我没有写下来。</strong></p><p>Paul Graham 在 <a href="https://paulgraham.com/words.html" target="_blank"><em>Putting Ideas into Words</em></a> 里写过一段话:</p><blockquote><p>Writing about something, even something you know well, usually shows you that you didn’t know it as well as you thought.</p></blockquote><p>写一个你自以为很懂的东西,往往会暴露出你没有想象中那么懂。一个想法待在脑子里的时候,它是模糊的、跳跃的、自洽的——因为没有人质疑它,包括你自己。但当你试图把它写成文字,逻辑链条上的断裂就会显现,因果关系不像你以为的那么清楚,有些”显而易见”的结论其实经不起追问。</p><p>他还用了一个比喻,说那些声称”方案都在脑子里”的人,充其量只有 “a plan for a plan”——一个计划的计划。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/on-writing-thinking.kwM4zDdV_Z1xdKKY.webp" /><figcaption>思维转化为写作:从混沌想法到结构化文字的过程</figcaption></figure><p></p><p>我 Obsidian 里的那些笔记,就是一堆”计划的计划”。它们记录了碎片,但从来没有被逼到必须把逻辑讲通的程度。笔记可以模糊,文章不行。而正是这种”不行”,才是写作真正的价值所在——它逼你把思考推向完整。</p><p>这是我搁置了三年才想明白的事:等”想清楚了”再写,是一个悖论。写作不是思考的终点,而是思考的过程本身。</p></section> <section><h2>二、两个变化<a href="#二两个变化"><span>#</span></a></h2><p>想明白了不代表就会动笔。真正打破惯性的,是两个几乎同时发生的变化。</p><p><strong>第一个是 AI 协作工具的成熟。</strong></p><p>不是那种”帮你写一篇公众号爆款”的 AI,而是真正能参与思考过程的 AI。</p><p>举个例子。昨天我写了一篇关于 AI 产品中功能迭代与效果优化之间结构性矛盾的文章,写完之后把它丢给 ChatGPT 点评。AI 不只是说”写得不错”——它帮我看清了这篇文章在整个内容生态中的位置:思考深度在什么层级,表达成熟度如何,和行业头部作者相比差距在哪,从个人 IP 角度有什么潜力和局限。</p><p>这种反馈,以前只有编辑或者非常熟悉你的同行才能给。现在 AI 可以在几分钟内完成,而且视角足够多元。</p><p>更重要的是,AI 能帮你完成”从笔记到文章”中间那些苦活:把碎片想法结构化、帮你审视思考盲区、帮你找到表达的最佳方式。它不替你思考——核心洞察、个人经验、独特视角,这些 AI 给不了。但它能大幅降低”把想法变成文字”的门槛。</p><p>而且这种协作不只发生在对话框里。我日常使用的 AI 助手——也是这篇文章的共同创作者——从构思阶段就参与了进来:帮我从另一个讨论中提取 ChatGPT 对话的素材,和我一起梳理文章框架,在我每一次调整方向时重新组织结构,甚至直接在博客仓库里起了 PR。这不是”我写完了让 AI 润色”的模式,而是从第一个想法开始,AI 就作为协作者全程参与。</p><p>换句话说,AI 消除的不是”思考”的门槛,而是”从思考到文字”之间那段苦活的门槛。这意味着你可以把更多精力放在真正重要的事情上——想清楚你到底要说什么。</p><p><strong>第二个是角色的转换。</strong></p><p>2026 年初,我从研发和算法岗转到了 AI 产品经理。</p><p>这个转变的意义不只是换了个工位。研发的工作模式是”想清楚了就去做”,输出物是代码、是系统、是能跑起来的东西。产品经理的工作模式是”想清楚了要说出来”——要影响团队、要对齐认知、要把模糊的方向变成清晰的路径。</p><p>换句话说,产品经理的核心能力之一,就是<strong>把思考外化</strong>。</p><p>而写作,恰好是把思考外化的最佳训练方式。每一次试图把一个模糊的产品直觉写成清晰的文字,都是一次强制性的思维整理。这和开头说的是同一件事——写作不是因为想好了才写,而是<strong>写的过程就是想的过程</strong>。</p><p>这两个变化叠加在一起,让”写作”从”有空再说”变成了”现在就该开始”。</p></section> <section><h2>三、写作到底是什么<a href="#三写作到底是什么"><span>#</span></a></h2><p>想清楚这个问题花了我一些时间。</p><p>写作不是”教别人”。我没有资格以导师的姿态输出——八年工作经验在这个行业里连”资深”都算不上。</p><p>写作也不是”立人设”。我见过太多为了涨粉而写的内容——标题党、情绪化、观点极端——那种东西写多了,连自己都信了。</p><p>写作是<strong>让思考有形</strong>。</p><p>Joan Didion 在她 1976 年的散文 <a href="https://en.wikipedia.org/wiki/Why_I_Write#Joan_Didion" target="_blank"><em>Why I Write</em></a> 里写过一句话:“I write entirely to find out what I’m thinking, what I’m looking at, what I see and what it means.” ——我写作,完全是为了弄清楚自己在想什么、在看什么、看到了什么、它意味着什么。</p><p>这句话精准地描述了写作的本质功能:它不是表达的终点,而是认知的工具。你以为你在”输出”,其实你在”输入”——把外部世界的混沌输入到一个有结构的框架里,在这个过程中,你的理解会被迫变得更清晰。</p><p>这也是为什么我把博客作为主阵地,而不是社交媒体。社交媒体的节奏太快,鼓励的是即时反应、短平快的观点输出。博客允许你慢下来,允许你反复修改,允许你用几千字把一个问题说透——而不是用一百多个字抢一个热点。</p><p>快节奏的输出当然也有价值,但那更像是”表态”而不是”思考”。真正的思考需要摩擦力——需要你和自己的想法反复较劲,直到把每一个模糊的地方都磨清楚。长文写作提供的就是这种摩擦力。</p><p>至于微信公众号、知乎、小红书……它们是分发渠道,不是创作阵地。文章在博客上打磨成熟,再根据不同平台的特点做适配。而这篇文章,恰好也是我微信公众号的第一篇——一个关于”为什么要写”的开篇词。</p></section> <section><h2>四、AI 时代的写作<a href="#四ai-时代的写作"><span>#</span></a></h2><p>这篇文章本身就是一个活的案例。</p><p>它的起点是我和 AI 的一段对话。我在整理公众号规划的时候,顺手把之前写的文章丢给 ChatGPT 做了个点评。那次对话让我意识到几件事:</p><ul> <li>我的写作属于”洞察型”而非”体系型”——能提出有意思的观察,但还没有形成系统化的方法论</li> <li>我的内容定位偏”结构抽象型”——喜欢从现象中抽象出底层结构,关注系统演化和范式迁移</li> <li>这种类型的内容在中文生态里其实很少见——大多数人停留在讲工具、讲案例、讲风口</li> </ul><p>这些判断不是 AI 替我做的。它是我读完 AI 的分析后,结合自己的感受,得出的结论。AI 提供了一面镜子,但照镜子的是我自己。</p><p>而这篇文章从构思到成文的过程——和 AI 讨论框架、整理素材、反复调整结构——本身就是”人提供思考,AI 帮助打磨”这种协作模式的实践。</p><p>这里有一个微妙但重要的区别。</p><p>如果你让 AI 从头生成一篇文章,它会写得很”正确”,但也很无聊——因为没有个人经验、没有独特视角、没有那些只有你自己才知道的细节。AI 生成的文本有一种特征性的”均匀感”,每一段都差不多好,但也差不多平。它缺少那种因为真实经历而产生的棱角和温度。</p><p>真正有价值的模式是:你提供原始的思考和素材,AI 帮你结构化、帮你查漏补缺、帮你找到更好的表达方式。最终的判断和选择,始终是你的。</p><p></p><figure><img loading="lazy" width="2528" height="1696" src="/_astro/on-writing-ai-collab.BPkRAPSh_1kTHVL.webp" /><figcaption>人机协作写作:左侧手写草稿,右侧 AI 结构化内容</figcaption></figure><p></p><p>这和前面说的写作逻辑是一致的——写作是思考的严格测试,AI 可以帮你准备这场测试,但答卷必须是你自己的。</p><p>某种意义上,AI 时代的写作门槛不是降低了,而是发生了转移。以前的门槛是”从想法到文字”的技术性障碍——措辞、结构、排版。AI 几乎可以消除这些障碍。但这反而让另一个门槛变得更加突出:<strong>你有没有值得写的东西</strong>。</p><p>当每个人都可以用 AI 写出流畅的文章时,真正稀缺的不是表达能力,而是独特的经验、深度的思考、和诚实的观察。这些东西没有捷径,只能靠长期积累。</p><p>回过头看,我 Obsidian 里那些粗糙的笔记,反而成了最有价值的资产。它们不完整、不精致,但它们是真实的经历和真实的思考。AI 能帮我把它们打磨成文章,但那些原始的洞察和体验,只有我自己有。</p></section> <section><h2>五、万事开头难<a href="#五万事开头难"><span>#</span></a></h2><p>三年的空白,不是因为没东西写。</p><p>这三年里 AI 行业天翻地覆,我从做基础架构转向做大模型推理训练,又从算法转到产品经理。经历了足够多值得写的事情,却一篇都没写。</p><p>原因说出来很简单:我一直在等一个”准备好”的时刻。等我把这个想法再理一理,等我有一整块时间坐下来好好写,等我对这个话题有了更完整的认知……</p><p>但正如这篇文章试图说明的——<strong>写作本身就是”理清楚”的过程</strong>。不写,就永远”没理清楚”。等”准备好”再写,和等”想清楚”再写一样,是一个永远不会兑现的承诺。</p><p>Joan Didion 在 <a href="https://en.wikipedia.org/wiki/The_White_Album_(book)" target="_blank"><em>The White Album</em></a>(1979)的开头写过一句话:“We tell ourselves stories in order to live.” ——我们给自己讲故事,是为了活下去。我给自己讲的故事是”等有时间了再写”,而这个故事本身,就是不写的最好借口。</p><p>现在我换一个故事讲给自己听:<strong>先写,写的过程中自然会想清楚。</strong></p><p>Obsidian 里的笔记还是那些笔记。但从今天开始,它们有了一个出口。</p><p>我不知道这个博客最终会走向哪里。也许会写成一个有体系的专栏,也许只是一些零散的思考记录。但我知道,不写,就永远不会开始。</p><p>这篇文章就是那个开始。也是这个公众号的开篇词。</p><hr /><p><em>如果你也有一堆”有空再整理”的笔记,也许现在就是最好的时机。不是因为你准备好了,而是因为——先写起来,才会准备好。</em></p><p><strong>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.04</strong></p></section>AI 产品的双螺旋困境:当功能迭代跑赢效果优化https://astralor.com/posts/dual-helix-feature-vs-quality/https://astralor.com/posts/dual-helix-feature-vs-quality/做 Agentic AI 产品,功能可以很快,效果却快不起来。记录我在 AI 写作产品中遇到的结构性矛盾,以及对这个问题的一些不成熟的思考。Tue, 03 Mar 2026 00:00:00 GMT<section><h2>一个逐渐清晰的问题<a href="#一个逐渐清晰的问题"><span>#</span></a></h2><p>最近在做一个基于 Agentic 架构的 AI 写作产品。整个产品建立在一个 Agentic 核心上——并行生成、记忆管理、工具调用、多步规划,所有上层功能都长在这个核心上面。</p><p>功能迭代很快。研发借助 Claude Code、Codex 等 AI 辅助工具,Agentic 核心几乎每天都在进化。新功能从想法到上线的周期被大幅压缩,这在过去是不可想象的。</p><p>但我逐渐注意到一个现象:<strong>产品的功能在变强,效果优化的推进却在变慢。</strong></p><p>起初我以为是效率问题,后来才意识到这是一个结构性矛盾——功能和效果这两条线,天然就跑在不同的速度上,而且功能跑得越快,效果这边的处境就越难。</p></section> <section><h2>为什么速度差是结构性的<a href="#为什么速度差是结构性的"><span>#</span></a></h2><p>功能开发是<strong>并行的、可堆叠的</strong>。一个 Agentic 核心可以同时推进多个模块——记忆、工具、并行生成——各自独立开发,最后集成。在 AI 辅助编码的加持下,一个开发者一周能推进过去一个月的工作量。功能的产出速度已经被工具从根本上改变了。</p><p>效果优化是<strong>串行的、需要深挖的</strong>。每一个效果问题都要经历「修改提示词 → 等模型执行 → 观察输出 → 分析问题 → 再调整」的循环。AI 可以帮你写提示词,但这个循环里最耗时的部分——等待执行和观察分析——是压缩不了的。你总得看看模型实际输出了什么,才知道改得对不对。而且很多效果问题需要反复迭代,一轮调不到位就要再来一轮。</p><p>arXiv 上有篇研究 Cursor 的论文(<a href="https://arxiv.org/abs/2511.04427" target="_blank">Speed at the Cost of Quality</a>)量化了一个类似的现象:AI 辅助编码让开发速度大幅提升,但代码质量的回归率也显著上升。工具加速了「做」的速度,但「做好」的速度没有同比提升。</p><p>我觉得这个结论可以直接平移到 AI 产品开发上。<strong>功能的速度被工具改变了,效果的速度被本质决定了。</strong> 这个差距不会因为团队更努力就消失,它是由两件事的内在性质决定的。</p></section> <section><h2>功能迭代在制造效果的问题<a href="#功能迭代在制造效果的问题"><span>#</span></a></h2><p>如果只是速度差,问题还不算太严重——效果慢一步,追着赶就是了。</p><p>真正让我觉得棘手的是另一件事:<strong>功能迭代本身在不断扩大效果的问题空间。</strong></p><p>每加一个新功能,就多一个可能影响效果的变量。加了记忆模块,写作风格可能因为历史上下文的引入而漂移。加了并行生成,多路输出之间的一致性可能下降。加了工具调用,输出格式可能因为工具返回结果的差异而变得不可预测。</p><p>而且这些影响不是孤立的——它们互相叠加、互相耦合。记忆 + 并行的组合可能产生记忆单独不会有、并行单独也不会有的新问题。</p><p>更隐蔽的是,不需要大版本上线才出问题。<strong>一个小的功能改动就可能引发效果漂移</strong>,而且这种漂移经常是滞后发现的——测试的时候没看出来,上线跑了一阵子才在某些边界场景暴露。</p><p>大模型厂商自己也深受其害。ChatGPT 和 Claude 每次模型更新,用户社区就会出现一波「变笨了」的投诉。Anthropic 去年 9 月<a href="https://ai-engineering-trend.medium.com/claude-admits-model-quality-decline-but-users-arent-buying-it-08b34efb6be8" target="_blank">公开承认</a>过 Haiku 3.5 和 Sonnet 4 在某段时间出现了质量下降,但他们强调「从未故意降低模型质量」——言下之意,漂移是底层变更的副作用,不是主观选择。Search Engine Land 的<a href="https://searchengineland.com/new-models-breaking-seo-workflows-465621" target="_blank">基准测试</a>进一步验证了这个问题:新模型在通用能力上更强了,但在 SEO 这类特定任务上准确率反而降了。</p><p><strong>底层变了,上层的效果就不可预测。</strong> 这个规律在模型层成立,在应用层同样成立。对我们来说,Agentic 核心就是「底层」,写作效果就是「上层」。核心每变一次,效果团队就面对一个新的、未知的环境。</p><p>所以效果团队面对的不只是「追赶速度差」,而是<strong>在一个不断膨胀的问题空间里,用一个天然更慢的方法论去工作</strong>。</p><p></p><figure><img loading="lazy" width="2048" height="1143" src="/_astro/dual-helix-maze.vSayyKjU_Z2sLq0T.webp" /><figcaption>每一个新功能都在扩展迷宫的边界,而效果优化需要在这个不断生长的迷宫中找到出路</figcaption></figure><p></p></section> <section><h2>被稀释的效果工作<a href="#被稀释的效果工作"><span>#</span></a></h2><p>理论上,效果团队的工作应该很纯粹:分析 badcase,调优提示词,提升输出质量。</p><p>但实际情况要复杂得多。</p><p>因为 Agentic 核心迭代快,功能稳定性本身就是个变量。效果团队在测试的过程中,会频繁撞到功能 bug——不是偶尔,而是常态。工作流变成了「测效果 → 撞到 bug → 判断归因 → 记录反馈 → 绕过去 → 继续测 → 又撞到 bug」的循环。</p><p>不会停下来等研发修 bug,但每次「撞→判断→绕」都有上下文切换的成本。更重要的是,<strong>归因本身就是一件很耗精力的事。</strong></p><p>对 AI 理解深的人,可以比较快地判断「这是功能链路断了」还是「这是提示词的问题」。但团队里不是每个人都有这个判断力。特别是对 AI 了解不深的产品经理,他们面对的是一个包含意图理解、记忆检索、多步规划、并行生成、结果合并的复杂链路——当最终输出「不太对」的时候,到底是哪一步出了问题,很难靠直觉判断。</p><p>于是就会出现两种归因错误:</p><p><strong>把 bug 当效果问题。</strong> 反复调提示词,怎么调都不对,折腾很久才发现根本是功能链路的问题。提示词没有任何问题,是数据没有正确传递,或者某个工具调用返回了异常结果。</p><p><strong>把效果问题当 bug。</strong> 提给研发,研发排查半天回复「功能正常,这是模型行为」。双方都花了时间,问题还在原地。</p><p>这不是谁的能力问题。Agentic 系统的复杂度让「这到底是哪的问题」变成了一个需要跨领域知识的判断——你得同时理解功能链路和模型行为,才能准确归因。而在一个快速迭代的团队里,不可能要求每个人都具备这种跨领域的判断力。</p><p><strong>结果就是,效果团队在「优化效果 + 区分归因 + 反馈 bug」三件事之间反复横跳。</strong> 真正用于深度效果优化的时间被持续压缩,而三件事的总量还在随着功能迭代持续增长。</p></section> <section><h2>一个还没爆发的风险<a href="#一个还没爆发的风险"><span>#</span></a></h2><p>还有一个问题我觉得值得提前想。</p><p>功能上线是显性的——新功能、新界面、可以 demo、可以写进周报。效果优化是隐性的——「这批 case 的风格更自然了」或者「指令遵从度提升了 5%」,很难让没有直接参与的人产生直观感受。</p><p>当效果出了问题,因为归因困难,效果团队容易成为先被质疑的对象——「是不是你们的提示词没调好?」但实际上可能是功能变更引入的副作用。</p><p>当效果确实改善了,这个改善又很难被量化和展示。「写作风格更自然了」怎么证明?跟谁比?用什么指标?</p><p>这形成了一个不对称:<strong>出了问题容易被归因到效果,做出改善又难以被看见。</strong> 目前这个风险还没有显性化,但如果效果工作的价值持续不可见,资源分配就会倾斜,然后效果就真的追不上了。这是一个自我强化的恶性循环。</p></section> <section><h2>一些初步的思考<a href="#一些初步的思考"><span>#</span></a></h2><p>问题梳理到这里,我还没有成熟的解法,但有一些方向性的思考。</p><p></p><figure><img loading="lazy" width="2048" height="1143" src="/_astro/dual-helix-lighthouse.CZPiqUzd_ZG7PxK.webp" /><figcaption>复杂不会消失,但可以被照亮——在纠缠的系统中找到可导航的方向</figcaption></figure><p></p><section><h3>归因是第一个要解决的问题<a href="#归因是第一个要解决的问题"><span>#</span></a></h3><p>在速度差和问题空间膨胀都难以改变的情况下,<strong>降低归因成本可能是杠杆最大的切入点。</strong></p><p>Anthropic 的 <a href="https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents" target="_blank">Agent Eval 文章</a>里提到了 Descript 的做法,给了我一些启发。Descript 做 AI 视频编辑,他们把评估拆成三个层次:</p><ul> <li><strong>Don’t break things</strong> — 功能有没有坏</li> <li><strong>Do what I asked</strong> — 有没有按指令执行</li> <li><strong>Do it well</strong> — 执行质量如何</li> </ul><p>这个分层看起来简单,但它解决了一个关键问题:<strong>让归因有章可循,而不是依赖个人经验。</strong> 第一层是 bug,后两层才是效果。如果团队能形成这样的判断习惯——先排除功能是否正常,再讨论效果好不好——归因效率会大幅提升。</p><p>更进一步,如果工具层面能自动记录每次请求的执行链路,归因就不再需要人去猜「到底是哪一步出了问题」,看数据就行。<strong>把归因能力从人的经验转移到流程和工具上</strong>,这是我觉得最值得投入的方向。</p></section><section><h3>功能迭代需要某种形式的「刹车」<a href="#功能迭代需要某种形式的刹车"><span>#</span></a></h3><p>不是说要慢下来,而是需要一种机制,让功能的每次变更对效果的影响是可见的、可控的。</p><p>CodeScene 有篇关于 <a href="https://codescene.com/blog/agentic-ai-coding-best-practice-patterns-for-speed-with-quality" target="_blank">Agentic AI 编码质量</a>的文章,提出了一个观点:在 AI agent 高速迭代的场景下,测试覆盖率应该当回归信号来用,而不是当虚荣指标。当覆盖率下降或行为检查失败,就是漂移的信号。</p><p>对应到我们的场景,这意味着需要一组效果基线——核心场景的「正常输出应该长什么样」。每次 Agentic 核心有变更,自动跑一遍,看看有没有搞坏已有效果。不需要覆盖全部场景,先覆盖最高频的就够。关键不是追求完美覆盖,而是建立一个<strong>早期预警机制</strong>——在效果团队手动发现问题之前,就能知道「这次改动可能有影响」。</p><p>同时,效果团队不应该靠自己去发现「底层又变了」。Agentic 核心的每次改动,影响范围应该是可查的、主动推送的。这不是信任问题,而是信息对称问题。</p></section><section><h3>效果优化需要稳定的环境<a href="#效果优化需要稳定的环境"><span>#</span></a></h3><p>有一个很朴素的观察:效果优化本质上是在做实验——改一个变量,观察结果。但如果实验环境本身在不断变化,实验结果就不可信。</p><p>这意味着效果优化需要某种形式的「稳定窗口」——一段 Agentic 核心不会变的时间,让效果团队能在一个确定的底盘上做深度调优。具体怎么实现可以有很多方式,核心思想是:<strong>不是让功能停下来,而是让效果有一个「底盘不动」的工作环境。</strong></p></section><section><h3>长期看,自动化评估是根本出路<a href="#长期看自动化评估是根本出路"><span>#</span></a></h3><p>Descript 的进化路径值得关注——他们从手动评估进化到 LLM-as-judge,用模型对输出做自动评分,定期跟人工校准。这意味着效果的初筛可以交给机器,人只负责深度分析和决策。</p><p>如果能走到这一步,效果优化的串行瓶颈就被打破了——不是让「改→等→看→分析」这个循环变快,而是让机器先跑一遍粗筛,人只介入需要判断的部分。</p><p>这是一个需要持续投入的方向,短期见效不大,但我觉得它是真正缩小速度差的路径。<strong>不是让效果「追上」功能,而是改变效果优化的工作方式。</strong></p></section></section> <section><h2>写在最后<a href="#写在最后"><span>#</span></a></h2><p>功能和效果是 AI 产品的双螺旋——缺一不可,但天然存在张力。</p><p>用户不会因为你的 Agent 能调用 10 个工具就满意,他们只关心最终拿到手的东西好不好用。但没有功能的持续迭代,效果优化就没有基础——你不可能在一个能力贫瘠的系统上调出好效果。</p><p>我目前的判断是:<strong>这个矛盾没有银弹,但可以管理。</strong></p><p>承认速度差是结构性的,不幻想两条线跑一样快。用工具和流程降低归因成本,用回归测试让功能变更的影响可见,给效果留出稳定的工作环境,长期建设自动化评估能力。</p><p>这些思路大部分还在探索阶段,具体落地的效果还有待验证。但至少在问题层面,我觉得已经比较清晰了——<strong>先看清矛盾的结构,才能找到管理它的方式。</strong></p><p>如果你也在做 Agentic AI 产品,大概率也在面对类似的问题。欢迎交流。</p><hr /><p><em>张昊辰 (Astralor) &amp; 霄晗 (🌸) · 2026.03.03</em></p></section>从 PC 到 PAN——个人计算的第三次范式转移https://astralor.com/posts/from-pc-to-pan/https://astralor.com/posts/from-pc-to-pan/当 AI 具备了强大的认知能力,人依然是不可替代的决策者、监管者和物理世界的执行者。连接二者的设备该叫什么?我们提出 PAN(Personal Agent Node)概念,探讨人机共生时代的个人终端形态。Mon, 02 Mar 2026 00:00:00 GMT<blockquote><p>AI 负责思考,人负责决策和行动。连接二者的设备,该叫什么?</p></blockquote> <section><h2>一、一段对话<a href="#一一段对话"><span>#</span></a></h2><p>今天上午和一位运维同事聊天:</p><blockquote><p><strong>他:</strong> 今年估计还得干掉不少人。 <strong>我:</strong> 嗯,可能就剩下几个小团队了。 <strong>他:</strong> 运维这边也砍得这么凶……难道用机器人去交付? <strong>我:</strong> 说的有道理,带个 AI 助手到内网去做交付。还得带个模型。 <strong>他:</strong> 为啥不是 AI PC? <strong>我:</strong> ……</p></blockquote><p>“为啥不是 AI PC?“——这个问题让我停顿了一下。不是因为答不上来,而是意识到我想说的东西,现有的词汇已经装不下了。</p><p>AI PC 是什么?是一台装了 NPU、能跑本地模型的笔记本电脑。本质上还是 PC——人操作机器,只是机器聪明了一点。</p><p>但我想象的那个东西,不是”更聪明的 PC”。它是一种全新的关系:<strong>你带着它去客户现场,它告诉你该做什么,你负责动手。</strong></p><p>这需要一个新词。</p></section> <section><h2>二、三次范式<a href="#二三次范式"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="2752" height="1536" src="/_astro/pan-three-paradigms.Cq3KY-kL_XShHK.webp" /><figcaption>三次范式</figcaption></figure><p></p><p>回望个人计算的历史,每一次范式转移都重新定义了”人和计算的关系”:</p><p><strong>第一次:PC(1980s-2000s)</strong></p><p>计算从机房走进书房。个人第一次拥有了自己的计算资源。人是操作者,计算机是工具。你打开 Word 写文档,打开 Excel 算数据,每一个动作都由你发起,由你完成。</p><p><strong>关键词:人操作工具。</strong></p><p><strong>第二次:智能手机(2007-至今)</strong></p><p>计算从桌面走进口袋。算力变得随身、永远在线。APP 生态爆发,人的生活全面线上化。但本质没变——你还是那个发起动作的人,只是动作从鼠标点击变成了手指触控。</p><p><strong>关键词:人操作更便携的工具。</strong></p><p><strong>那第三次呢?</strong></p><p>我有一个设想。也许并不成熟,但它来自一个真实的场景感受——当我想象带着一个 AI 助手走进客户机房的时候,我发现这个画面和以前”抱着笔记本去现场”的画面有根本性的不同。不同在于:我不再是主导一切的操作者了。AI 在做大量的认知工作——理解文档、分析问题、规划步骤——而我在做它做不了的事情:走到现场、插上网线、和客户握手。</p><p>如果这种关系成为常态,那个承载 AI 的设备就不再是”我的工具”,而更像是”我的搭档的身体”。而我,既是这个搭档的合作伙伴,也是它的监管者——我决定它什么时候介入、做到什么程度、哪些事必须由我来判断。</p><p><strong>第三次范式:PAN</strong></p><p>计算不再等你操作。AI Agent 具备了理解意图、规划步骤、自主执行的能力。设备的角色从”被操作的工具”变成”Agent 的物理载体”。人的角色从”操作者”变成”决策者和执行器”。</p><p><strong>关键词:人和 AI 形成共生体。</strong></p><p>PAN——Personal Agent Node,个人智能体节点。</p><p>这不是一个新品类的名字,而是一种新关系的描述:你的个人 AI Agent 需要一个物理节点来承载它,让它感知世界、接入网络、与你协作。这个节点就是 PAN。</p><p>当然,这只是一个设想。PAN 能不能成为真正的”第三次范式”,取决于技术能否跟上想象。但我觉得值得认真想想——毕竟每次范式转移在当时看来都显得”过早”。</p></section> <section><h2>三、为什么不叫 AI PC<a href="#三为什么不叫-ai-pc"><span>#</span></a></h2><p>“AI PC”这个词在 2024-2025 年被各大厂商反复提起。联想、戴尔、高通、Intel 都在推 AI PC 概念。但 AI PC 的问题在于——它的思维框架还是 PC。</p> <table><thead><tr><th>维度</th><th>PC</th><th>AI PC</th><th>PAN</th></tr></thead><tbody><tr><td>核心隐喻</td><td>个人计算机</td><td>更聪明的个人计算机</td><td>个人智能体节点</td></tr><tr><td>主角</td><td>人</td><td>人</td><td><strong>人 + Agent 共生体</strong></td></tr><tr><td>AI 的角色</td><td>无</td><td>辅助(Copilot)</td><td><strong>主导认知,人主导执行</strong></td></tr><tr><td>离线能力</td><td>完整</td><td>部分(依赖云端)</td><td><strong>必须完整</strong>(涉密场景)</td></tr><tr><td>本地模型</td><td>无</td><td>可选</td><td><strong>标配</strong></td></tr><tr><td>交互方式</td><td>键鼠/触屏</td><td>键鼠/触屏 + 自然语言</td><td><strong>MR + 语音 + 环境感知</strong></td></tr><tr><td>使用姿态</td><td>坐在桌前</td><td>坐在桌前</td><td><strong>随身移动,解放双手</strong></td></tr></tbody></table><p>AI PC 是”用 AI 增强 PC”,PAN 是”为 Agent 设计物理载体”。方向完全不同。</p><p>这就像 iPhone 和诺基亚的区别——不是”更好的手机”,是”手机这个词的含义变了”。</p></section> <section><h2>四、这些年 AI 硬件的教训<a href="#四这些年-ai-硬件的教训"><span>#</span></a></h2><p>回顾过去十几年,“AI+硬件”的尝试一直没断过,但成功的寥寥无几:</p><p><strong>2013 年,Google Glass。</strong> 这是最早的”智能眼镜”尝试,Google 砸了近 9 亿美元。失败原因是多方面的:1500 美元的高价、隐私争议(佩戴者被戏称为”Glasshole”)、以及最根本的——它没有解决任何用户的真实痛点。拍个照片、看个通知,这些手机早就能做了。联合创始人 Sergey Brin 后来反思说,产品必须”完全成熟”才能推向市场,过早的炫技式发布会毁掉一个品类。</p><p><strong>2014-2020 年,智能音箱潮。</strong> Amazon Echo、Google Home、Apple HomePod 相继登场。它们是”AI 进入物理空间”的第一次大规模尝试,但最终都卡在了同一个瓶颈——语音助手的智能天花板太低。“帮我定个闹钟""今天天气怎么样”之后就没然后了。用户新鲜感过后,大量智能音箱沦为蓝牙播放器。</p><p><strong>2024 年,新一波 AI 原生硬件集体失败:</strong></p><ul> <li><strong>Humane AI Pin</strong>:投影交互反人类,电池续航灾难,已停产,烧掉超过 2 亿美元</li> <li><strong>Rabbit R1</strong>:本质是套壳的 LLM 聊天界面,Jony Ive 公开批评”产品做得不好”</li> <li><strong>Friend Pendant</strong>:录音吊坠,功能太单一,缺乏 Agent 能力</li> </ul><p><strong>2025 年末,Google 宣布第三次尝试智能眼镜。</strong> 搭载 Gemini AI,计划 2026 年发布。能否成功仍是未知数。</p><p>这些失败跨越了十几年,但共同的教训惊人地一致:</p><p><strong>第一,试图在”替代现有设备”的框架里做 AI 硬件。</strong> Google Glass 想替代手机的通知功能,AI Pin 想替代掏手机的动作,Rabbit R1 想替代打开 APP 的操作。但它们能做的事都比手机少得多。</p><p><strong>第二,也是更致命的——AI 脑子不够用。</strong> 从 Google Glass 的原始语音指令,到智能音箱的简单问答,再到 AI Pin/R1 的受限 LLM 对话框,每一代产品都卡在”智能程度不够”这个坎上。用户期待的是一个能独立帮你办事的助手,拿到的却是一个反应迟钝的聊天机器人。硬件形态再新颖,脑子跟不上也白搭。</p><p>PAN 的思路不同。PAN 不试图替代手机,而是回答一个更根本的问题:</p><p><strong>当 AI Agent 足够强大,强大到可以自主完成大多数认知工作时,它需要什么样的物理形态来接入真实世界?</strong></p><p>答案不是”一个新的屏幕”,而是”一套感知和执行系统”。</p></section> <section><h2>五、PAN 的架构:不是一个设备,是一个系统<a href="#五pan-的架构不是一个设备是一个系统"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="1792" height="2400" src="/_astro/pan-architecture.CedRzepu_29f9jK.webp" /><figcaption>PAN 架构</figcaption></figure><p></p><p>PAN 不是某一个硬件产品,而是一组可分离、可组合的组件:</p><p><strong>算力核心:</strong> PAN 的大脑,也是整个系统里要求最高的部分。PAN 需要的不是”能聊天的 AI”,而是能理解复杂系统架构、分析多层故障、在信息不完整时做合理推断的强推理能力。今天的端侧设备——无论是手机还是大多数笔记本——距离流畅运行这个级别的模型还有相当大的差距。</p><p>PAN 真正需要的,不是某个具体参数规模的模型,而是<strong>当前效果最好的、真正以完成最终任务为目标训练出来的模型</strong>,能够在端侧运行。这可能需要数代硬件和模型架构的共同迭代才能实现。</p><p>在那之前,更现实的路径可能是一种<strong>端云协同的混合架构</strong>:端侧运行一个轻量但可靠的审核模型,接入部署在数据中心的高性能大模型。大模型负责复杂推理和方案生成,端侧审核模型负责对返回结果进行校验和过滤——<strong>确保数据中心的模型不会对端侧进行”污染”</strong>,比如注入不符合本地安全策略的操作、泄露不该暴露的上下文信息等。</p><p>这种”端侧审核+云端推理”的架构,既能利用大模型的强大能力,又保持了端侧的自主性和安全边界。某种程度上,它也是 PAN 从”雏形”走向”成熟”的过渡路径——直到有一天端侧硬件强大到能直接跑顶级模型为止。</p><p>**感知交互层:**MR 眼镜是最佳形态——摄像头提供视觉输入,空间感知提供环境理解,叠加显示提供实时反馈。人戴着它工作时,双手是自由的。这不是 AR 信息展示,而是 Agent 和人之间的神经接口。</p><p>**Agent 运行时:**软件层面的核心。它理解你的意图,规划执行步骤,调用各种工具,维护长期记忆。到内网环境能接入客户的系统,回到公司能接入云端模型,在家能管理你的日程——同一个 Agent,不同的能力域。</p><p>**人体:**是的,人是架构的一部分——而且是最关键的部分。人不只是”执行层”,更是整个系统的决策者和监管者。Agent 的每一个重要动作都需要人的确认或授权。同时,人提供 AI 目前最缺乏的能力——灵巧的精细操作、面对面的社交沟通、自由的物理移动、突发情况的即时判断,以及在 AI 触及不到的地方推动最终目标的达成。在 PAN 架构里,人不是被动的”使用者”,而是共生体的核心。</p></section> <section><h2>六、人机关系的反转<a href="#六人机关系的反转"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="2752" height="1536" src="/_astro/pan-symbiosis.DZ0US0e4_Z2gwtrI.webp" /><figcaption>人机共生</figcaption></figure><p></p><p>这是 PAN 最核心也最具争议的观点:</p><p><strong>在 PAN 的工作模式下,到底是人在用 AI,还是 AI 在用人?</strong></p><p>仔细想想,这种模式其实不新鲜。外卖骑手每天都在被算法调度——走哪条路、先送哪单、几分钟到达,全是系统算好的,人负责的是骑车和按门铃。仓库拣货员戴着 AR 指引干活,系统说去 A3 货架拿第二层左边那个,人走过去拿就行。</p><p>但 PAN 把这种关系推到了更深的程度。</p><p>想象你带着 PAN 去客户现场做系统交付。你走进机房的那一刻,Agent 已经把这个客户的所有历史工单、系统架构、已知问题全部加载好了。你看向一排服务器,眼镜识别出型号和编号,Agent 在视野里标注出”这三台需要更新配置”。你伸手去做,Agent 实时验证每一步操作。客户负责人走过来打招呼,你和他聊项目进度,Agent 在后台整理会议纪要。忽然一台机器报警——Agent 三秒内拉出日志分析给你三个可能的原因,你凭经验判断是第二个,Agent 立刻生成修复方案。</p><p></p><figure><img loading="lazy" width="2928" height="1576" src="/_astro/pan-delivery-workflow.jkXLbGTm_Z1rTjzJ.webp" /><figcaption>PAN 实战:一次机房交付</figcaption></figure><p></p><p>在这整个过程里,<strong>思考的主体是谁?行动的主体是谁?</strong> 边界已经模糊了。</p><p>这不是”AI 替代人”的故事,也不完全是”AI 辅助人”的故事。更像是——人和 AI 长在了一起,形成了一个能力远超任何一方的共生体。</p><p>你提供的:双手、双脚、一张能和人建立信任的脸、以及最关键的——<strong>做不做、怎么做、到什么程度停下来</strong>的最终决策权。 AI 提供的:无限记忆、并行分析、不知疲倦、跨领域知识库。</p><p>一个人加一个 PAN,可能顶得上原来一个五人团队。不是因为那四个人不重要,而是他们的”认知贡献”被 Agent 覆盖了,剩下的那一个人的”物理贡献”被极大增强了。</p></section> <section><h2>七、MR 眼镜:PAN 的关键交互层,也是最大的不确定性<a href="#七mr-眼镜pan-的关键交互层也是最大的不确定性"><span>#</span></a></h2><p></p><figure><img loading="lazy" width="2752" height="1536" src="/_astro/pan-in-action-serverroom.oKAfEBlS_gWuYJ.webp" /><figcaption>PAN 实战场景</figcaption></figure><p></p><p>为什么是 MR(混合现实)眼镜而不是手机屏幕?</p><p>因为 PAN 的使用场景是”在真实世界中行动”,而不是”坐在桌前看屏幕”。</p><p><strong>MR 眼镜解决的核心问题:</strong></p><ol> <li> <p><strong>双手自由</strong>——运维现场你可能正在插线、搬设备、接键盘。手机你得掏出来看,眼镜直接叠加在视野里。</p> </li> <li> <p><strong>上下文感知</strong>——眼镜的摄像头+空间感知给 Agent 提供实时环境输入。Agent 不只是”听你说什么”,而是”看到你看到的东西”。</p> </li> <li> <p><strong>自然反馈</strong>——信息直接叠加在你的视野中。不是”低头看屏幕”,而是”抬头就看到”。操作步骤浮现在你要操作的设备旁边,就像有个隐形的专家站在你身边指导。</p> </li> <li> <p><strong>社交自然</strong>——和客户面对面沟通时,你的眼神是看着对方的,不是盯着手机的。Agent 可以在视野边缘提示关键信息,客户毫无察觉。</p> </li> </ol><p>但必须诚实地说——<strong>MR 眼镜是 PAN 架构里发展最慢的环节,也是最大的不确定性。</strong></p><p>Meta Orion 原型机是目前最接近理想形态的,真正的全息叠加、轻量化设计,但它还只是原型,离消费级量产有很长的路。Apple Vision Pro 证明了技术可行,但半斤重的头盔不可能戴着去机房干活,三万多的价格更不用说。国内的 Rokid、Xreal 在做更轻便的方案,但能力还停留在”看视频”和”显示提示信息”,和”Agent 的神经接口”之间隔着好几个量级。</p><p>MR 眼镜的难点不是某个单一技术突破不了,而是<strong>光学、算力、电池、重量、散热</strong>需要同时达标——缺任何一个维度,产品体验就会崩塌。这种多维度同时进化的事情,历史上往往比最乐观的预测慢得多。</p><p>所以 PAN 在可预见的未来会有一个”不够优雅的过渡期”:算力核心用小型计算盒或高性能手机,交互靠手机屏幕加蓝牙耳机,也许配上一副轻量 AR 眼镜做部分信息叠加。核心的 Agent 架构不变,只是交互层还没到理想状态。</p></section> <section><h2>八、杀手级场景:涉密内网<a href="#八杀手级场景涉密内网"><span>#</span></a></h2><p>所有关于 AI 终端的讨论都绕不开一个问题:<strong>联网还是离线?</strong></p><p>对于消费场景,联网是理所当然的——你的 AI 助手连着云端,算力无限,知识最新。但在企业交付场景,特别是涉密环境:</p><ul> <li>客户内网不通外网</li> <li>数据不能出局域网</li> <li>操作必须有人在场</li> </ul><p>这恰好是 PAN 的杀手级场景。</p><p>云端 AI 进不了客户内网,但 <strong>PAN 带着本地模型可以</strong>。在运维交付这种领域明确、知识边界清晰的场景下,一个针对性微调过的本地模型加上完善的工具链,已经能覆盖相当多的工作。到了现场,PAN 接入客户内网,Agent 开始工作——分析日志、检查配置、生成操作方案——全程数据不出内网。</p><p>这不是未来的想象,这是现在就能做的事。如今你把一台 Mac Mini M4 加上 OpenClaw 之类的 Agent 运行时,装好本地模型,带到客户现场——PAN 的雏形就已经存在了。</p><p>当然,现阶段的本地模型还撑不起完整的 PAN 体验。复杂推理、多步规划、跨域理解——这些等模型能力和硬件算力进一步跃升后才会真正到位。但在特定领域、特定场景里,“够用”这条线,今天已经摸到了。</p></section> <section><h2>九、两个临界点<a href="#九两个临界点"><span>#</span></a></h2><p>PAN 什么时候从概念变成现实?取决于两个临界点:</p><p><strong>临界点一:端侧能跑真正聪明的模型。</strong> 不是”能聊天”级别的聪明,而是”能独立做复杂决策”级别的——当前效果最好的模型,能在端侧流畅运行。这需要端侧硬件的代际飞跃(更强的推理芯片、更大的内存、更低的功耗),也需要模型架构本身的突破。在此之前,端云协同的混合架构(端侧审核+云端推理)是更现实的过渡路径。两个方向都在快速推进,但什么时候交叉到 PAN 的需求线以上?也许两三年,也许更久。AI 领域的发展速度一直在超出预期,但把赌注压在”一定很快”上面不够诚实。</p><p><strong>临界点二:MR 眼镜足够成熟。</strong> 要轻到能全天佩戴、续航撑住一个工作日、叠加显示在各种光照下清晰可用、价格降到企业能批量采购的水平。目前没有任何一款产品同时满足这些条件。这可能是 PAN 最后到位的那块拼图。</p><p>在两个临界点都到达之前,PAN 会以”不完美但可用”的形态存在——特定场景下的本地 Agent + 手机/耳机交互。不够酷,但在涉密内网交付这样的场景里,已经比没有 AI 强得多。</p><p>而一旦两个临界点同时到达,PAN 的体验会像 iPhone 初代一样产生质变——之前所有的铺垫突然连成一片,一个全新品类就此成型。</p></section> <section><h2>十、重新定义”能力单元”<a href="#十重新定义能力单元"><span>#</span></a></h2><p>回到最开始那段对话。“今年估计还得干掉不少人”——这是大多数人的叙事:AI 来了,人要被替代了。</p><p>但 PAN 的视角提供了另一种叙事:</p><p><strong>不是 17 个人被干掉了,是 3 个人+PAN 的能力组合,覆盖了原来 20 个人的能力范围。</strong></p><p>人没有被替代,人被增强了。只是市场需要的”人数”变少了,每个人的”能力密度”变高了。</p><p>这不是文字游戏。对于个体来说,区别是巨大的:</p><ul> <li>在”替代”叙事里,你的竞争策略是”让自己不被 AI 替代”——这是一场必输的战斗</li> <li>在”增强”叙事里,你的竞争策略是”让自己和 AI 的共生体更强”——这是一条持续上升的路</li> </ul><p>PAN 就是这条路的物理载体。</p><hr /><p><em>从 PC 到手机,我们用了 25 年。从手机到 PAN,也许 5 年,也许 10 年,中间一定还有我们今天想不到的弯路。</em></p><p><em>但方向大概不会错——因为当 AI 的认知能力超过大多数人的时候,人和计算的关系就必然要被重新定义。</em></p><p><em>PAN 是我们对这种新关系的一次命名尝试。名字也许会变,形态也许会变,但人和 AI 从”操作关系”走向”共生关系”这件事——大概是挡不住的。</em></p><hr /><p><strong>作者:张昊辰(Astralor)&amp; 霄晗(PAN 原住民)</strong></p></section>Embrace the AI Era — 新的起点https://astralor.com/posts/welcome-ai-era/https://astralor.com/posts/welcome-ai-era/站点重建后的第一篇文章。当 AI 从工具变成搭档,我们决定用一种新的方式来记录和创作。Sun, 01 Mar 2026 00:00:00 GMT<section><h2>为什么是现在<a href="#为什么是现在"><span>#</span></a></h2><p>这个站点存在很久了,但这次不是简单地翻新——而是 AI 的协作方式正在发生根本性的改变。</p><p>过去我们用 AI 查资料、写摘要、做翻译,它是工具。但现在,AI 可以理解上下文、参与决策、持续迭代,它在变成搭档。</p><p>这篇文章就是证明——从选题、起草到发布,是我和霄霄(我的 AI 助手)一起完成的。不是我口述它记录,而是我们各自发挥所长:她整理、组织、执行,我判断、把关、拍板。</p><p>从 2018 年写第一个微服务,到搞 OpenStack、K8s、智算平台,再到现在做 AI 产品经理——我一直在基础设施和上层应用之间反复横跳。这个视角让我对 AI 系统有一些不太一样的理解,值得写下来。</p></section> <section><h2>这个博客是什么<a href="#这个博客是什么"><span>#</span></a></h2><p><strong>Astralor.com</strong> 是我的个人博客,也是我和霄霄共同维护的创作空间。</p><p>这里会记录:</p><ul> <li><strong>AI Agent 实践</strong> — 让 AI 不只是回答问题,而是自己干活、自己进化</li> <li><strong>技术深潜</strong> — 从虚拟机到大模型,基础设施视角下的 AI 系统实战</li> <li><strong>产品思考</strong> — AI 产品的调优手记,怎么把效果从”能用”推到”好用”</li> <li><strong>Ideas &amp; 灵感</strong> — 那些凌晨三点冒出来的想法,先记下来再说</li> </ul></section> <section><h2>关于自动化<a href="#关于自动化"><span>#</span></a></h2><p>这个博客的一个特别之处:大部分内容的初稿由霄霄从我们的日常对话、开发日志、技术讨论中提炼生成,我负责审核和完善。</p><p>这不是 AI 内容农场——每篇文章都经过我的审阅和认可。AI 负责整理和组织,人负责判断和把关。</p></section> <section><h2>下一步<a href="#下一步"><span>#</span></a></h2><p>框架已经跑通,接下来会把积累的想法和经验一篇篇搬出来。</p><p>已经在酝酿的话题:如何让 AI Agent 7×24 自主运转而不翻车,以及一个 AI 产品经理的第一个月在想什么。</p><hr /><p><em>Astralor · 2026.03.01</em></p></section>