🐎 第6章 海纳百川:MCP
📄 一句话概括

同一个协议能架在三种传输上:标准输入输出、HTTP 加事件流、流式 HTTP。 差别不在协议,在「连接活多久」。 一次会话调一百次,stdio 握手一次就够,HTTP 要握手一百次。 远程传输里一半的功夫花在连接复用上。

📝 本章和前面几章的关系

上一节把协议说清了,这一节说它架在什么上面跑。 这一节的账很简单,但选错了要多干很多活——本机工具写成远程服务,会凭空多出认证和超时。

一、三种形态

标准输入输出(stdio):宿主起一个子进程,走管道说话。只在本机,连接活一整段会话。 HTTP 加事件流:一次请求建连,服务器用事件流把结果推回来。可以远程,连接通常活一次调用。 流式 HTTP:一个端点两种用法,能升级成长连接。可以远程,寿命看用法。

三种的协议部分完全一样,换的只是「消息从哪儿进去、从哪儿出来」。所以服务器代码基本不用改。

二、握手一次能撑几次调用

演示里一百次调用:stdio 握手一次,HTTP 握手一百次,流式 HTTP 握手一次。 按一次握手一百二十 token 算,stdio 和流式总共只花一百二,HTTP 是一万二。 所以「远程」这件事的第一笔账不是网络延迟,是握手。

延迟是毫秒级、能忍;握手是每次几千 token 的清单拉取,忍不了。

三、握手的开销是什么

不只是网络往返。一次握手可能包含:版本协商、能力交换、工具清单拉取、身份校验。 其中「工具清单拉取」最贵:十几个工具,每个带一段 schema,一次就是几千 token。 所以远程传输的实现在「连接复用」上花的功夫,全是为了省这一笔。

也所以工具 schema 要短——它不只在启动时花一次,是在每一次新连接上都要花一次。

四、怎么选

本机工具、要读写文件、要跑命令——用 stdio。最简单、最快、不用管认证。 跨机器的共享服务,比如数据库、工单系统——用 HTTP 系。它需要一个能长期跑的服务端。 要不要用流式那个,看服务端支不支持「长任务边跑边回」。不需要就退回普通 HTTP。

判据就一句:这个东西的数据在哪台机器上?在本机就 stdio,在别的机器就 HTTP。

五、一个常见错误

把本机工具写成远程服务。看起来更通用,实际上要为认证、超时、断线重连付一堆没必要的工作。 反过来也错:把跨机器的服务包成本机进程。跨机器的东西包不过来,只能包个壳。 这类错误有个共同点:都是按「哪种更高级」选的,不是按「数据在哪儿」选的。

按数据位置选,几乎所有纠结都会消失。

六、动手 Demo:三种传输方式,握手一次能撑几次调用

同一个协议架在三种传输上,差别不在协议,在「连接活多久」。 按一次会话一百次调用来算,看三种分别要握手几次、花多少 token。

TRANS = [(u"stdio", 1, 120),        # 起进程一次,之后复用
         (u"HTTP", 100, 12000),      # 每次调用都要握手
         (u"流式 HTTP", 1, 120)]      # 可复用

实跑输出:

--------------------------------------------------------------------
三种传输方式,握手一次能撑几次调用
--------------------------------------------------------------------

  同一个协议,可以架在三种传输上:标准输入输出、HTTP 加事件流、流式 HTTP。
  它们的差别不在协议,在「连接活多久」。

  ① 三种形态
  --------------------------------------------------------------------
| 传输 | 怎么连 | 能不能远程 | 连接寿命 |
|---|---|---|---|
| stdio | 宿主起子进程,走管道 | 本机 | 整段会话 |
| HTTP + SSE | 一次请求,服务器用事件流回 | 可以远程 | 一次调用 |
| 流式 HTTP | 一个端点两种用法,可升可降 | 可以远程 | 一次调用或更长 |


  ② 一次会话调一百次,握手几次
  --------------------------------------------------------------------
| 传输 | 握手次数 | 握手开销(token) | 说明 |
|---|---:|---:|---|
| stdio | 1 | 120 | 起进程一次 |
| HTTP | 100 | 12000 | 每次都要 |
| 流式 HTTP | 1 | 120 | 可复用 |

  stdio 起一次进程就一直在,一百次调用零成本;HTTP 每次都要建连、带认证头、服务器还要认一次身份。

  ③ 握手的开销是什么
  --------------------------------------------------------------------
  不是网络延迟那么简单。每一次握手都可能包含:版本协商、能力交换、工具清单拉取、身份校验。
  其中「工具清单拉取」最贵:十几个工具,每个带一段 schema,一次就是几千 token。
  所以远程传输的实现在「连接复用」上花的功夫,全是为了省这一笔。

  ④ 怎么选
  --------------------------------------------------------------------
  本机工具、要读写文件、要跑命令——用 stdio。它最简单、最快、不用管认证。
  跨机器的共享服务(数据库、工单系统)——用 HTTP 系。它需要一个能长期跑的服务端。
  要不要用流式那个,看服务端支不支持「长任务边跑边回」。不需要就退回普通 HTTP。
  ! 一句话:stdio 是「进程内的工具」,HTTP 是「网络上的服务」。
  分不清这个,会把本机工具写成远程服务,然后为认证和超时付出一堆没必要的工作。

①三种形态:stdio 起子进程走管道、HTTP 加事件流、流式 HTTP。 协议部分完全一样,换的只是消息从哪儿进出。 ②stdio 起一次进程就一直在,一百次调用零额外成本; HTTP 每次都要建连、带认证头、服务器还要认一次身份。 ③握手的开销不只是网络延迟:版本协商、能力交换、工具清单拉取、身份校验。 最贵的是工具清单——十几个工具各带一段 schema,一次就是几千 token。 ④怎么选就一句:这个东西的数据在哪台机器上?在本机就 stdio,在别的机器就 HTTP。 按数据位置选,纠结基本消失。

30 秒实验

  1. 把调用次数从一百改成一千,重跑一遍。HTTP 那一行的握手次数和 token 涨到多少? stdio 那一行变了吗?
  2. 把工具数量从两个加到二十个(每个 schema 一百二十 token),重算一次握手的开销。 连接复用省下的钱涨了几倍?
  3. 给 stdio 加上「每次调用重启一次进程」的假设,重跑一遍。它和 HTTP 还有区别吗? 这说明 stdio 的优势来自哪儿?

常见误区

  1. 把本机工具写成远程服务。凭空多出认证、超时、重连的工作,而它的数据根本不在别的机器上。
  2. 用 HTTP 却每次调用都重新握手。远程的开销几乎全在这一步,复用一次就省一次。
  3. 以为 stdio 只能做简单事。它只是不能跨机器,能力上没有任何限制。
  4. 把工具 schema 写得很长。它不只在启动时花一次,每次新连接都要花一次。
  5. 按「哪种更高级」选传输。该按「数据在哪台机器上」选。
自测三问(点开对答案) 1. 三种传输的根本差别是什么? —— 不是协议,是连接能活多久。stdio 活一整段会话,HTTP 通常活一次调用,流式 HTTP 可长可短。 2. 握手的开销主要花在哪? —— 工具清单拉取。十几个工具各带一段 schema,一次就是几千 token,所以远程实现都在做连接复用。 3. 怎么判断该用 stdio 还是 HTTP? —— 看数据在哪台机器上。在本机就 stdio,在别的机器就 HTTP。

载体选定了,下一节讲怎么把它接进来:两行命令或者一个配置文件。

相关笔记