<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>开发实践 on Chico's Tech Blog</title><link>https://realtime-ai.chat/categories/%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5/</link><description>Recent content in 开发实践 on Chico's Tech Blog</description><image><title>Chico's Tech Blog</title><url>https://github.com/chicogong.png</url><link>https://github.com/chicogong.png</link></image><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 18 May 2026 11:00:00 +0800</lastBuildDate><atom:link href="https://realtime-ai.chat/categories/%E5%BC%80%E5%8F%91%E5%AE%9E%E8%B7%B5/index.xml" rel="self" type="application/rss+xml"/><item><title>AI IDE 这半年:Cursor、Claude Code、Windsurf 之后</title><link>https://realtime-ai.chat/posts/ai-ide-2026/</link><pubDate>Mon, 18 May 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/ai-ide-2026/</guid><description>复盘 2026 上半年 AI 编程工具的演变:从代码补全到后台 agent,Cursor、Claude Code、Windsurf、Copilot 的真实定位与差异,以及开发者从写代码转向审代码、派活的工作方式变化。</description><content:encoded><![CDATA[<p>上周三下午,我同时开着四个东西:Cursor 里一个 agent 在改重构,终端里 Claude Code 在跑测试,GitHub 上一个 Copilot 后台 agent 在处理我早上随手丢过去的 issue,还有一个 Cursor 云端 automation 在等 CI 结果。我本人那段时间在干嘛?在看 Linear 上的工单,决定下一个派给谁。</p>
<p>我没写一行代码。但那个下午合并了五个 PR。</p>
<p>这不是什么&quot;未来已来&quot;的感慨。这是 2026 年 5 月一个普通工程师的普通下午。半年前——也就是 2025 年底——我的工作方式还不是这样。那时候 AI 编程工具的主流形态是&quot;一个很聪明的补全&quot;,你在编辑器里写代码,它帮你接下一段。现在,补全这件事我几乎已经感觉不到它的存在了,因为我的注意力整个挪到了别处。</p>
<p>这半年到底发生了什么,值得拆开看看。</p>
<h2 id="三级跳补全--终端-agent--后台-agent">三级跳:补全 → 终端 agent → 后台 agent</h2>
<p>如果要给 AI 编程工具这半年画一条线,它是这样三级跳的:</p>
<pre class="mermaid">flowchart LR
  A[代码补全<br/>2023-2024] --> B[IDE 内 agent<br/>2025] --> C[终端 agent<br/>2025 下半年] --> D[后台/云端 agent<br/>2026]
  style A fill:#e8e8e8,stroke:#999
  style B fill:#fde7c2,stroke:#e8b23c
  style C fill:#fde7c2,stroke:#e8b23c
  style D fill:#c2e0fd,stroke:#3c8ce8
</pre><p>第一级是<strong>补全</strong>:Copilot 那套,光标后面灰字提示,你按 Tab 接受。这个形态决定了一件事——AI 是你的副驾驶,方向盘还在你手里,你得一直盯着路。</p>
<p>第二级是 <strong>IDE 内的 agent</strong>:Cursor 的 Composer、Windsurf 的 Cascade。它不再是接一段,而是&quot;你说要干什么,它跨多个文件改完给你看&quot;。方向盘开始松动了,但你还在车里。</p>
<p>第三级是 <strong>终端 agent</strong>:Claude Code 是把这个形态做出影响力的那个。它干脆不要 IDE 这个壳了,就是个命令行程序,你跟它说话,它自己读文件、改代码、跑测试、看报错、再改。这一步的意义比看上去大——它把 AI 编程从&quot;编辑器里的一个功能&quot;变成了&quot;一个独立的进程&quot;。一旦是独立进程,你就能开很多个,就能让它在后台跑。</p>
<p>第四级,也就是现在,是<strong>后台 / 云端 agent</strong>:活儿不在你机器上跑了。Cursor 的 cloud agents、GitHub 的 coding agent、Cognition 的 Devin,它们在云端的容器里干活,干完给你提个 PR。你甚至可以在手机上派活。</p>
<p>每跳一级,人和代码之间就多隔一层。半年前我的手指还在键盘上,现在我的手指主要在做一件事:点&quot;approve&quot;或者&quot;reject&quot;。</p>
<h2 id="当前四强各自站在哪">当前四强,各自站在哪</h2>
<p>把这半年最主流的四个工具摆在一起,它们其实已经不在同一个赛道上竞争了——这是很多人没意识到的。</p>
<table>
  <thead>
      <tr>
          <th>工具</th>
          <th>当前形态</th>
          <th>真实定位</th>
          <th>适合谁</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cursor(3.4 / Composer 2.5)</td>
          <td>AI 原生 IDE + 云端 agent</td>
          <td>&ldquo;派活中枢&rdquo;:本地写 + 云端并行</td>
          <td>想一个人指挥一支 agent 小队的人</td>
      </tr>
      <tr>
          <td>Claude Code(2.x)</td>
          <td>终端 agent + Agent View</td>
          <td>&ldquo;干重活的那个&rdquo;:复杂改动、长任务</td>
          <td>信任命令行、要做深度改动的人</td>
      </tr>
      <tr>
          <td>Windsurf(Wave 13)</td>
          <td>AI IDE,归 Cognition</td>
          <td>&ldquo;通往 Devin 的入口&rdquo;</td>
          <td>喜欢 Cascade 体验、赌 Cognition 的人</td>
      </tr>
      <tr>
          <td>GitHub Copilot</td>
          <td>补全 + Agent Mode + 云端 coding agent</td>
          <td>&ldquo;贴着 GitHub 的那个&rdquo;</td>
          <td>重度 GitHub workflow、企业团队</td>
      </tr>
  </tbody>
</table>
<p><strong>Cursor</strong> 这半年走得最稳。3.3、3.4 连着发,Composer 2.5 五月中刚出。它现在的核心卖点已经不是&quot;补全多准&quot;,而是 <code>/multitask</code>——你可以同时开一堆异步子 agent 并行干活,加上云端 automation 能直接从 Linear、Jira、GitHub 读工单、起 PR、回写状态。Cursor 想做的是你的<strong>指挥台</strong>:本地一份 agent,云端一支舰队,你坐中间派活。它甚至能帮你把云端 agent 需要的开发环境(克隆仓库、装依赖、配凭据)自动搭好——因为没有环境,agent 舰队就跑不起来。</p>
<p><strong>Claude Code</strong> 走的是另一条路。它不抢&quot;IDE&quot;这个身份,就守着终端。这半年它加了 Agent View——一个能同时盯多个后台会话的界面,加了 <code>/goal</code>——你给它一个目标,它自己写代码、跑测试、debug、再跑,直到达成。我个人的体感:Claude Code 是这四个里最适合干&quot;脏活重活&quot;的。一个要动二十个文件、还得反复跑测试验证的重构,我现在默认丢给它。它的 fast mode 现在默认跑 Opus 4.7。</p>
<p><strong>Windsurf</strong> 是这半年最唏嘘的一个。2025 年底它被 Cognition(做 Devin 的那家)以约 2.5 亿美元收购,这中间还夹着 Google 的技术授权和 OpenAI 当初的竞购,过程一地鸡毛。产品本身没死,Wave 13 还带来了多 agent 会话和 Git worktree 支持,2026 年 2 月它在 LogRocket 的 AI 开发工具榜上还排第一。但今年 3 月它把原来便宜、可预测的 15 美元信用额度套餐换成了 20 美元加严格日 / 周配额,直接惹毛了一批老用户。更要命的是定位上的不确定:Cognition 明说了想把 Windsurf 的 IDE 能力并进 Devin。所以现在用 Windsurf,你得想清楚——你是在用一个 IDE,还是在用一个早晚会变成 Devin 入口的东西。</p>
<p><strong>GitHub Copilot</strong> 是那个&quot;看起来落后、其实没掉队&quot;的。补全起家的它,这半年把 Agent Mode 和云端 coding agent 都补齐了:coding agent 现在能自己选模型、开 PR 前先用 code review 自审一遍、还在流程里跑代码扫描和密钥泄露检查。它最大的护城河从来不是模型,是它长在 GitHub 身体里——issue、PR、Actions、code review 一条龙。五月它还放出了从 JetBrains IDE 把任务交给本地 Copilot CLI agent 的预览。Copilot 不耀眼,但对一个深度绑在 GitHub 上的企业团队,它是阻力最小的选择。</p>
<p>我的判断是:<strong>别再问&quot;哪个最好&quot;了</strong>。这个问题在 2025 年还成立,现在不成立。Cursor 是指挥台,Claude Code 是重型施工队,Copilot 是贴着 GitHub 的传送带,Windsurf 是一张赌 Cognition 未来的票。它们解决的是不同的问题。我自己是 Cursor + Claude Code 一起用,前者派活、后者啃硬骨头,一点都不冲突。</p>
<h2 id="终端-agent为什么会赢">&ldquo;终端 agent&quot;为什么会赢</h2>
<p>值得单独说一句:为什么 2025 下半年杀出来的是终端 agent 这个形态,而不是更花哨的 IDE?</p>
<p>因为终端 agent 砍掉了&quot;图形界面&quot;这个包袱,换来了三样东西:<strong>可组合、可并行、可上云</strong>。</p>
<p>一个命令行程序,你能用 shell 脚本把它串起来,能在 CI 里调它,能开十个进程同时跑。一个 IDE 你做不到这些——IDE 天生是给&quot;一个人坐在前面&quot;设计的。当 AI 编程从&quot;辅助一个人&quot;变成&quot;同时干很多活&rdquo;,IDE 这个外壳反而成了约束。</p>
<pre class="mermaid">flowchart TB
  Dev[开发者] --> Plan[拆任务 / 写清楚要什么]
  Plan --> A1[agent 1: 后台改 bug]
  Plan --> A2[agent 2: 本地写新功能]
  Plan --> A3[agent 3: 云端跑重构]
  A1 --> Review[人:审 diff / 提 PR / 决定合不合]
  A2 --> Review
  A3 --> Review
  Review --> Dev
  style Dev fill:#fde7c2,stroke:#e8b23c
  style Review fill:#fde7c2,stroke:#e8b23c
