Skip to content

Latest commit

 

History

History
119 lines (93 loc) · 5.78 KB

PLAN-newapi-alignment.md

File metadata and controls

119 lines (93 loc) · 5.78 KB

对标 New API 的健壮性改造计划

目标:把 New API(QuantumNous/new-api @ 33c61a2)已验证的网关机制, 按本仓的既有约定移植过来。不是照搬代码,是对齐机制 + 保留本仓的领域差异。

0. 先划清边界:什么抄、什么不抄

New API 有 757 个 Go 文件、完整的多租户计费体系。本仓是单部署聚合网关。

New API 机制 抄? 理由
错误码体系 + 错误脱敏 抄 我们现在的错误体直接把上游地址/原文吐给客户端
重试决策(SkipRetry / LocalError / 状态码分档) 抄 我们的 400 会污染账号池,正是这套要解决的
渠道亲和 / 会话粘性 已有,对齐语义 我们已有粘性,缺「亲和不命中时不重试」这条
自动禁用阈值 + 恢复探测 抄 我们只有冷却,没有阈值化禁用与自动恢复
超时可配置 + 流式超时 抄 我们现在硬编码,且流式超时与普通超时不分
参数覆盖(param override) 抄 渠道级改参数是刚需(reasoning_effort 只是个例子)
性能指标(延迟/成功率的 P 值) 抄 选号只看「健不健康」不够,要有实测延迟
敏感词检查 不抄 本仓不承担内容审核职责
多租户计费/预扣/退款 不抄 本仓无计费
插件系统 / JS 运行时 不抄 超出范围
SSRF 防护 抄简化版 渠道 base_url 是用户填的,需要挡住内网地址

1. 现状差距(可验证的事实)

# 差距 证据 影响
G1 错误体泄露上游 403 曾吐出整份上游白名单(已修);但上游 5xx 的原文仍原样透传 对外部署等于公布后端
G2 400 污染账号池 已修一半(400 直接返回),但 applyErrorPolicy 仍按 kind 粗分 参数错误可能仍罚号
G3 无自动禁用阈值 只有冷却时长 坏号永远在池里偶尔被选中
G4 超时硬编码 无配置项 无法按上游调(001 慢、003 会 78s)
G5 无渠道级参数覆盖 只能改 body 全局 reasoning_effort 这类只能全局归一化
G6 选号无延迟数据 只看健康状态 无法「优先快的」
G7 无 base_url 安全校验 用户可填任意地址 SSRF 面

2. 任务拆分(每个任务独立文件,可并行)

Wave 1 — 基础层(无依赖,可 3 路并行)

任务 文件 验收
T1 错误码体系 internal/gateway/errcode.go 现有 ErrorKind 映射到稳定 code;新增 code 不破坏既有测试
T2 错误脱敏 internal/gateway/errmask.go 上游 host/path/IP/query/userinfo/api_key 全部打码;表驱动测试
T3 超时配置 internal/timeouts/timeouts.go + cmd/server/config.go relay_timeout/streaming_timeout/idle_conn_timeout 可配,默认对齐 new-api(0/300/90)

Wave 2 — 决策层(依赖 T1,2 路并行)

任务 文件 验收
T4 重试决策 internal/server/retry_decision.go 复刻 decideTaskRetry:400/408/私有错误不重试;429/5xx 重试;跳过码表可配
T5 自动禁用 internal/pool/autodisable.go 连续 N 次失败 → 禁用(非冷却);成功一次 → 恢复;阈值可配

Wave 3 — 能力层(依赖 Wave 1/2,3 路并行)

任务 文件 验收
T6 参数覆盖 internal/server/param_override.go 渠道级 overrides.param 生效;现有 reasoning_effort 归一化改为其特例
T7 延迟指标 internal/pool/latency.go 记录每号 P50/P95;选号可「同档内优先低延迟」
T8 base_url 校验 internal/gateway/urlguard.go 拒绝私网/回环/metadata 地址(可白名单放行)

Wave 4 — 集成验证

任务 验收
T9 全量测试 go vet + go test ./... 全绿
T10 空端口实测 在 7868 起实例,六个通道各打 3 次,全部 200
T11 错误脱敏实测 故意构造上游失败,确认错误体不含 host/IP

3. 并行策略

Wave 1(并行 3 个 agent)
  A1: T1 错误码
  A2: T2 错误脱敏
  A3: T3 超时配置
        ↓ 汇总(主脑检查冲突:T1/T2 都动 gateway 包)
Wave 2(并行 2 个 agent)
  A4: T4 重试决策
  A5: T5 自动禁用
        ↓ 汇总
Wave 3(并行 3 个 agent)
  A6: T6 参数覆盖
  A7: T7 延迟指标
  A8: T8 URL 校验
        ↓
Wave 4(主脑自己跑)
  T9/T10/T11 → 报结果

文件隔离约定:每个 agent 只写自己那几个文件,不改 handler.go。 集成点由主脑统一改(避免并发写同一文件)。

4. 风险与回滚

风险 处置
错误脱敏把有用信息也抹了 脱敏只作用于出站给客户端的错误;日志保持原文
自动禁用误杀健康号 阈值默认保守(连续 5 次);且成功一次即恢复
超时默认值改变行为 默认值对齐现有硬编码,不改变既有部署行为
参数覆盖与 reasoning 归一化冲突 T6 落地后,归一化退化为 override 的默认规则

每个 Wave 结束都 git commit,出错可单独回滚。

5. 不做的事

  • 不引入 gin(本仓用 net/http)
  • 不引入 GORM(本仓无 DB)
  • 不搬计费/多租户/插件
  • 不改 webui.html 的既有结构(只在必要处加展示)

6. 验证口径

「能用」的定义(对齐用户当前诉求):

  1. 六个通道各 3 次请求,成功率 100%(001 限流除外,允许 1 次 429 重试后成功)
  2. 错误响应体不含任何上游 host / IP / base_url
  3. reasoning_effort: off 不再 503
  4. max_tokens 为负仍拒绝,其余合法值直通
  5. 模型列表 701 条,ctx 缺失数不增加