软件架构

API 契约接口边界

当 AI 系统调用工具、串联服务或交换结构化上下文时,稳定的契约至关重要。

基础
工作流

这个概念是什么意思

接口契约是一个承诺,不是一份文档。完整的承诺有四件事:输入的形状、输出的形状、出错时的形状、以及这个承诺将来怎么改。前两件所有人都会写,后两件经常没人写——而决定你的集成能不能活过一年的,恰恰是后两件。

变更规则是那条决定寿命的

MCP 2.0 把弃用写成了规范的一部分:任何被废弃的能力至少保留 12 个月。这看起来是最无聊的一条改动,实际上它是唯一一条直接决定「我敢不敢把它接进生产」的改动——没有它,你的集成可能在任何一个周二早上失效,而你事先什么都做不了。

判断一个外部接口值不值得深接,看它有没有回答这三个问题:什么时候会改、改之前你会知道多久、旧的还能用多久。答不上来,就按「随时会断」来设计。

出错时的形状也是契约

一个例子:Ollama 在 0.32.6 里把被截断的响应从 finish_reason: "tool_calls" 改成了 finish_reason: "length"。功能没变,但这是在修一个会说谎的契约——调用方原本会以为模型要调工具,实际上只是输出被截断了,于是下游走进完全错误的分支。

这类错误比直接失败贵得多。返回 500 的接口会被你处理,返回 200 但语义是错的接口会被你相信。

边界画在哪里,决定了谁能参与

MCP 2.0 把方法名和工具名从请求体搬进 HTTP 头,于是网关不必解析请求体就能路由和鉴权。同一套能力,只因为契约的形状变了,可参与的角色就多了一类。

反过来也成立:契约把信息藏得越深,能帮上忙的组件就越少,最后所有逻辑都被迫挤在一个地方。

一个契约值多少,看它让多少东西不必被改写

vLLM 的 Transformers 后端是这条的极端案例:因为有一个统一的模型接口,450+ 架构不必逐个移植就能跑。契约的价值不在于它描述得多细,而在于它替多少人挡住了改写。

落到日常,有一个很好用的检验:加一个字段,是不是所有调用方都得跟着一起改? 如果是,那不是契约,只是当前实现的一份快照。

边界之外的事交给邻近条目:一次调用本身分成哪几步,去看《工具使用与函数调用》;工具层要怎么建、怎么吸收混乱,去看技能《工具集成模式》;而「边界应该画在哪一层」本身是一次取舍,去看《系统设计的权衡》。

关系网络

在关系网络中的位置

这个概念相邻的技术信号与相关技能,点击节点可继续探索。

可解释

这个概念能解释的技术信号

搭配技能

使用这个概念的技能