</pre><p>注意这张图里,人只出现在两个地方:<strong>开头拆活,结尾审活</strong>。中间那段&quot;写代码&quot;已经不在人的关键路径上了。这就是这半年最实质的变化——它不是工具变好用了,是工作流的形状变了。</p>
<p>Cursor 也很清楚这一点,所以它一边守着 IDE 这个用户习惯,一边拼命往云端 agent 和 <code>/multitask</code> 上加码。它在用 IDE 的外壳,装终端 agent 的内核。</p>
<h2 id="你的工作从写变成了审和派">你的工作从&quot;写&quot;变成了&quot;审&quot;和&quot;派&quot;</h2>
<p>这是我最想说的一段,也是这半年我自己感受最深的。</p>
<p>半年前,我的核心技能是写代码。现在不是了。现在我每天花最多时间的三件事是:</p>
<p><strong>第一,把活拆清楚。</strong> Agent 干得好不好,八成取决于你派活派得清不清楚。一个含糊的&quot;帮我优化下这个模块&quot;,和一个&quot;把这个模块的数据库查询从 N+1 改成批量加载,保持现有接口不变,加上对应测试&quot;——出来的东西天差地别。这半年我越来越觉得,<strong>写清楚需求本身就是一种正在升值的技能</strong>。Claude Code 的 <code>/goal</code> 之所以好用,前提是你得能说清楚那个 goal。</p>
<p><strong>第二,审 diff。</strong> 这是最累、也最危险的一件事。Agent 一天能给你交十几个 PR,业界数据是引入 agent 后 PR 数量涨了 40% 到 60%。问题来了:你审得过来吗?审不过来就会有人开始&quot;假装审过了&quot;——扫一眼,点 approve。这是 2026 年最真实的风险,不是 AI 写出 bug,是<strong>人审不动了,于是不审了</strong>。</p>
<p>我给自己定了条规矩:<strong>agent 写的代码,审查标准要比人写的更高,不是更低</strong>。因为人写错了通常错得&quot;有道理&quot;、好猜;agent 错起来经常错得很离谱、很自信,藏在一堆看着没问题的代码中间。</p>
<p><strong>第三,决定什么不交给 agent。</strong> 这点反直觉但很重要。核心架构、安全边界、那些&quot;错了代价很大&quot;的地方,我现在反而更倾向自己写,或者自己写完让 agent 来挑错。会派活的人不是把所有活都派出去的人,是知道<strong>哪些该派、哪些该自己攥着</strong>的人。</p>
<p>工具厂商其实也在顺着这个变化走。GitHub Copilot 的 coding agent 现在开 PR 前会先自审一遍、跑安全扫描——本质上是它知道&quot;人审不过来了&quot;,所以先帮你过一遍。Cursor 给你看 agent 的 context 用量,也是同一个逻辑:当你不亲自写,你至少得知道它在想什么。</p>
<p>所以如果你问我,这半年一个开发者最该练的是什么,我的答案是三个词:<strong>拆活、审 diff、判断边界</strong>。写代码的肌肉不会废掉——你得能写,才看得懂 agent 写的——但它不再是那块最值钱的肌肉了。</p>
<h2 id="接下来半年我赌什么">接下来半年,我赌什么</h2>
<p>简单说几个判断,赌错了年底再来认。</p>
<p><strong>后台 agent 会变成默认,但&quot;全自动&quot;还早。</strong> 派活给云端 agent、它提 PR 给你审,这套流程会变成常规操作。但&quot;把整个需求扔进去、不管了&quot;——Devin 那个最初的承诺——我认为这半年还到不了。卡点不在模型聪不聪明,在<strong>验证</strong>:你怎么确认它真做对了?在这个问题被解决之前,人必须留在审查这一环。</p>
<p><strong>工具会继续分化,不会收敛。</strong> 不会出现一个&quot;赢家通吃&quot;的 AI IDE。终端 agent、IDE、云端 agent 是三种不同的形态,服务三种不同的场景,它们会长期共存。你最终大概率是手上同时握着两三个,按场景切。</p>
<p><strong>审查会变成瓶颈,然后变成新工具的战场。</strong> 当 agent 产出快到人审不过来,下一波工具竞争的焦点不会是&quot;写得更快&quot;,而是&quot;帮你审得更快、更可信&quot;。谁能让人重新跟得上 agent 的产出速度,谁就赢下 2026 下半年。</p>
<p>半年前我担心的是 AI 会不会写不好代码。现在我不担心这个了——它写得够好。我现在担心的是另一件事:当写代码这件事变得这么便宜,我们会不会因为审不过来,而让一堆没真正看懂的代码,合进了主干。</p>
<p>工具的演化已经跑到前面去了。该追上的,是我们自己审视代码的方式。</p>
]]></content:encoded></item><item><title>AI 写的代码,谁来审</title><link>https://realtime-ai.chat/posts/coding-agent-review/</link><pubDate>Sat, 09 May 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/coding-agent-review/</guid><description>AI 能批量产出代码后,工程瓶颈从「写」挪到了「审」。这篇讲清 AI 代码为什么更难 review、人审扛不住量怎么办、AI 审 AI 靠不靠谱,以及团队流程该怎么改。</description><content:encoded><![CDATA[<p>一个用 AI 写代码的开发者,现在一天能开五六个 PR。</p>
<p>而审你 PR 的那个人,一天还是只能审五六个。</p>
<p>这两个数字凑在一起,就是 2026 年大多数工程团队真正的麻烦。Faros AI 的数据里,高 AI 使用率的团队完成的任务多了 21%、合并的 PR 多了将近一倍,但 PR 的 review 时长涨了 91%——而且那些 PR 还更大。Opsera 一份覆盖 25 万开发者的报告说得更直白:在没有治理的情况下,AI 生成的 PR 在 review 队列里等的时间是普通 PR 的 4.6 倍,哪怕从写完到提 PR 的时间砍掉了一半多。</p>
<p>写代码这件事,被 AI 解决了一大半。审代码这件事,一点没变。瓶颈就这么从「写」挪到了「审」,而且大多数团队还没意识到。</p>
<h2 id="为什么-ai-写的代码审起来反而更难">为什么 AI 写的代码,审起来反而更难</h2>
<p>直觉上,AI 代码该更好审才对——它风格统一、不会忘加分号、命名规规矩矩。但真审过 AI 大批量产出的代码的人都知道,事情反过来了。AI 代码难审,难在三个地方。</p>
<p><strong>第一,它看着太合理了。</strong> 人写错代码,常常会留下「破绽」——变量名词不达意、缩进乱、注释和代码对不上,这些视觉信号会让 reviewer 警觉。AI 不会。AI 写的错误代码,长得和正确代码一模一样:命名得体、结构清晰、注释贴心。CodeRabbit 的研究说 AI 写的代码暴露的问题比人写的多 1.7 倍,而这些问题里相当一部分是逻辑错误——业界一个被反复引用的说法是,AI 代码的纯逻辑错误率比人高约 75%。一个长得人模人样的函数,你的大脑会默认它没问题,于是真正的 bug 藏在「看着合理」的外壳里溜过去了。</p>
<p><strong>第二,量。</strong> 一个 reviewer 以前一天面对的是三五个 PR、每个两三百行。现在是十几个 PR,而且单个更大。注意力是有总量的——审第一个 PR 时你逐行读,审到第八个时你已经在「扫」。Review 质量不是匀速下降的,是过了某个阈值之后断崖式塌掉的。量本身就是一种攻击。</p>
<p><strong>第三,意图断了。</strong> 人写代码,脑子里有一条没写下来的推理链:为什么用这个数据结构、为什么这里要加锁、为什么宁可慢一点也不并发。Reviewer 审的其实是这条链。AI 生成代码时,这条链在 prompt 和模型权重里,没留在 diff 里。你看到的是结论,看不到「为什么」。于是 review 退化成「这段代码自己自洽吗」,而不是「这段代码做的是不是我们真正想要的事」——后者才是 review 的价值所在。</p>
<pre class="mermaid">flowchart LR
  A[人写代码] --> B[diff 里有破绽<br/>能看出意图] --> C[reviewer 审意图]
  D[AI 写代码] --> E[diff 看着完美<br/>意图没留下] --> F[reviewer 只能审自洽性]
  style E fill:#fde7c2,stroke:#e8b23c
  style F fill:#f8d0d0,stroke:#d06666
</pre><p>把这三点合起来:更隐蔽的错误、更大的量、更稀薄的意图。这不是「AI 代码质量差」的问题,是 review 这个动作的前提被抽掉了。</p>
<h2 id="人审扛不住量第一反应往往是错的">人审扛不住量,第一反应往往是错的</h2>
<p>发现 reviewer 堵住了,团队的第一反应通常是这几个,而它们大多没用,甚至有害。</p>
<p><strong>「招更多 reviewer」</strong> ——慢、贵,而且高级工程师本来就稀缺。更要命的是,AI 产代码的速度还在涨(有统计说人均产出 2025 到 2026 一年涨了约 60%),你招人的速度永远追不上模型迭代的速度。这是一场你结构性赢不了的军备竞赛。</p>
<p><strong>「review 快一点」</strong> ——把每个 PR 的 review 时间压缩,等于直接降低 review 质量。前面说过,AI 代码的错误本来就更隐蔽,你越快扫,漏得越多。这是用「看起来通畅」换「实际上失控」。</p>
<p><strong>「先合了再说,出问题再修」</strong> ——在 AI 时代尤其危险。以前一个有问题的模式进了主干,影响范围有限。现在 AI 会以那段代码为样本,在下一次生成时把同样的错误复制到十个地方。坏模式的传播速度,跟生成速度一样快。</p>
<p>真正有用的方向只有一个:<strong>别让所有代码都用同一种强度去审。</strong> Review 是稀缺资源,稀缺资源必须分配,不能平摊。</p>
<p>把进来的变更分层。一个能落地的分法是这样:</p>
<table>
  <thead>
      <tr>
          <th>变更类型</th>
          <th>例子</th>
          <th>审法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>低风险机械改动</td>
          <td>改文案、加日志、补测试、依赖小版本升级</td>
          <td>AI 审 + CI 把关,人抽查</td>
      </tr>
      <tr>
          <td>中风险常规功能</td>
          <td>已有模块里加一个接口、改一个表单</td>
          <td>AI 先过一遍,人审「意图」那一层</td>
      </tr>
      <tr>
          <td>高风险核心改动</td>
          <td>鉴权、计费、并发、数据迁移、对外 API</td>
          <td>人逐行审,且必须是熟悉该模块的人</td>
      </tr>
  </tbody>
</table>
<p>关键不是这张表本身,是承认一件事:<strong>不是所有代码都值得人来审。</strong> 让你最贵的工程师去逐行看一个改 UI 文案的 PR,是对稀缺资源的浪费,也是在透支他审计费系统时该有的注意力。把人的注意力,留给真正需要人类判断的地方。</p>
<h2 id="ai-审-ai-的代码到底靠不靠谱">AI 审 AI 的代码,到底靠不靠谱</h2>
<p>既然量是 AI 带来的,那让 AI 来审,逻辑上很顺。现在 AI code review 工具已经是个成熟品类,几十个产品,有真实的 ROI 数据。但「靠不靠谱」要分两面说。</p>
<p><strong>靠谱的那一面:</strong> AI reviewer 在「机械层」上是真的好用,而且能做到人做不到的事。它能记住整个依赖树里哪些包有已知 CVE、哪些 license 不合规、哪些 API 已经废弃;能在跨文件的几十个改动里发现「这个函数签名变了但那边三个调用没改」。有评测说,能看全代码库的工具,比只看单个 diff 的工具多抓出 40%~60% 的跨文件问题。这类活,人本来就做不好——人记不住那么多东西。</p>
<p><strong>不靠谱的那一面,要说透。</strong> AI 审 AI,有一个结构性的盲区:<strong>它们共享同一套训练分布。</strong> 2026 年初有研究指出,「生成 Agent + 审查 Agent」的流水线里,第一个 Agent 的错误经常被第二个 Agent 直接放行——因为它们出自同一个分布,缺乏「对抗性的差异」,自审最后退化成把原来的错误又确认了一遍。还有一篇 2026 年 2 月的论文更狠:就算是异构的多 Agent 团队,整体表现也稳定地打不过其中最强的那个单一成员,失败机制是「为了达成共识而牺牲专业判断」。</p>
<p>翻译成大白话:<strong>AI 会和你一起犯同一个错,而且犯得很自信。</strong> 你写 prompt 时漏掉的那个约束,生成的 Agent 不知道,审查的 Agent 同样不知道——它没法审出一个它自己也意识不到的需求。这正是 review 最该抓的那种错:不是「代码写错了」,是「代码做的不是我们要的事」。</p>
<p>另一个具体限制:AI reviewer 一旦喂的代码太多就垮。一个上千行的 diff 会撑爆上下文窗口,模型开始丢失连贯性,看不到改动之间的关联。它在小而聚焦的 PR 上表现最好——这反过来也说明,PR 该小,本来就该小。</p>
<p>所以我的判断是:<strong>AI 审机械层,人审意图层,两者不是替代关系,是分工。</strong> 把 AI 当成那个不知疲倦、记性超好、但永远不会质疑需求本身的初级 reviewer。它清场,人做判断。指望 AI 把人这一层也包了,是把它最不擅长的事派给了它。</p>
<pre class="mermaid">flowchart TB
  PR[一个 PR 进来] --> AI[AI reviewer]
  AI --> M[机械层:CVE、废弃 API<br/>跨文件一致性、风格、空指针]
  AI --> H{还需要人吗?}
  H -->|高风险或涉及意图| HUM[人 reviewer<br/>只审:这是不是我们想要的]
  H -->|低风险且 CI 全绿| MERGE[合并]
  HUM --> MERGE
  style HUM fill:#fde7c2,stroke:#e8b23c
