AI Agent 工程师课程
程序员基础版

第 2 周 · 原生模型 API 与 Model Gateway

不用任何框架,手写统一 Model Gateway,掌握多 Provider、流式取消与成本追踪

本周产出packages/model-gateway,支持至少两个 Provider · 预计投入:15 到 20 小时 · 对应原 24 周编号:第 2 周

学前自测

1. 流式响应和普通响应,在错误处理上有什么本质区别?

普通响应的错误在一次 await 里抛出,捕获点唯一。流式响应已经吐出了一半内容才失败,这时你面对的是部分结果加一个错误,必须决定是丢弃、保留还是标记不完整。绝大多数人第一版实现都会漏掉流中断的处理。

2. 什么是 Circuit Breaker?和 Retry 的区别是什么?

Retry 是单次请求失败后重试,解决瞬时抖动。Circuit Breaker 是在连续失败达到阈值后直接短路,不再发请求,解决下游已经挂了还在疯狂重试打爆自己的问题。两者是互补的,只有 Retry 没有 Breaker 的系统在 Provider 故障时会自我雪崩。

3. 为什么要在请求前做 capability 预检,而不是让它运行时失败?

因为运行时的静默降级最难排查。你请求一个不支持 tool calling 的模型去调工具,如果 Gateway 悄悄降级成纯文本生成,Agent 会拿到一段看起来正常的文字然后走进错误分支,几十步之后才暴露问题,且没有任何日志指向真实原因。预检的价值是把失败提前到唯一能定位的地方。

4. Token 和字符是什么关系?为什么成本要按 Token 算而不是按请求算?

Token 是模型处理文本的最小单位,中文大致一个字一到两个 Token,英文大致一个词零点七五个 Token。按 Token 计费是因为模型的计算量正比于 Token 数量。这直接影响架构决策:同样一次 Agent Run,上下文管理做得差可能贵十倍。

学习目标

不使用 LangChain 或 Mastra,实现统一 Model Gateway。

这一周的核心不是学会调 API,而是建立一层能挡住 Provider 差异的抽象。等到第 7 周引入 Mastra 时,你会发现自己已经理解了框架在这一层帮你做了什么,以及它没做什么。这是判断框架该不该用的唯一可靠方式。

课程内容

  1. Messages 与 Instructions
  2. Text Generation
  3. Streaming
  4. Structured Output
  5. Tool Calling
  6. 多模态输入
  7. Usage 与 Token
  8. 模型成本计算
  9. Timeout、Retry、Backoff
  10. Rate Limit
  11. Circuit Breaker
  12. Provider Adapter
  13. Model Fallback
  14. Request Trace
  15. Capability Discovery(tools / vision / structured output / reasoning)
  16. Finish Reason 与错误语义归一化
  17. 首 Token 延迟、生成吞吐与端到端 SLO
  18. Provider Contract Test 与录制回放

实施任务

实现:

interface ModelGateway {
  capabilities(model: ModelRef): Promise<ModelCapabilities>
  generate(request: GenerateRequest): Promise<GenerateResult>
  stream(request: GenerateRequest): AsyncIterable<ModelEvent>
  generateObject<T>(request: StructuredRequest<T>): Promise<T>
  generateWithTools(request: ToolRequest): Promise<ToolResult>
}

支持至少两个 Provider。

用同一输入集对两个 Provider 做配对测试,记录成功率、Schema 合规率、首 Token 延迟、总延迟、Token 与成本。禁止把 Provider 原始对象泄漏到业务层。

动手挑战

做一次真实的取消实验,测量你到底浪费了多少钱。

步骤:发起一个会生成 2000 Token 的流式请求,在收到第 50 个 Token 时调用 abort。然后回答三个问题:

  1. 你的 Gateway 有没有真的中断上游 HTTP 连接,还是只是停止了消费?
  2. Provider 的账单里这次请求算了多少 Token?
  3. 你的成本追踪记录的是 50 还是 2000?

大多数人第一版实现三个答案都是错的。修到三个都对,你就真正理解了取消传播。

Agent OS 里程碑

完成 packages/model-gateway

验收标准

核心档(程序员基础版毕业线)

  • 可配置切换两个模型 Provider
  • 输出通过 Zod 校验
  • 支持取消流式请求
  • 记录 Token、延迟、成本、错误
  • 模型失败可重试或降级
  • 不支持的 capability 在请求前失败,而不是运行中静默降级

进阶档验收见程序员进阶版附录 B。

学后自测

1. 你的配对测试里,两个 Provider 的 Schema 合规率差多少?差距来自哪里?

这个数字要能报出来。差距通常来自结构化输出的实现方式不同:有的 Provider 用约束解码保证 JSON 合法,有的只是在 Prompt 里要求。知道这个差异,才能在选型时判断哪些场景必须锁定某个 Provider。

2. 模型返回 finish_reason 为 length 时,你的系统怎么处理?

这代表输出被 max_tokens 截断了,内容是不完整的。绝对不能当作正常结果返回给业务层,否则会得到半截 JSON 或者半句话。正确做法是归一化成一个明确的截断错误,让调用方决定是重试加大预算还是走降级路径。

3. 业务代码里有没有出现过 Provider SDK 的类型?怎么验证?

用 ESLint 的 no-restricted-imports 规则在 CI 里强制,比人工 review 可靠。这条规则从第 2 周加上,一直守到第 7 周引入 Mastra,那时候它会救你。

本周作业

  1. packages/model-gateway/:完整实现,含单元测试与集成测试
  2. docs/model-gateway.md:设计文档,说明 Provider 抽象边界、错误分类表、降级策略
  3. docs/provider-comparison.md:两个 Provider 的配对测试报告,六个指标的实测数据加你的选型结论

配对测试报告是这周最值钱的作品集素材,因为它证明你做过量化选型,而不是跟风。

面试考点

这一周对应面试里的工程稳定性考察,是后端出身候选人最容易拿分的地方。

  • 「模型 API 超时了你怎么办?」:不要只答重试。完整答法是分层:超时归一化 → 判断是否可重试(幂等性)→ 指数退避 → 熔断 → 降级到备用模型 → 最终失败时的用户可见错误。能把这条链路说完整,直接拉开和其他候选人的差距。
  • 「你怎么控制 AI 功能的成本?」:这一周的答案是可观测(Token、延迟、成本全记录),后面第 5 周会补上下文预算,第 9 周补 Policy 层预算。面试时按这三层答。
  • 「为什么不直接用 LangChain 的 LLM 抽象?」:答你需要 capability 预检和错误语义归一化,而通用抽象为了兼容所有 Provider 会把这两件事削平。注意态度要中立,不要显得为了造轮子而造轮子,重点讲你的具体需求。
  • 手写题:现场实现一个带超时和取消的流式包装函数。这道题高频,建议提前手写熟练。

复习与延伸

官方文档

本仓库对应源码

  • packages/contracts/src/model.ts 是框架无关的模型请求类型定义,你的 Gateway 应该实现这套契约而不是自己另起一套

下一步第 3 周 · Tool Runtime、Sandbox 与 Permission

On this page