PMFlow/docs/GLM5_SIGNAL_PLANNER_IMPLEME...

10 KiB
Raw Permalink Blame History

GLM-5 Signal Planner + 增量任务包管理实施清单(可打勾执行版)

使用规则:严格按步骤推进;每个步骤完成后再勾选;未完成禁止进入下一步。

0. 全局硬约束(执行前必须确认)

  • 所有业务写操作必须通过 service/repository 入口调用。
  • 严禁在调用链路散落裸 ORM insert/update/commit。
  • 数据库结构改动仅通过 Alembic migration。
  • API 统一包络:{code, message, data}。
  • 后端契约变更必须同步前端 TS 类型与文档。
  • 删除任何代码前必须执行 FIND_USAGE 并留证据。
  • 发现违例立即停止并输出 [VIOLATION: 裸写位置]。
  • 模型选择必须接口化配置,禁止在业务代码写死 provider/model/api_env。

1. 执行总览(里程碑)

  • Step 0:基线文档与自动增量机制
  • Step 1:Signal Planner 数据层改造
  • Step 2:写入服务收口(StrategicAnalysis + Outbox)
  • Step 3:SignalPlannerService 接入
  • Step 4:主链路触发与路由配置
  • Step 5:模型灵活配置(接口化,禁止写死)
  • Step 6:前端展示与侧边栏新增功能
  • Step 7:脏代码/无用代码删减
  • Step 8:验收与交付

Step 0:基线文档与自动增量机制

入口条件

  • 项目当前主分支可读,文档目录可写。

执行项

  • 新建 docs/architecture/MASTER_CONTRACT.md
  • 新建 docs/architecture/API_CONTRACTS.md
  • 新建 docs/architecture/DATAFLOW.md
  • 新建 docs/architecture/TASK_BRIEF_TEMPLATE.md
  • 新建 scripts/gen_task_brief.sh(自动生成增量任务包)
  • 新建 scripts/check_contract_sync.sh(契约同步检查)
  • CI 增加 contract-check job

完成标志

  • 本地可自动生成一份有效增量任务包
  • CI 可检测契约文档未同步并正确失败

Step 1:Signal Planner 数据层改造

入口条件

  • Step 0 完成

执行项

  • 新增 migration:signals.planner_status VARCHAR(20) DEFAULT 'pending'
  • 新增 migration:signals.planner_analyzed_at TIMESTAMP
  • 新增 migration:signals.planner_assignee_user_id INTEGER
  • 为 planner_status 增加索引
  • 同步更新 backend/app/models/signal.py

完成标志

  • alembic upgrade 后表结构正确
  • ORM 模型可读写三字段

Step 2:写入服务收口

入口条件

  • Step 1 完成

执行项

  • 新建 backend/app/services/signal_strategic_analysis_service.py
  • 实现 merge_and_save(db, signal_id, planner_result, tenant_id)
  • 实现 mark_failed(db, signal_id, tenant_id, reason)
  • 新建 backend/app/services/feishu_outbox_service.py
  • 实现 enqueue(db, chat_id, text, source_message_id, dedupe_seed)
  • 幂等策略复用 reply_hash,不新增 outbox 冗余字段

完成标志

  • 新增 service 覆盖 Planner 写回与补发入队
  • 新增 service 文件中无业务外层裸写调用

Step 3:SignalPlannerService 接入

入口条件

  • Step 2 完成

执行项

  • 新建 backend/app/services/signal_planner_service.py
  • analyze(...) 内部使用独立 AsyncSessionLocal
  • 上下文查询使用现网字段:signals.matched_project_id
  • 成员查询通过 user_projects -> users -> user_workloads -> user_skill_bindings -> skill_tags
  • 调用 llm_service.generate_structured_object(function_name="signal_planner_analyze")
  • 成功路径调用 SignalStrategicAnalysisService.merge_and_save
  • 失败路径调用 SignalStrategicAnalysisService.mark_failed
  • 补发路径调用 FeishuOutboxService.enqueue

完成标志

  • Planner 失败不阻断主链路
  • Planner 成功后 strategic_analysis.ai_planner 写回成功

Step 4:主链路触发与路由配置

入口条件

  • Step 3 完成

执行项

  • 修改 backend/app/services/ai_pmo_kernel_service.py
  • signal.create 成功提交后 create_task(SignalPlannerService.analyze(...))
  • 在 backend/app/config/ai_prompts.py 增加 PROMPT_SIGNAL_PLANNER
  • 在 LLM 结构化 schema 注册 signal_planner_analyze
  • 更新 backend/.control_plane/pmflow-routing-rules.json 添加 high tier 路由

完成标志

  • 触发点仅在 commit 后
  • 路由命中 signal_planner_analyze

Step 5:模型灵活配置(接口化,禁止写死)

入口条件

  • Step 4 完成

执行项

  • 新建后端配置接口:backend/app/api/model_routing.py
  • 新建后端服务:backend/app/services/model_routing_service.py
  • 提供查询接口:按 function_name 读取当前生效模型路由
  • 提供更新接口:按 function_name 更新 provider/model/api_env/tier
  • 配置持久化到统一配置源(数据库 Integration 或统一配置表)
  • SignalPlannerService 改为运行时读取 signal_planner_analyze 路由配置,不在代码中写死模型
  • 保留默认兜底:当配置缺失时走安全默认路由,但记录告警日志
  • 增加权限控制:仅管理员可修改模型路由配置
  • 增加审计:每次配置变更写 operation_log