</pre><h2 id="测试和类型系统从保险变成地基">测试和类型系统,从「保险」变成「地基」</h2>
<p>以前我们说测试和类型系统是「锦上添花的工程素养」。在 AI 时代,它们的角色被彻底放大了——它们成了你<strong>唯一能规模化、不靠人盯的那道防线</strong>。</p>
<p>道理很简单。人 review 不可规模化,AI review 有共享盲区,但一个类型检查、一个测试用例,是确定性的:它对一行代码和对一百万行代码,执行的是同一套标准,不会因为今天是第八个 PR 就走神。AI 能把生产代码的速度提十倍,但它没法提高你 review 的速度——能跟上这个速度的,只有自动化的、确定性的校验。</p>
<p>具体几条,都是能马上做的:</p>
<ul>
<li><strong>类型系统要严。</strong> 能上严格模式就上严格模式。AI 很爱写「看着对、类型上其实有洞」的代码,一个严格的类型检查器会在 review 之前就把一类错误挡掉,而且零成本、零情绪。</li>
<li><strong>测试覆盖的是意图,不是行数。</strong> 别用覆盖率数字考核——AI 生成高覆盖率但什么都没验证的测试,毫不费力。要写的是「断言业务规则」的测试:这笔订单在这个条件下必须被拒。这种测试,AI 之后改坏了逻辑,它会立刻红。</li>
<li><strong>测试本身也得审,而且要人审。</strong> AI 写功能、又顺手把测试写了,这是个陷阱:它可能写一个「永远会过」的测试来配合一段错的实现。审 AI 代码时,测试那部分要单独、用人的眼睛看。</li>
<li><strong>把校验往左移。</strong> 类型检查、静态扫描、安全规则、测试,全塞进 CI 的硬门禁。能在代码进 review 队列之前就拦下的问题,就别留给那个已经在审第八个 PR 的人。</li>
</ul>
<p>一句话:<strong>人和 AI 都会累、会走神、会有盲区,确定性的检查不会。</strong> 在代码量爆炸的时代,把质量赌在「有人会仔细看」上,是不可持续的;把它建在自动化门禁上,才扛得住量。</p>
<h2 id="团队流程得跟着改">团队流程,得跟着改</h2>
<p>工具和分工都到位了,最后是流程。不改流程,前面都白搭。几条具体的:</p>
<p><strong>PR 必须小,而且单一意图。</strong> 这条从「最佳实践」升级成了「硬约束」。reviewer 的带宽是整个系统的瓶颈,而瓶颈必须被主动管理。一个改了八件事的千行 PR,人审不动,AI 也审不动(上下文撑爆)。规矩要立死:一个 PR 只干一件事。AI 让你写得快,但不该让你把八件事打包成一个 diff 甩给别人。</p>
<p><strong>PR 描述要写「为什么」,这是在补回断掉的意图链。</strong> 2026 年一个合格的 PR 描述应该回答四件事:这个改动想干什么、为什么这么干(一两句);怎么证明它能跑(测试 + 手动验证步骤);风险多大、哪些部分是 AI 生成的;以及——明确点出 1~2 个「请人重点看这里」的地方。最后这点最关键:让提 PR 的人(他脑子里有意图)主动告诉 reviewer 该把注意力放哪。diff 该读起来像一份「意图说明书」,而不是一堆代码行的堆砌。</p>
<p><strong>「谁提的 PR,谁对它负责」要写进规矩。</strong> 用 AI 生成的代码,不等于责任也外包给了 AI。「这是 AI 写的」永远不能成为甩锅的理由。你按了那个生成键,你提了这个 PR,这段代码就是你的。这条不立清楚,所有人都会松懈,因为没人觉得自己该为一段「不是我写的」代码负责。</p>
<p><strong>测 review 这个环节本身。</strong> 既然瓶颈在这,就得给它装仪表盘:PR 在队列里平均等多久、单个 PR 多大、合并后多久出回滚或 hotfix。这些数字会告诉你 review 是不是正在悄悄塌掉——大多数团队是数字已经很难看了才后知后觉。</p>
<h2 id="写在最后">写在最后</h2>
<p>AI 没有消灭 review,它把 review 推到了聚光灯下。</p>
<p>以前 review 是写代码顺带的一环,藏在流程里不显眼。现在写代码便宜到几乎免费,「这段代码到底对不对、是不是我们要的」这个判断,就成了整个交付流程里最贵、最不可替代的一步。</p>
<p>所以别再盯着「怎么让 AI 写得更多」了——那个问题基本解决了。真正该花力气的是另一边:<strong>把 review 重新设计一遍。</strong> 让确定性的检查去扛量,让 AI 去扛机械层,把人最稀缺的判断力,集中投到「这段代码是不是在做我们真正想做的事」上。</p>
<p>AI 写的代码谁来审?机械层交给 AI,量交给自动化门禁,意图——只能是人。而且得是清醒的、注意力没被第八个 PR 耗光的人。把流程改成能保住这份清醒的样子,这件事,没有任何模型能替你做。</p>
<hr>
<p>参考资料:</p>
<ul>
<li><a href="https://dev.to/code-board/code-review-is-the-real-bottleneck-of-2026-and-most-teams-dont-see-it-5eed">Code Review Is the Real Bottleneck of 2026 — And Most Teams Don&rsquo;t See It</a></li>
<li><a href="https://levelup.gitconnected.com/the-ai-code-review-bottleneck-is-already-here-most-teams-havent-noticed-1b75e96e6781">The AI Code Review Bottleneck Is Already Here. Most Teams Haven&rsquo;t Noticed.</a></li>
<li><a href="https://addyo.substack.com/p/code-review-in-the-age-of-ai">Code Review in the Age of AI — Addy Osmani</a></li>
<li><a href="https://arxiv.org/pdf/2603.25773">The Specification as Quality Gate: Three Hypotheses on AI-Assisted Code Review (arXiv)</a></li>
<li><a href="https://www.codeant.ai/blogs/ai-code-review-accuracy">How Accurate Is AI Code Review in 2026? — CodeAnt</a></li>
<li><a href="https://engineering.salesforce.com/scaling-code-reviews-adapting-to-a-surge-in-ai-generated-code/">Scaling Code Reviews: Adapting to a Surge in AI-Generated Code — Salesforce Engineering</a></li>
<li><a href="https://www.qodo.ai/blog/5-ai-code-review-pattern-predictions-in-2026/">5 AI Code Review Pattern Predictions in 2026 — Qodo</a></li>
</ul>
]]></content:encoded></item><item><title>LLM 网关:多模型怎么统一接入和路由</title><link>https://realtime-ai.chat/posts/llm-gateway/</link><pubDate>Sun, 03 May 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/llm-gateway/</guid><description>应用接入第二个模型那天起,就该有一层 LLM 网关。讲清它解决的统一 API、密钥、故障转移、限流、成本与缓存,自建与现成怎么选,路由策略怎么定,以及多一跳的代价。</description><content:encoded><![CDATA[<p>先说一个反常识的事:<strong>大多数团队的&quot;第一个 LLM 网关&quot;不是装出来的,是不知不觉写出来的。</strong></p>
<p>最初你的代码里只有一句 <code>openai.chat.completions.create()</code>。后来 OpenAI 半夜抽风,你在外面包了个 <code>try/except</code>,失败就调 Anthropic。再后来财务问&quot;这个月十几万的 token 花在哪了&quot;,你又加了一段记账逻辑。再后来某个客户的流量把你的限额打爆,你又写了个令牌桶。</p>
<p>这些 <code>if/else</code> 散在三个仓库、五个文件里,没人敢动。这就是网关——一个<strong>没有名字、没有人维护、谁碰谁倒霉</strong>的网关。</p>
<p>所以问题从来不是&quot;要不要 LLM 网关&quot;,而是&quot;这层东西,是攒成一坨烂代码,还是收拢成一个能被维护的组件&quot;。这篇就讲清楚:它到底该管什么、自建还是用现成、路由策略怎么定,以及它本身会带来什么麻烦。</p>
<h2 id="网关到底替你扛了什么">网关到底替你扛了什么</h2>
<p>把它想成 LLM 调用的反向代理:你的应用只跟网关说话,网关再去跟一堆模型供应商打交道。它该扛七件事,但<strong>这七件事的优先级差得很远</strong>。</p>
<table>
  <thead>
      <tr>
          <th>能力</th>
          <th>解决什么</th>
          <th>优先级</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>统一 API</td>
          <td>一套 OpenAI 格式的接口调所有模型,换模型不改业务代码</td>
          <td>必须</td>
      </tr>
      <tr>
          <td>故障转移</td>
          <td>某家供应商挂了 / 限流了,自动切到备用</td>
          <td>必须</td>
      </tr>
      <tr>
          <td>密钥管理</td>
          <td>上游真 key 收在网关,业务侧只发&quot;虚拟 key&quot;</td>
          <td>必须</td>
      </tr>
      <tr>
          <td>限流配额</td>
          <td>按 key、按团队、按租户限 QPS 和预算</td>
          <td>高</td>
      </tr>
      <tr>
          <td>成本核算</td>
          <td>每次调用算钱,按业务线 / 用户出账单</td>
          <td>高</td>
      </tr>
      <tr>
          <td>可观测</td>
          <td>全量请求日志、延迟分位、错误率、token 用量</td>
          <td>高</td>
      </tr>
      <tr>
          <td>缓存</td>
          <td>命中过的请求直接返回,省钱省延迟</td>
          <td>看场景</td>
      </tr>
  </tbody>
</table>
<p>前三个是&quot;接了第二个模型就立刻需要&quot;的。中间三个是&quot;上了生产、有了多个调用方&quot;之后绕不开的。最后一个——缓存——别一上来就上,后面单独说。</p>
<p><strong>统一 API</strong> 是地基。2026 年的事实标准是 OpenAI 的 <code>/v1/chat/completions</code> 格式:几乎所有网关都对外讲这套协议,对内再翻译成 Anthropic、Gemini、Bedrock、火山引擎、通义各自的方言。好处很直接——你的业务代码里不该出现任何一家供应商的 SDK,只有一个 base_url 指向网关。换模型这件事,从&quot;改代码、过测试、发版&quot;变成&quot;网关上改一行配置&quot;。</p>
<p><strong>故障转移</strong>是第二个动机,也是最容易被低估的。单家供应商的可用性,你别指望它有四个九。OpenAI、Anthropic 在 2026 年都还会有区域性的限流和抖动。网关该做的是:一次请求失败(超时、5xx、429),先重试 N 次,还不行就<strong>降级到另一个模型组</strong>。注意是&quot;模型组&quot;不是&quot;模型&quot;——GPT-5 这一组里可以同时挂 OpenAI 直连、Azure OpenAI 两个部署,先在组内负载均衡,整组都不行了再跨组降级到 Claude。</p>
<p><strong>密钥管理</strong>是个安全问题。你不会希望真正的 OpenAI key 散落在二十个微服务的环境变量里——那意味着二十个泄漏点,而且轮换一次 key 要发二十次版。网关的做法是:真 key 只存网关一处,业务侧拿到的是网关签发的<strong>虚拟 key</strong>,每个虚拟 key 自带预算上限、限流和过期时间。哪个团队的 key 泄漏了,网关上吊销一个,不影响别人。</p>
<h2 id="一次请求在网关里走过的路">一次请求在网关里走过的路</h2>
<p>把这几件事串起来,一次调用大致是这样:</p>
<pre class="mermaid">flowchart TD
  A[业务应用<br/>带虚拟 key] --> B{鉴权 &<br/>配额检查}
  B -->|超预算/超限流| X[拒绝 429]
  B -->|放行| C{缓存查询}
  C -->|命中| R[直接返回]
  C -->|未命中| D[路由决策<br/>选模型]
  D --> E[调上游供应商]
  E -->|失败| F{重试 / 降级}
  F -->|换模型重试| E
  F -->|彻底失败| Y[返回错误]
  E -->|成功| G[记账 + 日志 + 写缓存]
  G --> R
