# P15:AI 监控后台 + 测试重建 + 回填 > 状态:Draft | 创建日期:2026-03-21 | 依赖:P14(DashScope 迁移 + 调度器完善) > 前置条件:P14 全部完成并验证通过后,方可开始 P15 实施 --- ## 一、执行摘要 P14 完成 SDK 迁移和调度器修复后,本 PRD 覆盖三个方面: 1. admin-web AI 监控后台(运行总览、调度状态、调用明细、手动操作) 2. 测试体系重建(旧脚本归档、新全链路测试、属性测试更新) 3. 历史数据回填(半年内活跃会员,<100 人) ### 问题覆盖 本 PRD 覆盖 `docs/reports/2026-03-21__ai_module_issues.md` 中的: - P2-1:App5 话术缺分类 - P2-2:MCP 无健康检查 - P2-4:全链路测试不完整 - P3-3:Prompt 版本管理(仅监控展示部分) --- ## 二、admin-web AI 监控后台 ### 2.1 技术基础 - 框架:React + Vite + Ant Design(已有 8 个页面,加页面即可) - 认证:JWT Bearer Token,复用现有 admin 权限体系 - API 前缀:`/api/admin/ai/*` - 权限:系统管理员全量可见,不脱敏,点开详情看原文 - 门店筛选:支持按 `site_id` 筛选查看 ### 2.2 页面规划 #### 页面 1:AI 运行总览(Dashboard) | 区域 | 内容 | 数据来源 | |------|------|---------| | 顶部统计卡片 | 今日调用次数、成功率、Token 消耗、平均延迟 | `ai_run_logs` 聚合 | | 趋势图 | 近 7 天调用量 + 成功率折线图 | `ai_run_logs` 按日聚合 | | App 分布 | 各 App 调用占比饼图 | `ai_run_logs.app_type` 分组 | | Token 预算 | 日/月预算使用进度条 | `ai_run_logs.tokens_used` 聚合 | | 告警列表 | 最近失败/超时/熔断事件 | `ai_run_logs` WHERE status IN ('failed','timeout') | #### 页面 2:调度状态 | 区域 | 内容 | 数据来源 | |------|------|---------| | 触发任务列表 | 分页表格:事件类型、会员、状态、执行链、耗时 | `ai_trigger_jobs` | | 筛选器 | event_type / status / site_id / 日期范围 | — | | 操作列 | 查看详情、手动重跑 | — | | 去重统计 | 今日跳过的重复事件数 | `ai_trigger_jobs` WHERE status='skipped_duplicate' | #### 页面 3:调用明细 | 区域 | 内容 | 数据来源 | |------|------|---------| | 调用记录表格 | app_type、trigger_type、member_id、tokens、延迟、状态 | `ai_run_logs` | | 筛选器 | app_type / status / trigger_type / site_id / 日期范围 | — | | 详情抽屉 | 点击行展开:完整 prompt、完整 response、error_message | `ai_run_logs` 单条 | #### 页面 4:手动操作 | 功能 | 说明 | |------|------| | 手动重跑 | 选择 App + 会员 + 门店,触发单次执行(标记 `is_forced=true`) | | 缓存失效 | 按 App / 会员 / 门店批量将 `ai_cache.status` 设为 `invalidated` | | 成本二次确认 | 批量操作前展示预估调用次数和 Token 消耗,点"确认执行"后才真正执行 | | 告警确认/忽略 | 对失败告警标记"已确认"或"忽略" | ### 2.3 后端 API 清单 ``` GET /api/admin/ai/dashboard — 总览统计数据 GET /api/admin/ai/trigger-jobs — 调度任务列表(分页 + 筛选) GET /api/admin/ai/trigger-jobs/:id — 调度任务详情 POST /api/admin/ai/trigger-jobs/:id/retry — 手动重跑 GET /api/admin/ai/run-logs — 调用记录列表(分页 + 筛选) GET /api/admin/ai/run-logs/:id — 调用记录详情(含完整 prompt/response) POST /api/admin/ai/cache/invalidate — 批量缓存失效 GET /api/admin/ai/budget — Token 预算使用情况 POST /api/admin/ai/batch-run — 批量执行(需二次确认) POST /api/admin/ai/batch-run/confirm — 确认批量执行 GET /api/admin/ai/alerts — 告警列表 POST /api/admin/ai/alerts/:id/ack — 确认告警 POST /api/admin/ai/alerts/:id/ignore — 忽略告警 ``` ### 2.4 成本二次确认流程 ``` 管理员选择批量操作(如:回填 50 个会员) → POST /api/admin/ai/batch-run → 后端计算:50 会员 × 5 App = 250 次调用,预估 ~500K tokens → 返回 { batch_id, estimated_calls: 250, estimated_tokens: 500000 } → 前端展示确认弹窗:"本次将执行 250 次 AI 调用,预估消耗 50 万 tokens,确认执行?" → 管理员点"确认执行" → POST /api/admin/ai/batch-run/confirm { batch_id } → 后端异步执行 ``` --- ## 三、测试体系重建 ### 3.1 旧测试脚本归档 以下 4 个脚本移至 `_archived/` 目录: | 脚本 | 原位置 | 归档位置 | |------|---------|---------| | `ai_full_chain_test.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `test_chat_e2e.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `test_chat_ai_quality.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `test_bailian_apps.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `test_bailian_single.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `test_bailian_full.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `_run_ai_tests_remaining.py` | `scripts/ops/` | `scripts/ops/_archived/` | | `test_ai_bailian.py` | `apps/backend/tests/` | `apps/backend/tests/_archived/` | | `2026-03-21__ai_full_chain_test.md` | `docs/reports/` | `docs/reports/_archived/` | 归档时保留文件内容不变,仅移动位置。审计记录(`docs/audit/`)不删除,只停止引用。 ### 3.2 新全链路测试 #### 测试覆盖矩阵 | 测试场景 | 覆盖 App | 验证点 | |---------|---------|--------| | App1 对话(10 种入口) | App1 | SSE 流式、session_id 双轨、对话复用规则 | | App2 定时预生成 | App2 | 8 个时间维度、缓存写入、JSON 合法性 | | 消费事件触发链 | App3→App8→App7 | 事件传播、缓存写入、业务表写入 | | 助教消费触发链 | App3→App8→App7→App4→App5 | 完整链路、助教关联 | | 备注事件触发链 | App6→App8 | 备注分析、线索整合 | | 任务分配触发链 | App4→App5 | 关系分析、话术生成 | | 缓存命中 | App2~8 | 缓存有效期内直接返回、过期后重新生成 | | 缓存失效 | App2~8 | admin-web 手动失效后重新生成 | | 熔断触发 | 任意 App | 连续 5 次失败→熔断→半开→恢复 | | Token 预算超限 | 任意 App | 超限后正确降级 | | 失败记录 | 任意 App | `ai_run_logs` 记录完整、error_message 有值 | | 后台可见性 | 全部 | admin-web 能看到所有运行记录和详情 | | JSON 兜底 | App2~8 | 非法 JSON 重试 3 次 | | 幂等验证 | App8 | 同一 member 同一天重复触发只执行一次 | | 内容质量 | App2~8 | 返回内容包含必要字段、格式正确 | #### App1 的 10 种入口 1. general(通用对话,始终新建) 2. customer_detail(客户详情页) 3. coach_detail(助教详情页) 4. task_detail(任务详情页) 5. finance_overview(财务总览页) 6. member_list(会员列表页) 7. settlement_detail(结算详情页) 8. note_detail(备注详情页) 9. dashboard(首页仪表盘) 10. report(报表页) ### 3.3 属性测试更新 更新 `tests/` 下的 Hypothesis 属性测试: | 属性测试 | 验证不变量 | |---------|-----------| | 熔断器状态机 | 状态转换合法性:closed→open→half_open→closed/open | | Token 预算计算 | 日/月聚合值 = 各条记录 tokens_used 之和 | | 去重逻辑 | 相同 (event_type, member_id, site_id, date) 只产生一条非 skipped 记录 | | 缓存过期 | expires_at 过期的缓存 status 必须为 expired | | App8 幂等 | 同一 member 同一天的 member_retention_clue 只有一组记录 | | session_id 重建 | 重建后的 messages 数组与本地 ai_messages 一致 | | 限流计数 | 窗口内请求数不超过上限 | --- ## 四、历史数据回填 ### 4.1 回填范围 半年内(2025-09-21 ~ 2026-03-21)三者并集: - 有消费记录的 member - 有备注记录的 member - 有任务变更的 member 预估规模:<100 会员。 门店范围:`site_id = 2790685415443269`(写死)。 ### 4.2 回填策略 - 执行方式:专门脚本(`scripts/ops/ai_backfill.py`) - 分批执行:每批 10 个会员,批间间隔 5 秒 - 断点续跑:脚本记录已完成的 member_id 列表到本地文件,失败后从断点继续 - 不备份现有数据 - App8 写业务表(`member_retention_clue`):DELETE + INSERT,事务包裹 ### 4.3 回填调用链 每个会员执行: ``` App3(维客线索)→ App8(线索整理)→ App7(客户分析) 如有助教关联:→ App4(关系分析)→ App5(话术参考) 如有备注:→ App6(备注分析)→ App8(再次整合) ``` ### 4.4 成本预估 - 100 会员 × 平均 5 个 App = 500 次调用 - 每次约 2000 tokens → 总计约 100 万 tokens - 执行前通过 admin-web 二次确认 --- ## 五、数据保留策略 | 数据类型 | 保留策略 | 清理方式 | |---------|---------|---------| | App1 对话记录(ai_conversations + ai_messages) | 永久保留,不自动删除 | — | | App2~8 缓存(ai_cache) | 每个 App 保留最新 20,000 条 | 定时任务:按 created_at 排序,超出部分 DELETE | | AI 运行记录(ai_run_logs) | 保留 90 天 | 定时任务:DELETE WHERE created_at < now() - 90 days | | 调度记录(ai_trigger_jobs) | 保留 90 天 | 同上 | 清理定时任务建议每日凌晨 03:00 执行。 --- ## 六、后端 API 变更汇总 ### 新增路由文件 `apps/backend/app/routers/admin_ai.py` ### 新增 Service `apps/backend/app/services/ai/admin_service.py` — 聚合查询、批量操作、告警管理 ### 数据库查询优化 - `ai_run_logs` 的 Dashboard 聚合查询需要按日分区或添加 BRIN 索引 - `ai_trigger_jobs` 的去重查询已有复合索引(§P14 六.2) --- ## 七、问题修复映射 | 问题编号 | 优先级 | 描述 | 本 PRD 对应章节 | |---------|--------|------|----------------| | P2-1 | P2 | App5 话术缺分类 | 回填时验证 App5 输出包含分类字段 | | P2-2 | P2 | MCP 无健康检查 | admin-web Dashboard 展示各 App 最近调用状态 | | P2-4 | P2 | 全链路测试不完整 | §3.2(新全链路测试) | | P3-3 | P3 | Prompt 版本管理 | admin-web 展示当前 App 配置(只读) | --- ## 八、收尾标准流程 ### 8.1 DDL 迁移 本 PRD 无新增表(P14 已创建)。如有字段调整: 1. 编写增量迁移脚本 2. 测试库验证 3. 合并基线 ### 8.2 BD 手册更新 - 更新 `docs/database/BD_Manual_ai_tables.md`:补充 admin API 相关的查询模式说明 ### 8.3 文档同步 | 文档 | 更新内容 | |------|---------| | `apps/admin-web/README.md` | 新增 AI 监控页面说明 | | `apps/backend/README.md` | 新增 admin AI API 说明 | | `docs/DOCUMENTATION-MAP.md` | 新增条目 | | `docs/prd/ai-app-prompts.md` | 确认环境变量已全部更新 | ### 8.4 属性测试 - 新增 §3.3 中列出的 7 个属性测试 - 确保所有属性测试通过 ### 8.5 最终检查点 - [ ] admin-web AI 监控 4 个页面功能正常 - [ ] 手动重跑功能正常,标记 forced - [ ] 缓存失效功能正常 - [ ] 成本二次确认流程完整 - [ ] 旧测试脚本已归档到 `_archived/` - [ ] 新全链路测试覆盖 15 个场景 - [ ] 属性测试全部通过 - [ ] 回填脚本执行完成,<100 会员数据完整 - [ ] 数据保留定时任务配置完成 - [ ] 所有文档已同步更新 --- ## 九、风险与缓解 | 风险 | 影响 | 缓解措施 | |------|------|---------| | 回填触发大量 API 调用 | 成本突增 | 分批执行 + admin-web 二次确认 | | 回填中途失败 | 部分会员数据不完整 | 断点续跑机制 | | admin-web 查询大量 ai_run_logs 性能差 | 页面卡顿 | 分页 + 索引 + 90 天保留策略 | | 全链路测试依赖真实百炼 API | 测试不稳定 | Mock 模式 + 真实 API 模式双轨 | --- ## 十、不在本 PRD 范围 - 多门店支持(BACKLOG) - 消息队列(单独 PRD) - Prompt 版本管理的编辑功能(BACKLOG,本轮仅展示) - 前端刷新机制(P1-5) - FDW 数据一致性(P1-6) - 企业微信/邮件告警推送(后续迭代)