完成标志

  • 通过接口切换模型后,Planner 无需改代码即可生效
  • 业务代码中不存在写死的 signal_planner_analyze -> GLM-5 绑定

Step 6:前端展示与侧边栏新增功能

入口条件

  • Step 5 完成

执行项(Signal 展示)

  • 修改 backend/app/api/sstc.py 返回 planner 字段与 strategic_analysis
  • 修改 frontend/src/api/sstc.ts 扩展 SSTCSignal 类型
  • 修改 frontend/src/components/sstc/SignalContentHoverCard.tsx
  • planner_status=pending 显示“AI 分析中...”
  • planner_status=completed 显示分析区块
  • planner_status=failed 不显示分析区块

执行项(侧边栏任务包管理)

  • 修改 frontend/src/components/layout/Sidebar.tsx 增加入口:增量任务包中心
  • 修改 frontend/src/components/layout/Sidebar.tsx 增加入口:任务包模板管理
  • 修改 frontend/src/components/layout/Sidebar.tsx 增加入口:任务包生成记录
  • 修改 frontend/src/components/layout/Sidebar.tsx 增加入口:契约同步看板
  • 新建页面 frontend/src/pages/TaskBriefCenterPage.tsx
  • 新建页面 frontend/src/pages/TaskBriefTemplatePage.tsx
  • 新建页面 frontend/src/pages/TaskBriefRunsPage.tsx
  • 新建页面 frontend/src/pages/ContractSyncBoardPage.tsx
  • 修改 frontend/src/router/index.tsx 注册新路由
  • 新建 frontend/src/api/taskBriefs.ts
  • 新建后端 backend/app/api/task_briefs.py
  • 新建后端 backend/app/services/task_brief_service.py
  • 新增模型路由管理入口:模型路由配置
  • 新建页面 frontend/src/pages/ModelRoutingConfigPage.tsx
  • 新建前端 API frontend/src/api/modelRouting.ts
  • 页面通过接口读取/更新 signal_planner_analyze 模型映射

完成标志

  • 侧边栏 4 个新入口均可访问
  • 任务包管理基础流程可跑通
  • 模型路由可在前端页面配置并即时生效

Step 7:脏代码/无用代码删减(强制)

入口条件

  • Step 6 完成

执行项

  • 清理未使用 imports/variables/functions/components/routes
  • 清理重复工具函数与废弃 fallback 分支
  • 删除无效 feature flag 与历史临时代码
  • 清理无引用 API 封装与页面入口
  • 每一处删除前后均有 FIND_USAGE 结果留档

门禁

  • PR 附“删除清单 + 引用扫描结果”
  • 删除后构建与回归通过,否则回退该删除批次

完成标志

  • 无死代码残留在本次改动链路
  • 无跨域误删

Step 8:验收与交付

入口条件

  • Step 7 完成

功能验收

  • 飞书触发后信号主链路正常入库
  • 30 秒内 planner_status=completed
  • strategic_analysis.ai_planner 非空
  • 相同消息补发不重复入队
  • 通过模型路由接口切换模型后,Planner 走新模型且结果正常

数据库只读验收

  • 执行:
    • SELECT planner_status, planner_analyzed_at, strategic_analysis::jsonb->'ai_planner' FROM signals ORDER BY created_at DESC LIMIT 1;
  • 三项均符合预期

构建验收

  • python -m py_compile 通过
  • npm run build 通过
  • tsc --noEmit 零错误

文档验收

  • MASTER_CONTRACT.md 同步
  • API_CONTRACTS.md 同步
  • DATAFLOW.md 同步
  • CLAUDE.md 同步

交付物

  • 变更文件清单
  • 飞书补发记录截图
  • 数据库查询截图
  • 侧边栏新增功能截图
  • 模型路由接口调用与生效截图
  • 脏代码删减清单与 FIND_USAGE 证据

Step 7/8 执行证据(2026-03-12)

  • 删除清单:
    • frontend/src/api/modelRouting.ts 删除零引用方法 modelRoutingApi.getFunction
    • backend/app/services/model_routing_service.py 修复 JSON 浅拷贝导致配置更新不落库
    • backend/app/services/task_brief_service.py 修复 JSON 浅拷贝导致任务包配置更新不落库
    • backend/app/services/signal_planner_service.py 增加结构化失败降级与 25s 硬超时收敛
  • FIND_USAGE(删除前后):
    • 删除前:rg -n "modelRoutingApi\\.getFunction|getFunction\\(" frontend/src 命中 frontend/src/api/modelRouting.ts:38
    • 删除后:同命令无输出(0 命中)
    • 共享符号追踪:rg -n "class SignalPlannerService|SignalPlannerService\\.analyze\\(" backend/app 命中 signal_planner_service.py 与 ai_pmo_kernel_service.py:1695
  • 功能验收样本:
    • signal_id=273:elapsed_seconds=30,planner_status=completed,ai_planner_state=NOT_NULL
    • 重复消息幂等:source_message_id=dedupe-signal-1773313023 在 ingest_events/work_items 计数均为 1
    • 模型路由覆盖生效日志:函数覆盖路由命中:function=signal_planner_analyze, provider=glm, model=qwen-plus
  • 截图产物:
    • docs/task_briefs/sidebar_new_entries_20260312.png
    • docs/task_briefs/model_routing_override_effective_20260312.png
  • [BOUNDARY: 当前任务未接入飞书真实回调流量,飞书补发记录截图 与 数据库查询截图 需人工在目标环境补齐]