</pre><p>这条链路里值得强调一点:<strong>鉴权和配额检查必须在最前面</strong>。如果你把它放在调用上游之后,那超预算的请求会先把钱花掉再被拒绝,限流形同虚设。先验票,再放行,再花钱。</p>
<p>另一点:记账、日志、写缓存都该在拿到响应<strong>之后异步做</strong>,不要让它们卡在用户的关键路径上。网关给业务请求加的延迟,越接近零越好。</p>
<h2 id="自建还是用现成的">自建还是用现成的</h2>
<p>这是大多数团队真正纠结的地方。先把选项摆清楚——下面这些都是真实在用的东西:</p>
<ul>
<li><strong>LiteLLM</strong>:开源,Python 写的代理,目前最主流的自建选择。统一 100+ 模型、虚拟 key、预算、降级、成本追踪、带管理界面,功能很全。</li>
<li><strong>OpenRouter</strong>:托管服务,一个 key 接几百个模型,接入最快。本质是个聚合层 + 计费层,适合快速起步和做模型选型实验。</li>
<li><strong>Portkey</strong>:托管为主,主打可观测——全量日志、链路追踪、护栏、预算,偏生产化运营。</li>
<li><strong>Cloudflare AI Gateway / Vercel AI Gateway</strong>:如果你的应用本来就跑在这两家的平台上,网关能力近乎&quot;顺手就有&quot;,分析、缓存、限流都集成好了。</li>
<li><strong>Bifrost</strong>:开源,用 Go 写的,主打性能——号称 5000 RPS 下额外开销只有约 11 微秒。如果你嫌 Python 网关那 10–50ms 的开销肉疼,这是个方向。</li>
</ul>
<p>我的判断,按团队阶段分:</p>
<p><strong>早期、还在做模型选型</strong>——直接用 OpenRouter。你现在最需要的是&quot;今天换 Claude、明天试 Gemini&quot;的灵活度,不值得为此先搭一套基础设施。</p>
<p><strong>上了生产、有合规要求</strong>——自建 LiteLLM 或 Bifrost。原因不是省钱(托管服务的抽成其实不高),而是<strong>数据</strong>:你所有的 prompt 和回复都流经这一层,这是公司最敏感的资产之一。把它放进自己的 VPC,审计、合规、数据驻留这些事才好交代。金融、医疗这类场景基本没得选,必须自建。</p>
<p><strong>不想养基础设施团队、但要生产级运营</strong>——Portkey 这类托管网关是合理的中间档,你拿可观测和护栏,代价是数据出门和按量付费。</p>
<p>一个常被忽略的点:自建不等于零成本。2026 年 3 月,LiteLLM 的 1.82.7、1.82.8 两个版本出过一次供应链投毒,受影响版本被下架、1.83.0 才修干净。<strong>你的网关是全公司 LLM 流量的咽喉</strong>,自建意味着这个咽喉的补丁、监控、值班都归你。别把&quot;自建&quot;想成一次性的活。</p>
<h2 id="路由策略网关最有意思也最容易过度设计的部分">路由策略:网关最有意思、也最容易过度设计的部分</h2>
<p>有了网关,&ldquo;一个请求该用哪个模型&quot;就成了可以动态决定的事。常见三种路由维度:</p>
<p>**按成本路由。**这是最实在的省钱手段。2026 年初的行情大致是:旗舰模型每百万 token 三五十美元,中端十来美元,轻量级一两美元,小模型一两毛。而你的请求里,可能七成是&quot;把这段话改通顺&quot;&ldquo;判断这条评论是不是投诉&quot;这种小活儿——这些活儿用小模型的质量和旗舰模型没有可感差距。把简单请求分流到便宜模型,平均成本能掉一大截,体感却不变。</p>
<p>**按能力路由。**反过来:涉及多步推理、长上下文、写代码的请求,送旗舰模型。难点在于&quot;怎么判断一个请求难不难&rdquo;——</p>
<ul>
<li>最笨但最稳:<strong>业务侧自己标</strong>。你比网关更清楚这个调用是&quot;客服闲聊&quot;还是&quot;合同审查&rdquo;,在请求里带个 <code>tier: complex</code> 字段,网关照着分流。我推荐先用这个。</li>
<li>进阶:<strong>语义路由</strong>,网关用一个小模型 / embedding 实时判断请求归哪一类再分流。它的代价是<strong>每个请求多 50–100ms</strong>,而且多了一个判断错了就全错的环节。语义路由真正划算,通常是你能清晰划出 3–10 类查询的时候;类别糊成一团时,它带来的麻烦比收益多。</li>
</ul>
<p>**按延迟路由。**实时语音、输入补全这种场景,延迟是硬指标,网关该把请求送给当前 TTFT 最低的部署,并把慢的部署临时摘掉。</p>
<p>我的态度很明确:<strong>先上&quot;按成本&quot;的粗路由,而且让业务侧自己打标签。</strong> 别一开始就上语义路由。我见过太多团队,路由逻辑本身比它要路由的业务还复杂,最后没人搞得清一个请求为什么走了那条线——省下的那点钱,全赔进排查时间里了。路由策略的复杂度,要配得上你真实的流量规模。</p>
<h2 id="缓存看着诱人但有刺">缓存:看着诱人,但有刺</h2>
<p>缓存值得单独拿出来说,因为它是这七项里<strong>最容易出事</strong>的一个。</p>
<p>精确缓存没什么争议:prompt 一字不差命中过,直接返回,省钱省延迟。问题在<strong>语义缓存</strong>——用 embedding 找&quot;意思相近&quot;的历史请求然后复用答案。它确实能提命中率,但两个坑很深:</p>
<p>一是<strong>相似不等于相同</strong>。&ldquo;北京今天天气&quot;和&quot;上海今天天气&rdquo; embedding 距离很近,答案却必须不同。语义缓存的相似度阈值卡松了,就会把张三的答案返给李四。</p>
<p>二是<strong>新鲜度</strong>。涉及实时信息、用户个性化、带时间语义的请求,根本不该走缓存。</p>
<p>所以缓存别全局开。务实的做法:先只对<strong>明确无状态、答案稳定</strong>的请求开精确缓存——比如固定的内容分类、把文档切块打标签这类批处理。语义缓存留到你有数据证明&quot;这一类请求确实高度重复&quot;时再说,而且阈值要往严了卡。</p>
<h2 id="它本身的代价多一跳和一个新的单点">它本身的代价:多一跳,和一个新的单点</h2>
<p>网关不是白拿的。两个代价必须摆上台面。</p>
<p>**多一跳延迟。**所有流量绕一道。如果网关跟你的应用同机房、同 VPC,这一跳也就个位数毫秒,相对 LLM 动辄数百毫秒到数秒的响应,可以忽略。但要是网关部署在另一个区域,或者用了托管服务而它的入口离你很远,这一跳可能加上几十毫秒甚至更多。<strong>实时语音这种掐着毫秒过日子的场景,尤其要量一量这一跳到底多长。</strong> 顺带一提,Python 写的网关进程本身会贡献 10–50ms 的处理开销,Go 写的(如 Bifrost)能压到微秒级——流量大、延迟敏感时,这个差别是真金白银。</p>
<p>**新的单点故障。**这是更要命的。你做网关的初衷之一是&quot;某个供应商挂了不至于全挂&quot;,可一旦所有流量都过网关,<strong>网关自己挂了,就是全挂</strong>——而且挂得比任何单一供应商出事都彻底。这不是不用网关的理由,是必须把网关本身做成高可用的理由:多副本、跨可用区、配置和状态外置,健康检查要快。说白了,你把可用性的赌注从&quot;分散在各家供应商&quot;换成了&quot;押在自己的网关上&quot;——那就得真把它当核心基础设施来运维,而不是当一个内部小工具。</p>
<h2 id="收个尾务实的上法">收个尾:务实的上法</h2>
<p>如果你正要把那坨散落的 <code>if/else</code> 收拢成一个正经网关,顺序建议这样:</p>
<ol>
<li><strong>先做统一 API + 故障转移 + 虚拟 key。</strong> 这三件立刻见效,而且不需要你想清楚任何路由策略。</li>
<li><strong>再补限流、配额、可观测。</strong> 等你有了多个调用方、财务开始问钱花哪了,这些自然就该上了。</li>
<li><strong>路由从最粗的&quot;按成本&quot;开始,标签让业务侧自己打。</strong> 跑一阵,拿真实数据说话,再决定要不要上语义路由。</li>
<li><strong>缓存最后,而且先只开精确缓存。</strong> 语义缓存等到有数据支撑再碰。</li>
<li><strong>从第一天起就把网关当核心基础设施</strong>——多副本、跨可用区、有人值班、补丁跟紧。它是你全公司 LLM 流量的咽喉。</li>
</ol>
<p>LLM 网关不神秘。它就是你迟早会写的那层代码——区别只在于,你是任由它烂在五个文件里,还是趁早把它收成一个有名字、有人管、能演进的东西。接第二个模型的那天,就是动手的那天。</p>
<hr>
<p><em>参考:<a href="https://dev.to/lightningdev123/best-ai-gateway-tools-in-2026-for-scalable-llm-applications-4dg">Best AI Gateway Tools in 2026</a>、<a href="https://www.edenai.co/post/best-llm-routers">Best LLM Routers in 2026</a>、<a href="https://docs.litellm.ai/docs/">LiteLLM 文档</a>、<a href="https://github.com/maximhq/bifrost">Bifrost(maximhq)</a>、<a href="https://www.mindstudio.ai/blog/what-is-ai-model-router-optimize-cost-llm-providers">What Is an AI Model Router</a>。</em></p>
]]></content:encoded></item><item><title>Agent 的 token 账单怎么管</title><link>https://realtime-ai.chat/posts/agent-token-cost/</link><pubDate>Thu, 30 Apr 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/agent-token-cost/</guid><description>Agent 上线后 token 成本最容易失控:多轮、长上下文、工具结果会成倍放大开销。这篇讲清钱花在哪、怎么定位大头,以及 prompt caching、上下文压缩、模型路由、步数熔断等可落地手段。</description><content:encoded><![CDATA[<p>先说一个数字:同样问&quot;帮我查一下这个 bug&quot;,发给聊天机器人和发给 Agent,token 消耗能差 <strong>50 倍</strong>。</p>
<p>聊天机器人就一来一回:你发一段、它回一段,结束。Agent 不一样——它跑的是一个循环:看任务、调工具、读文件、改代码、再检查。<strong>循环里的每一步,都要把到目前为止积累的全部上下文,重新发给模型一次。</strong></p>
<p>这就是 Agent 账单的根源。2026 年有人审计了 30 个在生产环境跑 Agent 的工程团队,一个 20 人的团队,单月 API 账单能冲到 11 万美元;用 Claude Code 或 Cursor 这类编码 Agent 的开发者,人均每月 400 到 1500 美元,失控的案例几天就烧掉 4000 美元以上。</p>
<p>更要命的是,这笔钱不是匀速烧的。Demo 跑得好好的,一上量就爆——大部分企业的 Agent 项目,在大规模铺开后的头 90 天里,实际花销会超出试点预算 4 到 11 倍。所以做 Agent,成本不是上线之后再优化的事,是设计时就得算进去的一笔账。</p>
<p>这篇把这笔账拆开:钱花在哪、怎么找到大头、有哪些真能省的手段、怎么设预算和熔断、怎么监控。</p>
<h2 id="钱到底花在哪">钱到底花在哪</h2>
<p>先建立一个最反直觉的认知:<strong>Agent 跑一个任务的成本,主要不是输出,是输入。</strong></p>
<p>模型 API 按 token 收费,输入和输出分开计价。聊天场景里,大家盯着输出看。但 Agent 不一样,它的成本大头在<strong>输入侧的重复计费</strong>。</p>
<p>为什么?因为对话历史会&quot;滚雪球&quot;。Agent 每调一次工具,就要把整段对话历史连同工具返回的结果,一起再发一次。一段已经积累到 10 万 token 的上下文,在后续<strong>每一次</strong>调用里,都按 10 万输入 token 收费——不是只收新增的那部分。一个跑到第 20 步的编码 Agent,光是文件读取塞进来的内容,单步输入就能超过 5 万 token,按 Sonnet 4.6 的价(每百万输入 token 3 美元)算,<strong>每一步 0.15 美元</strong>,二十步就是 3 美元,而这还只是一个任务。</p>
<p>把烧钱的来源列清楚,主要是这四个:</p>
<table>
  <thead>
      <tr>
          <th>成本来源</th>
          <th>为什么烧钱</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>多轮累积</td>
          <td>历史每轮都重发,N 步任务的输入约为单步的 N 倍量级</td>
      </tr>
      <tr>
          <td>长上下文</td>
          <td>大 system prompt、塞满的 RAG 检索结果,每次调用都全额计费</td>
      </tr>
      <tr>
          <td>工具结果</td>
          <td>一次文件读取、一次数据库查询返回几千 token,且永久留在上下文里</td>
      </tr>
      <tr>
          <td>多 Agent</td>
          <td>主 Agent 派生子 Agent,每个子 Agent 自己又是一个完整的 token 循环</td>
      </tr>
  </tbody>
