调用大模型 API 的第一步通常不难:准备密钥,发送请求,拿到一段回答。
真正进入项目后,问题会逐渐变成:为什么换一个模型就报参数错误?为什么 Chat 能返回,图片却一直等待?为什么网络超时后再试一次,账单里出现了两次消费?
这些问题横跨协议、任务状态、网络和费用。本文先梳理接入结构,后续文章再用可以独立运行的 Python 示例逐步展开。
> 系列示例使用 Python 3.10+ 和标准库。Tuzi 作为示例网关,具体路径和模型权限以账户对应文档为准;文中的适配方法也可用于其他供应商。
一、先区分四种工作方式

"支持某个模型"和"支持所有调用方式"是两回事。一个网关列出了模型 ID,并不能说明这个模型支持 JSON 模式、图片输入或者流式工具调用。
适配时应该同时确认两个问题:模型能做什么,以及应该按什么协议调用。
二、把变化集中到适配层
一个足够简单的结构是:
bash
业务代码
|
v
业务请求:回答问题 / 生成图片 / 查询任务
|
v
供应商适配层
|-- 认证与请求构造
|-- 协议与响应解析
|-- 超时与错误分类
|-- 流式事件与任务状态
|-- 用量与请求 ID
|
v
具体网关和模型
业务层不应该到处出现 `response"choices"0`、供应商状态名或者临时图片下载地址。适配层先理解原始响应,再把业务需要的结果交出去。
例如,两个网关分别返回 `completed` 和 `succeeded`,业务层可以统一理解为成功;但原始状态仍应作为受控诊断信息保留,方便排查映射问题。
三、适配不意味着把所有参数强行统一
假设模型 A 支持图片输入,模型 B 只支持文本。如果为了统一接口,把所有参数都原样透传给两个模型,本地代码虽然简洁,远端错误却会增多。
更实际的方式是建立一个小型能力表:
javascript
{
"model_id": "YOUR_MODEL_ID",
"protocol": "chat",
"input_modalities": ["text"],
"output_modalities": ["text"],
"supports_stream": false,
"supports_json_mode": false
}
这里的值是示例,不是任何真实模型的能力声明。真实值要从文档和联调结果中确定。
暂时不支持的能力应明确拒绝;还没有实现的协议也应显式标记。否则,调用方会把"参数可以传进去"误认为"功能可以正常运行"。
四、第一次接入按这个顺序进行

-
确认 Base URL、认证方式、模型 ID 和目标接口。
-
使用 dry-run 查看最终 URL 和请求 JSON。
-
先发送一个非流式、短输出的请求。
-
校验 HTTP 状态、响应外壳和业务字段。
-
再加入 SSE、图片或异步任务。
-
用离线 fixture 和 Mock 固定已经确认的协议形状。
dry-run 的价值是发现本地错误,例如 `/v1/v1/chat/completions`。它不验证真实权限、额度,也不能代替联调。
五、什么时候值得增加抽象
只有一个文本模型、一个调用入口时,先保留清晰的小函数就够了。出现以下情况后,再增加相应能力:
|-------------------|-------------------|
| 出现的问题 | 值得增加的能力 |
| 切换供应商总要改业务代码 | 供应商适配器 |
| 相同错误在多个入口重复处理 | 统一错误对象 |
| 任务完成时间超过 Web 请求预算 | 后台任务与状态持久化 |
| 多个模型支持的参数不同 | 能力注册表 |
| 修改代码后不敢请求真实 API | fixture 与 Mock 测试 |
每增加一层抽象,也会增加配置、测试和排障成本。不要为了覆盖未来可能出现的所有接口,提前构建一个没有真实使用场景的框架。
六、系列阅读顺序
|----|--------------|------------------|
| 篇次 | 主题 | 可以得到什么 |
| 一 | 接入路线与适配层 | 协议分类和工程边界 |
| 二 | 第一次请求 | 可 dry-run 的标准库脚本 |
| 三 | Chat 参数与 SSE | 可离线执行的事件解析例子 |
| 四 | 多模态与图片生成 | 完整生图请求、解码示例和实际成图 |
| 五 | 异步任务 | 退避轮询、终态与验签例子 |
| 六 | 生产实践 | 脱敏日志、费用与重试边界 |
| 七 | Mock 测试 | 不访问真实网关的测试文件 |
后续示例均会区分"本地可以验证的行为"和"需要供应商契约确认的行为"。单测通过,说明代码在预设条件下工作,并不能证明真实网关支持文章中所有可选参数。
参考资料
Tuzi API 文档总览(https://tuzi-api.apifox.cn/)
Chat 接口示例(https://tuzi-api.apifox.cn/343647063e0)
图像生成接口示例(https://tuzi-api.apifox.cn/448333922e0)