- DEFAULT_CHAIN_ADMISSION.md: reviewed and approved, real artifact refs added - DEFAULT_DATA_IDEMPOTENT_RELEASE_GATE.md: reviewed and approved - scripts/setup_default_data.sh: idempotent init with --dry-run/--apply/artifact - scripts/test/test_default_data.sh: 4 test cases all pass - scripts/acceptance/verify_user_key_self_service.sh: Phase 0 skeleton - .gitignore: add generated artifact directories
357 lines
12 KiB
Markdown
357 lines
12 KiB
Markdown
# Spec: 插件增强与宿主深度适配 vNext
|
||
|
||
## Objective
|
||
|
||
为 `sub2api-cn-relay-manager` 的下一版本建立明确规格:在“不修改宿主后端源码、不直接写宿主数据库”的前提下,先完成 vNext.1 的能力真相与模型池基础,再把用户 key 自助、治理、SLO 拆到后续版本。
|
||
|
||
当前版本目标不是一次性把“宿主适配、池化、前端、自助 key、治理、SLO”全部做完,而是先把最小可发布范围说清楚,避免再次在 Kimi / 多供应商聚合 / 用户端能力上反复试错,或在未审核设计上直接进入实现。
|
||
|
||
## 背景与问题陈述
|
||
|
||
当前已知问题来自真实线上使用:
|
||
|
||
1. 宿主协议转换能力不透明
|
||
- Kimi 接入时多次遇到协议转换偏差
|
||
- 需确认宿主是否只稳定支持 OpenAI Chat Completions,还是也支持 Responses / Anthropic / Gemini 兼容转换
|
||
2. 同模型多中转聚合能力不足
|
||
- 需要确认同一个逻辑模型(如 `gpt-5.4`、`kimi-k2.6`)是否能通过一个分组聚合多个供应商账号/线路,形成池化与故障切换
|
||
3. 用户前端能力弱
|
||
- 现有插件前端更偏管理与目录展示,用户要拿 key、看用法、理解分组限制仍较弱
|
||
- 希望尽量在插件/portal 前端内完成,不修改宿主后端代码
|
||
4. 用户自助取 key 能力不足
|
||
- 需要插件帮助生成 key,并把 key 的分组、模型、调用地址、状态、剩余额度/限制等信息交给最终用户
|
||
5. key / 账号治理能力不足
|
||
- 需要暂停 key、暂停账号、设置限额、设置默认分组或默认上限等能力
|
||
|
||
## Host Hard Constraints
|
||
|
||
1. 不修改 sub2api 宿主后端源码
|
||
2. 不向宿主数据库做常态化直写作为产品能力
|
||
3. 只允许通过:
|
||
- 宿主公开 HTTP API
|
||
- 宿主管理 API / 管理页面可达契约
|
||
- 插件自身控制面、SQLite、portal 前端
|
||
4. 如发现宿主现有 API 无法支撑某项需求,必须:
|
||
- 先记录为协议能力缺口
|
||
- 再决定是否由插件侧前端/控制面补偿
|
||
- 不能把“未来也许能改宿主”当作当前方案前提
|
||
|
||
## Access Closure
|
||
|
||
对本版本所有功能,完成判定不能停在“资源创建成功”。至少要同时满足:
|
||
|
||
1. 管理面闭环:控制面/前端能看到配置结果
|
||
2. 用户面闭环:真实用户拿到 key 后,按文档发起一次最小 `POST /v1/chat/completions` 成功
|
||
3. 证据闭环:保留当前运行日志、API 回包、页面回读或脚本输出
|
||
|
||
## Tech Stack
|
||
|
||
- Go 1.22 控制面
|
||
- `internal/host/sub2api` 宿主适配器
|
||
- `internal/provision` 导入编排
|
||
- `internal/access` 访问闭环
|
||
- `deploy/tksea-portal/` 静态前端
|
||
- SQLite 本地状态存储
|
||
|
||
## Commands
|
||
|
||
规格与后续实现的标准命令:
|
||
|
||
- 文档真相核对:
|
||
- `git status --short`
|
||
- `git log --oneline -n 5`
|
||
- Go 质量门禁:
|
||
- `gofmt -l .`
|
||
- `go vet ./...`
|
||
- `go test -cover ./internal/...`
|
||
- `go test ./tests/integration/... -count=1`
|
||
- 前端门禁(若触及 portal):
|
||
- `bash ./scripts/test/test_tksea_portal_assets.sh`
|
||
- `bash ./scripts/test/verify_frontend_smoke.sh`
|
||
- `bash ./scripts/acceptance/verify_provider_admin_actions.sh`
|
||
- 宿主协议探测(需新增脚本后执行):
|
||
- `bash ./scripts/acceptance/verify_host_protocol_matrix.sh`
|
||
- `bash ./scripts/acceptance/verify_host_pool_routing.sh`
|
||
- `bash ./scripts/acceptance/verify_user_key_self_service.sh`
|
||
|
||
## Project Structure
|
||
|
||
本次规划预计涉及的目录:
|
||
|
||
- `docs/` — SPEC、TDD 计划、执行板
|
||
- `internal/host/sub2api/` — 宿主能力探测、协议/契约抽象
|
||
- `internal/provision/` — 导入、聚合池配置、账号/key 治理编排
|
||
- `internal/access/` — 用户访问闭环、key 可用性验证
|
||
- `internal/app/` — 控制面 API(若新增插件自有 API)
|
||
- `deploy/tksea-portal/` — 用户 portal / admin 页面增强
|
||
- `tests/integration/` — 集成测试
|
||
- `scripts/acceptance/` — 宿主真实验收脚本
|
||
|
||
## Code Style
|
||
|
||
遵循仓库既有约束:
|
||
|
||
- Go 包按 `host/app/provision/access/store` 分层
|
||
- 错误统一 `fmt.Errorf("context: %w", err)`
|
||
- 新能力优先通过 adapter/service/repo 组合扩展,不把宿主特例硬编码到 handler
|
||
- 与宿主的“协议差异”必须放在 adapter / capability 层,不把协议分支散到 portal 页面
|
||
|
||
## Testing Strategy
|
||
|
||
本版本的测试要分五层:
|
||
|
||
1. 单元测试
|
||
- 宿主 capability 解析
|
||
- 模型池聚合策略
|
||
- key/账号状态机(active / paused / quota exceeded)
|
||
2. 集成测试
|
||
- SQLite repo + app handler + provision service
|
||
3. 前端 smoke
|
||
- key 发放页、key 状态页、限额/暂停页渲染与动作契约
|
||
4. 宿主真实验收
|
||
- 协议矩阵
|
||
- 池化分发
|
||
- 用户取 key 到调用成功
|
||
5. 生产准入验证
|
||
- 仅将“真实用户 chat=200”的模型/池写入默认链路
|
||
|
||
## Boundaries
|
||
|
||
Always:
|
||
|
||
- 先写 spec,再写 TDD 计划,再开始实现
|
||
- 所有“宿主支持某协议/某模型/某聚合方式”的结论都必须来自真实验收
|
||
- 触及 portal 时必须跑前端门禁
|
||
- 每个能力都要有用户面闭环,不只看 admin 成功
|
||
|
||
Ask first:
|
||
|
||
- 需要新增外部依赖
|
||
- 需要改变 key 发放产品策略(如收费、默认余额、默认分组)
|
||
- 需要把某个模型池写入 OpenClaw 默认链路
|
||
|
||
Never:
|
||
|
||
- 直接修改宿主后端源码
|
||
- 直接把宿主数据库写入当成长期产品方案
|
||
- 用 models=200 代替真实 chat=200
|
||
- 把“协议猜测”当成功能完成
|
||
|
||
## Release Scope
|
||
|
||
当前发布范围以 `docs/2026-06-04-vnext-release-scope.md` 为真相源。
|
||
|
||
- vNext.1(当前要审核并准备实施的版本):
|
||
- 宿主协议能力矩阵
|
||
- 模型池抽象
|
||
- pool 到现有 priority failover 运行面的映射
|
||
- 默认链路准入规则
|
||
- 幂等默认数据/初始化脚本前置
|
||
- vNext.2(本轮只设计,不进入当前实现):
|
||
- KEY_SECURITY_MODEL
|
||
- 用户 key 自助申请
|
||
- portal 首次调用闭环
|
||
- vNext.3(本轮只设计,不进入当前实现):
|
||
- key/account 治理
|
||
- quota/limit
|
||
- SLO/指标/告警
|
||
|
||
## Scope
|
||
|
||
### A. 宿主协议能力矩阵
|
||
|
||
要回答:
|
||
|
||
- 宿主当前稳定支持哪些协议入口/返回格式?
|
||
- 哪些模型需要额外转换层?
|
||
- Kimi 失败到底是上游问题、宿主协议问题,还是导入配置问题?
|
||
|
||
本版本输出:
|
||
|
||
- 一份宿主协议能力矩阵文档
|
||
- 一组可重复执行的协议探测脚本
|
||
- 明确“受支持 / 需插件适配 / 当前不支持”的分类
|
||
|
||
### B. 同模型多供应商池化分发
|
||
|
||
要回答:
|
||
|
||
- 同一逻辑分组下是否能挂多个账号/多个 channel
|
||
- 是否能对同一个公共模型名映射到多个供应商线路
|
||
- 现有宿主选路是否已有健康分发/优先级/冷却能力
|
||
|
||
本版本输出:
|
||
|
||
- 池化模型设计:`logical model -> route set -> provider accounts`
|
||
- 插件侧“模型池”抽象,而不是单 provider 绑定
|
||
- 验证脚本证明:同组多供应商可轮转 / 故障切换 / 人工禁用后可收敛
|
||
|
||
### C. 前端承接用户能力
|
||
|
||
要回答:
|
||
|
||
- 哪些宿主原生用户能力不足,需要 portal 前端承接
|
||
- 在不改宿主后端时,哪些能力可由插件自有 API + portal 完成
|
||
|
||
本版本输出:
|
||
|
||
- 用户产品面信息架构:
|
||
- 可申请的模型组
|
||
- 已有 key
|
||
- key 状态/限额/暂停
|
||
- 推荐 base URL / model / curl 示例
|
||
- admin 侧操作页:
|
||
- 发放 key
|
||
- 暂停/恢复 key
|
||
- 设置额度/限额
|
||
- 查看池健康
|
||
|
||
### D. 插件辅助生成 key
|
||
|
||
要回答:
|
||
|
||
- key 是由宿主生成还是插件包装生成
|
||
- 用户拿到 key 后需要看到哪些元数据
|
||
- 是否支持一键复制 SDK/curl 示例
|
||
|
||
本版本输出:
|
||
|
||
- 自助 key 发放流程
|
||
- key 元信息展示规范
|
||
- 用户端“从登录到首次 200 调用”的最短路径
|
||
|
||
### E. key / 账号治理
|
||
|
||
要回答:
|
||
|
||
- key 暂停、账号暂停、限额是否已有宿主 API 可控点
|
||
- 如果宿主无足够字段,插件侧是否能通过控制面侧策略先拦截
|
||
|
||
本版本输出:
|
||
|
||
- key 状态模型
|
||
- account 状态模型
|
||
- quota / budget / request limit 的最小可落地方案
|
||
- 与真实验收一致的治理 runbook
|
||
|
||
## Functional Requirements
|
||
|
||
### FR-1 协议能力探测
|
||
|
||
系统必须能输出一份按模型/协议/供应商分类的能力矩阵,至少覆盖:
|
||
|
||
- OpenAI Chat Completions
|
||
- OpenAI Responses(若宿主不支持,要明确标红)
|
||
- Kimi 兼容接口
|
||
- DeepSeek
|
||
- MiniMax
|
||
- GLM
|
||
- GPT 中转常见供应商
|
||
|
||
### FR-2 宿主兼容性标签
|
||
|
||
系统必须把模型线路分类为:
|
||
|
||
- `supported-direct`
|
||
- `supported-with-plugin-adapter`
|
||
- `unsupported-by-host`
|
||
- `upstream-unhealthy`
|
||
|
||
### FR-3 模型池抽象
|
||
|
||
系统必须允许一个逻辑模型对应多个候选线路,并记录:
|
||
|
||
- provider name
|
||
- base_url
|
||
- supported models
|
||
- priority
|
||
- schedulable
|
||
- last health state
|
||
- cooldown / disable reason
|
||
|
||
### FR-4 池化验收
|
||
|
||
必须证明在同组内:
|
||
|
||
- 至少两个候选线路可共同服务一个模型名
|
||
- 一个线路失败后能切到另一条
|
||
- 被人工暂停的线路不会继续被分发
|
||
|
||
### FR-5 模型池 active 准入
|
||
|
||
vNext.1 的 active model pool 必须默认排除:
|
||
|
||
- `Schedulable=false` 的候选
|
||
- `HostReady=false` 的候选
|
||
- `unsupported-by-host`
|
||
- `upstream-unhealthy`
|
||
|
||
如需展示不可进入 active pool 的候选,应输出 rejected/reason 视图,而不是混入 active routes。
|
||
|
||
### FR-6 默认链路准入
|
||
|
||
只有通过真实用户链路 `POST /v1/chat/completions=200` 的模型池,才允许进入默认链路。
|
||
|
||
每条准入记录必须至少包含:
|
||
|
||
- model pool ID
|
||
- route/provider/account 证据
|
||
- upstream / host / user-key 三层 probe 路径
|
||
- artifact 路径
|
||
- 最近 N 次 chat=200 结果
|
||
- owner approval
|
||
|
||
### FR-7 后续版本保留项
|
||
|
||
以下需求仍保留,但不属于 vNext.1 实现范围:
|
||
|
||
- 用户 portal 承接
|
||
- key 自助发放
|
||
- key/account 暂停恢复
|
||
- quota/limit
|
||
- SLO/告警
|
||
|
||
这些内容必须在后续文档中单独落地:
|
||
|
||
- `KEY_SECURITY_MODEL.md`
|
||
- `PORTAL_KEY_EXPERIENCE.md`
|
||
- `KEY_ACCOUNT_GOVERNANCE.md`
|
||
- `SLO_AND_OBSERVABILITY.md`
|
||
|
||
## Non-Goals
|
||
|
||
本版本不做:
|
||
|
||
- 修改宿主后端源码
|
||
- 自研完整计费系统
|
||
- 自研多租户 IAM
|
||
- 直接替换宿主所有 UI
|
||
- 在没有真实上游证据前承诺“所有主流模型都支持”
|
||
|
||
## Success Criteria
|
||
|
||
vNext.1 当前审核通过标准:
|
||
|
||
1. 范围层面
|
||
- 已冻结 vNext.1 / vNext.2 / vNext.3 边界
|
||
- 未经审核通过,不继续实现后续版本主链功能
|
||
2. 设计层面
|
||
- 完成协议矩阵设计 + 模型池设计 + 默认链路准入设计
|
||
- 明确当前只承诺 priority failover,不承诺完整负载均衡池化
|
||
3. 证据层面
|
||
- 每个“支持”结论都绑定真实探测脚本与输出
|
||
- probe 必须区分 upstream / host / user-key 三层证据
|
||
4. 发布层面
|
||
- active pool 默认排除 `HostReady=false` 与 `Schedulable=false`
|
||
- 只有通过真实用户链路的模型池才能进入默认链路
|
||
5. 规划层面
|
||
- vNext.2/vNext.3 的 key 安全模型、治理状态模型、SLO 文档已列为必备后续设计产物
|
||
|
||
## Open Questions
|
||
|
||
1. 宿主当前对 key 暂停/禁用/限额是否已有稳定 API?需要先做 capability inventory。
|
||
2. 如果宿主无法直接生成明文 key,插件是否应改为“调用宿主生成 + 自身只投影展示”,而不是自造 key。
|
||
3. 限额优先做哪一种:余额、请求次数、模型级预算、日限额?
|
||
4. 用户登录态是否继续沿用 portal 当前机制,还是需要更明确的“申请 key / 管理 key”入口分离。
|
||
5. Kimi 与 GLM 是否都坚持走宿主统一协议,还是先接受“部分模型在插件侧标记为实验支持”。
|