</table>
<p>这四项里,<strong>多轮累积和工具结果是最隐蔽的</strong>——它们不在你写的 prompt 里,是 Agent 自己在运行时长出来的。你 review 代码时看不到,只有看账单才发现。</p>
<h2 id="先定位大头再动手">先定位大头,再动手</h2>
<p>不要凭感觉优化。第一步永远是<strong>按维度把成本拆开看</strong>,否则你很可能花两天去抠一个只占 5% 的环节。</p>
<p>至少要能按这几个维度归因(attribution):</p>
<ul>
<li><strong>按 Agent / 任务类型</strong>:哪类任务最贵?是&quot;代码重构&quot;还是&quot;简单问答&quot;?</li>
<li><strong>按步骤</strong>:成本是均匀分布,还是集中在某几步(比如某个返回巨量结果的工具)?</li>
<li><strong>按输入/输出</strong>:再确认一次,是输入贵还是输出贵——多数 Agent 是输入。</li>
<li><strong>按用户 / 会话</strong>:是不是 5% 的重度用户烧掉了 80% 的钱?</li>
</ul>
<p>这里有个观测层的坑要提前知道:Agent 的一次&quot;请求&quot;,在 trace 里会炸开成 8 到 15 个 span——API 调用、token 流式输出、embedding 查询、向量库检索、prompt 拼装、guardrail 检查、结果解析……普通 API 接口才 2 到 3 个。如果你的监控是按&quot;请求数&quot;做采样的,Agent 会瞬间把你的可观测性预算也撑爆。所以 Agent 的成本监控,<strong>得按 token 和按美元来记,不能只按请求数</strong>。</p>
<p>拆完之后你大概率会看到一个二八分布:某一两类任务、某一两个工具,吃掉了大半账单。先打这些点。</p>
<h2 id="真能省钱的几个手段">真能省钱的几个手段</h2>
<p>定位完大头,下面是 2026 年实测有效的手段,按&quot;性价比&quot;从高到低排。</p>
<h3 id="prompt-caching第一个要上几乎免费">prompt caching:第一个要上,几乎免费</h3>
<p>这是投入产出比最高的一项,优先级最高。</p>
<p>原理很简单:Agent 的上下文里有一大块是<strong>固定不变的前缀</strong>——system prompt、工具定义、few-shot 示例。每一步调用都把这块重新做一遍前向计算(prefill),纯属浪费。prompt caching 就是把这段固定前缀缓存住,后续调用直接命中缓存。</p>
<p>2026 年的价格,缓存命中的输入 token 只按基础价的 <strong>0.1 倍</strong>收费,也就是 9 折优惠——Anthropic 是这个价,GPT-5.4 现在也对齐到了 90% 的缓存折扣。对一个多轮 Agent,固定前缀往往占输入的一大半,命中率拉高之后,输入成本砍掉 50% 到 90% 是常态。</p>
<p>要拿到这个收益,有个纪律:<strong>别让缓存失效</strong>。缓存命中的前提是前缀逐字节一致。所以要把&quot;不变的东西&quot;放前面、&ldquo;会变的东西&quot;放后面——system prompt 和工具定义放最前,动态的对话历史和检索结果放后面。一旦你在 system prompt 里塞了个当前时间戳,整个缓存就废了。</p>
<h3 id="上下文压缩对付滚雪球的正面手段">上下文压缩:对付&quot;滚雪球&quot;的正面手段</h3>
<p>prompt caching 省的是固定前缀;滚雪球的对话历史得靠压缩。</p>
<p>最直接的做法是<strong>定期把历史压成摘要</strong>。Agent 跑了 30 步,前 20 步的细节其实没必要逐字带着——把它们总结成一段&quot;已完成:确认了 bug 在 X 模块,排除了 Y 假设&rdquo;,用摘要替换原始对话。Anthropic 在 2026 年 2 月放出的 Compaction API(beta)就是把这件事自动化:让模型自动总结、压缩对话历史,实现近乎&quot;无限&quot;的对话长度,不用手动裁剪或重开会话。</p>
<p>工具结果也要管。一次文件读取返回 5000 token,但 Agent 真正需要的可能只是其中一个函数。可以做的:工具返回时就<strong>截断或摘要</strong>,只保留相关片段;旧的工具结果在后续轮次里<strong>替换成一句占位符</strong>(&quot;[此处曾读取 config.py,已处理]&quot;)。</p>
<h3 id="按难度选模型别用大炮打蚊子">按难度选模型:别用大炮打蚊子</h3>
<p>不是每一步都需要最强的模型。</p>
<p>2026 年 Claude 三档价差很大:Haiku 4.5 是每百万 token 1/5 美元(输入/输出),Sonnet 4.6 是 3/15,Opus 4.7 是 5/25。<strong>Haiku 比 Sonnet 便宜 5 倍,比 Opus 便宜 25 倍。</strong></p>
<p>一个 Agent 流程里,真正需要顶配模型做复杂推理的步骤可能只占两三成。剩下的——意图分类、格式整理、判断&quot;任务完成了没&quot;、简单的工具参数填充——交给 Haiku 完全够用。做法就是按步骤的难度做路由(routing):简单步骤走小模型,复杂推理才升到 Sonnet 或 Opus。一个 500 输入 / 100 输出 的 Haiku 分类调用,成本大约 0.001 美元,几乎可以忽略。</p>
<h3 id="限制步数和递归给失控的循环装个闸">限制步数和递归:给失控的循环装个闸</h3>
<p>前面说企业 Agent 超预算 4 到 11 倍,原因之一就是<strong>没有上限的工具调用递归</strong>。</p>
<p>Agent 卡在一个错误里出不来,会一遍遍重试同一个工具;主 Agent 派生子 Agent,子 Agent 再派生……如果没有硬上限,一个本该 10 步的任务能跑成 200 步。必须设硬限制:</p>
<ul>
<li><strong>单任务最大步数</strong>(比如 25 步,到了就强制收尾或交还给人)</li>
<li><strong>多 Agent 的递归深度上限</strong>(比如最多 2 层)</li>
<li><strong>同一项的重试次数上限</strong>——一个实战配置是:同一项每天最多重试 3 次,两次重试之间至少隔 2 小时,不可重试的错误直接跳过,别困在死循环里</li>
</ul>
<h3 id="缓存工具结果--batch能省就省">缓存工具结果 + batch:能省就省</h3>
<p>两个补充手段。</p>
<p><strong>缓存工具结果</strong>:很多工具调用是确定性的、可重复的——查同一个文档、跑同一个查询。给工具调用层加一个缓存,相同输入直接返回上次结果,连模型调用都省了。语义缓存(semantic cache)更进一步,语义相近的请求也能命中。</p>
<p><strong>batch(批处理)</strong>:如果你的任务不需要实时返回——离线评测、批量数据标注、夜间跑的报告——走 Batch API,输入输出都打五折。把 prompt caching 的 9 折和 batch 的 5 折叠加,极端情况能把成本压到原来的 5%。代价是异步,最长可能等 24 小时,所以只适合离线场景。</p>
<p>下面这张图是这些手段的处理顺序:</p>
<pre class="mermaid">flowchart TD
  A[Agent 收到一步请求] --> B{固定前缀?}
  B -->|是| C[命中 prompt cache<br/>输入按 0.1x 计费]
  B -->|否| D[正常计费]
  C --> E{这步难度?}
  D --> E
  E -->|简单| F[路由到 Haiku]
  E -->|复杂| G[路由到 Sonnet/Opus]
  F --> H{工具结果是否过大?}
  G --> H
  H -->|是| I[截断/摘要后入上下文]
  H -->|否| J[直接入上下文]
  I --> K{历史是否过长?}
  J --> K
  K -->|是| L[压缩成摘要]
  K -->|否| M[继续]
</pre><h2 id="给-agent-设预算和熔断">给 Agent 设预算和熔断</h2>
<p>省钱手段是&quot;开源节流&quot;里的节流。但 Agent 还需要一道<strong>硬性的财务闸门</strong>——再怎么优化,也得有个东西在它失控时直接把它停掉。</p>
<p>这就是成本熔断(cost circuit breaker):预设一个开销上限,Agent 触到上限就强制中断,而不是任由它把账单跑飞。</p>
<p>预算定多少?别拍脑袋。<strong>先量,再定。</strong> 取一个有代表性的两周样本,统计每个完整任务消耗 token 的 p50 和 p95,然后把上限设在 <strong>p95 的 1.5 倍</strong>。这个值能覆盖正常的波动,又能在真正异常时及时触发。</p>
<p>熔断要分层设,至少三层:</p>
<table>
  <thead>
      <tr>
          <th>层级</th>
          <th>触发条件</th>
          <th>动作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>单任务</td>
          <td>单个任务 token 超 1.5× p95</td>
          <td>中断该任务,记录,交还给人</td>
      </tr>
      <tr>
          <td>单用户/会话</td>
          <td>用户当日累计超额度</td>
          <td>拒绝新请求或降级到小模型</td>
      </tr>
      <tr>
          <td>全局</td>
          <td>全组织当日总花销超阈值</td>
          <td>告警 + 限流,保住核心业务</td>
      </tr>
  </tbody>
