/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */
#content_views .toc,
/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */
#content_views.markdown_views > p:empty:has(+ .toc),
#content_views.markdown_views > .toc + p:empty,
/* 富文本旧版目录标记 */
#content_views.htmledit_views #main-toc,
#content_views.htmledit_views #hr-toc,
#content_views.htmledit_views p[id*=\”-toc\”] {
display: none !important;
}
/* 目录去掉后,紧跟的首个标题不再多出一块上边距 */
#content_views.markdown_views > .toc + h1,
#content_views.markdown_views > .toc + h2,
#content_views.markdown_views > .toc + h3,
#content_views.markdown_views > .toc + h4,
#content_views.markdown_views > .toc + p:empty + h1,
#content_views.markdown_views > .toc + p:empty + h2,
#content_views.markdown_views > .toc + p:empty + h3,
#content_views.markdown_views > .toc + p:empty + h4 {
margin-top: 0 !important;
}
本篇是《智能体演化史》系列第 7 篇 系列主线不是"某年出现了某技术",而是"因为上一步崩了,所以下一步才出现"。 全系列共用一个从 34 行长到 216 行的 tiny-agent,本篇是它的 v0.7。
上一篇拆出了 3 个 agent,接下来要接 10 个数据源——3×10=30 套适配器。MCP 承诺把这个乘法变成加法。它做到了,但省下来的东西,会以另一种形式收回去。
怎么读这篇
- 🚶 12 分钟版:只看「崩坏现场」「一句话原理」和 M×N 那张表,理解标准化到底省了什么。
- 🏃 40 分钟版(推荐):加读延迟绑定的 token 账、三层架构和 v0.7 实现,你会知道"规划税"是什么、怎么量。
- 🤿 深潜版:想清楚最后一节——标准化在历史上每次都收同一种过路费,这次也不例外。
01 · 崩坏现场:30 套适配器,和没人愿意改的第二次
一个团队要给内部 Agent 接 5 个数据源:代码仓库、工单系统、数据库、文档库、监控平台。彼时他们只有一个 Agent,所以老老实实写了 5 套适配器。
半年后,按 P5 的思路拆成了 6 个专职 agent。适配器从 5 套变成 30 套。
真正致命的不是数量,是变更成本:
- 工单系统升级 API,6 个 agent 的工单适配器全要改,改法还各不相同(因为当初是 6 个人写的)。
- 新增一个 agent,要复制粘贴 5 套适配器,再一个个调通。
- 认证方式有三种:OAuth、API Key、服务账号。没有一个 agent 说清楚自己到底有哪些权限。
- 最糟的是:某个 agent 偷偷拿到了它不该有的数据库写权限,因为当初复制适配器时顺手带上了。
这是典型的 M×N 集成问题。 M 个消费方 × N 个数据源 = M×N 套适配代码。它不随规模线性增长,它相乘。而且每一套都有自己的认证逻辑、错误处理和字段映射——出错的地方也是 M×N 个。
02 · 一句话原理
标准化把"对接成本"变成了"决策成本" —— 便宜了集成,贵了规划。
这是本篇的反常识钩子,也是很多人用上 MCP 三个月后才反应过来的事。账单上的 token 确实少了,但模型变得更容易选错工具、或者不敢选工具——而这个代价不出现在账单上,它出现在成功率里。
03 · M×N 到底多可怕:一个乘法,而不是加法
标准化之后:3 + 5 = 8 —— 每个 agent 实现一次协议,每个源暴露一次协议 M×N 集成爆炸。左边 15 条连线,每条都是一份要维护的代码;右边变成 8。规模越大,差距越夸张——见下表。
M×N vs M+N:规模越大越夸张
| 2 | 5 | 10 | 7 | 30% |
| 3 | 10 | 30 | 13 | 57% |
| 5 | 20 | 100 | 25 | 75% |
| 8 | 30 | 240 | 38 | 84% |
| 12 | 50 | 600 | 62 | 90% |
最后一个数字值得盯着看一眼:600 套 vs 62 套。 这不是"省了点事",这是"能做"和"做不了"的区别。
04 · 三层架构:Host / Client / Server
MCP 的具体做法并不神秘,本质是把"直连"改成"经过一个标准层"。它有三个角色:
#mermaid-svg-o9XR5esj4aMe5J5d{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-o9XR5esj4aMe5J5d .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-o9XR5esj4aMe5J5d .error-icon{fill:#552222;}#mermaid-svg-o9XR5esj4aMe5J5d .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-o9XR5esj4aMe5J5d .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-o9XR5esj4aMe5J5d .marker{fill:#333333;stroke:#333333;}#mermaid-svg-o9XR5esj4aMe5J5d .marker.cross{stroke:#333333;}#mermaid-svg-o9XR5esj4aMe5J5d svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-o9XR5esj4aMe5J5d p{margin:0;}#mermaid-svg-o9XR5esj4aMe5J5d .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-o9XR5esj4aMe5J5d .cluster-label text{fill:#333;}#mermaid-svg-o9XR5esj4aMe5J5d .cluster-label span{color:#333;}#mermaid-svg-o9XR5esj4aMe5J5d .cluster-label span p{background-color:transparent;}#mermaid-svg-o9XR5esj4aMe5J5d .label text,#mermaid-svg-o9XR5esj4aMe5J5d span{fill:#333;color:#333;}#mermaid-svg-o9XR5esj4aMe5J5d .node rect,#mermaid-svg-o9XR5esj4aMe5J5d .node circle,#mermaid-svg-o9XR5esj4aMe5J5d .node ellipse,#mermaid-svg-o9XR5esj4aMe5J5d .node polygon,#mermaid-svg-o9XR5esj4aMe5J5d .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-o9XR5esj4aMe5J5d .rough-node .label text,#mermaid-svg-o9XR5esj4aMe5J5d .node .label text,#mermaid-svg-o9XR5esj4aMe5J5d .image-shape .label,#mermaid-svg-o9XR5esj4aMe5J5d .icon-shape .label{text-anchor:middle;}#mermaid-svg-o9XR5esj4aMe5J5d .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-o9XR5esj4aMe5J5d .rough-node .label,#mermaid-svg-o9XR5esj4aMe5J5d .node .label,#mermaid-svg-o9XR5esj4aMe5J5d .image-shape .label,#mermaid-svg-o9XR5esj4aMe5J5d .icon-shape .label{text-align:center;}#mermaid-svg-o9XR5esj4aMe5J5d .node.clickable{cursor:pointer;}#mermaid-svg-o9XR5esj4aMe5J5d .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-o9XR5esj4aMe5J5d .arrowheadPath{fill:#333333;}#mermaid-svg-o9XR5esj4aMe5J5d .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-o9XR5esj4aMe5J5d .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-o9XR5esj4aMe5J5d .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-o9XR5esj4aMe5J5d .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-o9XR5esj4aMe5J5d .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-o9XR5esj4aMe5J5d .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-o9XR5esj4aMe5J5d .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-o9XR5esj4aMe5J5d .cluster text{fill:#333;}#mermaid-svg-o9XR5esj4aMe5J5d .cluster span{color:#333;}#mermaid-svg-o9XR5esj4aMe5J5d div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-o9XR5esj4aMe5J5d .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-o9XR5esj4aMe5J5d rect.text{fill:none;stroke-width:0;}#mermaid-svg-o9XR5esj4aMe5J5d .icon-shape,#mermaid-svg-o9XR5esj4aMe5J5d .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-o9XR5esj4aMe5J5d .icon-shape p,#mermaid-svg-o9XR5esj4aMe5J5d .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-o9XR5esj4aMe5J5d .icon-shape .label rect,#mermaid-svg-o9XR5esj4aMe5J5d .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-o9XR5esj4aMe5J5d .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-o9XR5esj4aMe5J5d .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-o9XR5esj4aMe5J5d :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Host(宿主应用)
你的 Agent / IDE
MCP Client每个 Server 一个连接
Server · GitHub
Server · 数据库
Server · 文件系统
| Host | 宿主应用(你的 Agent / IDE)。负责权限与审批 |
| Client | 内嵌在 Host 里,每个 Server 一个连接,走 JSON-RPC |
| Server | 暴露 Tools / Resources / Prompts(90% 的场景只用得到 Tools) |
关键:权限边界落在 Host 上 —— Server 说"我能做什么",Host 决定"准不准做"。 这个分离是 P8 三道锁能落地的前提。
05 · 延迟绑定:省下的 token,和交出去的东西
接上 MCP 之后,马上会遇到新问题:50 个工具的完整 schema 每轮都要重发——P1 我们算过,详细型 schema 平均 233 token,50 个就是 11,650 token/轮,而且跟任务内容一个字关系都没有。
解法叫延迟绑定(lazy binding):常驻上下文的只有一份"目录"(每个工具名字 + 一句话),决定要调用某个工具时,才把它的详细 schema 拉进来。
| 全量下发 schema | 11,650 | — |
| 目录 + 按需展开(只拉 3 个) | 1,299 | 省 89% |
| 计入 15% 规划税(选错重来)后 | 1,494 | 仍省 87% |
假设:目录项 12 token/个、详细 schema 233 token/个(来自 P1 实测)、一轮展开 3 个、选错率 15%。
从账面上看,这是纯赚。 那代价在哪?
| 选错工具 | 只看名字猜功能 | 调了语义相近的另一个 | 统计"首次调用即正确"的比例 |
| 不敢下手 | 参数不确定,怕报错 | 多轮自我询问,步数虚高 | 统计"决策轮 / 总轮数" |
| 反复试探 | 用报错反推 schema | 同一工具连续调用失败 | 统计"参数校验失败率" |
| 漏掉该用的 | 目录里没看出有这个能力 | 绕远路,用笨办法达成 | 对比"最优路径命中率" |
规划税的本质: 信息从"模型看得到"变成了"模型要开口要"。一次 API 调用的成本变成了账单上的数字,而一次决策失误的成本变成了日志里的失败率。 后者没人天天看,所以它经常被忽略到上线之后。
怎么压低规划税?三个做法,按性价比排序:
06 · 最小实现:目录 + 按需展开
(完整代码 106 行)
# 常驻上下文的只有目录:名字 + 一句话,约 12 token/个
CATALOG_TEXT = "\\n".join(f"{srv}/{n}" for srv, names in SERVERS.items() for n in names)
SYSTEM = f"可用工具目录:\\n{CATALOG_TEXT}\\n\\n" \\
"流程:选工具 -> load_schema 拉详细定义 -> 再调用"
def load_schema(names):
got = [FULL_SCHEMAS[n] for n in names if n in FULL_SCHEMAS]
loaded.extend(...)
return json.dumps([g["function"] for g in got])
# 每轮只带:目录工具 + 最近展开过的几个(不是全部 50 个)
resp = client.chat.completions.create(
model=MODEL, messages=messages,
tools=catalog_lines() + [FULL_SCHEMAS[n] for n in loaded[–6:]]
)
| 模拟实现里 50 个工具怎么来的? | 按 github / db / slack / web / fs 五个 server 各 10 个生成。真实环境来自 tools/list,可能来自不同进程 |
| 为什么要保留"最近展开过的 6 个"? | 一个任务里同一个工具往往要调多次。每次都重新展开等于反复交税。这是缓存与上下文的折中 |
| 目录里要不要写服务名? | 要,写成 github/list_pr 而不是 list_pr。命名空间本身就是消歧信息,成本几乎为零 |
| 延迟绑定对短任务是赚是赔? | 工具少于 10 个时是赔:目录 + 展开的往返,比直接全量下发还贵。阈值大致在 15-20 个工具 |
07 · 过路费:历史上每次标准化都收同一种
| USB-C | 一堆专用线缆和转接头 | "我到底该插哪个口"的决策 | 用户 |
| 容器 / K8s | "在我机器上能跑"的问题 | 编排复杂度、YAML 地狱 | 运维 |
| 微服务 + HTTP | 单体耦合 | 分布式事务、链路追踪 | 架构 |
| MCP | M×N 适配器 | 规划税(决策成本) | 模型(和你的成功率) |
规律很清楚:标准化永远不会消灭复杂度,它只改变复杂度落在谁头上。
USB-C 之前,你包里有一堆线;USB-C 之后,你只有一个口——但要随时判断"这次该插显示器还是硬盘"。省下的是物理负担,多出来的是每一次的决策负担。 MCP 完全同构:省下的是工程师写适配器的负担,多出来的是模型每次选工具的决策负担。
知道这个规律有什么用? 它让你能提前预判:凡是"统一了接口"的技术,上线后一定会出现一类新的、不在账单上的失败。你应该在上线前就为它埋好监控指标(比如"工具首次调用正确率"),而不是等成功率掉了再去猜原因。
08 · 现实对照:USB-C 之后,你还是得想插哪个
| 接显示器 | 找 HDMI/DP/VGA 转接头 | 一根线解决 |
| 接硬盘 + 显示器 + 充电 | 三个口,各插各的 | 一个口,但要选顺序或上拓展坞 |
| 出差前检查 | “每种线都带一根” | “带一根就行” |
| 到了会议室 | 发现少带一个转接头 | 发现这个口不支持视频输出 |
| 失败形态 | 物理上不可能(缺件) | 能力上不确定(不知道行不行) |
最后一行是重点:统一前的失败是"做不到",统一后的失败是"不确定能不能做到"。 后者更隐蔽,也更难排查——它需要你主动去问,而不是看一眼就知道。
09 · 下一篇
到这里,tiny-agent 有手、有循环、有脑子、有记忆、能分工、能接标准协议。演示的时候它做得很漂亮。
然后上线第一周:成本超预算 20 倍,且没人知道它为什么失败——因为从来没有人系统地记录过它是怎么失败的。
下一篇是这个系列竞争最小、价值最高的一篇:P8《为什么你的 Agent 演示惊艳、上线就崩》,讲失败谱、评测集,以及五道防线各自能压掉多少失败率。
思考题: 你的 Agent 有没有一个"工具首次调用正确率"的指标?如果没有,你很可能已经交了规划税,只是账单上看不出来。
系列导航
| P1 | Agent演化史(一)剥掉营销话术后,智能体只剩 34 行代码 | 已完稿 |
| P2 | Agent演化史(二)模型从没碰过你的工具:Function Calling 只是一份申请书 | 已完稿 |
| P3 | while True 的威力与恐怖:循环与四道刹车 | 已完稿 |
| P4 | 上下文工程的诞生,为什么"提示词工程"这个岗位消失了 | 已完稿 |
| P5 | 从RAG到记忆图谱,同一个坑踩十次,它每次都踩得同样认真 | 已完稿 |
| P6 | 一个上帝模型不够用,47 个工具,它每 5 次就选错 1 次 | 已完稿 |
| P7 | MCP智能体世界的USB-C,和它偷偷收的过路费 | 本篇 |
本篇资产
- tiny-agent-v0.7.py —— 106 行,5 个 server / 50 个工具的目录 + 延迟绑定,可在资料库进行下载
- calc_metrics_2.py —— M×N 对照表与延迟绑定 token 账,参数可改
本文为盘子工具站生态原创技术专题系列,转载请注明出处。

网硕互联帮助中心






评论前必须登录!
注册