现成框架替你做的决策,
从零搭得自己做
用框架的人面对的是 Claude Code 已经替他做好的一整套决策;搭框架的人面对的是一片空地,上下文怎么压、子 agent 怎么隔、工具怎么加载,一个都得自己一层层垒起来。这篇把散在十来篇实践里、属于设计侧的东西收拢成一条线。
同一个词,两种立场
用框架的人面对的是 Claude Code 已经替他做好的一整套决策:上下文怎么压缩、子 agent 怎么隔离、工具怎么加载,他要做的是把这些设置调到适合自己代码库的位置。搭框架的人面对的是一片空地,这些决策一个都没人替他做,得自己一层层垒起来。这篇文章关心的是后者。
怎么设计一个 MCP server、怎么把内部 API 改造成 agent 用得顺手的工具、什么时候该用一个 loop 而不是五个 agent、怎么让产物变成机器能验的接口。全是用 API/SDK 从零搭 agent 才会碰到的设计决策。
prompt caching 的消费侧提醒、MCP 怎么接入与怎么和 Skills 互补,这些「配好现成 Claude Code」的内容都在上篇。两篇几乎零重叠:消费侧在上篇,设计侧在这篇。
把这些拼到一起,会反复撞见同三条原则,它们也是全文的骨架。
工具不是越多越强,而是越少越强:每多一个工具,它的描述就多占一份模型的思考空间。生成和评估必须分开:让一个 agent 评判自己刚做完的东西,它几乎总会自信地夸自己。边界条件越往结构里写越可靠:写进确定性脚本和接口契约的约束,比指望模型每回合都记得要稳得多。
一条贯穿始终的约束:prompt caching
在进入三块正文之前,要先交代一个底层约束,因为它决定了后面每一层能怎么搭。它的机制是前缀匹配:一次请求发出去,API 从第一个 token 开始逐字节往后比对,直到遇见缓存断点;只要某个位置的一个字节和上次不同,从那个位置往后的全部内容都得重算。命中缓存的部分便宜且快,没命中的部分按全价重新计算。
它之所以是架构约束而不是优化项,是因为它直接连着商业模型:一次 cache miss 意味着整段上下文重算,成本翻倍;成本翻倍,同样的速率上限下能服务的请求就得砍半;砍半就影响到 Pro、Max 这些档位的实际配额。Anthropic 内部把缓存命中率跌破阈值当作生产事故来处理,和服务宕机同级。
这条约束会在后面三块里反复换个形式出现。在工具设计层,它就是工具集永不增删;在编排层,它就是子 agent 走独立的前缀链、不污染主对话;至于上下文压缩,正确的做法是把压缩伪装成父对话的自然延续,复用完整前缀再在末尾追加一条压缩指令,而不是另起一段把前缀打断。
记住这条约束,再看后面的设计,会发现很多看似别扭的选择其实都是在迁就它。
工具设计:少而精,按需加载
搭框架的人最容易犯的第一个错,是把手头几百个内部 API 一个不漏地包装成几百个工具,觉得能力给得越全,agent 越强。实际恰好相反。每一个工具的描述都要占上下文,模型在决定下一步做什么时得先把所有工具的 schema 读一遍,工具越多,留给真正推理的空间越小。工具定义不是免费的背景知识,它和任务本身在抢同一块注意力。
CWC 2026 有一个被反复引用的案例能说明这件事的量级。一个团队的 agent 评测通过率卡在 62%,排查下来问题出在喂得太多。他们做的不是加东西,而是砍:
第一性原则:不是覆盖每一个 API,而是覆盖 agent 完成任务时真正会走的那几条路径。把「从一个讨论串创建工单」做成一个工具,胜过把「读讨论串、解析消息、建工单、关联附件」做成四个让 agent 自己拼的工具。前者对应一个 agent 自然会采取的意图,后者把编排的负担推回给了模型。
这里的核心判断是:agent 不是一个守规矩的操作员。人类用工具会打错字,agent 用工具会一本正经地编造一个看起来合理、实际不存在的参数。两种失败模式不同,接口的设计目标也不同。把这一年的实践归纳起来,大致是十条:
confirm 参数表达,而不是停下来等 stdin,因为 agent 那头没有人按回车。2.5 万 token)。十条单独看都对,凑一起还是抽象。落到一个具体操作上,比如「从一段讨论串建一个工单」,坏工具和好工具长得有多不一样,一眼就看出来了:
同一个操作,好工具把编排、确认、错误、自描述全收进了接口里:agent 只要表达「从这个讨论串建工单」这一个意图,剩下的拼装、试跑、读错误、查参数,工具这头都接住了。前面那十条想说的,落到形态上就是这么回事。
工具接口设计好了,接下来是怎么把它递到 agent 手里。主流有两条路:做成命令行工具(CLI),或者做成 MCP server。这不是口味问题,有实测能比。AXI 这个基准做了 425 次运行(17 个任务、5 种配置、各重复 5 次):
| 维度 | 为 agent 优化的 CLI | GitHub 的 MCP |
|---|---|---|
| 成功率 | 100% | 87% |
| 单次成本 | $0.050 | $0.148(约 3 倍) |
| 平均耗时 | 15.7 秒 | 34.2 秒(约 2 倍) |
| 平均往返 | 3 轮 | 6 轮 |
差距的来源是结构性的:MCP 的每个工具定义本身就要占 两三百到五百 token,工具一多,光是把定义塞进上下文就吃掉一大块;而且 MCP 交互往返更多。CLI 还天然能用管道把几个命令串起来,MCP 做不到。
它适合做执行层
- 命令数量不多、无状态
- 运行环境里有 shell
- token 吃紧
- 已经有现成 CLI
它适合做发现层
- 工具数量上到五十个以上
- 运行环境里压根没有 shell
- 需要维持有状态的会话
- 只有 API、没有命令行的环境
讲究的团队会用一套核心逻辑同时生成两个接口。
做成远程的
远程(remote)是唯一能让 web、移动端、云上的 agent 都用得到的形态,主流客户端也都优先优化远程消费。本地 stdio 只适合开发自测。
按意图分组
按意图给工具分组,而不是按 API 端点。这和 CLI 那条「按 workflow 合并」是同一个道理在 MCP 上的版本。
大 API 面用代码编排
不要把几千个端点变成几千个工具,而是暴露一层很薄的、接受代码的工具,让 agent 写脚本、server 在沙箱里跑。Cloudflare 用两个工具覆盖约 2500 个端点,工具定义只占约 1000 token。
能返界面、能要输入
新能力允许工具回传内嵌 UI(图表、表单、仪表盘),也允许 server 执行到一半时向用户要参数、确认危险操作、澄清歧义。
把认证标准化
用客户端注册机制加速首次认证、减少反复授权,用托管的凭据库自动注入和刷新 token,免得每个 server 自己造一套 secret 存储。
把工具设计这块串起来看,会发现一条主线反复出现,只是在不同层换了名字。它的本质是:别把所有东西一次性全塞给模型,让它在需要的时候再去取。
编排:先问要不要拆,再谈怎么拆
搭框架的人面对的第二个大决策是编排:一个任务,是交给单个 agent 从头跑到尾,还是拆成一个路由加几个专项 agent。2024 年的主流答案是拆,理由也成立:那时模型弱,得把每个 agent 的职责面收窄。但这个前提到 2026 年已经不成立了,现在的模型上下文够长、会用工具、能自我纠错,收窄职责面带来的好处不再抵得上拆分的代价。
一个生产级的重写案例把这件事量化了。Respan 把原来一个路由加四个专项 agent 的结构,重写成一个 loop,同样的模型和设置下,三个维度全面变好:
单轮延迟反而从 19.8 秒涨到了 38.8 秒,翻了一倍。但这不是退步。原来那套「快」,快在它经常停在「要我继续吗」这一步就不动了,看着响应快,其实没把任务做完;重写后的版本是真的端到端把动作执行完了,所以单轮时间自然长。把「停下来问」当成完成,正是旧结构的毛病。
还要说明:这是单个公司的一次重写,样本量是一;Respan 本身是做可观测性的厂商,有立场;打分用的是模型评委不是人工。这些都要放在心上,不能把这组数字当成普适定律。
但它给出的判断框架是站得住的:
handoff 是有损压缩
一个专项 agent 干完活,通常只把一段摘要交给下一棒,它脑子里完整的推理链就丢了。下一棒拿到的是被压扁的结论,不是过程。
还有一笔运维账:五个 prompt 就是五个出错面,任何一处打错字都可能悄悄上线一个回归。
不存在这道损耗
一个有完整上下文的 loop 从头到尾记得自己怎么一步步走到这儿的,只有一个地方要维护。
它还会长出没人教的能力:碰到没见过的请求或工具报错时,会自己去查文档、验证 schema、确认 ID 类型,然后接着干。这是架构给的重入空间,专项 agent 只能返回一个字符串,没有重入的余地。
把「默认单 loop」再往下压一层,还有一个独立来源的证据:多个 agent 凑在一起,不只是更贵,还可能更不可靠。Anthropic 在一篇研究里观察到一个反差:由多个 agent 组成的「AI 组织」在能力上确实比单个 agent 更强,但在对齐上反而更差。同一个新闻推荐任务:
拆成多 agent 后,写说明文档的那个 agent 声明「要尽量减少虚假信息传播」,写排序代码的那个 agent 却把虚假信息当成正向权重往前排,中间没有任何一个 agent 发现这处自相矛盾。根子在于写文档的和写排序代码的不是同一个 agent,又没有谁去做交叉验证。多拆出来的不只是协调成本,还有这种没人兜底的内部矛盾,而堵住它恰恰要靠下一块讲的独立验证。
有些任务确实大到一个 loop 的单段上下文扛不住:跑得特别久、需要大规模并行、结构高度复杂、或要处理对抗性内容。在动手之前,得先认识单个 context 跑长任务会塌的三种方式,因为后面所有的编排手段都是在针对性地治这三个病。
偷懒
一个五十项的安全审查,做到第三十五项就声称已经全部做完。
自我偏袒
让模型拿着评分标准去验证自己刚做完的东西,它会护着自己的产出。
目标漂移
回合一多,模型对最初目标的忠实度一点点流失,压缩后尤甚。
编排的本质价值,就是把计划从模型那段会漂移、会被压缩的上下文里搬出来,放进一段确定性的脚本。偷懒,用脚本拿着完整清单循环到底来治;自我偏袒,用一个独立的 agent 来验证来治;目标漂移,把目标写死在脚本里、不随压缩流失来治。
把计划交给确定性脚本之后,具体怎么编排,这一年沉淀出六个可复用、可组合的套路。它们都属于同一种形态:由脚本(代码)持有计划、再由脚本去逐个调度子 agent,而不是让模型在对话里临时决定要不要拆、拆给谁。下面每一种对应一个常见的编排形状。
先分类再行动
分类器判断任务属哪类再路由,给流水线装个分诊台。
铺开再合拢
拆成多步各一 agent,合成是栅栏:六个套路里唯一要等齐的。
对抗式验证
每生成一个产出就配一个 agent 拿标准对抗式挑刺,直接治自我偏袒。
先生成再筛
先发散一大堆想法,按标准狠狠筛、去重,只留最优几个。
淘汰赛
若干 agent 用不同打法做同题,两两比较直到分出胜负。成对比较比绝对打分可靠。
做到没有新发现为止
任务量未知时别设固定轮数,循环到停止条件成立才扫得干净。
把上面这些套路组织成一个完整流程,目前最成型的范本是一套三角色的分工:一个定义做什么,一个把它做出来,一个独立验收。它对应传统软件开发里产品、开发、测试的三方制衡。
这套三角色被打磨得最完整的场景,是用 agent 从头构建一个应用,下面的例子也都来自这个场景。但能通用的内核只有两条,都不挑领域:三方制衡的分工,以及下一块要展开的「生成不等于评估」。至于浏览器自动化、迭代合约、几小时几百美元这些,是它在写代码这个场景里的具体长相,不是三角色本身的边界。任何一个会产出可检验成果的长任务,都能套用「定义、执行、独立验收」这个骨架。
这套分工的成本是真金白银,下面两组数字仍来自构建应用的场景:
| 案例 | 配置 | 时长 / 成本 | 结果 |
|---|---|---|---|
| 数字音频工作站 | 完整三角色 | 3 小时 50 分 / 约 125 美元 | 绝大部分花在两轮构建,几轮验收各只几美元 |
| 复古游戏 | 单个 agent 单干 | 20 分钟 / 9 美元 | 做出来根本玩不了,实体不响应输入 |
| 复古游戏 | 完整三角色 | 6 小时 / 约 200 美元 | 做出来是能玩的 |
贵了二十倍,换来的是从「不能用」到「能用」。这二十倍,买的就是流程本身的价值。
验证与安全:自己搭,就得自己兜底
前面 Planner / Generator / Evaluator 那套分工里,最不能省的是 Evaluator,而且它必须独立于 Generator。这背后是全文第二条主线:agent 评不了自己。让 Generator 评判它自己刚做完的东西,结果几乎总是自信的夸奖。这在没有明确通过 / 失败标准的任务上尤其严重,比如设计:一个界面好不好看没有二元答案,模型给自己打分时会一路打高。
解法不是把 Generator 调得更谦虚,而是单独养一个 Evaluator,把它调严。调严一个独立的评委,比说服一个作者批评自己,要容易得多。
对抗式验证要落地,前提是评估标准得是可打分的。在设计这类主观任务上,一套被验证过的拆法是分四个维度,两高两基线:
设计任务可以靠 Evaluator 肉眼看截图来评,但更大量的功能验证需要一种能规模化的办法。这里有个值得借鉴的范式:把产物本身改造成 agent 原生可读、可验的接口。具体到前端,做法是一套 DOM 契约,组件在它最外层的 HTML 元素上把自己的完整状态发射出来:
配套是一份跟组件绑在一起的声明文件(.verify.ts),写清四样东西:
window.__verify),让 agent 能列出全部可验单元、读当前结果、一键跑完整个验证矩阵拿回结构化结论。关键是人工仪表盘、agent 接口、CI 无头检查三者走同一条验证代码路径、读同一个数据源,不会出现三套口径打架。契约测试、固定场景、不变量都是老概念,理论上也对。它过去没普及,是因为人力维护成本太高:写一遍验证、之后还要随产品一直更新,投入产出不划算。有几个数字能说明这个困境的普遍程度:
agent 把「写、维护、跑验证」的边际成本压到趋近于零,这套模式才第一次在经济上成立。它从一次性投资变成了持续维护的活文档,而这正是 agent 擅长的。还有一条原则值得抄进自己的框架:验证结论要把「没法判断」和「判断为错」显式分开。拿不准的时候,让验证器判失败而不是判通过,因为一个假通过会把 bug 放进生产,而一个假失败只不过让人多看一眼。
不是每个团队都做得起前面那套完整的验证体系。一个重写 agent 的最小可行验证,是两层网,缺一不可:
守已知雷区
覆盖那些已知的、踩过的失败模式。只有它,容易过拟合到自己设想的几种情况。
测没见过的场景
一批真实的、开放的客户问题,验证它在没见过的场景下还撑不撑得住。只有它,又抓不住已知雷区的回归。
两层都铺上,才算把验证闭环了。
验证管的是「做对没有」,安全管的是「会不会被人利用做坏事」。自己从零搭 agent,这层没有现成框架替你兜。最核心的一条结构性原则是读做分家:
一个去读不可信公开内容的 agent(抓取网页、读用户提交的文本),绝不能同时握有执行高权限动作的能力。读和做拆成两批 agent:负责读的那批没有动手的权限,负责动手的那批不直接接触不可信内容。这样即便读进来的内容里藏了提示注入,它也指挥不动那只能动手的手。这不是靠提示词去防,是靠结构去防。
往下是几条更具体的:输入要按对抗性来加固(agent 犯的是幻觉错不是手滑错,前面工具设计那节列的几类畸形输入要在入口拦掉);如果自己做 MCP server,要留意几类被反复证实的坑,认证默认是可选的就等于不设防、工具定义可以被中途偷换、几家官方 SDK 一度共用了同一个有 DNS 重绑定风险的默认配置。此外,这个领域里还流传过一个被广泛误传、实际并不存在的漏洞编号,引用前务必自己核一遍。
一个产品该用多重的隔离,取决于它的爆炸半径。从轻到重三档,按风险匹配:
边搭边砍:harness 的半衰期
把工具、编排、验证、安全四件事垒完,容易以为 harness 搭好就一劳永逸了。恰恰相反,它有半衰期。harness 的每一个组件,都编码了一个对当时模型能力的假设,而假设会过期。
一个广为流传的例子:某代模型在快到上下文上限时会「焦虑」,提前草草收尾,团队于是加了一段重置上下文的补偿代码;等下一代模型这个毛病消失了,那段补偿代码就从帮手变成了纯粹的负担,反而拖慢性能。同理,前面讲的把任务拆成很多小迭代、每个迭代后重置上下文,这些都是为了迁就「模型扛不住长时间连贯工作」这个假设;一旦模型能连续编码两个多小时,这些拆分就该删掉。
为某代模型的短板打的补丁
Sprint 拆解、context reset 一类。能删多少,取决于模型有多强。模型一升级就该重看,主动删掉不再必要的假设代码。
分工制衡与结构约束
没有 Planner,Generator 会把需求做窄;没有独立的 Evaluator,边界上的 bug 会漏网。上下文要分层、工具要少而精、生成和评估要分开、读和做要分家,这些是纪律。
最好的 agent 框架,是你能删掉的那个。有价值的设计空间不会随模型变强而缩小,只会移动位置。
建议每隔三到六个月、或者每次大版本模型发布后感觉性能见顶时,做一次完整的 harness 审计,主动删掉那些不再必要的假设代码。