跳转到主要内容

Agent 的端口与适配器架构:为什么你的工具 Schema 应该比供应商更长寿

阅读需 2 分钟Tian PanTian Pan

这是一个在每一个发布 Agent 的团队中都会重复发生的迁移故事。你基于某个供应商的 SDK 构建了你的 Agent。工具定义以该供应商预期的 JSON Schema 形式存在。工具结果被格式化为该供应商的消息结构。接着,某些原因迫使你做出改变 —— 竞争对手发布了更好的模型,采购部门为了冗余要求引入第二个供应商,或者一个 MCP 服务器取代了手写的集成 —— 然后你发现迁移的真正工作量:它不仅仅是一个 API 客户端。它是代码库中的每一个工具定义、每一个结果格式化器、每一个重试处理器以及每一个测试固件。

失败的原因并不是你选错了供应商。而是你让别人的序列化格式变成了你的内部架构。针对这个问题,早在二十年前就有了一个答案 —— Alistair Cockburn 的六边形架构,更广为人知的名字是“端口与适配器” —— 而 Agent 系统是它多年来最引人注目的新用例。

工具层才是锁定的真正所在

当工程师担心 LLM 的供应商锁定(Vendor Lock-in)时,他们通常想到的是 Prompt。Prompt 确实会偏向某个模型的惯用表达,但它们只是字符串 —— 重新调整虽然烦人,但隔离成本很低。工具层则本质上不同。一个生产环境的 Agent 可能会暴露几十个工具,而每一个工具至少在四个地方触及供应商特定的格式:

  • Schema 声明 —— 工具的名称、描述和参数如何被序列化到请求中。
  • 调用解析 —— 模型决定调用工具时,如何返回(一个专门的消息角色、一个内容块、或者一个流式增量)。
  • 结果格式化 —— 你在下一轮对话中如何将工具的输出交还给模型。
  • 错误与重试语义 —— 当模型生成了格式错误的参数或工具执行失败时会发生什么。

这些格式确实存在差异,而且不仅仅是表面上的。OpenAI 通过专门的 tool 角色返回工具结果;Anthropic 将它们作为结构化内容块映射到用户消息中。Anthropic 要求系统 Prompt 作为顶级字段,而 OpenAI 则在消息数组中接受它们。Google 的 API 会拒绝带有未类型化数组项的 JSON Schema,而这些在其他地方完全有效,并且没有主流供应商接受顶级的 $ref

这些怪癖比序列化更深入。如果你在启用扩展思考(Extended Thinking)时强制使用工具,Anthropic 会报错。而流式处理(Streaming)比这些都要糟糕:一个供应商发出结构化的多阶段事件,另一个发出生成片段(Completion Chunks),在两者之间转换需要在流的过程中维护状态。

这些差异如果只处理一次并不难。问题在于团队在哪里处理它们。当供应商的格式就是你编写工具的格式时,每一个怪癖都要在每一个工具定义处处理,你在迁移过程中必须修改的地方的数量随工具数量而扩展,而不是随供应商数量而扩展。

端口:你拥有的 Schema

六边形架构的核心举措是将依赖箭头指向内部。应用核心定义了端口(Ports) —— 用领域自身的词汇表达的稳定接口 —— 而混乱的外部世界通过实现这些端口的**适配器(Adapters)**进行连接。核心从不导入适配器;而是适配器导入核心。

应用到 Agent 上,端口就是你的工具契约:一个名称、一个人类和模型均可读的描述、一个参数 Schema、一个结果类型和错误语义 —— 编写一次,采用你版本化并拥有的中立表示。既不是 “OpenAI 函数调用格式”,也不是 “MCP 服务器发布的格式”,即使你的中立格式碰巧看起来与其中之一相似。区别不在于语法,而在于所有权。当你拥有契约时,供应商改变其序列化方式只是一个适配器 Bug。当供应商拥有契约时,同样的改变就是一个波及整个代码库的事件。

基于这个单一契约,薄薄的适配器在两个方向上进行机械转换:

  • 供应商适配器 (Provider Adapter) 将你的工具契约序列化为每个厂商的请求格式,并从每个厂商的响应格式中解析出工具调用决策 —— 包括流式变体。
  • 后端适配器 (Backend Adapter) 将契约的执行侧连接到实际执行工作的任何地方:一个本地函数、一个内部 REST 服务、一个 MCP 服务器、或者一个队列。

这与 LLM 网关(Gateway)的形式相同,网关是购买现成的供应商适配器部分的好方法。但网关只规范了面向模型的一侧。后端一侧 —— “search_orders” 今天是一个 Postgres 查询,下个季度是一个由另一个团队拥有的 MCP 服务器 —— 这是你的领域,没有任何供应商产品会为你定义这些契约。

真正重要的边界不是 Agent 与工具之间

会员专享

余下内容仅对会员开放。

会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。

  • 完整文章,包含未公开存档的部分
  • 可落地的工作框架,附带权衡与决策依据
  • 新文章抢先看,先于公开发布

随时取消 · 一次订阅,畅读全部

参考资料

保持联系,关注我获取更多内容

阅读需 9 分钟

Postel 法则在工具边界是一种负担

宽容的解析器通过强制转换“差一点就对”的工具调用,会误导 AI Agent 认为草率的调用也是可行的,从而在循环中累积错误。带有清晰示例且包含错误的严格验证是一种循环内训练信号 —— 本文将探讨何时应保持严格,以及 Postel 法则在何处依然适用。

insider
ai-agents
阅读需 11 分钟

无法收敛的验证器循环

Worker-critic 代理循环承诺向质量收敛,但很少真正兑现——验证器是一个随机策略,max-iterations 上限是披着质量门外衣的预算门,而能恢复终止性的模式都把满足曲面当作真正的架构问题来处理。

insider
ai-agents
阅读需 10 分钟

聊天机器人、Copilot 还是 Agent:改变你架构决策的分类学

选错 AI 交互范式——聊天机器人、Copilot 还是 Agent——会造成无法靠调整提示词来修复的架构债务。本文深入分析应在写下第一行代码之前就驱动这一决策的信任模型、上下文窗口策略和错误恢复需求。

insider
ai-agents
阅读需 9 分钟

当时钟成为工具:Agent、时区以及那个只在午夜发生的 Bug

LLM 没有内部时钟,因此 Agent 会自信地漂移到过时的时间上——这表现为错过的任务调度、错误的时区计算以及破坏缓存的时间戳。本文将介绍如何将当前时刻作为基础设施来提供。

insider
ai-agents
阅读需 9 分钟

填充式工具调用:当智能体在表演勤奋而不是真正干活

生产环境中的智能体不断发出对答案毫无影响的工具调用——烧掉 token、拖慢延迟、损害准确率。本文讲清楚填充式调用是如何从训练中长出来的、它真正的成本是多少,以及如何用反事实测量和调用预算把它从工作流里剔除出去。

insider
ai-agents