W1D4 学习手册 1.为何统一2.统一请求3.Provider4.路由5.超时重试6.Fallback7.Token成本8.Trace 9.流式10.架构图11.LiteLLM12.医保实战13.达标①14.达标② 15.自测16.速记

FDE W1D4 学习手册 · 多模型统一接入

W1 Day4 · A 级(必须掌握,面试核心)· 4h · 学完能画出统一接入层架构,并讲清超时/重试/Fallback/Trace/成本记录的全链路设计

本日定位:Day3 讲"选哪个模型",Day4 讲"怎么把多个模型接进来还能稳、能观测、能降级"。这是 FDE 工程能力的体现——生产环境绝不能直接裸调各家 API,必须有一层统一接入。
学完能回答:① 统一接入层的完整架构(请求→路由→provider→统一响应→Trace);② Provider Adapter 怎么写;③ 超时/重试/Fallback 怎么设计;④ Token 成本与 Trace ID 怎么记录和串联。
使用方法:先看 s10 架构图建立整体认知 → 重点背 s13/s14 两个达标线 → 配合《FDE-W1D4-评测题.md》自测。选中不熟的词可标注(左下★重要 / 右下📌待查)。

一、为什么需要统一接入层

裸调各家 API 的痛点:每个厂商的请求格式、鉴权、响应结构、错误码、流式格式都不同。业务代码若直接耦合 Qwen/DeepSeek/Claude/Ollama,会带来:

统一接入层(Unified Model Gateway)把这些横切关注点收口到一层,业务只面对"一个统一接口"。

📚 延伸资源:通义千问 API(阿里云百炼)DeepSeek API 文档Claude API 文档LiteLLM 文档
统一接入层解决"厂商差异 + 容错 + 观测 + 复用"四大问题。核心价值:业务只调一个接口,背后可任意换模型、可降级、可统计成本、可追踪。没有这层,生产就是裸奔。
① 别在业务代码里直接写死某个厂商的 SDK 调用,这是最常见的架构债。② 统一层不是"再包一层 HTTP",它要承载路由、容错、观测、计费等横切能力,否则只是换个地方耦合。

二、统一请求结构(Model Adapter)

2.1 原理

定义一个与厂商无关的内部请求/响应结构,所有业务都用它。Adapter 负责把它翻译成具体厂商格式,再把厂商响应翻译回统一结构。

业务调用 → UnifiedRequest → [Adapter] → 厂商特定请求 → 厂商响应 → [Adapter] → UnifiedResponse → 业务

2.2 统一请求字段(建议)

字段含义
model / model_key逻辑模型名(如 "qwen_max"),不直接暴露厂商 ID
messages标准化对话消息(role/content)
paramstemperature / top_p / max_tokens 等
response_formatjson / text,统一抽象
stream是否流式
trace_id / user_id贯穿全链路的追踪与计费维度
timeout_ms本次调用超时

2.3 统一响应结构

{
  "content": "模型文本输出",
  "finish_reason": "stop",
  "usage": { "prompt_tokens": 120, "completion_tokens": 30, "total_tokens": 150 },
  "model": "qwen-max",         // 实际命中的底层模型
  "provider": "qwen",
  "trace_id": "tr-abc-123",
  "latency_ms": 820
}
统一结构让"换模型"变成"改配置"而非"改代码"。逻辑模型名(qwen_max)与物理模型(qwen-plus / 具体版本)解耦,便于灰度、A/B、成本切换。所有横切逻辑(超时、重试、计费)只在 Adapter 内写一次。
Model Adapter = 一个与厂商无关的统一请求/响应结构 + 每个厂商一个翻译器。业务只认统一接口,换模型改配置即可。关键字段:逻辑 model_key、messages、usage、trace_id、latency_ms。

三、Provider Adapter(Qwen / DeepSeek / Claude / Ollama)

每个厂商一个 Adapter,实现统一接口 chat(req) → UnifiedResponse。差异点:

厂商鉴权消息格式流式结构化
Qwen(通义)API-Key BearerOpenAI 兼容 messagesSSEresponse_format json_object
DeepSeekAPI-Key BearerOpenAI 兼容 messagesSSEresponse_format json_object
Claude(Anthropic)x-api-key Headersystem + messages(不同)SSE(events)tool_use / 预填充
Ollama(本地)无/本地OpenAI 兼容SSEformat: json schema

3.1 关键差异处理

