Files
sub2api-cn-relay-manager/docs/REAL_HOST_ACCEPTANCE_LEARNINGS.md
2026-05-21 09:16:45 +08:00

174 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 真实宿主验收经验与已调通细节
日期2026-05-21
## 目的
这份文档不替代 `docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md`,而是把已经在线下真实打通过、以及多次踩坑后确认的细节沉淀下来,避免后续重复误判。
建议阅读顺序:
1. `docs/EXECUTION_BOARD.md` —— 看当前 gate 与最新真相
2. `docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md` —— 看标准执行步骤
3. 本文 —— 看调试经验、误判点、诊断顺序
## 已经确认打通的事实
1. account 视角模型暴露可以正确落库
- CRM 在 account 创建/导入时写入 `credentials.model_mapping`
- 宿主 `GET /api/v1/admin/accounts/:id/models` 已能返回目标 provider 模型,而不是一律回退到 GPT 默认集合
- DeepSeek / MiniMax 都已在 live 验收中确认
2. channel 视角模型映射与定价可以正确落库
- channel 创建时需要同时下发:
- `model_mapping`
- `model_pricing`
- `restrict_models=true`
- `billing_model_source=channel_mapped`
- 对既有 channelCRM 需要走 `UpdateChannel` 做纠偏;这一点已在 latest-head fresh rerun 上确认生效
- 旧现象“MiniMax channel 有 model_mapping 但没有 pricing”已经被 `ca1d448` 修复并完成 live 验证
3. subscription 场景的真实 probe key 语义已经确认
- closure 最终用于宿主 `/v1/models` 探测的,不是外部传入的原始 `access_api_key`
- 真正使用的是 CRM 在宿主侧创建/查找出来的 managed key`sk-relay-*` 风格)
- 因此 subscription 验收如果直接拿调用方原始 probe key 去打 `/v1/models`,出现 `403 not assigned to any group` 并不代表 CRM 主链路失败,而是 probe key 用错了
4. group 聚合视角与 account 单体视角必须分开看
- `GET /api/v1/admin/accounts/:id/models` 是 account 单体视角
- `GET /v1/models` 是普通用户 key + group 聚合视角
- 二者语义不同,不能互相替代
- 正确诊断顺序应该是:
1) 先看 account models 是否正确
2) 再看 managed key 视角 `/v1/models` 是否正确
3) 最后才看 completion smoke 是否通过
## 已调通的宿主侧前置动作
### self_service
至少满足:
1. 普通用户已真实创建
2. 普通用户 key 已生成且可用
3. 该 key 已绑定目标标准 group
4. 用户具备可用余额
经验结论:
- 若只做了 key/group 绑定但没余额,`/v1/models` 可能从 403 进入 `INSUFFICIENT_BALANCE`
- 这不是 CRM 导入逻辑失败,而是宿主运营前置未完成
### subscription
至少满足:
1. 普通用户已真实创建
2. 普通用户 key 已生成且可用
3. 目标 group 是 `subscription` 类型
4. 普通用户已完成 subscription 分配
5. 普通用户 key 已绑定该 subscription group
经验结论:
- 只有管理员主体、只有 group、或者只有 subscription 记录都不够
- 必须把“普通用户 + key + group + subscription”整条链补齐`/v1/models` 才会稳定通过
## 已确认的高频误判点
1.`/accounts/:id/models``/v1/models` 混为一谈
- 前者对,后者错,不代表 account 落库失败;往往是 key/group/subscription 问题
2. 用错 probe key
- subscription 场景拿原始 `access_api_key` 直打宿主 `/v1/models`,很容易得到 403
- 这时应先回到 closure 结果或 managed access 证据,而不是先否定产品链路
3. 旧 CRM 进程误导当前结论
- live 行为必须先确认运行中的 CRM 进程是否真的包含最新提交
- 之前 MiniMax existing channel 没自动补 `model_pricing`,最终确认根因就是在线 CRM 进程早于修复提交 `ca1d448`
4. `PACK_PATH` 使用了 operator 机器的概念路径,而不是 CRM 进程本机可读路径
- 当 CRM 改在本机运行时,继续传远端 `/home/ubuntu/...` 会直接触发 `stat pack path ... no such file or directory`
- 这个报错属于验收 harness / 环境参数问题,不是 import 业务逻辑问题
5. remote43/fresh-host 的 Postgres/Redis 容器目标写错
- 若脚本仍打到旧 relaymgr 宿主,会看到 managed user / key / subscription 状态为空或串台
- 需要确保脚本明确指向 fresh host 对应的 `{postgres,redis}` 容器
6.`/v1/models` 已通误认为 completion 也一定通
- 这不成立
- 当前最新真相就是DeepSeek / MiniMax 的 `/v1/models` 可以 200`/v1/chat/completions` 仍可能因为 host 兼容性或上游 quota 问题失败
## 推荐诊断顺序
### 一、先确认是不是环境/脚本问题
1. 确认当前运行 CRM 的提交版本与启动时间
2. 确认 `PACK_PATH` 是 CRM 本机可读路径
3. 确认 `CRM_HOST_BASE` 是否与实际 CRM 到 host 的可达地址一致
4. 确认脚本命中的 Postgres/Redis 容器属于目标 fresh host而不是旧环境
### 二、再确认导入数据是否正确写入宿主
1. account
- `GET /api/v1/admin/accounts/:id`
-`credentials.model_mapping`
2. account models
- `GET /api/v1/admin/accounts/:id/models`
3. channel
- `GET /api/v1/admin/channels/:id`
- 看:
- `model_mapping`
- `model_pricing`
- `restrict_models`
- `billing_model_source`
### 三、最后再确认普通用户访问链路
1. self_service看普通用户 key/group/balance
2. subscription看 managed key / allowed_groups / user_subscriptions
3. 宿主 `/v1/models`
4. 宿主 `/v1/chat/completions`
## 如何解释常见现象
### 现象 A`/accounts/:id/models` 正确,但 `/v1/models` 返回 403
优先判断:
- 普通用户 key 没绑定 group
- subscription 场景用错了原始 probe key
- subscription 分配或 allowed_groups 未完成
### 现象 B`/v1/models` 返回 GPT 系模型,而不是目标国产模型
优先判断:
- account `credentials.model_mapping` 是否落库
- channel 是否同时具备 `model_mapping + model_pricing + restrict_models + billing_model_source=channel_mapped`
- 是否误打到了旧 CRM 进程
### 现象 C`/v1/models` 已 200但 `/v1/chat/completions` 返回 502
优先判断:
- host 侧 provider 兼容性问题
- 上游 provider key/quota 问题
- 不要再把问题回退归因为 CRM 导入或 access closure
## 当前建议固化到后续文档/脚本的规则
1. 所有真实宿主验收结论都要同时记录:
- account 视角结果
- managed key 视角 `/v1/models` 结果
- completion smoke 结果
2. 任何“MiniMax/DeepSeek 没生效”的结论前,必须先检查在线 CRM 是否为最新提交
3. 任何 subscription 验收脚本都不应默认把外部 `access_api_key` 当最终 probe key
4. 任何 fresh-host 验收脚本都必须参数化:
- `PACK_PATH`
- `CRM_HOST_BASE`
- 目标 Postgres 容器
- 目标 Redis 容器
## 相关证据入口
- 当前执行真相:`docs/EXECUTION_BOARD.md`
- 当前收口真相:`docs/PRODUCTION_CLOSURE_BOARD.md`
- 标准操作步骤:`docs/REAL_HOST_ACCEPTANCE_RUNBOOK.md`
- 关键 live 证据:
- `artifacts/real-host-acceptance/20260520_222713_crm18100_live_model_mapping_validation`
- `artifacts/real-host-acceptance/20260521_011544_remote43_minimax_key_import`
- `artifacts/real-host-acceptance/20260521_011717_remote43_deepseek_key_import`
- `artifacts/real-host-acceptance/20260521_064910_completion_smoke_calibration.md`