目标:把 New API(QuantumNous/new-api @ 33c61a2)已验证的网关机制,
按本仓的既有约定移植过来。不是照搬代码 ,是对齐机制 + 保留本仓的领域差异。
New API 有 757 个 Go 文件、完整的多租户计费体系。本仓是单部署聚合网关。
New API 机制
抄?
理由
错误码体系 + 错误脱敏
抄
我们现在的错误体直接把上游地址/原文吐给客户端
重试决策(SkipRetry / LocalError / 状态码分档)
抄
我们的 400 会污染账号池,正是这套要解决的
渠道亲和 / 会话粘性
已有,对齐语义
我们已有粘性,缺「亲和不命中时不重试」这条
自动禁用阈值 + 恢复探测
抄
我们只有冷却,没有阈值化禁用与自动恢复
超时可配置 + 流式超时
抄
我们现在硬编码,且流式超时与普通超时不分
参数覆盖(param override)
抄
渠道级改参数是刚需(reasoning_effort 只是个例子)
性能指标(延迟/成功率的 P 值)
抄
选号只看「健不健康」不够,要有实测延迟
敏感词检查
不抄
本仓不承担内容审核职责
多租户计费/预扣/退款
不抄
本仓无计费
插件系统 / JS 运行时
不抄
超出范围
SSRF 防护
抄简化版
渠道 base_url 是用户填的,需要挡住内网地址
#
差距
证据
影响
G1
错误体泄露上游
403 曾吐出整份上游白名单(已修);但上游 5xx 的原文仍原样透传
对外部署等于公布后端
G2
400 污染账号池
已修一半(400 直接返回),但 applyErrorPolicy 仍按 kind 粗分
参数错误可能仍罚号
G3
无自动禁用阈值
只有冷却时长
坏号永远在池里偶尔被选中
G4
超时硬编码
无配置项
无法按上游调(001 慢、003 会 78s)
G5
无渠道级参数覆盖
只能改 body 全局
reasoning_effort 这类只能全局归一化
G6
选号无延迟数据
只看健康状态
无法「优先快的」
G7
无 base_url 安全校验
用户可填任意地址
SSRF 面
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 地址(可白名单放行)
任务
验收
T9 全量测试
go vet + go test ./... 全绿
T10 空端口实测
在 7868 起实例,六个通道各打 3 次,全部 200
T11 错误脱敏实测
故意构造上游失败,确认错误体不含 host/IP
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。
集成点由主脑统一改(避免并发写同一文件)。
风险
处置
错误脱敏把有用信息也抹了
脱敏只作用于出站给客户端的错误 ;日志保持原文
自动禁用误杀健康号
阈值默认保守(连续 5 次);且成功一次即恢复
超时默认值改变行为
默认值对齐现有硬编码,不改变 既有部署行为
参数覆盖与 reasoning 归一化冲突
T6 落地后,归一化退化为 override 的默认规则
每个 Wave 结束都 git commit,出错可单独回滚。
不引入 gin(本仓用 net/http)
不引入 GORM(本仓无 DB)
不搬计费/多租户/插件
不改 webui.html 的既有结构(只在必要处加展示)
「能用」的定义(对齐用户当前诉求):
六个通道各 3 次请求,成功率 100%(001 限流除外,允许 1 次 429 重试后成功)
错误响应体不含任何上游 host / IP / base_url
reasoning_effort: off 不再 503
max_tokens 为负仍拒绝,其余合法值直通
模型列表 701 条,ctx 缺失数不增加