把"OpenAI 兼容"的厂商(Qwen/DeepSeek/Ollama)归为一类基类 Adapter,Claude 单独一类。这样新增一个兼容厂商只需配 base_url+key,开发成本极低。Adapter 还要做错误码归一化(各家 429/5xx 映射成统一错误类型)。
Provider Adapter 每个厂商一个,实现统一 chat 接口。重点处理差异:Claude 的 system 是顶层字段、错误码不同、工具调用格式不同;Qwen/DeepSeek/Ollama 多为 OpenAI 兼容可共用基类。Adapter 还要归一化错误码和 usage 字段。
① 不要假设所有厂商都 OpenAI 兼容——Claude 的 system 位置、流式事件、限流码都不同,漏适配会出诡异 bug。② usage 字段名各家不同(prompt_tokens vs input_tokens),统一层必须归一,否则成本统计错。③ 本地 Ollama 没有真实鉴权,但要有内部限流,防止压垮单机。

四、模型路由(Routing)

4.1 原理

路由决定"这次请求走哪个逻辑模型"。可按多维度决策:

请求(metadata) → 路由策略(规则/分类/健康度/灰度) → 选定 model_key → 查 Provider → 调用
路由是"成本与能力调度中枢"。生产常用"小模型打底 + 大模型兜底 + 按健康度自动切换"。路由策略应可配置化,结合 Day3 的选型结论——把选型决策沉淀为路由规则。
模型路由决定请求走哪个模型:静态配置、按能力级联(简单→小模型)、按健康度切换、按 user_id 灰度 A/B、按语义分类。它是成本与能力的调度中枢,应配置化。

五、超时与重试

5.1 超时设计

5.2 重试策略

超时是第一道熔断。重试必须用指数退避+抖动,否则大量并发同时重试会形成"重试风暴"把厂商打挂(也把自己打挂)。区分可重试错误(429/5xx 临时)与不可重试(400 参数错、鉴权错)。
超时:连接超时(短)+读取超时(长)+整体预算。重试:指数退避+抖动、限次(2~3)、只重试幂等/可重试错误(429/5xx),超次就 Fallback。盲目重试会风暴,必须退避。
① 重试一定要加退避和上限,否则"重试风暴"会雪崩。② 对 400/401(参数/鉴权错)重试无意义,要直接报错。③ 流式请求中断的重试要能"续传"或整体重发,否则用户看到半截答案。

六、Fallback(降级)策略

6.1 原理

当主模型失败(超时/限流/5xx/内容违规)且重试耗尽,自动切换到备用模型/方案,保证业务不中断。

6.2 Fallback 层级

  1. 同厂商换模型:qwen-max 挂 → qwen-plus。
  2. 换厂商:qwen 挂 → deepseek / claude(需语义等价,注意风格差异)。
  3. 换小模型/规则:复杂模型都挂 → 退简单模型或规则兜底。
  4. 缓存/默认/转人工:都不可用 → 返回缓存答案、兜底文案或转人工。

6.3 Fallback 设计要点

Fallback 是"可用性兜底"的核心。生产必须有至少两级 Fallback(换模型→换厂商→兜底)。配合熔断器:某 provider 连续失败就临时摘除,避免每次请求都先踩坑再降级。降级链路也要有超时,否则"备用也慢"会拖死整体。
Fallback:主模型挂且重试尽 → 自动切备用(同厂商换模型→换厂商→小模型/规则→缓存/转人工)。要点:备选要任务等价、要有超时防连环、要熔断(连续失败临时摘除)、要记录是否降级。
① Fallback 不是随便换模型——语义要等价,否则降级后答非所问比报错更糟(尤其保险理赔,错答比拒答危险)。② 忘记给 Fallback 设超时,会"主慢+备慢"双倍拖时。③ 没有熔断,每次请求都先打挂掉的 provider 再降级,延迟和成本都亏。

七、Token 统计与成本记录

7.1 为什么记

7.2 记录维度

策略适用错误注意
指数退避 + 抖动429 限流、5xx 临时错误避免重试风暴打爆厂商
限次(如 2~3 次)所有可重试错误超过即 Fallback/降级
仅重试幂等调用纯生成(无副作用)有副作用的不能盲目重试
维度说明
model / provider哪个模型产生的费用
prompt / completion tokens拆分输入与输出(单价不同)
单价(配置)每千 token 价格,换算成本
user_id / tenant_id按用户/租户分摊
trace_id与一次请求全链路关联
is_fallback / retry_count降级/重试额外花费
成本记录要进统一日志/数仓,按 tenant 计费是 SaaS 标配。重要:重试和 Fallback 会额外烧 token,成本统计必须含 retry_count 和 is_fallback,否则账单对不上、也发现不了"某路径疯狂重试"。
Token 统计要拆分 prompt/completion、绑定 model/provider/user/tenant/trace_id,再乘单价算成本。关键:重试和 Fallback 会额外烧 token,成本记录必须包含 retry_count 和 is_fallback,否则账单失真。
① 各家 usage 字段名不同,统一层要归一,否则成本统计错。② 只记成功调用会漏掉"重试失败也花了 token"的成本。③ 不按 tenant 分摊,就无法做内部结算和异常定位。

