Files
2026-05-07 10:16:46 +08:00

568 lines
38 KiB
Markdown
Raw Permalink 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.
# 供应链智能增强系统Supply IntelligencePRD
> 状态说明2026-05 收敛修订):本文件保留为历史版本参考,已不再作为当前实现真源。
> 当前产品真源以“2026-05 新 PM 基线 + tech/BASELINE_TECHLEAD_V2.md + 已收敛的测试/部署/任务决议文档”为准。
> 若本文件与上述新真源冲突,以新真源为准,尤其是以下方面不得再按本文件旧口径执行:
> 1. pricing / prediction / 向量检索 / 广义开放平台能力
> 2. 探针 timeout / TCP / DNS 触发惩罚性降级
> 3. 自动发布 / 自动下架 / disabled 自动恢复
> 4. gateway 强耦合同步热更新主路径
> 5. 以独立平台化重部署作为默认落地方式
> 文档版本v1.0
> 撰写日期2026-04-27
> 撰写人PM产品经理
> 评审状态:待 TechLead 评审
---
## 1. 概述
### 1.1 一句话价值
通过自动化探针、全网扫描与准入测试,让平台供应链中的供应商账号、可用模型列表始终保持最新且可路由,消除人工维护滞后导致的可用性黑洞。
### 1.2 用户问题
- 运营团队每日需要人工检查数十个供应商账号的状态额度、密钥失效、TOS 变更),遗漏率高。
- 新模型上线后,平台未能及时感知,导致流量无法路由到新模型,竞争力下降。
- 供应商账号过期或密钥失效后,网关仍在尝试路由请求,直接引发用户端报错。
- 手动在各运营商后台注册账号、申请 API Key 的周期以天计,阻碍新供应商的快速接入。
### 1.3 业务意义
- 将供应链信息的保鲜周期从“人工天级”缩短到“自动分钟级”。
- 降低因供应商/模型失效导致的用户可见错误率。
- 缩短新模型上线到平台可售卖之间的上市时间Time-to-Market
- 为后续动态定价、智能路由提供实时、准确的供应链数据底座。
---
## 2. 目标
### 2.1 业务目标
| 目标编号 | 目标描述 | 度量方式 |
|---------|---------|---------|
| BG-01 | 供应商账号异常状态从发生到被标记的平均时间 ≤ 15 分钟 | 从供应商侧异常发生到本系统将其 status 改为 `suspended``disabled` 的时间差 |
| BG-02 | 全网新模型从发布到进入平台可售卖列表的平均时间 ≤ 4 小时 | 从模型在官方文档/接口中出现到本系统将其对应的 supply_package 状态置为 `active` 的时间差 |
| BG-03 | 因供应商账号失效导致的用户可见错误率下降 80% | 对比上线前 30 天与上线后 30 天,网关返回 502/503 且根因指向供应商失效的请求占比 |
| BG-04 | 人工维护供应商基础信息的工作量减少 70% | 运营团队每周在供应商信息维护上投入的小时数对比 |
### 2.2 用户目标
- **平台运营团队**:在一个界面看到所有供应商账号的健康度、模型覆盖度、待处理事项,不再需要逐家登录供应商后台确认。
- **供应链管理人员**:新供应商或新模型的接入流程从“人工申请-测试-录入”变为“自动发现-自动测试-人工确认一键上架”。
- **技术负责人**:系统具备明确的熔断、降级、审计能力,自动化操作不引入新的稳定性风险。
- **商务负责人**:新模型上架速度成为可量化指标,可用于对外商务承诺。
### 2.3 成功定义
项目被判定为成功的条件是:
1. BG-01、BG-03、BG-04 三项指标在正式上线后 30 天内全部达成。
2. 系统在连续 7 天内未出现因本系统自身故障导致的供应商状态误标记false positive 率 ≤ 1%)。
3. 所有自动化操作(状态变更、模型录入、账号注册)具备完整审计日志,且日志保留 ≥ 90 天。
---
## 3. 范围
### 3.1 In Scope
#### 模块 A供应商品质探针Supply Health Probe
- 对已录入 `supply_accounts` 的账号,按配置周期发起连通性、额度、密钥有效性探针。
- 根据探针结果,自动将账号状态在 `active``suspended``disabled` 之间迁移(需满足状态机规则,不允许直接 `active``disabled`,必须经过 `suspended`)。
- 对探针结果生成风险评分,写入 `supply_accounts.risk_score``risk_reason`
- 对状态变更事件写入审计日志。
#### 模块 B全网模型发现Model Discovery
- 对接各供应商官方 API / 文档 / 变更源,扫描其已发布的模型列表。
- 将扫描到的模型与平台现有 `supply_packages` 中的 `platform` + `model` 组合进行比对,识别“新增模型”。
- 对新增模型创建候选记录(`supply_intelligence.model_candidates` 表,状态为 `discovered`),等待准入测试。
- 对已从官方列表下架但平台仍有 `active` 套餐的模型,标记为 `deprecated`,触发告警通知运营团队。
#### 模块 C模型准入测试Model Admission Test
- 对状态为 `discovered` 的候选模型,使用标准化测试用例集(覆盖 chat/completion/embedding 等 endpoint进行功能验证。
- 测试维度包括:接口可用性、响应格式合规性、延迟 P50/P99、token 计数一致性、错误码映射正确性。
- 测试通过后,候选模型状态迁移为 `test_passed`,并自动生成一份 `supply_package` 草稿(`draft` 状态),等待运营团队确认后发布。
- 测试失败的模型状态迁移为 `test_failed`,记录失败原因与日志,保留 30 天后自动清理。
#### 模块 D账号自动注册Account Auto-Registration
- 针对支持自动化注册流程的供应商(需配置化白名单),系统通过其公开注册接口或模拟浏览器流程完成账号注册。
- 注册成功后,自动申请 API Key将凭证加密后写入 `supply_accounts`,状态置为 `pending`
- 注册过程中涉及的手机/邮箱验证,接入平台已集成的 SMS/邮件网关;若 SMS/邮件网关未就绪,该供应商的自动注册能力必须 fail-closed拒绝启动不静默降级
- 注册行为必须写入审计日志,凭证指纹写入 `credential_fingerprint`
#### 模块 E运营工作台Operations Dashboard
- 展示待处理候选模型列表、待确认供应商状态变更、自动注册任务队列。
- 提供“一键确认上架”、“忽略此模型”、“手动触发探针”三个人工干预入口。
- 展示供应链覆盖率(平台已上架模型数 / 全网可发现模型数)。
### 3.2 Out of Scope
| 编号 | 内容 | 原因 |
|-----|------|------|
| OOS-01 | 供应商侧计费系统对接与自动充值 | 属于财务结算域,不在供应链智能范围内 |
| OOS-02 | 基于发现结果的动态定价算法 | 属于 pricing-engine 项目,本系统只生成 package 草稿中的建议价 |
| OOS-03 | 供应商账号的 TOS 法律合规性自动审查 | 法律文本语义分析超出当前工程边界本系统只做“TOS 变更标记” |
| OOS-04 | 不支持公开注册接口的供应商(如需要企业资质审核、线下合同)的自动注册 | 无法工程化闭环,保留人工注册入口 |
| OOS-05 | 对供应商内部模型版本迭代(如从 gpt-4-turbo 到 gpt-4-turbo-2024-04-09的语义级差异分析 | 成本过高,只识别模型 ID 维度的新增/下架 |
| OOS-06 | 跨供应商的模型能力等价性判定(如“模型 A 是否等价于模型 B” | 属于模型评估平台,非供应链基础能力 |
### 3.3 假设与依赖
| 编号 | 假设/依赖 | 影响 |
|-----|----------|------|
| ASP-01 | 各供应商均提供可公开访问的模型列表接口或文档页面 | 若某供应商关闭列表接口,该供应商的模型发现能力降级为手动录入 |
| ASP-02 | 账号自动注册仅针对已签署技术合作框架协议、允许自动化注册的供应商 | 法律合规问题由商务团队前置解决 |
| ASP-03 | `supply-api` 现有的 `supply_accounts` 表结构在上线前不做破坏性变更 | 本系统的新增表需通过标准 migration 脚本创建 |
| ASP-04 | 平台已具备 SMS/邮件网关的运行时能力,或本模块的自动注册可被条件关闭 | 参照 `supply-api/CLAUDE.md` 中“条件能力必须 fail-closed”原则 |
| ASP-05 | 探针任务调度依赖平台统一的 job scheduler如内部 cron 或 Temporal不重新造调度器 | 若 scheduler 不可用,探针模块延迟启动 |
| ASP-06 | 测试用例集的维护由 QA 团队负责,本系统负责调度执行与结果收集 | 测试用例本身不在本系统代码库内管理 |
---
## 4. 用户场景
### 4.1 主流程
#### 场景 S1供应商账号自动探针与状态变更
```
1. 调度器按配置周期(默认 5 分钟)触发对供应商账号 A 的探针任务。
2. 探针模块调用供应商健康检查端点(或发送一条低成本测试请求)。
3. 供应商返回 401/403 或超时 > 10 秒,探针判定为“密钥失效或账号异常”。
4. 系统检查该账号当前状态:
a. 若为 active → 改为 suspendedrisk_score 设为 80risk_reason 写入“密钥失效”。
b. 若为 suspended 且连续 3 次探针失败 → 改为 disabled。
5. 状态变更事件写入审计日志object_type=supply_account, action=auto_suspend
6. 向运营团队发送告警通知(钉钉/企业微信),包含账号、供应商、原因、时间。
```
#### 场景 S2全网扫描发现新模型
```
1. 调度器每 1 小时触发一次全网扫描任务。
2. 扫描模块向各供应商的模型列表接口发起请求,解析出当前所有 model_id。
3. 与 supply_packages 中 status ∈ {active, paused, draft} 的记录去重比对。
4. 发现供应商 X 新增模型 "new-model-v1",平台暂无记录。
5. 在 model_candidates 表中插入一条记录:
- platform = X, model_id = "new-model-v1"
- status = discovered
- discovered_at = NOW()
6. 触发准入测试流水线(异步任务)。
```
#### 场景 S3新模型准入测试通过并上架
```
1. 准入测试模块从 model_candidates 取出 status = discovered 的记录。
2. 使用对应供应商的测试账号,发送标准化测试请求集(≥ 5 个不同用例)。
3. 所有用例返回 HTTP 200响应体符合 OpenAI-compatible schema延迟 P99 < 30 秒。
4. 将 candidate 状态更新为 test_passed并生成 supply_package 草稿:
- platform = X, model = "new-model-v1"
- status = draft
- price_per_1m_input / price_per_1m_output 使用预设默认值(可配置)
5. 运营工作台出现“待上架新模型”卡片。
6. 运营人员点击“确认上架”package 状态改为 active进入 gateway 路由表。
```
#### 场景 S4供应商账号自动注册
```
1. 运营人员在后台勾选“启用供应商 Y 的自动注册”,并配置注册参数(如邮箱域名、账号前缀规则)。
2. 系统检测到供应商 Y 的可用账号数 < 配置阈值(如 < 2 个 active 账号)。
3. 触发自动注册任务:
a. 调用供应商 Y 的注册接口,提交随机生成的用户名、密码、企业邮箱。
b. 等待并解析注册确认邮件,点击确认链接(或输入邮件验证码)。
c. 登录账号后台,申请 API Key。
4. 将 API Key 经 KMS 加密后写入 supply_accountsstatus = pending。
5. 触发自动验证(复用现有 Verify 流程),验证通过后 status 改为 active。
```
### 4.2 异常流程
#### 场景 E1探针遭遇供应商 Rate Limit
```
1. 探针请求返回 429。
2. 该次探针标记为 inconclusive不计入连续失败次数。
3. 调度器在指数退避后1min → 2min → 4min重试最多重试 3 次。
4. 若 3 次后仍为 429本次探针周期跳过该账号记录日志不触发状态变更。
```
#### 场景 E2模型准入测试超时
```
1. 某测试用例在 60 秒内未收到响应。
2. 该用例标记为 timeout测试流水线整体标记为 test_failed。
3. candidate 状态更新为 test_failed失败原因写入 "admission_test_timeout"。
4. 运营工作台展示失败详情,运营人员可选择:
a. 手动重新触发测试;
b. 标记为 ignore该 model_id 在 7 天内不再自动扫描。
```
#### 场景 E3自动注册时 SMS/邮件网关不可用
```
1. 注册流程进行到验证码接收步骤。
2. 调用 SMS/邮件网关返回 503 或超时。
3. 该注册任务整体失败写入审计日志action=auto_register_failed
4. 依据 fail-closed 原则,不向用户或上游返回任何“注册成功”的虚假状态。
5. 任务进入死信队列24 小时后由人工或系统重试。
```
### 4.3 边缘流程
#### 场景 B1供应商模型 ID 变更(非新增/下架,而是重命名)
- 扫描模块发现旧 model_id 消失、新 model_id 出现,但模型能力描述高度相似。
- 系统无法自动判定为“重命名”还是“旧模型下架+新模型上线”。
- 生成一条运营待办事项,由运营人员人工确认关系,系统不做自动关联。
#### 场景 B2运营人员手动暂停自动探针
- 运营人员可在后台对单个供应商账号勾选“暂停自动探针”。
- 该账号的探针任务在调度器中被跳过,但运营人员仍可手动触发单次探针。
- 暂停状态写入 `supply_accounts` 的扩展字段(或通过新增 `auto_probe_enabled` 字段),探针模块读取该字段后决定是否执行。
#### 场景 B3账号处于 suspended 期间收到用户请求
- 本系统不直接处理流量路由,但需向 gateway 提供实时供应商状态查询接口。
- gateway 在路由决策时查询该接口,若账号为 suspended/disabled则将该账号从候选池移除。
- 该接口的 SLAP99 延迟 < 50ms可用性 ≥ 99.9%。
### 4.4 用户故事
| 编号 | 角色 | 故事 | 验收对应 |
|-----|------|------|---------|
| US-01 | 运营人员 | 我想在一个页面看到所有供应商账号最近一次探针的时间和结果,以便快速定位异常账号 | AC-01, AC-02 |
| US-02 | 供应链管理员 | 我想在新模型被系统发现后收到通知,并在工作台一键确认上架,以便缩短上市时间 | AC-03, AC-04 |
| US-03 | 技术负责人 | 我想所有自动化状态变更都有审计日志和回滚记录,以便在误操作时追溯和恢复 | AC-05, AC-09 |
| US-04 | 商务负责人 | 我想看到平台模型覆盖率与竞品对比的报表,以便对外展示平台能力 | AC-07 |
| US-05 | 运营人员 | 我想对特定账号暂停自动探针,以便在供应商维护窗口期避免误报警 | AC-08 |
| US-06 | 供应链管理员 | 我想对支持自动注册的供应商配置自动补货策略,以便在可用账号不足时自动补充 | AC-06 |
---
## 5. 验收标准AC
> 以下每条 AC 均为可测试、无模糊词的要求。QA 可直接据此编写测试用例。
### 模块 A供应商品质探针
**AC-01 探针覆盖度**
- 给定 `supply_accounts``status``active``suspended` 的账号数量 N系统在任意时刻 T最近 15 分钟内被探针覆盖的账号数量 M 必须满足 M/N ≥ 99%。
- 测试方法:插入 100 条测试账号记录,观察 15 分钟窗口内探针日志条数是否 ≥ 99。
**AC-02 状态变更正确性**
- 给定一个 `status=active` 的账号,模拟其返回 401 连续 1 次,系统在 60 秒内将其 `status` 更新为 `suspended`
- 给定一个 `status=suspended` 的账号,模拟其连续 3 次探针返回 401系统在 60 秒内将其 `status` 更新为 `disabled`
- 给定一个 `status=active` 的账号,模拟其返回 429 单次,其 `status` 在 15 分钟内保持 `active` 不变。
- 测试方法Mock 供应商响应,查询数据库字段值。
**AC-03 误报率**
- 在 7 天连续运行测试中,探针将实际正常的账号标记为 `suspended``disabled` 的次数 ≤ 总探针次数的 1%。
- 测试方法:使用全部正常的测试账号运行 7 天,统计状态误变更次数。
### 模块 B全网模型发现
**AC-04 新模型发现延迟**
- 给定一个已对接的供应商,在其模型列表中新增一个 model_id系统在 2 个扫描周期(默认 2 小时)内将该 model_id 写入 `model_candidates``status=discovered`
- 测试方法Mock 供应商模型列表接口,在 T0 新增 model_idT0+2h 查询数据库验证。
**AC-05 已下架模型告警**
- 给定一个 `supply_packages``status=active` 的 model_id在供应商侧该 model_id 消失后,系统在 2 个扫描周期内:
- 将该 package 的 `status` 保持 `active` 不变(不自动下架,避免误伤);
- 在运营工作台生成一条“模型已下架”告警待办;
- 向运营人员发送通知。
- 测试方法Mock 供应商模型列表,移除 model_id验证告警产生与 package 状态未变。
### 模块 C模型准入测试
**AC-06 准入测试通过**
- 给定一个 `status=discovered` 的 candidate其供应商测试账号正常系统在 30 分钟内完成全部测试用例执行candidate 状态变为 `test_passed`,且自动生成一条 `supply_packages` 记录(`status=draft`)。
- 测试方法:使用真实或 Mock 供应商响应,验证数据库状态与 package 草稿字段完整性。
**AC-07 准入测试失败**
- 给定一个 `status=discovered` 的 candidate模拟其接口返回 500 或响应格式不合法,系统在 30 分钟内将 candidate 状态更新为 `test_failed``failure_reason` 字段非空,且运营工作台展示失败详情。
- 测试方法Mock 供应商返回 500验证数据库字段与前端展示。
### 模块 D账号自动注册
**AC-08 自动注册成功**
- 给定一个已配置自动注册白名单的供应商,配置其可用账号数阈值为 2当前可用账号数为 1系统在 10 分钟内触发注册流程,在 30 分钟内完成注册、密钥申请、凭证加密存储,最终 `supply_accounts` 中新增一条 `status=active` 的记录。
- 测试方法:使用供应商沙箱环境或高保真 Mock验证端到端流程与数据库记录。
**AC-09 自动注册 fail-closed**
- 给定自动注册配置 `enabled=true`,但 SMS/邮件网关返回 503 或超时,系统在 60 秒内将注册任务标记为 `failed`,不向任何上游返回成功状态码,审计日志中包含 `action=auto_register_failed` 与错误详情。
- 测试方法Mock SMS 网关返回 503验证接口响应、数据库状态、审计日志。
### 模块 E运营工作台与通用
**AC-10 审计日志完整性**
- 任意自动化操作状态变更、candidate 状态迁移、自动注册、手动触发探针)发生后 5 秒内,审计存储中必须存在对应记录,字段包含:
- `object_type``object_id``action``result_code``before_state`(变更前)、`after_state`(变更后)、`request_id`
- 测试方法:触发各项操作,查询审计存储验证字段完整性。
**AC-11 运营工作台干预**
- 运营人员点击“一键确认上架”后,对应的 `supply_packages` 记录在 3 秒内从 `draft` 变为 `active`
- 运营人员点击“忽略此模型”后,该 candidate 在 7 天内不再出现在待处理列表中,且 7 天后自动恢复为 `discovered`
- 测试方法E2E 测试或 UI 自动化测试。
**AC-12 配置热更新**
- 探针周期、扫描周期、测试超时时间、自动注册阈值等配置项,在修改配置文件并下发后 60 秒内生效,不重启进程。
- 测试方法:修改配置,观察调度器行为变化时间差。
---
## 6. 边缘情况与失败路径
| 编号 | 边缘/失败场景 | 系统行为 | 验证方式 |
|-----|-------------|---------|---------|
| FP-01 | 供应商探针接口完全不可用DNS 失败、TCP 超时) | 标记为 inconclusive按 429 退避逻辑处理,不直接变更状态 | 模拟 iptables DROP验证状态不变 |
| FP-02 | 供应商返回 200 但响应体为空或格式突变 | 解析失败视为 inconclusive记录 error_log不触发状态变更 | Mock 返回空 JSON验证状态与日志 |
| FP-03 | 同一账号在探针执行期间被运营人员手动变更状态 | 乐观锁冲突:探针更新时 version 不匹配,更新失败,探针记录冲突日志,由下次探针或运营人员覆盖 | 并发测试:手动 update 同时触发探针 |
| FP-04 | 模型准入测试期间,测试账号被探针标记为 suspended | 准入测试流水线检测到测试账号不可用,任务标记为 `test_failed`,原因写为 `test_account_unavailable` | Mock 测试账号 suspended验证流水线行为 |
| FP-05 | 自动注册时供应商注册接口返回 400如邮箱已被注册 | 任务标记为 `failed`,原因写入具体错误码,同一邮箱不再重复使用,审计日志记录完整请求/响应摘要(脱敏后) | Mock 注册接口返回 400验证数据库与日志 |
| FP-06 | 自动注册成功后,验证步骤发现密钥无效 | 账号状态保持 `pending`,自动注册任务标记为 `verify_failed`,触发告警,不进入 active | Mock verify 返回失败,验证状态机 |
| FP-07 | 全网扫描时供应商模型列表分页异常(如页码越界返回 500 | 扫描任务记录分页失败,已获取的部分模型仍正常处理,失败页在下一周期重试 | Mock 分页接口第 3 页返回 500验证整体任务不中断 |
| FP-08 | 数据库在探针执行期间不可用 | 探针任务失败,记录错误,不触发状态变更;调度器按配置重试;连续失败 5 次后暂停该批次探针,触发系统级告警 | 模拟 PostgreSQL 断开,验证行为 |
| FP-09 | 运营人员同时点击“确认上架”与“忽略此模型” | 乐观锁或幂等键保证只有一个操作生效,第二个操作返回 409 Conflict界面提示“该模型已被处理” | 并发 UI 操作测试 |
| FP-10 | 凭证加密 KMS 服务在自动注册期间不可用 | 注册流程在加密步骤阻塞,等待 KMS 恢复或超时60 秒);超时后任务标记为 `failed`,明文凭证不得落盘 | Mock KMS 超时,验证明文不出现在日志/数据库 |
---
## 7. 上线与运营准备
### 7.1 发布策略
- **阶段 1灰度**:选择 2 个非核心供应商(如测试环境专用供应商)开启自动探针与模型发现,观察 7 天。
- **阶段 2扩展**:覆盖全部供应商的探针与发现能力,但自动状态变更仅对 `sandbox` 环境账号生效,生产环境账号的探针结果只生成告警,不自动改状态。
- **阶段 3全量**:生产环境账号启用自动状态变更,模型准入测试与自动注册按需逐步开启。
### 7.2 灰度/回滚
- 灰度开关通过配置中心控制,维度包括:
- `probe.enabled`:全局探针开关
- `probe.auto_transition.supplier_ids`:允许自动状态变更的供应商白名单
- `discovery.enabled`:全网扫描开关
- `admission_test.enabled`:准入测试开关
- `auto_registration.enabled`:自动注册开关
- 回滚条件(任一触发即全量关闭对应模块):
- 1 小时内探针误报率 > 5%
- 自动状态变更导致用户可见错误率上升(对比基线)> 2%
- 自动注册任务连续失败率 > 50%(持续 1 小时)
- 回滚操作:修改配置中心对应开关为 `false`60 秒内生效,已变更的状态不自动回退,由运营人员人工审核。
### 7.3 埋点/监控/告警
#### 埋点事件
| 事件名 | 触发时机 | 关键属性 |
|-------|---------|---------|
| `si_probe_executed` | 每次探针执行完成 | `platform`, `account_id`, `result`, `latency_ms` |
| `si_state_transitioned` | 账号状态自动变更 | `platform`, `account_id`, `from_status`, `to_status`, `reason` |
| `si_model_discovered` | 发现新模型 | `platform`, `model_id`, `discovery_source` |
| `si_admission_test_completed` | 准入测试完成 | `platform`, `model_id`, `result`, `duration_sec` |
| `si_auto_register_completed` | 自动注册完成 | `platform`, `result`, `duration_sec` |
#### 监控指标Prometheus
| 指标名 | 类型 | 说明 |
|-------|------|------|
| `si_probe_latency_seconds` | Histogram | 探针请求延迟 |
| `si_probe_result_total` | Counter | 探针结果分类success/failure/inconclusive |
| `si_state_transition_total` | Counter | 状态变更次数 |
| `si_discovery_models_total` | Gauge | 当前候选模型数量(按 status 分标签) |
| `si_admission_test_duration_seconds` | Histogram | 准入测试耗时 |
| `si_auto_register_result_total` | Counter | 自动注册结果分类 |
#### 告警规则
| 告警名 | 条件 | 通知对象 | 级别 |
|-------|------|---------|------|
| 探针大面积失败 | 1 小时内探针失败率 > 20% | 技术负责人 | P1 |
| 供应商账号全部失效 | 某供应商 active 账号数 = 0 持续 > 10 分钟 | 运营+技术 | P0 |
| 自动注册连续失败 | 1 小时内自动注册失败率 > 50% | 供应链管理员 | P1 |
| 新模型堆积未处理 | `status=discovered` 的候选模型数 > 20 且持续 > 24 小时 | 运营团队 | P2 |
| 系统自身健康异常 | 本服务 `/actuator/health/ready` 返回非 200 持续 > 1 分钟 | 技术负责人 | P0 |
### 7.4 FAQ预置
**Q1自动状态变更会不会把正常的供应商误杀掉**
A探针采用“连续失败才降级”策略active → suspended 需 1 次明确失败suspended → disabled 需连续 3 次失败。运营人员可随时在后台暂停单个账号的自动探针。
**Q2模型准入测试失败了我还能手动上架吗**
A可以。运营人员可以在工作台查看失败详情选择“手动强制上架”此时系统生成 package 草稿但标记为 `manually_forced`,并强制要求运营人员填写强制上架理由,该理由写入审计日志。
**Q3自动注册生成的账号归属谁**
A自动注册账号的 `user_id` / `supplier_user_id` 关联到平台运营系统账号(可配置),收益结算走平台统一账户。
---
## 8. 商业化与价值闭环
### 8.1 收益路径
| 路径 | 描述 | 量化 |
|-----|------|------|
| 直接收益 | 新模型上架速度提升 → 平台可售模型数增加 → 订单量增长 | 每提前 1 天上架一个热点模型,预估带来 X 订单增量(需商务提供历史数据基线) |
| 成本节省 | 运营人力减少 → 供应链维护 headcount 或工时下降 | 按 BG-04 目标,每周节省 70% 工时,折算年化人力成本 |
| 质量溢价 | 供应商失效导致的客诉减少 → NPS 提升 → 客户续约率提升 | 减少的客诉数 × 单客诉处理成本 + 续约率提升带来的 LTV 增量 |
### 8.2 北极星指标
- **供应链接新鲜度指数Supply Freshness Index, SFI**
- 定义SFI = (过去 1 小时成功探针的账号数 / 应探针账号总数) × (过去 24 小时进入 active 的新模型数 / 过去 24 小时发现的新模型总数)
- 目标值SFI ≥ 0.95
- 采集周期:每小时计算一次,写入时序数据库
### 8.3 失败判定线
项目在以下任一条件触发时,判定为失败并启动止损:
1. 上线后 30 天内因本系统导致的供应商状态误变更false positive累计 > 50 次。
2. 上线后 30 天内,因自动状态变更或自动注册导致用户可见支付/使用故障 > 3 次。
3. SFI 连续 7 天 < 0.70,且技术团队无法给出明确修复排期。
4. 自动注册模块因供应商接口变更导致连续 14 天成功率 < 30%,且无替代方案。
### 8.4 止损条件
- 触发失败判定线后PM 与 TechLead 在 24 小时内决定是否:
- **降级**:关闭自动状态变更与自动注册,仅保留探针监控与模型发现(纯观测模式)。
- **下线**:完全卸载本系统,回退至纯人工维护模式,保留审计日志备查。
- 无论降级或下线,已生成的 supply_package 草稿和已注册的账号不受影响,由运营人员人工接管。
---
## 9. 依赖与风险
### 9.1 外部依赖
| 依赖方 | 依赖内容 | 风险等级 | 缓解措施 |
|-------|---------|---------|---------|
| 各供应商 | 模型列表接口、注册接口、探针端点的稳定性与兼容性 | 高 | 接口变更监测Mock 回归测试集;供应商接口版本锁定 |
| SMS/邮件网关 | 自动注册验证码接收 | 中 | fail-closed备用邮箱池人工兜底流程 |
| KMS 服务 | 新注册账号凭证加密 | 中 | 加密失败阻塞落盘,任务进死信队列 |
| 平台 Job Scheduler | 定时任务调度 | 低 | 调度失败时探针/扫描延迟,不引入错误状态 |
| supply-api 现有服务 | 复用 Verify、AccountStore、PackageStore、AuditStore | 低 | 接口契约冻结;变更需双方 CR |
### 9.2 技术风险
| 风险编号 | 风险描述 | 概率 | 影响 | 应对 |
|---------|---------|------|------|------|
| R-01 | 探针频率过高导致供应商侧将我们视为攻击源,封禁平台 IP | 中 | 高 | 探针频率可配置;使用平台统一出口 IP 池;对每家供应商遵守其 rate limit 文档 |
| R-02 | 供应商模型列表接口返回缓存旧数据,导致“已下架模型”误判 | 中 | 中 | 列表接口响应加 TTL 校验;结合官方文档 RSS/变更日志交叉验证 |
| R-03 | 自动注册的浏览器自动化流程(如 Selenium/Playwright因供应商前端改版失效 | 高 | 中 | 优先使用官方 API 注册;浏览器自动化作为 fallback前端改版监控 |
| R-04 | 准入测试用例不足以覆盖供应商实际兼容性问题,导致 test_passed 但上线后用户报错 | 中 | 高 | 测试用例由 QA 维护并定期评审;上线后 24h 内对新模型增加采样监控 |
| R-05 | 数据库 model_candidates 表数据膨胀,影响查询性能 | 低 | 中 | 设置自动清理策略test_failed 且超过 30 天未手动处理的记录自动删除 |
### 9.3 合规与隐私风险
- 自动注册过程中收集的邮箱、手机号属于个人信息,需符合平台隐私政策与相关法律法规。
- 凭证指纹(`credential_fingerprint`)仅存储哈希值,不得存储明文 API Key。
- 审计日志中的请求/响应摘要需脱敏,不得包含完整 credential。
---
## 10. 技术栈与集成约束
### 统一技术栈
本项目必须与立交桥主项目保持一致:
- **语言**: Go 1.22+
- **HTTP框架**: 标准库 `net/http` + 自定义中间件(禁止引入 Gin/Echo 等第三方框架,保持与 gateway/ 和 supply-api/ 的一致性)
- **数据库**: PostgreSQL 15+ ,驱动 `jackc/pgx/v5`
- **缓存**: Redis客户端 `redis/go-redis/v9`
- **配置**: YAML + Viper环境变量覆盖敏感字段
- **日志/审计**: 结构化日志,审计事件模型与 supply-api/ 一致
- **错误码**: `{SOURCE}_{CATEGORY}_{CODE}` 格式,例如 `SUP_INT_4001`
- **健康检查**: `/actuator/health``/actuator/health/live``/actuator/health/ready`
- **测试**: Go testing + testify覆盖率门槛 domain ≥ 70%、service/handler ≥ 80%
### 独立运行与集成运行
本系统必须同时支持两种运行模式:
| 模式 | 特征 | 部署方式 | 适用场景 |
|------|------|---------|---------|
| **独立运行** | 自有 `cmd/supply-intelligence/main.go`,独立数据库 schema独立 docker-compose | `docker-compose up` 或单独容器 | 外部用户只需要供应链管理能力,不想接入立交桥全套 |
| **集成运行** | 作为 Go module 被 `supply-api/` 引入,共享数据库连接池和配置,通过内部接口注册 | 编译时作为子模块编译,运行时挂载到 supply-api 主进程 | 立交桥用户希望获得一体化供应链能力 |
**集成约束**:
- 独立运行时,系统必须提供完整的 HTTP API 和运营工作台。
- 集成运行时,系统必须提供 `IntegrationPlugin` 接口,允许主程序通过配置开关启用/禁用各模块。
- 数据库 schema 必须使用独立的 `supply_intelligence_` 前缀,避免与主项目表名冲突。
- 配置文件必须支持分离加载:独立运行时读取自己的 `config.yaml`,集成运行时合并到主项目配置。
### NewAPI / Sub2API 适配支持
本系统的核心能力必须能够对接 NewAPI 和 Sub2API 系统:
- **供应商状态同步**: 提供标准化的供应商健康状态接口NewAPI/Sub2API 可定期获取供应商可用性状态。
- **模型列表推送**: 提供 `/models` 接口返回平台已发现、已测试通过的模型列表NewAPI/Sub2API 可消费此数据自动补充自己的模型库。
- **账号注册适配**: 自动注册模块通过适配层支持 NewAPI/Sub2API 的账号管理 API实现跨平台账号生命周期管理。
- **独立部署时**: 通过配置文件指定 NewAPI/Sub2API 的管理端点地址和鉴权信息本系统通过适配层Adapter与之交互。
- **集成部署时**: 若立交桥 gateway/ 已接入 NewAPI/Sub2API本系统通过 supply-api/ 的内部接口操作上游状态。
### 对外接口契约
- 必须提供 OpenAPI 3.0 接口文档,确保 NewAPI/Sub2API 开发者可以独立接入。
- 接口路径前缀默认为 `/api/v1/supply-intelligence/`,集成运行时可通过配置改为 `/internal/supply-intelligence/`
---
## 11. 阶段门控结论
### 11.1 当前状态
**可进入 TechLead 评审,但需补充以下信息后方可进入开发排期:**
1. **供应商接口清单**:需由商务/技术团队提供 Phase 1 目标供应商的模型列表接口文档、注册接口文档(或明确标注哪些供应商不支持自动注册)。
2. **测试用例集范围**:需 QA 团队确认准入测试用例集的初始版本(≥ 5 个用例/模型类型)及维护 SLA。
3. **Job Scheduler 契约**:需明确平台统一调度器的接口契约(如任务提交格式、超时控制、死信策略)。
4. **KMS 与 SMS 网关就绪状态**:生产环境 KMS 与 SMS/邮件网关当前不可用需寻找合适的供应商并确认集成方案。若短期内无法就绪自动注册模块Phase 3需明确为远期交付当前 Phase 1/2 不受影响。
### 11.2 建议开发优先级
| 阶段 | 内容 | 目标 |
|-----|------|------|
| Phase 1 | 供应商品质探针(模块 A+ 运营工作台观测视图(模块 E 只读部分) | 解决最痛的可用性黑洞问题7 天灰度验证 |
| Phase 2 | 全网模型发现(模块 B+ 模型准入测试(模块 C | 解决新模型上市滞后问题 |
| Phase 3 | 账号自动注册(模块 D+ 运营工作台完整干预能力(模块 E 读写部分) | 解决供应商账号补充效率问题 |
### 11.3 门控决策
- **不阻塞 TechLead 评审**PRD 中需求边界、验收标准、失败路径已清晰。
- **阻塞开发排期**:直到上述 4 项补充信息供应商接口清单、测试用例集、Job Scheduler 契约、KMS/SMS 就绪状态)以文档形式补充到本 PRD 附录后方可进入技术方案设计HLD阶段。
- **技术栈与集成约束已明确**:统一 Go 标准库、独立/集成双模式、NewAPI/Sub2API 适配层已纳入范围。
---
## 附录 A新增数据表草案供 TechLead 参考,非最终 Schema
> 本附录仅用于需求对齐,最终 Schema 由 TechLead 设计并通过标准 SQL migration 落地。
### A.1 model_candidates
| 字段 | 类型 | 说明 |
|-----|------|------|
| id | BIGINT PK | 自增 |
| platform | VARCHAR(50) | 供应商标识,与 supply_accounts.platform 同枚举 |
| model_id | VARCHAR(100) | 模型标识 |
| model_name | VARCHAR(200) | 可读的模型名称(从供应商接口获取) |
| status | VARCHAR(20) | `discovered`, `testing`, `test_passed`, `test_failed`, `ignored`, `expired` |
| discovered_at | TIMESTAMPTZ | 首次发现时间 |
| tested_at | TIMESTAMPTZ | 最近一次测试时间 |
| failure_reason | TEXT | 测试失败原因 |
| ignored_until | TIMESTAMPTZ | 忽略有效期 |
| created_at | TIMESTAMPTZ | |
| updated_at | TIMESTAMPTZ | |
唯一约束:`(platform, model_id)`
### A.2 auto_registration_tasks
| 字段 | 类型 | 说明 |
|-----|------|------|
| id | BIGINT PK | 自增 |
| platform | VARCHAR(50) | 目标供应商 |
| task_type | VARCHAR(20) | `register`, `verify`, `rotate_key` |
| status | VARCHAR(20) | `pending`, `running`, `completed`, `failed`, `dead_letter` |
| context | JSONB | 任务上下文(如申请的邮箱、注册步骤状态机) |
| result_account_id | BIGINT | 成功后关联的 supply_accounts.id |
| failure_reason | TEXT | |
| retry_count | INT DEFAULT 0 | |
| next_retry_at | TIMESTAMPTZ | |
| created_at | TIMESTAMPTZ | |
| updated_at | TIMESTAMPTZ | |
### A.3 probe_execution_logs
| 字段 | 类型 | 说明 |
|-----|------|------|
| id | BIGINT PK | 自增 |
| account_id | BIGINT FK | supply_accounts.id |
| probe_type | VARCHAR(20) | `connectivity`, `quota`, `key_validity` |
| result | VARCHAR(20) | `success`, `failure`, `inconclusive` |
| http_status | INT | |
| latency_ms | INT | |
| error_code | VARCHAR(50) | 平台内部错误码 |
| error_message | TEXT | |
| executed_at | TIMESTAMPTZ | |
索引:`account_id + executed_at DESC`,保留策略 30 天。
---
## 自检清单
- [x] 已明确真实目标(降低供应商失效导致的错误率、缩短新模型上市时间、减少人工维护工时),不是只复述功能。
- [x] 已写清 In Scope / Out of Scope边界以模块和具体场景描述。
- [x] 每个 AC 都可被 QA 或测试用例直接验证(含具体数值、时间、状态、测试方法)。
- [x] 已覆盖异常流Rate Limit、超时、网关不可用、边缘流模型 ID 变更、手动暂停探针、并发操作)与失败路径(共 10 条)。
- [x] 已补齐上线、运营、监控、回滚要求(灰度三阶段、回滚条件、埋点、监控指标、告警规则、预置 FAQ
- [x] 已定义商业化/价值闭环(直接收益、成本节省、质量溢价三条路径)。
- [x] 已定义成功指标BG-01/03/04 + SFI与失败判定线4 条止损条件)。
- [x] 已明确当前是否可进入 TechLead 阶段:可进入 TechLead 评审,但需补充 4 项信息后方可进入开发排期。
- [x] 没有使用"优化、支持、友好、尽量、快速"等模糊词替代明确要求;所有时间、比例、次数均为具体数值或明确公式。
---