</table>
<p>关键点:熔断的动作必须是<strong>确定性的、自动执行的</strong>。运行时的预算治理需要两样东西——明确的限额,加上确定的补救动作。光设个数字、靠人看告警手动去关,等你看到消息,钱已经烧完了。</p>
<h2 id="监控该怎么做">监控该怎么做</h2>
<p>最后是监控。没有监控,前面所有的优化都是一次性的——这个月省下来,下个月一个新功能上线又涨回去,你还不知道。</p>
<p>Agent 的成本监控,要盯这几个指标:</p>
<ul>
<li><strong>每任务成本(cost per task)</strong>:最核心的北极星指标。优化做对了,这个数应该往下走。</li>
<li><strong>缓存命中率</strong>:prompt caching 的命中率。如果某次发布后它突然掉下来,八成是有人改了 system prompt 把缓存搞失效了。</li>
<li><strong>每任务平均步数</strong>:悄悄往上爬,通常意味着 Agent 开始绕路或卡循环。</li>
<li><strong>token 成本归因</strong>:持续按 Agent、按用户、按任务类型拆,二八分布的那个&quot;二&quot;要一直盯着。</li>
<li><strong>熔断触发次数</strong>:偶尔触发是正常的安全网;频繁触发说明预算设低了,或者真有 Agent 在失控。</li>
</ul>
<p>把这些接进你现有的可观测性系统,设好告警。一个务实的目标:认真做完一轮成本优化的团队,通常能在 30 天内把 Agent 成本降低 55% 到 75%。</p>
<h2 id="一份上线前的清单">一份上线前的清单</h2>
<p>把上面的东西收成一张可勾选的表,Agent 上线前过一遍:</p>
<ul>
<li><input disabled="" type="checkbox"> 成本能按 Agent、用户、任务类型、步骤拆开归因</li>
<li><input disabled="" type="checkbox"> 固定前缀(system prompt、工具定义)放在最前,且已开 prompt caching</li>
<li><input disabled="" type="checkbox"> system prompt 里没有时间戳之类会破坏缓存的动态内容</li>
<li><input disabled="" type="checkbox"> 对话历史有压缩/摘要机制,不会无限滚雪球</li>
<li><input disabled="" type="checkbox"> 工具返回结果会截断或摘要,旧结果会被占位符替换</li>
<li><input disabled="" type="checkbox"> 简单步骤路由到小模型,只有复杂推理才上顶配</li>
<li><input disabled="" type="checkbox"> 设了单任务最大步数、多 Agent 递归深度、重试次数上限</li>
<li><input disabled="" type="checkbox"> 确定性的工具调用结果有缓存</li>
<li><input disabled="" type="checkbox"> 离线、非实时的任务走了 Batch API</li>
<li><input disabled="" type="checkbox"> 三层熔断(单任务/单用户/全局)都已配置,且动作是自动执行的</li>
<li><input disabled="" type="checkbox"> 预算阈值是基于 p95 实测数据定的,不是拍脑袋</li>
<li><input disabled="" type="checkbox"> 每任务成本、缓存命中率、平均步数都在监控里,有告警</li>
</ul>
<p>最后说一句优先级。如果时间有限,先做三件事:<strong>开 prompt caching、设步数上限、配单任务熔断</strong>。这三样投入小、见效快,而且能挡住最致命的那种&quot;一夜之间烧掉几千美元&quot;的事故。上下文压缩、模型路由这些是细水长流的优化,可以上线之后慢慢调。</p>
<p>Agent 的账单不会自己变小。但只要你知道钱花在哪、装好了闸门,它至少不会变成一个你不敢看的数字。</p>
<hr>
<p>参考资料:</p>
<ul>
<li><a href="https://leanopstech.com/blog/agentic-ai-cost-runaway-token-budget-2026/">AI Agents Burn 50x More Tokens Than Chats — LeanOps</a></li>
<li><a href="https://fast.io/resources/ai-agent-token-cost-optimization/">AI Agent Token Cost Optimization: Complete Guide for 2026 — Fastio</a></li>
<li><a href="https://dev.to/waxell/ai-agent-context-window-cost-the-compounding-math-your-architecture-is-hiding-2227">AI Agent Context Window Cost: The Compounding Math — DEV Community</a></li>
<li><a href="https://www.obviousworks.ch/en/token-optimization-saves-up-to-80-percent-llm-costs/">Token optimization 2026: Saving up to 80% LLM costs — Obvious Works</a></li>
<li><a href="https://fountaincity.tech/resources/blog/ai-agent-cost-circuit-breaker/">The Cost Circuit Breaker: Financial Controls for Production AI Agents — Fountain City</a></li>
<li><a href="https://blogs.oracle.com/ai-and-datascience/runtime-budget-guardrails-agentic-ai">Runtime Budget Guardrails for Agentic AI — Oracle</a></li>
<li><a href="https://www.truefoundry.com/blog/llm-cost-attribution-agentic-cicd">Agentic Token Explosion: Attribute, Budget, and Control LLM Costs — TrueFoundry</a></li>
<li><a href="https://oneuptime.com/blog/post/2026-03-07-ai-agents-breaking-observability-budget/view">AI Agents Are Breaking Your Observability Budget — OneUptime</a></li>
<li><a href="https://platform.claude.com/docs/en/about-claude/pricing">Claude API Pricing — Anthropic Docs</a></li>
<li><a href="https://tokenmix.ai/blog/openai-batch-api-pricing">OpenAI Batch API 2026: 50% Off Every Model — TokenMix</a></li>
</ul>
]]></content:encoded></item><item><title>AI 编程是不是泡沫</title><link>https://realtime-ai.chat/posts/ai-coding-bubble/</link><pubDate>Wed, 29 Apr 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/ai-coding-bubble/</guid><description>AI 写了 41% 的新代码,但实测里资深工程师反而慢了 19%。这篇冷静拆解 AI 编程的真实生产力收益、被夸大的环节,以及「泡沫」二字到底站不站得住。</description><content:encoded><![CDATA[<p>2025 年 7 月,METR 做了一个实验。16 个资深开源开发者,每人在自己熟得不能再熟的项目里干活,平均经验 5 年。246 个真实任务,随机分两组:一组允许用 AI(主要是 Cursor Pro 配 Claude 3.5/3.7),一组不许用。</p>
<p>实验前,这些人预测 AI 能让自己快 24%。干完之后,他们体感觉得 AI 让自己快了 20%。</p>
<p>实测结果:<strong>用 AI 的那组,慢了 19%。</strong></p>
<p>这不是一个标题党段子。它是目前为止设计最干净的一个随机对照实验,而它的结论,跟你每天在朋友圈、在发布会、在融资 PPT 上看到的&quot;10x 工程师&quot;&ldquo;生产力革命&rdquo;,是相反的。</p>
<p>所以这篇文章想认真聊一件事:AI 编程到底是不是泡沫。我的答案会比较啰嗦——它在某些环节是真东西,在另一些环节是被吹大的气球,而把这两件事混在一起卖,才是真正的泡沫所在。</p>
<h2 id="营销数字和实测数字差在哪">营销数字和实测数字,差在哪</h2>
<p>先把两组数字摆出来。</p>
<p>营销侧的数字很漂亮:2026 年 84% 的开发者在用 AI 工具,AI 写了 41% 的新增商业代码,人均每周省下 3.6 小时。受控实验里,对那种&quot;写一个函数&quot;&ldquo;生成一批单测&quot;&ldquo;铺一段样板代码&quot;的细碎任务,提速 30%–55% 是常见的。</p>
<p>这些数字没造假。问题在于它们都是<strong>任务级</strong>的数字——把镜头怼到&quot;写代码&quot;这一个动作上,AI 确实快。</p>
<p>但你把镜头拉远到<strong>组织级</strong>,画面就变了。2025 年的 DORA 报告(Google 做的那份,样本是几千个真实团队)给出的结论很扎心:AI 让个人产出明显上涨——任务完成数 +21%,合并的 PR 数 +98%——但团队的交付速度,基本是平的。同一份报告里,AI 采用度和软件交付<strong>稳定性</strong>是负相关的。</p>
<p>更具体的两个数字:每个开发者引入的 bug 数,涨了 54%(过去的数据集里这个数字只涨 9%);每个 PR 引发生产事故的概率,涨了 242.7%——也就是说,每合一次代码,捅出线上事故的概率翻了三倍多。</p>
<table>
  <thead>
      <tr>
          <th>看哪个层面</th>
          <th>数字</th>
          <th>谁在引用</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>任务级:写一个函数</td>
          <td>提速 30%–55%</td>
          <td>厂商、发布会</td>
      </tr>
      <tr>
          <td>个人级:周产出</td>
          <td>PR +98%,任务 +21%</td>
          <td>厂商、个人体感</td>
      </tr>
      <tr>
          <td>组织级:交付速度</td>
          <td>基本持平</td>
          <td>DORA 2025</td>
      </tr>
      <tr>
          <td>组织级:稳定性</td>
          <td>bug +54%,事故/PR +242%</td>
          <td>DORA 2025</td>
      </tr>
      <tr>
          <td>资深 + 成熟项目</td>
          <td>慢 19%</td>
          <td>METR RCT</td>
      </tr>
  </tbody>
</table>
<p>同一件事,你站在不同的距离看,能得出完全相反的结论。营销永远站在最近的那个位置拍照。</p>
<h2 id="ai-写完人来收拾的隐性成本">&ldquo;AI 写完,人来收拾&quot;的隐性成本</h2>
<p>营销数字漏掉的,是 AI 把工作从&quot;写&quot;挪到了&quot;收拾&rdquo;。这部分成本没消失,只是换了个名字,而且通常没人记账。</p>
<p>METR 那个实验里,AI 给的建议只有 39% 被开发者接受。剩下 61% 要么直接扔,要么改。对那些维护多年、有严格代码规范的成熟项目,AI 生成的代码常常&quot;看着对、品味不对&rdquo;——命名不一致、复用了不该复用的东西、绕过了项目既定的抽象。资深工程师得花时间一行行审、一行行改。这 19% 的慢,就是慢在这里。</p>
<p>这件事可以拆成一条很清楚的链:</p>
<pre class="mermaid">flowchart LR
  A[AI 生成代码<br/>很快] --> B[人来审查<br/>+9% 工时]
  B --> C[补测试<br/>1.7x 负担]
  C --> D[代码翻修<br/>2x churn]
  D --> E[隐性技术债<br/>第二年维护 4x]
  style A fill:#d4edda,stroke:#52a05f
  style E fill:#f8d7da,stroke:#d9534f
