跳到主要内容

为什么我更喜欢把 AI 能力做成可组合服务:先拆 contract、适配器,再谈 Agent

· 阅读需 4 分钟
一介布衣
全栈开发者

我现在越来越少把一整段 AI 逻辑塞进一个“很聪明的 Agent”里。不是因为 Agent 没价值,而是只要功能开始进入多人协作、线上排查和持续演进阶段,把能力拆成可组合服务,几乎总会比单一大黑盒更容易维护。

我最在意的不是“它看起来够不够智能”,而是这些能力以后能不能被:

  • 单独测试
  • 替换实现
  • 组合进别的流程
  • 在事故后重放

如果这些事情做不到,系统一复杂,后面的排查和演进都会变得很费劲。

先定义 service contract,而不是先写 Prompt

我现在做 AI 服务时,更喜欢先把 contract 写出来。最小的一层大概像这样:

type RewriteServiceRequest = {
requestId: string;
scene: 'title' | 'summary' | 'review';
input: string;
policyProfile: string;
promptVersion: string;
};

type RewriteServiceResponse = {
output: string;
decision: 'accept' | 'review' | 'reject';
traceId: string;
replayId: string;
};

只要这层先清楚,后面你用哪个模型、接哪套工具、是不是要换供应商,都不会立刻影响调用方。

工具适配器应该和业务编排分开

我见过一种很常见的写法:业务服务里直接拼 API 调用、错误处理、重试和业务判断。短期看很快,长期看特别容易缠住。

我更喜欢把工具适配器单独拎出来:

  • 适配器只负责对接外部世界
  • 服务 contract 只负责定义能力边界
  • 编排层只负责决定这些能力怎么组合

这样做以后,替换实现会舒服很多。比如你今天用一种 OCR,明天换另一家 OCR,调用方并不需要跟着改整个流程。

“可组合”真正值钱的地方,在于可以拆着复用

一旦能力是服务化的,你会很自然地开始做这些事情:

  • 标题生成单独复用
  • 摘要生成单独复用
  • 审核建议单独复用
  • 内容改写和审核编排成更长流程

反过来,如果所有能力都塞在一个超大 Agent prompt 里,表面上看也能完成任务,但你很难稳定回答:

  • 哪一步出了问题
  • 哪一步可以替换
  • 哪一步值得单独评测

回放接口最好跟服务一起生长

我现在很少把回放当成“后面再补”的东西。因为只要服务接口一稳定,回放需求很快就会出现:

  • 这个结果当时为什么这样输出
  • 同样输入今天还能不能复现
  • 这次事故是模型问题还是工具快照变了

所以我更愿意让服务从一开始就带着 replayId 这类句柄一起设计。这样后面做评测、复盘和抽检时,至少不是从日志堆里手工拼现场。

什么时候不必过度服务化

当然,我也不觉得所有能力都值得立刻拆成服务。如果只是一个特别短、没有复用需求的小功能,直接放在本地流程里也没问题。

但只要它满足下面任意两条,我就会很想把它抽出来:

  • 多个场景会用到
  • 不同团队会碰它
  • 后面可能换模型或换工具
  • 需要单独评测或回放

这时继续把它藏在一个大黑盒里,通常只是把未来问题往后拖。

我对可组合服务的判断

可组合服务的核心收益,不是抽象更优雅,而是每层都更容易测试、替换和复盘。真正该先拆的,不是“AI”这两个字,而是 contract、适配器和回放边界。

等这些基础清楚以后,再去谈 Agent 编排,系统会稳很多;反过来,如果边界一直糊着,再聪明的黑盒也很容易在规模一上来之后变成难以解释、难以维护的负担。