昨晚十一点半,我盯着自己那个钉钉数字员工项目里的一段代码发呆。
那是 core 模块里的轮询逻辑——每隔 3 秒去 serve 端拉一次会话状态,判断任务是否完成、是否超时、是否需要 abort。旁边是 session 管理:维护一个内存里的 Map,记录每个会话的生命周期、重试计数、上下文快照。再往下是 abort 清理:当用户取消任务时,要优雅地终止正在执行的工具调用、回收资源、把中间状态写回。
加起来大概 200 行。写得挺漂亮,有状态机、有超时退避、有异常兜底。我三个月前写它的时候,serve 端还没有原生的会话生命周期管理,没有 SSE 事件流推送,没有内置的 abort 语义。这 200 行是当时唯一的选择。
但昨晚我突然意识到: 这些代码的保质期,可能只剩一年。
不是因为它们写错了,而是因为它们正在被模型和运行时从两端同时吞噬。
一个正在发生的模式:模型吞噬清单
这不是我的个人焦虑。回看过去三年,Agent 框架的每一层「核心能力」都在被模型逐一内化:
2023 ReAct 框架 模型不会规划 → 框架写 prompt 模板强制 Thought-Action-Observation
2024 Function Calling 模型不会调工具 → 框架做 JSON Schema 解析 + 路由分发
2025 Native Tool Use 模型原生支持工具调用 → 框架的解析层变成透传
2026 Long Context 模型上下文够长 → 框架的记忆管理 / RAG 编排被压缩
? Self-made Tools 模型自己造工具 → 框架的工具注册表变成沙箱 + 权限
每一步的模式完全一样: 框架先替模型补能力,模型内化后,框架的那层代码就从「必要脚手架」变成「多余中间商」。
最硬的证据来自 Anthropic 自己。Claude 5 代模型发布时,他们把 Claude Code 的 system prompt 删掉了 80% 以上——那些曾经用来强制模型遵守的硬规则(「你必须先读文件再修改」「不要一次性写超过 300 行」),模型已经内化了。Eval 无损。
我在 模型与 Agent 的边界正在消失 里引用过 Anthropic 工程团队的一句话:
Harnesses encode assumptions about what Claude can’t do on its own. Those assumptions go stale as models improve.
Harness 编码的是「模型做不到什么」的假设。问题是, 这些假设的半衰期越来越短了。
本质问题:框架复杂度是负资产
大多数工程师对框架复杂度的直觉是:「多一层控制,多一分可靠。」这个直觉在模型能力不足时完全正确——2023 年没有 ReAct 框架,模型根本完不成多步任务。
但这里有一个被忽视的不对称性:
- 加代码的收益是即时的——加了轮询,任务状态立刻可观测了
- 删代码的收益是持续的——少了 200 行,每次迭代都快一点、认知负担轻一点、token 成本低一点
- 不删代码的成本是隐性的——它不会报错,只会让你的系统比「本可以」更慢、更贵、更难改
这就是为什么我说框架复杂度是 负资产:它不是中性的「多写了一些代码」,而是一笔持续产生利息的债。模型每吞噬一项能力,你框架里对应的那层代码就开始计息。你不还,它就复利。
Agent 层瘦身判断标准
那怎么判断什么该留、什么该交?我提炼了一个简单的二分法:
| 留在框架层(运行时治理) | 交给模型(能力内化) |
|---|---|
| 权限控制——谁能调什么、边界在哪 | 规划——下一步做什么、怎么分解任务 |
| 沙箱隔离——代码在哪跑、资源上限 | 记忆——上下文管理、长程状态 |
| 消息路由——请求从哪来、响应往哪去 | 工具选择——用哪个工具、参数怎么填 |
| 审计日志——做了什么、能不能回溯 | 错误恢复——失败了怎么重试、怎么降级 |
| 工具沉淀——造出来的工具存哪、怎么复用 | 工具制造——根据任务需要写新工具 |
判断标准只有一条: 这项能力,如果模型做错了,后果是「任务失败」还是「安全/合规事故」?
- 任务失败 → 交给模型。模型会越来越好,你的兜底代码会越来越多余。
- 安全事故 → 留在框架。权限、沙箱、审计不会因为模型变强而消失——它们是运行时的物理约束,不是能力补丁。
我在 Loop Engineering 里画过一张五层演进表:从 Prompt Engineering 到 Loop Engineering,每一层的本质都是「人少决定一步,模型多决定一步」。瘦身判断标准就是这张表的工程操作化——不是问「模型能不能做」,而是问「模型做错了,我能不能承受后果」。
贯穿案例:我的钉钉 harness 正在被吞噬
拿我自己这个钉钉数字员工项目做解剖。
三个月前,core 模块的架构长这样:
┌─────────────────────────────────────────────────────────┐
│ 我的 harness core │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ 轮询循环 │ │ Session 管理 │ │ Abort 清理逻辑 │ │
│ │ 3s 拉状态 │ │ 内存 Map │ │ 终止工具调用 │ │
│ │ 超时退避 │ │ 生命周期追踪 │ │ 资源回收 │ │
│ │ 异常兜底 │ │ 上下文快照 │ │ 中间状态持久化 │ │
│ └──────────┘ └──────────────┘ └───────────────────┘ │
│ │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ 工具注册 │ │ 错误重试 │ │ 上下文拼接 │ │
│ │ JSON 解析 │ │ 指数退避 │ │ 历史消息裁剪 │ │
│ │ 参数校验 │ │ 降级策略 │ │ system prompt │ │
│ └──────────┘ └──────────────┘ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
六个模块,大概 600 行核心逻辑。三个月后回头看:
| 模块 | 当时为什么需要 | 现在发生了什么 | 判断 |
|---|---|---|---|
| 轮询循环 | serve 端没有推送 | SSE 事件流已上线,推送替代拉取 | 可删 |
| Session 管理 | serve 端无状态 | serve 端开始维护会话生命周期 | 可删 |
| Abort 清理 | 没有原生取消语义 | serve 端支持 abort 指令 | 可删 |
| 工具注册 | 模型需要 JSON Schema | 原生 tool use,模型自己理解参数 | 可删 |
| 错误重试 | 模型不会自己重试 | 模型内化了 retry + 降级策略 | 可删 |
| 上下文拼接 | 上下文窗口不够 | 长上下文 + 模型自己管理注意力 | 大幅简化 |
六个模块,五个可删,一个大幅简化。600 行变 80 行——剩下的 80 行是什么? 消息路由(钉钉 → serve 的转发)和权限控制(谁能触发什么操作)。
这就是瘦身判断标准的实际效果:不是「模型能不能做」的问题——模型当然能做轮询和重试。是「做错了后果是什么」的问题。轮询做错了,任务晚完成 3 秒,无所谓。权限做错了,不该执行的操作执行了,这是事故。
我在 让钉钉机器人自己开发自己 里说过:「自主性的瓶颈从来不在模型能力,而在环境接入。」现在我要补一句: 环境接入解决之后,瓶颈转移到了运行时治理——不是「能不能让 Agent 做」,而是「敢不敢让它随便做」。
最后的拐点:模型造工具并沉淀复用
上面说的都是「模型吞噬已有框架层」。但还有一个更深的趋势:模型开始自己造新工具。
Code interpreter 是最朴素的形态——模型发现需要一个数据处理函数,自己写一个,执行,拿结果。我在 以前人给 AI 造工具,现在 AI 自己造工具 里详细讨论过这个范式转移:从声明式工具调用到程序化工具调用(PTC),人类从「工具制造者」退化为「工具审批者」。
但 code interpreter 有一个根本局限: 造出来的工具是一次性的。 每次新会话,模型重新造一遍同样的轮子。
真正的拐点不是「模型能不能造工具」——它已经能了。拐点是: 造出来的工具能不能被沉淀、复用、维护?
想象一个场景:
- 模型在执行任务时发现需要一个「从钉钉审批流里提取结构化数据」的工具
- 它自己写了一个 Python 函数,跑通了
- 它把这个函数存进工具库,写了一段文档说明参数和限制
- 下次另一个会话遇到类似需求,它直接调用,不用重新造
- 如果这个工具有 bug,它自己修,更新版本号
当这个闭环跑通,Agent 框架里「工具注册表」这个概念就彻底消失了。剩下的只有:
- 沙箱——模型造的工具在哪跑、不能碰什么
- 权限——哪些工具需要人审批才能入库
- 审计——谁在什么时候用了什么工具、产生了什么结果
框架从「能力编排器」退化为「运行时治理层」。这不是降级,是进化。
瓶颈不在模型,在运行时敢不敢放手
最后说一个反直觉的判断: 当前 Agent 落地的瓶颈,不是模型能力不够,是运行时环境不敢让模型随便执行。
模型已经能写代码、能调工具、能规划多步任务、能自己重试。但大多数生产环境还在用 2023 年的框架把它捆得死死的——每一步都要人审批,每一个工具调用都要过一层 JSON 解析,每一次上下文都要手动裁剪。
这不是谨慎,是 用旧地图走新路。
真正的谨慎应该是:把治理资源集中在真正需要治理的地方(权限边界、沙箱隔离、审计链路),而不是均匀地洒在每一层编排逻辑里。你在轮询逻辑上花的每一小时 code review,都是没花在权限模型设计上的时间。
升维问题:当框架只剩沙箱和权限,「Agent 工程师」做什么?
如果这个趋势成立,那「Agent 工程师」这个角色的核心技能正在发生一次根本性的迁移:
| 旧技能(编排时代) | 新技能(治理时代) |
|---|---|
| 写 ReAct prompt 模板 | 设计权限模型和审批流 |
| 实现工具注册和路由 | 构建沙箱策略和资源配额 |
| 管理上下文窗口和记忆 | 设计审计链路和可观测性 |
| 编写错误重试和降级逻辑 | 定义工具沉淀和复用机制 |
| 调参、调 prompt、调 workflow | 判断「这层代码该不该存在」 |
最后一行是最难的。写 200 行轮询逻辑是确定性工作——需求明确、接口清晰、写完就能跑。但判断「这 200 行该不该存在」需要你对模型能力曲线有判断力、对系统边界有全局观、对「做错了后果是什么」有清醒的认知。
这不是「Agent 工程师会消失」——是「只会写编排代码的 Agent 工程师会消失」。留下来的人,做的是 运行时架构师 的工作:不是告诉模型怎么做,而是划定模型能做什么、不能做什么、做完了怎么审计。
我在 Agent 应用工程师是增长最快的岗位 里讨论过这个岗位的崛起。现在我想修正一下:增长最快的不是「Agent 应用工程师」,是 Agent 运行时治理工程师——那些能判断「什么该薄、什么该厚」的人。
回到昨晚那 200 行代码。我没有删掉它们——serve 端的原生能力还在灰度,生产环境不能赌。但我做了一件事:在代码注释里写了一行 // TODO: 模型/运行时内化后删除,预计 2027 Q1。
给代码写保质期。这可能是 Agent 工程师在模型吞噬时代最重要的新习惯: 不是问「这段代码能不能跑」,而是问「这段代码还能跑多久」。
你在自己的 Agent 项目里,有没有已经开始计息的「负资产代码」?欢迎留言聊聊。