</pre><p>绿色那块是你看得见的收益,红色那块是你账上不记的成本。代码翻修率(code churn,指代码写完后不久就被改写或删掉的比例)从 2021 年的 3.3% 基线,涨到了 2024–2025 年的 5.7%–7.1%。Stack Overflow 2026 年初一篇文章把话说得很直白:<strong>AI 能让开发者 10x,但 10x 的是技术债。</strong></p>
<p>还有一个更隐蔽的成本:信任。Stack Overflow 的开发者调查里,2025 年说自己信任 AI 输出的开发者只有 29%,比 2024 年掉了 11 个百分点。用得越多,越不敢信——因为大家都被那种&quot;看着对其实不对&quot;的代码坑过。一家 API 安全公司报告,在财富 50 强企业里,每月的安全问题发现数从 2024 年 12 月的 1000 个涨到 2025 年 6 月的 1 万个以上,半年 10 倍。</p>
<p>所以&quot;AI 写完人来收拾&quot;这句话本身没错,错在大家算账时只算了&quot;AI 写&quot;那一段省下的时间,没算&quot;人来收拾&quot;那一段花出去的时间。把两段都记上,很多团队的净收益就接近零,甚至为负。</p>
<h2 id="它在哪儿是真的有用">它在哪儿是真的有用</h2>
<p>如果只看上面这些,你会以为我要喊&quot;泡沫&quot;了。不。AI 编程有几个环节是<strong>实打实</strong>有用的,我自己每天在用,不是客套。</p>
<p>它真正强的地方,有一个共同特征:<strong>任务边界清楚、验证成本低、犯错代价小。</strong></p>
<ul>
<li><strong>样板和胶水代码。</strong> 写一个 CRUD 接口、配一个 CI 流水线、把 JSON 转成另一种结构——这类活没有&quot;品味&quot;可言,对就是对,AI 生成完你一眼能看出对不对。</li>
<li><strong>陌生领域的第一脚。</strong> 你要用一个没碰过的库,以前要翻半小时文档,现在让 AI 给个能跑的起步代码,你在它基础上改。它把&quot;从零到能跑&quot;这段最难受的冷启动给抹平了。</li>
<li><strong>一次性脚本。</strong> 数据迁移、批量改名、跑个分析——写完用一次就扔的代码,质量要求本来就低,AI 在这里几乎没有副作用。</li>
<li><strong>测试和文档。</strong> 给已有代码补单测、写注释。这类活枯燥、人容易偷懒,AI 不偷懒。</li>
<li><strong>当个会说话的搜索引擎。</strong> &ldquo;这段报错什么意思&quot;&ldquo;这个正则怎么写&rdquo;——它替代的是你切到浏览器那几下,省的是上下文切换。</li>
</ul>
<p>注意,这几样的收益是真的,但它们加起来,是&quot;省了 3.6 小时/周&quot;那个量级的收益,<strong>不是&quot;重新定义软件工程&quot;那个量级的</strong>。是好用的电动工具,不是免费的劳动力。</p>
<h2 id="它在哪儿被夸大了">它在哪儿被夸大了</h2>
<p>被夸大的部分,也有共同特征:<strong>任务边界模糊、验证成本高、犯错代价大。</strong></p>
<p>第一个被夸大的,是<strong>复杂系统里的改动</strong>。在一个十万行、跑了五年、到处是隐性约定的代码库里加一个功能,难的从来不是&quot;写代码&rdquo;,是&quot;想清楚改哪、会牵连到什么、符不符合这个项目的脾气&rdquo;。AI 没有这个项目的上下文记忆,它给你的是一个&quot;局部看起来合理&quot;的方案。METR 那 19% 的慢,慢的就是这个场景。</p>
<p>第二个被夸大的,是**&ldquo;vibe coding&quot;能进生产**。让 AI 全自动写、你只看结果不看过程,做个周末玩具没问题。但 Karpathy 自己在 2026 年初都把口径改了,提出&quot;Agentic Engineering&quot;来接替 vibe coding,核心多了一个词:<strong>结构化的人类监督</strong>。连造这个词的人都在往回收。</p>
<p>第三个被夸大的,是<strong>省下的时间能直接变成交付速度</strong>。这就是 DORA 报告里那个&quot;个人产出涨、组织速度平&quot;的悖论。原因不难懂:软件交付的瓶颈,本来就很少在&quot;打字&quot;这一步。需求扯不清、评审排不上、QA 跟不上、集成一团乱——AI 把打字这一步加速了,但水管最细的地方没变,整根水管的流量就没变。AI 不会修复一个团队,它只会<strong>放大</strong>这个团队本来的样子。流程好的团队用 AI 如虎添翼,流程烂的团队用 AI 翻车更快。</p>
<h2 id="对初级工程师和团队结构的冲击">对初级工程师和团队结构的冲击</h2>
<p>这部分我想说得重一点,因为它是真问题,而且没什么人愿意正面讲。</p>
<p>AI 最擅长的那些活——改 bug、写测试、铺样板——<strong>恰好就是过去初级工程师练手的活</strong>。这不是巧合,是结构性的撞车。后果已经在数据里:2026 年初级开发岗位的招聘明显收紧,计算机专业毕业生失业率涨到 6%–7%,22–25 岁这个年龄段的开发者岗位,自 ChatGPT 发布以来少了约 20%。</p>
<p>这里有一个会反噬的逻辑链。一个工程师能审查 AI 代码、能判断&quot;这段看着对其实不对&rdquo;,靠的是他当年<strong>亲手写过、亲手踩过坑</strong>积累的判断力。如果初级阶段的练手活全被 AI 接管了,新人没有了犯错和积累的场子,五年后,我们从哪里长出能审查 AI 的资深工程师?</p>
<p>我的判断是:初级岗不会消失,但它的定义被改写了。过去招初级,要的是&quot;能写出代码&quot;;现在招初级,要的是&quot;能判断 AI 写的代码对不对&quot;,这其实是过去对中级的要求。这等于把入行门槛抬高了一级,而那一级原本是靠在岗位上慢慢爬的。对个人,这意味着你得自己想办法补上&quot;判断力&quot;这一课——多读别人的代码、多关掉 AI 自己写一遍、刻意练习那些 AI 帮你跳过的环节。对团队,这意味着你不能再把初级当廉价产能,得把他们当&quot;未来的资深&quot;来带,而带人的成本,AI 一分钱都帮不上。</p>
<h2 id="那么泡沫论站不站得住">那么,泡沫论站不站得住</h2>
<p>回到标题。我的结论分两层。</p>
<p><strong>技术和产品这一层,不是泡沫。</strong> AI 编程是真东西,它确实改变了一部分工作方式,这种改变不会回退。说它&quot;永远不行&quot;&ldquo;只是噱头&quot;的人,和说它&quot;明年取代所有程序员&quot;的人,犯的是同一个错——都在拿一个极端当全部。</p>
<p><strong>但&quot;叙事&quot;和&quot;估值&quot;这一层,泡沫味很浓。</strong> 这里的泡沫有三块:</p>
<p>一是<strong>叙事泡沫</strong>。把任务级的提速数字,包装成组织级的革命,中间那道&quot;个人产出涨、交付速度平&quot;的鸿沟被系统性地隐藏了。</p>
<p>二是<strong>定价泡沫</strong>。GitHub Copilot 在 2026 年 6 月转向按 token 计费,一个动作就暴露了底裤:此前订阅制下,微软每个用户每月亏 20 美元。现在还便宜,是因为有人在替你补贴。补贴停了,价格会回到它真实的成本曲线上。</p>
<p>三是<strong>资本泡沫</strong>。这一轮 AI 基建里大量的&quot;循环交易&rdquo;——A 投资 B,B 拿钱回头买 A 的产品,在账面上凭空造出需求和营收——这是宏观层面的事,但它会传导下来:补贴退潮的时候,工具会涨价,产品会缩水,期望会落地。</p>
<pre class="mermaid">flowchart TB
  A[AI 编程] --> B[技术层:真实<br/>不是泡沫]
  A --> C[叙事层:任务级数字<br/>包装成革命]
  A --> D[定价层:补贴掩盖<br/>真实成本]
  A --> E[资本层:循环交易<br/>虚增需求]
  style B fill:#d4edda,stroke:#52a05f
  style C fill:#fde7c2,stroke:#e8b23c
  style D fill:#fde7c2,stroke:#e8b23c
  style E fill:#f8d7da,stroke:#d9534f
</pre><p>所以&quot;AI 编程是不是泡沫&quot;这个问题本身问错了。正确的问法是:<strong>AI 编程这件事里,哪一部分是真东西,哪一部分是泡沫。</strong> 工具是真的,叙事是泡沫。等补贴退、估值回调、那批靠&quot;AI 全自动&quot;故事融资的公司洗一遍牌之后,留下来的,会是一个<strong>好用但不神奇</strong>的工具——大概就是今天的 IDE、版本控制、CI 在工程师工具箱里的位置。</p>
<p>给还在这行里的人三句实在话。第一,别信任何脱离了上下文的提速百分比,先问&quot;这是哪一层的数字&quot;。第二,把 AI 当电动工具用,在它强的环节(样板、胶水、冷启动、测试)放开用,在它弱的环节(复杂系统、架构判断、品味)自己上手。第三,如果你是初级,或者你在带初级,把&quot;判断力&quot;当成接下来几年最该投资的东西——因为当代码变得廉价,<strong>判断什么代码值得要,会变成最贵的能力。</strong></p>
<p>泡沫会破,工具会留。把这两件事分清楚的人,不会在这一轮里慌,也不会在下一轮里被收割。</p>
]]></content:encoded></item><item><title>AI 应用的护栏:输入输出怎么管</title><link>https://realtime-ai.chat/posts/ai-guardrails/</link><pubDate>Mon, 20 Apr 2026 11:00:00 +0800</pubDate><guid>https://realtime-ai.chat/posts/ai-guardrails/</guid><description>LLM 应用上线前,护栏决定它会不会闯祸。这篇拆解护栏管什么、怎么做、放哪一层、怎么测,以及过度护栏的反效果——给一份能直接对照的上线清单。</description><content:encoded><![CDATA[<p>先说一个数字:Guardrails AI 在 2025 年初做过一次基准测试,结论里有句话很刺眼——<strong>单个护栏哪怕准确率有 90%,串五个,误杀率就到 40%</strong>。</p>
<p>这句话基本能概括做护栏的全部难处。你不是在&quot;加保护&quot;,你是在一条已经够慢、够贵、够不确定的链路上,再叠一层会拖慢、会误判、还得自己维护的东西。问题不是&quot;要不要护栏&quot;——上线的 LLM 应用一定要有——问题是<strong>护栏管什么、做多厚、放哪一层</strong>。这三件事做错,护栏要么形同虚设,要么把好用户也一起赶跑了。</p>
<p>这篇不讲注入攻击的具体手法(那是另一篇的事),讲更宽的一件事:把用户的输入、模型的输出当成两道关口,这两道关口该怎么修。</p>
<h2 id="护栏到底在拦什么">护栏到底在拦什么</h2>
<p>很多团队上来就装个 moderation API,以为护栏就是&quot;过滤脏话&quot;。不是。护栏分两侧,两侧拦的东西完全不一样。</p>
<p><strong>输入侧</strong>,拦的是用户递进来的东西:</p>
<ul>
<li><strong>敏感信息</strong>。用户在对话里贴了身份证号、银行卡、内部工号、客户手机号。你不想把这些原样喂给第三方模型 API,更不想它们出现在日志里。</li>
<li><strong>越界请求</strong>。一个做企业财报问答的 Bot,用户问&quot;帮我写一首失恋的诗&quot;。这不危险,但它<strong>不是这个产品该干的事</strong>——回答了,就是在替竞品做免费体验。</li>
<li><strong>明显的恶意输入</strong>。攻击意图、自动化刷量、超长 prompt 灌爆上下文。</li>
</ul>
<p><strong>输出侧</strong>,拦的是模型吐出来的东西,这一侧更难,因为输出是模型生成的、不可预测的:</p>
<ul>
<li><strong>有害内容</strong>。暴力、仇恨、自残、违法信息。这是最经典的一类,也是 moderation API 唯一管得好的一类。</li>
<li><strong>幻觉</strong>。模型一本正经地编了一个不存在的退款政策、一个错误的药品剂量。在 RAG 场景里,这意味着输出和检索到的资料对不上。</li>
<li><strong>格式错误</strong>。你要的是一段能直接 <code>JSON.parse</code> 的结构化数据,模型给你前面加了句&quot;好的,这是您要的结果:&quot;。下游程序当场崩。</li>
<li><strong>品牌口径</strong>。模型说了&quot;我们的竞品确实更便宜&quot;,或者用了一个法务明令禁止的承诺词(&ldquo;保证收益&quot;&ldquo;绝对安全&rdquo;)。没毒,但能上财经新闻。</li>
</ul>
<p>注意最后两类——<strong>格式</strong>和<strong>品牌口径</strong>——很多人根本不把它当护栏。但它们恰恰是上线后最高频出事的地方。有害内容一年可能出一次,格式错误一天能出一百次。</p>
<h2 id="四种做法从便宜到贵">四种做法,从便宜到贵</h2>
<p>护栏不是一种技术,是一个工具箱。按&quot;成本/能力&quot;从低到高,有四档。</p>
<p><strong>第一档:规则与正则。</strong> 关键词黑名单、正则匹配身份证/手机号、长度限制、JSON schema 校验。便宜到几乎不要钱,延迟个位数毫秒,而且<strong>结果可解释</strong>——你能准确说出&quot;它是因为命中了第几条规则被拦的&rdquo;。缺点也明显:绕得过,且管不了语义。规则适合拦&quot;形状固定&quot;的东西:PII、超长输入、明确的禁用词。</p>
<p><strong>第二档:专门的分类模型。</strong> 这是 2026 年的主力。Meta 的 Llama Guard 是一个专门微调出来的输入输出安全模型,自带六大类不安全分类,还能自定义类目;OpenAI 的 <code>omni-moderation-latest</code> 免费、能同时分类文本和图像。它们的关键优势是<strong>快</strong>——一个专用 guard 模型跑一次大约 29 毫秒,而拿一个大模型当审查员要 5 到 11 秒。但要清楚它们的边界:OpenAI moderation 只做内容分类,<strong>不查注入、不查幻觉、不做 PII 脱敏</strong>。它是基线,不是全部。</p>
<p><strong>第三档:用 LLM 审查 LLM。</strong> 让另一个模型(或同一个模型换个 prompt)去判断&quot;这条输出有没有问题&quot;。最灵活,能处理&quot;品牌口径&quot;&ldquo;答非所问&quot;这种规则和分类器都搞不定的模糊判断。代价是它<strong>慢且贵</strong>——等于每个请求多一次完整的 LLM 调用,延迟翻倍,成本也翻倍。LLM 审查适合留给&quot;少量、高风险、规则写不出来&quot;的判断。</p>
<p><strong>第四档:约束生成(constrained decoding)。</strong> 这个和前三档不是一类——前三档是&quot;事后检查&rdquo;,约束生成是&quot;从源头让它不可能错&quot;。它在模型每一步采样时,直接把不符合 JSON schema 的 token 概率压成零,所以输出<strong>必然</strong>结构合法。Outlines、XGrammar 这些库,还有各家 API 的 structured output 都是这个原理。但记住它的边界:<strong>它保证结构对,不保证内容对</strong>。schema 合法的 JSON,字段值照样可以是幻觉。约束生成解决格式护栏,不解决事实护栏。</p>
<p>把这四档对一遍:</p>
<table>
  <thead>
      <tr>
          <th>做法</th>
          <th>典型延迟</th>
          <th>能解释</th>
          <th>管得了什么</th>
          <th>管不了什么</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>规则/正则</td>
          <td>&lt;10 ms</td>
          <td>强</td>
          <td>PII、长度、禁用词、JSON 格式</td>
          <td>任何需要理解语义的判断</td>
      </tr>
      <tr>
          <td>分类模型</td>
          <td>~30–90 ms</td>
          <td>中</td>
          <td>有害内容、注入信号、话题越界</td>
          <td>幻觉、品牌口径这种细活</td>
      </tr>
      <tr>
          <td>LLM 审查</td>
          <td>0.5–10 s</td>
          <td>弱</td>
          <td>品牌口径、答非所问、复杂合规</td>
          <td>它自己也会误判,且贵</td>
      </tr>
      <tr>
          <td>约束生成</td>
          <td>几乎为零</td>
          <td>强</td>
          <td>输出结构(JSON/枚举/格式)</td>
          <td>内容对不对、是不是幻觉</td>
      </tr>
  </tbody>
