接入前检查

把项目里的 LLM 调用搜一遍。如果到处都是 openai.chat.completions.create,model 名写死在页面和队列里,先别接更多供应商。越接越乱。

负责什么不该做什么
UI收集用户输入直接保存 provider key
Service定义任务类型写死模型价格
Router选择 provider 和 model处理业务文案
Provider发请求和解析响应判断用户套餐
Logger记录 token、延迟、错误默认存完整隐私内容

我一般会从三个变量开始抽:base_urlapi_keymodel。但只抽这三个还不够,生产里还要把 request id 和成本日志放进去。

怎么搭路由层

先定义内部模型别名,让业务侧只认识 fast-chatcode-heavycheap-summary 这种名字,不认识具体供应商。

type LlmTask = "fast-chat" | "code-heavy" | "cheap-summary";

const routes = {
  "fast-chat": { provider: "openaiCompat", model: "gpt-fast" },
  "code-heavy": { provider: "anthropic", model: "claude-code" },
  "cheap-summary": { provider: "openaiCompat", model: "small-summary" }
};

Provider 层只管协议。OpenAI-compatible endpoint 通常围绕 /v1/chat/completions、Bearer key、model 字段和 streaming。Anthropic 原生接口有自己的消息结构和版本 header。不要在同一个函数里用一堆 if 硬拼。

所有请求都带 request_id。用户投诉「刚才生成失败」时,你能按 id 找到 provider、model、token、延迟、状态码,而不是去日志里凭时间猜。

加预算闸门。免费用户走小模型,付费用户走主模型;单用户每小时和每天都要有上限。没有预算闸门的 AI SaaS,账单会教你做人。

日志字段设计

字段用途
request_id串起前端、后端、provider 日志
user_id / tenant_id算账和限流
provider / model排查路由是否跑偏
input_tokens / output_tokens成本和毛利
latency_ms判断体验问题
error_code触发重试和告警

完整 prompt 我只建议短期采样,而且要脱敏。独立开发者早期容易偷懒,等有企业客户后再补隐私策略会很痛。

跨地区使用和上线验证

开发期可以用多模型统一计费的 API 中转先把路由、日志和降级跑通。上线前再测三类真实任务:长输出 streaming、tool call、错误码返回。兼容接口最容易在边角能力上露馅。

常见失败原因

  • base_url 多写或少写 /v1
  • model 名是供应商别名,网关不认识
  • streaming 响应格式和 SDK 不匹配
  • 429 后没有按 retry-after 等待
  • fallback 没有最大次数,失败时雪崩
  • 日志里没有 token,毛利算不出来

还有一个坑是把「模型选择」交给用户。用户通常会想选高规格模型,但账单不会先到他那里。更好的做法是让用户选择效果档位,比如快速、标准、深度;后端再映射到具体模型和预算。这样你以后换供应商、改价格、临时降级,都不用改产品文案。

上线后第一周要盯两张表:每个任务的平均 token,以及每个模型的失败率。平均 token 决定毛利,失败率决定客服量。很多 AI SaaS 不是死在模型不好,而是死在「每个请求都用贵模型且没有上限」。路由层写得早一点,后面会少很多补丁。

还有产品层的兜底。模型路由失败时,按钮不要只变红。给用户一个任务状态、重试入口和简短解释;后台保留原始输入的哈希和任务 id。这样客服能补跑,用户也不会连点十次,把同一个任务送进队列十份。对一个人运营的产品来说,少一次重复生成,就是少一点账单和少一封解释邮件。别小看这些边角,付费用户多起来后,它们会变成真实成本项。

相关阅读