背景
目前 rosetta 不允许同名 model 存在,但实际场景中同一个 model 会有多个 provider(如 claude-opus-4 同时走 Anthropic direct 和 Bedrock)。需要引入 load balancer 解决路由问题,同时配套 token tracking 和 rate limiter。
一、Load Balancer(优先落地)
核心变化: model name 从唯一标识变成逻辑名,1:1 映射改成 1:N,同一个逻辑 model 下挂多个 backend。
方案:
- 配置层:同名 model 的多个 provider entry 收进列表,不再互相覆盖
- 路由策略:初期 priority-based failover(主备),后续可加 least-outstanding-requests 或 capacity-aware
- 健康管理:被动标记,连续 N 次 429/5xx 暂时摘除,过段时间恢复探测。不需要 active health check
- Failover:单个 backend 失败时自动尝试列表中下一个,控制 retry 次数
- 直接在 rosetta 内实现,不放 zerodep
二、Token Tracking
数据来源: Converter 转换 response 到 IR 时 usage 已标准化,proxy 层直接从 IR 读取,不需要单独的提取逻辑。
两条并行路径,互不依赖,同一个请求完成点写入:
- SQLite per-request record(source of truth)— 每个请求完成时 INSERT 一条,字段:
timestamp, consumer_key, logical_model, provider, backend_id, input_tokens, output_tokens, latency_ms, status。用于审计、成本分析、路由决策追溯
- 内存 counter(实时决策)— 按
(consumer_key, model, provider) 维度聚合,rate limiter 和 load balancer 直接读
完整链路:
provider response → converter → IR(含 usage)→ proxy 读 IR.usage + 路由上下文 → 写 SQLite record + 更新内存 counter
Streaming: 从最后一个 chunk 的 usage 拿,拿不到时 fallback estimation 标 estimated=true。
三、Rate Limiter(后续)
- 先只做 RPM,per-key per-provider
- Token bucket,内存维护
- TPM 等需要时再加维度
- 在内存 counter 基础上加一层判断即可
落地顺序
- Load Balancer — 解决同名 model 多 provider 路由
- Token Tracking — 两条路径一起做
- Rate Limiter — load balancer 和 token tracking 稳定后再叠加
设计原则
- 不用 log file 做 source of truth,用 SQLite structured record + 内存 counter
- Converter 只做本职(格式转换),usage 是 IR 的自然产物
- Proxy 负责补路由上下文和写入
背景
目前 rosetta 不允许同名 model 存在,但实际场景中同一个 model 会有多个 provider(如
claude-opus-4同时走 Anthropic direct 和 Bedrock)。需要引入 load balancer 解决路由问题,同时配套 token tracking 和 rate limiter。一、Load Balancer(优先落地)
核心变化: model name 从唯一标识变成逻辑名,1:1 映射改成 1:N,同一个逻辑 model 下挂多个 backend。
方案:
二、Token Tracking
数据来源: Converter 转换 response 到 IR 时 usage 已标准化,proxy 层直接从 IR 读取,不需要单独的提取逻辑。
两条并行路径,互不依赖,同一个请求完成点写入:
timestamp, consumer_key, logical_model, provider, backend_id, input_tokens, output_tokens, latency_ms, status。用于审计、成本分析、路由决策追溯(consumer_key, model, provider)维度聚合,rate limiter 和 load balancer 直接读完整链路:
Streaming: 从最后一个 chunk 的 usage 拿,拿不到时 fallback estimation 标
estimated=true。三、Rate Limiter(后续)
落地顺序
设计原则