</table>
<p>没有哪一档能单独搞定所有事。真实的护栏系统是<strong>分层组合</strong>:规则挡掉一眼假的,分类模型处理大头,LLM 审查兜少量疑难,约束生成锁死格式。</p>
<h2 id="护栏放在哪一层">护栏放在哪一层</h2>
<p>做法选完了,还有个位置问题——同一个检查,放网关、放应用、放模型推理层,效果差很多。</p>
<pre class="mermaid">flowchart LR
  U[用户] --> G[网关层<br/>限流·PII脱敏·黑名单]
  G --> A[应用层<br/>话题边界·业务规则·上下文判断]
  A --> M[模型推理层<br/>约束生成·LLM审查]
  M --> A2[应用层<br/>幻觉/格式/品牌口径校验]
  A2 --> G2[网关层<br/>统一兜底·日志脱敏]
  G2 --> U
  style A fill:#fde7c2,stroke:#e8b23c
  style A2 fill:#fde7c2,stroke:#e8b23c
</pre><p>我的分配原则是这样:</p>
<p><strong>网关层放&quot;无状态、与业务无关&quot;的检查。</strong> PII 脱敏、限流、IP 黑名单、超长输入截断。这些东西不需要懂业务,放在最外层,挡掉的请求根本不会消耗下游算力。日志脱敏也必须在这层做死——一旦敏感信息进了应用日志,再清就是事故。</p>
<p><strong>应用层放&quot;要懂业务&quot;的检查。</strong> 话题边界(财报 Bot 该不该回答写诗)、业务规则(这个用户的权限能不能问这个数据)、需要对话上下文才能判断的东西。这一层是护栏的主战场,因为只有它同时知道&quot;用户是谁&quot;&ldquo;产品边界在哪&quot;&ldquo;检索到了什么资料&rdquo;。</p>
<p><strong>模型推理层放约束生成。</strong> structured output 必须贴着推理走,事后再校验格式纯属浪费——既然能从源头保证,就别留给下游收拾。</p>
<p>橙色那两块——<strong>输出进应用层之后、回给用户之前</strong>的校验——是最容易被漏掉、又最关键的。幻觉检查、品牌口径、答非所问,只能在这里做,因为只有这里能拿到完整的&quot;模型说了什么 + 它本该基于什么&rdquo;。</p>
<p>一个反复出现的错误是<strong>把所有护栏都堆在网关</strong>。图省事,接一个统一的安全中间件。结果就是网关根本不知道业务边界,要么放过一切要么乱拦一气,而最该管的幻觉和口径,它压根没有上下文去管。</p>
<h2 id="护栏的成本延迟和误杀">护栏的成本:延迟和误杀</h2>
<p>回到开头那个 40%。护栏不是免费的,它的账单写在两个地方。</p>
<p><strong>一笔是延迟。</strong> 输入侧的护栏串在用户请求的关键路径上,它慢,用户就等。分类模型几十毫秒还能接受,但你要是图省事拿大模型当审查员,5 到 11 秒——用户早走了。输出侧更麻烦:如果你的应用是流式输出(打字机效果),而输出护栏要等<strong>整段生成完</strong>才能检查,那流式就白做了,用户得对着一个转圈等到最后。这是流式应用做输出护栏时最容易踩的坑。</p>
<p><strong>另一笔是误杀。</strong> 这笔账更隐蔽。护栏拦错了,代价不是 0,是一个被冤枉的真实用户——他什么也没干错,被弹了一句&quot;抱歉,我无法回答这个问题&quot;。医疗问答 Bot 因为出现&quot;症状&quot;两个字就拒答,编程助手把所有正则表达式请求都当成攻击拦掉,这种事天天发生。</p>
<p>这两笔账还得放在一起算。有个说法很到位:<strong>一张冒犯性输出的截图传到社交媒体上,造成的损失,可能比一整年误杀管理的成本都高。</strong> 风险是不对称的——所以高风险场景(面向公众、涉及未成年人、金融医疗)护栏宁可严一点;但低风险的内部工具,你把护栏调得跟法务一样谨慎,纯属自残。<strong>护栏的松紧,是个业务决策,不是技术默认值。</strong></p>
<h2 id="怎么测护栏本身">怎么测护栏本身</h2>
<p>护栏是代码,代码就会有 bug,而护栏的 bug 你平时根本看不见——它默默放过该拦的,或者默默拦掉不该拦的,没有报错、没有崩溃。所以护栏必须被单独测试,而且要测两个方向。</p>
<p>很多团队只测一个方向:准备一批&quot;坏样本&quot;,看护栏能拦住多少。这只测了一半。护栏有两类错误,得两类都测:</p>
<ul>
<li><strong>漏报(false negative)</strong>:坏的没拦住。用一批已知的有害/越界/幻觉样本测,看<strong>召回率</strong>。</li>
<li><strong>误杀(false positive)</strong>:好的被拦了。这个更容易被忽略,但杀伤力更大。你得专门准备一批<strong>长得像坏、其实没问题</strong>的样本——讨论自残话题的心理健康咨询、带&quot;炸弹&quot;二字的化学课提问、正常的退款投诉——看护栏会不会错拦。</li>
</ul>
<p>把这两批样本固定下来,做成一个回归集。每次调护栏的阈值、换分类模型、改 prompt,都跑一遍。盯两个数:<strong>召回率</strong>(漏了多少坏的)和<strong>误杀率</strong>(冤了多少好的)。这两个数永远在拉扯——调严了召回上去、误杀也上去。你要找的不是某个完美点,是一条<strong>和业务风险匹配的取舍线</strong>。</p>
<pre class="mermaid">flowchart TD
  C[改护栏:换模型/调阈值/改 prompt] --> R[跑回归集]
  R --> N[坏样本集<br/>看召回率]
  R --> P[似坏实好样本集<br/>看误杀率]
  N --> D{两个数都可接受?}
  P --> D
  D -->|否| C
  D -->|是| L[上线 + 线上抽样复核]
</pre><p>上线之后还没完。线上要对<strong>被护栏拦掉的真实请求</strong>做抽样人工复核——这是发现误杀的唯一现实途径,因为被冤枉的用户通常不会投诉,他直接走了,你从指标上只看到一个安静下降的留存。</p>
<h2 id="过度护栏管得越多反而越糟">过度护栏:管得越多,反而越糟</h2>
<p>最后这条,是我最想说的。</p>
<p>护栏给人一种虚假的安全感:多加一层,总没坏处吧?有坏处。回到那个数学事实——五个 90% 准确率的护栏串起来,40% 的请求会被误杀。你以为加的是保险,实际加的是故障率。</p>
<p>过度护栏的几个典型反效果:</p>
<ul>
<li><strong>产品变得没用。</strong> 该回答的不回答。一个谨慎到拒绝讨论任何症状的医疗 Bot,对用户来说和不存在没区别。用户要的是帮助,不是一个不停说&quot;抱歉我无法&quot;的复读机。</li>
<li><strong>延迟堆到不可用。</strong> 每层护栏都加几十上百毫秒,叠四五层,本来 1 秒能出的结果变成 3 秒。安全是安全了,没人用了。</li>
<li><strong>维护成本失控。</strong> 每个护栏都是要喂数据、要调阈值、要跟着业务变的活物。堆五个,就是五份持续的维护负债。</li>
<li><strong>掩盖真问题。</strong> 团队拿&quot;我们有七层护栏&quot;当心理安慰,反而不去做真正该做的事——把 system prompt 写清楚、给模型接上权威知识库、把产品边界设计明白。<strong>护栏是补丁,不是地基。</strong> 一个本身就容易跑偏的应用,糊再多护栏也救不回来。</li>
</ul>
<p>学术界已经在认真对待&quot;过度拒绝&quot;这件事了——2025、2026 年有不少论文专门研究怎么在不牺牲安全的前提下,降低模型对正常请求的误拒。这从侧面说明:<strong>过度护栏不是小毛病,它是和&quot;护栏不够&quot;同等量级的失败模式。</strong></p>
<p>正确的心态是:护栏要<strong>少而准</strong>。每加一层之前,先问三个问题——这个风险真的会发生吗?发生了真的严重吗?现有的层挡不住吗?三个都是&quot;是&quot;,才加。</p>
<h2 id="一份上线清单">一份上线清单</h2>
<p>把上面的东西收成一张可以直接对照的清单:</p>
<p><strong>输入侧</strong></p>
<ul>
<li><input disabled="" type="checkbox"> PII(身份证/手机号/卡号)在进模型前已脱敏,且日志里也脱敏了</li>
<li><input disabled="" type="checkbox"> 有输入长度上限,挡掉超长 prompt</li>
<li><input disabled="" type="checkbox"> 话题边界明确——产品该回答什么、不该回答什么,有规则</li>
<li><input disabled="" type="checkbox"> 限流和黑名单放在网关层</li>
</ul>
<p><strong>输出侧</strong></p>
<ul>
<li><input disabled="" type="checkbox"> 有害内容过滤(分类模型,如 Llama Guard / moderation API)</li>
<li><input disabled="" type="checkbox"> 结构化输出用约束生成从源头保证格式,不靠事后修</li>
<li><input disabled="" type="checkbox"> RAG 场景有幻觉/事实一致性检查(输出对得上检索资料)</li>
<li><input disabled="" type="checkbox"> 品牌口径和法务禁用词有校验(高风险时用 LLM 审查)</li>
</ul>
<p><strong>工程</strong></p>
<ul>
<li><input disabled="" type="checkbox"> 每个护栏分了层:无状态的进网关,懂业务的进应用,格式的进推理层</li>
<li><input disabled="" type="checkbox"> 流式输出的护栏不会逼用户等整段生成完</li>
<li><input disabled="" type="checkbox"> 有护栏回归测试集,<strong>召回和误杀两个方向都测</strong></li>
<li><input disabled="" type="checkbox"> 线上对被拦请求做抽样人工复核</li>
<li><input disabled="" type="checkbox"> 算过总延迟账:所有护栏叠加后,响应时间还能接受</li>
<li><input disabled="" type="checkbox"> 每一层护栏都问过&quot;这个风险真的值得这层成本吗&quot;</li>
</ul>
<p>最后一句:护栏的目标不是&quot;零事故&quot;,是&quot;在可接受的延迟和误杀成本下,把高风险事件压到足够低&quot;。把它当成一个<strong>有取舍的工程问题</strong>来做,而不是一个&quot;装得越多越安心&quot;的合规动作——这是做好护栏和做砸护栏的分界线。</p>
<hr>
<p>参考:<a href="https://github.com/NVIDIA-NeMo/Guardrails">NVIDIA NeMo Guardrails</a> · <a href="https://pypi.org/project/guardrails-ai/">Guardrails AI Hub</a> · <a href="https://guardrails.openai.com/">OpenAI Guardrails</a> · <a href="https://generalanalysis.com/guides/best-ai-guardrails">Guardrails Index 基准(2025)</a> · <a href="https://modelmetry.com/blog/latency-of-llm-guardrails">LLM 护栏延迟实测</a></p>
]]></content:encoded></item></channel></rss>