6 min read教程

M04. 模型:统一接口如何容纳不同供应商

理解模型适配器如何统一消息、流式事件、thinking、缓存与错误差异。

M04. 模型:统一接口如何容纳不同供应商#

Agent Loop 看起来只需要一个 stream(),现实却不是这样。不同模型供应商在消息角色、工具参数、SSE 事件、thinking、缓存和错误码上都有自己的方言。Pi 的模型层把这些差异集中在适配器,而不是散落在 Loop 和工具代码里。

1. 统一的对象与不统一的现实#

上层希望看到的是:一个模型对象、一份上下文和一条事件流。适配器负责把这三个对象翻译成具体供应商能接受的请求,再把响应翻译回来。

ts
const model = getModel(provider, modelId);
const context = {
  systemPrompt,
  messages,
};

for await (const event of stream(model, context)) {
  // text_delta、thinking_delta、tool_call 等统一事件
}

这层抽象并不意味着模型能力完全相同。统一接口只保证上层有稳定的最低公约数;供应商特性可以通过 model 配置、兼容字段或适配器内部处理。

2. 流式响应为什么要有事件协议#

如果 stream() 只返回最终字符串,UI 无法实时显示,工具调用也只能等完整响应结束后才开始处理。事件流把一次响应拆成生命周期:开始、文本增量、thinking 增量、工具调用增量、完成或错误。

text
message_start
  → text_delta × N
  → tool_call / tool_call_delta
  → message_end

事件协议的价值在于,上层可以做不同投影:终端显示文本,日志记录工具状态,评估器统计 token,Loop 只关注完整消息和 stop reason。

3. thinking 是模型方言的集中体现#

有的接口用 effort,有的用 budget,有的用枚举,有的根本不暴露 thinking。Pi 在上层提供 thinking level,再由适配器转换成具体供应商参数。切换模型时,上层代码不必知道每家 API 的字段名。

但“统一 thinking level”是有损的:不同模型在同一级别下的实际预算和行为并不相同。产品应该把它当作用户体验上的刻度,而不是跨模型的精确物理单位。

4. 上下文交接为什么需要专门处理#

会话中途切换模型时,历史消息通常还能复用,但 thinking 签名、缓存 blob 或模型特有字段未必能原样传递。pi-ai 的上下文交接逻辑负责尽可能保留语义,并在不能保留时做降级。

因此,“切模型”不是简单把 model 变量换掉。测试切换时,至少检查:普通文本、工具调用、工具结果、thinking 内容和缓存字段是否仍能被目标适配器接受。

5. 错误也应该进入统一协议#

网络失败、限流、无效模型、响应解析失败和供应商返回业务错误,最好在模型层被转成结构化错误事件。这样 Loop 才能根据错误类型决定重试、终止或让用户处理,而不是在每个 provider 分支里复制一套异常判断。

重试也要有边界:指数退避、最大等待时间和可取消信号应由运行时提供;模型适配器不应偷偷无限重发一个带副作用的请求。

6. 接入新模型的检查顺序#

  1. 确认供应商是 Anthropic messages、OpenAI completions、OpenAI responses 还是自定义协议。
  2. 确认消息、工具参数和流式事件的映射。
  3. 确认上下文窗口、最大输出、thinking 和缓存能力。
  4. 用纯文本、工具调用、工具错误和取消四组样例测试。
  5. 再把模型接到 Agent Loop,而不是反过来用 Loop 排查协议错误。

7. 读源码的关键问题#

  • 翻译发生在调用前还是事件产生后?
  • 统一类型丢掉了哪些供应商信息?
  • 错误是同步抛出、事件返回,还是封装成 assistant/tool result?
  • token 和费用统计使用供应商原始值还是本地估算?

这些问题比记住某个 API endpoint 更能帮助你判断模型层是否保持了良好边界。

8. 适配层的边界判据#

适配器的职责是把协议差异翻译掉,而不是把供应商行为伪装成完全相同。凡是会改变上层控制流的差异——例如工具调用是否完整、错误是否可重试、thinking 是否可恢复——都必须显式暴露给运行时。所谓“兼容接口”只能说明请求形状相近,不能证明语义、限流和上下文能力相同。

资料

本文依据 Pi 官方仓库SDK 文档pi-ai 的官方实现重新创作。

相关文章