跳到主要内容

01-模型网关与Provider适配

核对日期:2026-05-13。

不稳定项:模型 API、streaming 协议、工具调用格式、usage 字段、错误码、Batch 能力、供应商数据保留政策变化较快;生产接入前必须重新核对官方文档。

1. 学习目标

本专题聚焦 LLMOps 的入口层:如何把模型调用从业务代码中的零散 API 请求,升级为可治理、可审计、可扩展的模型访问层。

学完后你应该能做到:

  • 解释为什么业务系统不应该直连多个模型供应商。
  • 设计内部 AI SDK、LLM Gateway 和 Provider Adapter 的边界。
  • 定义统一请求、统一响应、统一错误和统一 usage 字段。
  • 处理 streaming、工具调用、结构化输出和 provider request id 差异。
  • 识别模型网关自身的单点风险、合规风险和抽象过度风险。

2. 核心机制

推荐调用链:

业务应用
-> 内部 AI SDK
-> LLM Gateway
-> Provider Adapter
-> 模型供应商

每一层的职责不同:

职责不应该做
业务应用传入任务、上下文和业务约束直接拼供应商参数
内部 AI SDK标准化调用体验、携带 trace、处理基础错误内置复杂路由和预算规则
LLM Gateway鉴权、路由、限流、预算、观测、安全策略理解每个业务细节
Provider Adapter映射供应商参数、错误、流式事件和 usage把供应商私有能力暴露到业务层

关键判断:SDK 解决“开发者怎么调用”,Gateway 解决“组织怎么治理”,Adapter 解决“供应商怎么适配”。

3. 统一请求模型

一个生产可用的标准请求至少包含:

字段说明
tenant_id租户或团队,用于预算和隔离
user_id_hash脱敏用户标识,用于审计和限流
feature业务功能,例如 support_draft
task_type分类、摘要、RAG、Agent、代码等
risk_levellow / medium / high
messages标准模型输入
tools可用工具 schema
output_schema结构化输出约束
prompt_versionPrompt 版本
policy_version安全策略版本
trace_id调用链 ID

示例:

{
"tenant_id": "team-rd",
"user_id_hash": "u_8f31",
"feature": "knowledge_qa",
"task_type": "rag_qa",
"risk_level": "medium",
"prompt_version": "kb-qa-v0.3",
"policy_version": "ai-policy-v1",
"trace_id": "trace_20260513_001",
"messages": [],
"tools": [],
"output_schema": "answer-v2"
}

4. 统一响应模型

响应不要只返回文本,至少要返回:

字段说明
output文本或结构化输出
model实际使用模型
provider实际供应商
usagetoken、缓存 token、费用估算
latency_ms总耗时
first_token_ms首 token 延迟
finish_reasonstop、length、tool_calls、error 等
fallback_used是否发生 fallback
provider_request_id上游请求 ID
trace_id内部 trace

这样才能定位:

  • 为什么这次比上次贵。
  • 为什么同一问题今天换了模型。
  • 哪个 provider 出错。
  • 是否发生 fallback 或重试。

5. Provider Adapter 设计

Adapter 需要屏蔽但不能抹平所有差异。

应该统一:

  • 消息格式。
  • streaming event。
  • usage 字段。
  • 错误码分类。
  • request id。
  • 超时和重试策略。
  • 工具调用结构。
  • 结构化输出解析。

应该保留:

  • provider 原始错误摘要。
  • provider 特有能力标记。
  • 模型能力元数据。
  • 区域和数据策略差异。

反模式是把所有 provider 压成最低公分母,导致高级能力无法使用;另一个反模式是完全不抽象,业务代码里到处都是供应商分支。

6. Streaming 适配

不同供应商的 streaming 事件结构可能不同,内部应统一成事件流:

message_start
content_delta
tool_call_delta
usage_delta
message_end
error

生产注意点:

  • streaming 中断时要区分用户取消、网络断开、provider 失败。
  • 已输出给用户的内容不一定能自动回滚。
  • 如果中途发生工具调用,必须保留 tool call id 和参数摘要。
  • 最终 usage 可能只在结束事件中返回,日志要补齐。

7. 错误分类

统一错误类型比保留原始错误码更重要。

类型示例处理
rate_limited429、配额超限退避、排队、切备用
timeout上游超时有条件重试或降级
invalid_request参数不合法不重试,修正代码
auth_failedkey 无效告警,停用 provider
safety_blocked安全策略拦截返回安全提示
schema_failed输出无法解析有限重试或拒答
provider_down服务不可用熔断和 fallback

错误分类要进入 trace 和监控面板,否则线上只会看到一堆混乱的 500。

8. 密钥和权限

模型密钥不应该出现在:

  • 前端。
  • 移动端。
  • 小程序端。
  • 普通业务配置文件。
  • 日志。
  • 评测样例。

推荐方式:

  • Gateway 保存供应商密钥。
  • 业务方使用内部虚拟 key。
  • 虚拟 key 绑定租户、功能、预算、模型白名单。
  • 高风险功能需要额外审批。
  • key 轮换和吊销要有审计。

9. 工程案例

9.1 从直连模型迁移到 Gateway

现状:

  • 客服系统、知识库系统、运营工具各自保存供应商 key。
  • 每个系统都实现一套 retry。
  • 成本只能看总账单。

改造:

  • 所有调用走内部 AI SDK。
  • SDK 自动注入 feature、tenant、trace 和 prompt_version。
  • Gateway 做预算、路由、日志和 provider adapter。

收益:

  • 统一密钥治理。
  • 统一成本报表。
  • 模型升级不需要每个业务改代码。

9.2 Adapter 抽象过薄

表现:

  • 业务代码里出现 if provider === ...
  • 工具调用格式散落在页面或服务里。
  • usage 字段不统一,成本统计缺失。

修正:

  • Adapter 输出统一 response。
  • 保留 provider metadata,但不让业务依赖原始结构。
  • 为每个 provider 建 contract test。

10. 常见反模式

反模式表现风险修正
业务直连供应商每个服务自己调 API密钥和成本失控统一 SDK/Gateway
Gateway 什么都做写入业务规则和复杂 prompt变成巨型服务保持平台职责
抽象最低公分母高级能力都用不上创新受阻标准字段 + 能力声明
不记录 request id上游问题无法追踪排障困难保存 provider request id
streaming 不归一前端适配多个协议体验不稳定统一事件流
错误码不分类全部变 500无法治理建错误分类表

11. 练习

为一个 RAG 问答系统设计内部 AI SDK 请求/响应结构,要求包含:

  • tenant、user、feature、task_type。
  • prompt_version、model、provider。
  • usage、latency、trace。
  • citations 和 schema 校验结果。
  • fallback 和 retry 标记。

再说明:哪些字段进入日志,哪些字段需要脱敏,哪些字段不能记录。

12. 验收题

  1. 内部 AI SDK、LLM Gateway 和 Provider Adapter 的职责边界是什么?
  2. 为什么业务系统不应该保存供应商 key?
  3. Provider Adapter 应该统一哪些差异,保留哪些差异?
  4. streaming 适配为什么比普通请求更容易出问题?
  5. 为什么 provider_request_id 对生产排障很重要?
  6. 抽象过薄和抽象过厚分别会造成什么问题?