八、Trace ID 与全链路追踪

8.1 原理

每个请求生成唯一 trace_id,在网关、路由、各 provider 调用、重试、Fallback、业务处理间全程透传。所有日志/指标都打上它,可回放一次请求的完整链路。

入口生成 trace_id → 注入每次 model 调用 → 记录 model/provider/latency/tokens/is_fallback/error → 统一收集 → 按 trace_id 串联排查

8.2 要记录的字段

Trace 是"线上出问题能查"的命脉。没有 trace_id,一次用户投诉你无法定位是路由错误、某 provider 超时还是 prompt 问题。建议接入 OpenTelemetry,把模型调用当作一个 span,和业务 span 串成一张图。
Trace ID 贯穿一次请求的所有模型调用与重试/Fallback。记录:model/provider/latency/usage/retry_count/is_fallback/error。作用是线上排查、成本归因、复现问题。建议用 OpenTelemetry 把模型调用做成 span。
① trace_id 必须在重试和 Fallback 时"透传不变",否则一次请求被拆成多条无法关联。② 记录输入/输出要脱敏(医保含个人信息),不能直接落明文日志。③ 只记成功不记失败/降级,排查时看不到"为什么走了兜底"。

九、流式输出(Streaming)

9.1 原理

流式让模型"边生成边返回",首字延迟(TTFT)大幅降低,用户体验更好。底层多为 SSE(Server-Sent Events)增量 chunk。

9.2 统一层要做的事

流式是用户体验关键,但增加了统一层复杂度:要归一 chunk、处理取消、算 TTFT。保险客服场景用流式能显著降低"等待焦虑"。注意:流式中途失败的重试要能优雅降级(提示重新生成而非卡死)。
流式=边生成边返回,降首字延迟(TTFT)。统一层要归一各厂商 chunk 格式、统计 TTFT/TPOT、支持取消、谨慎处理流式中断重试。医保客服用流式降低等待焦虑。

十、统一接入层架构图(达标线核心)

业务服务 │ UnifiedRequest(trace_id, model_key, messages, params...) ▼ [统一接入网关 Gateway] ├─ 路由 Routing(规则/健康度/灰度)→ 选定 model_key ├─ 超时控制 Timeout(连接/读取/预算) ├─ 重试 Retry(指数退避+限次,仅可重试错误) ├─ Fallback(换模型→换厂商→兜底,带熔断) ├─ 流式归一 Streaming(chunk 归一、TTFT) ▼ [Provider Adapter 层] ├─ QwenAdapter ├─ DeepSeekAdapter ├─ ClaudeAdapter ├─ OllamaAdapter(本地) ▼ 厂商特定请求/响应 [各厂商 API / 本地模型] ▲ └─ 统一响应 UnifiedResponse(content, usage, provider, trace_id, latency_ms) └─ 横切:Token成本记录 + Trace 全链路 + 监控告警
架构一句话:业务发统一请求(带 trace_id)→ 网关做路由/超时/重试/Fallback/流式归一 → Adapter 翻译到具体厂商 → 厂商响应翻译回统一结构 → 全程记 Token 成本与 Trace。这就是面试要能徒手画的那张图。

十一、LiteLLM 等开源方案

不必从零造轮子,社区已有成熟统一接入层:

方案定位特点
LiteLLM统一调用 100+ 模型的 Python 库 + 网关OpenAI 兼容格式,内置负载均衡、重试、Fallback、成本追踪、虚拟 key
One API / 快问国内多模型统一网关多租户、额度、转发
自研 Gateway深度定制完全可控,但要自己实现容错/观测
🔗 LiteLLM 文档:支持统一接口调 Qwen/DeepSeek/Claude/Ollama,内置 fallbacks、timeout、retry、cost tracking,可直接当生产网关用。
生产可基于 LiteLLM 起步,它已覆盖路由、重试、Fallback、成本、虚拟 key。但 FDE 要懂其原理——因为面试问的是"你怎么设计",而非"你用哪个库"。懂原理才能在做定制(如医保合规脱敏、私有 Trace)时改得动。
统一接入层不用从零写,LiteLLM 已覆盖 100+ 模型、内置 retry/Fallback/成本/路由。但面试要讲清"原理"而不只是"用库"——懂原理才能在合规脱敏、私有 Trace 等定制时改得动。
① 用 LiteLLM 不等于"架构设计完成",它只是工具;路由策略、熔断阈值、成本维度仍是你要设计的。② 默认配置未必满足医保合规(日志脱敏、数据不出域),要定制。③ 别把 API Key 硬编码进网关代码,用密钥管理。

十二、医疗保险实战:多模型冗余接入

医保理赔系统对可用性合规都极敏感。设计统一接入层:

用户提交 → 网关(脱敏+路由) → 本地模型抽取(主) ↘ 超时/失败 → 地端大模型(脱敏,备) ↘ 仍失败 → 规则兜底/转人工 (全程 Trace + 成本记录)
医保实战:主用本地模型保隐私,备用地端大模型(脱敏)攻复杂,再不行规则/转人工。Adapter 出域前做 PII 脱敏,Trace 不落明文。成本按机构/单号分摊。可用性靠 Fallback 链,合规靠脱敏+本地优先。

十三、面试达标线①:画出统一接入架构

面试官:"画一下你们的多模型统一接入层。"标准回答要包含 5 段:业务 → 网关(路由/超时/重试/Fallback/流式)→ Provider Adapter → 厂商 → 横切(成本+Trace)。

  1. 业务侧:只发统一请求(带 trace_id、model_key)。
  2. 网关:路由选模型 → 超时控制 → 重试(退避限次)→ Fallback(熔断)→ 流式归一。
  3. Adapter 层:每个厂商一个,翻译请求/响应、归一错误码与 usage。
  4. 厂商/本地:Qwen/DeepSeek/Claude/Ollama。
  5. 横切:Token 成本记录 + Trace 全链路 + 监控告警。
达标线①满分:能徒手画出"业务→网关(路由/超时/重试/Fallback/流式)→Adapter→厂商→横切(成本+Trace)"五段架构,并说出每段职责。漏掉横切(成本/Trace)或 Fallback 就是不及格。

十四、面试达标线②:Fallback + 成本/Trace 记录

14.1 Fallback 怎么设计

14.2 成本与 Trace 怎么记录

项目记录内容用途
成本model/provider、prompt/completion tokens、单价、tenant、retry_count、is_fallback分摊、异常、预算
Tracetrace_id 透传、每次调用的 model/latency/usage/error/降级排查、归因、复现
达标线②满分:Fallback 能说出层级+等价+超时+熔断+记录;成本记录含 prompt/completion 拆分、tenant、retry_count、is_fallback;Trace 靠 trace_id 透传贯穿所有调用与重试/Fallback,记录 model/latency/usage/error 用于排查与归因。
面试官常追问"重试和 Fallback 会不会让成本失控"——答:会,所以成本记录必须含 retry_count 和 is_fallback,并设重试上限与熔断,监控告警 token 异常暴涨。

十五、Day 4 自测清单

十六、高频面试题速记卡

Q:为什么需要统一接入层?
解决厂商锁定、无容错、不可观测、重复造轮子。业务只调一个接口,背后可换模型、可降级、可统计成本、可追踪。
Q:Model Adapter 做什么?
定义与厂商无关的统一请求/响应结构,每个厂商一个翻译器把统一结构↔厂商格式互转,并归一错误码和 usage。
Q:Claude 适配要注意什么?
system 是顶层字段不是 messages 里的 role;流式事件、限流码(429/529)、tool_use 格式都不同,需单独适配。
Q:重试三要素是什么?
指数退避+抖动(防风暴)、限次(2~3)、仅重试可重试错误(429/5xx),超次即 Fallback。400/401 不重试。
Q:Fallback 层级怎么排?
换模型(同厂商)→换厂商→小模型/规则→缓存/转人工。备选要任务等价、要有超时防连环、要熔断。
Q:成本记录为什么含 retry_count 和 is_fallback?
重试和降级会额外烧 token,不含这两个字段账单失真、也发现不了"某路径疯狂重试"。
Q:Trace ID 的关键要求?
一次请求内透传不变(含重试/Fallback),记录 model/provider/latency/usage/error/降级,用于排查与成本归因;日志需脱敏。
Q:流式输出统一层做什么?
归一各厂商 chunk 格式、统计 TTFT/TPOT、支持取消、谨慎处理流式中断重试,避免卡死或半截内容。
Q:LiteLLM 能替代自己设计吗?
它能覆盖路由/重试/Fallback/成本/虚拟key,但路由策略、熔断、合规脱敏等仍要你设计,面试考原理不考用库。
Q:医保场景接入层特殊点?
本地模型优先保隐私、出域前 PII 脱敏、Trace 不落明文、成本按机构分摊、Fallback 链保可用性。
FDE W1D4 学习手册 · 多模型统一接入(面试级)· 配合《FDE-W1D4-评测题.md》自测
📌 待查★ 重要