PMFlow/docs/FEISHU_AI_FLOW_CURRENT.md

247 lines
12 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.

# PMFlow 当前飞书接 AI 流程说明
更新时间:2026-03-10
## 1. 结论(当前接入方式)
- 当前生产链路是 **长连接(long_connection)**,不是 webhook。
- 真实入口链路:`FeishuLongConnectionManager -> FeishuIntegrationService -> ProactiveSignalCaptureService -> AIPMOKernelService`。
- 回消息统一走 **Outbox(feishu_reply_outbox)**,支持重试与补偿发送。
- `FeishuSignalPipelineService` 仍在代码中,但当前主链路未直接调用,主要用于历史/评测链路。
## 2. 端到端时序
```mermaid
sequenceDiagram
participant U as Feishu User
participant F as Feishu Open Platform
participant LC as FeishuLongConnectionManager
participant FI as FeishuIntegrationService
participant SC as ProactiveSignalCaptureService
participant K as AIPMOKernelService
participant DB as DB
participant OB as FeishuReplyOutbox
participant API as Feishu HTTP API
U->>F: 群消息 / @机器人
F-->>LC: long connection event (im.message.receive_v1)
LC->>FI: handle_message_event(event)
FI->>SC: capture_from_feishu(...)
SC->>K: process_feishu_message(...)
K->>DB: ingest_events/work_items/decision/plan/reply_receipts/signal
K-->>SC: capture_result (status/classification/direct_reply_text)
SC-->>FI: pipeline_result
FI->>OB: enqueue reply (pending)
OB->>API: send_message_to_group
API-->>OB: sent / retrying / failed
```
## 3. 详细流程
### 3.1 配置与启动
1. 前端配置页保存 `app_id/app_secret` 到 `POST /feishu/config`。
2. 后端写入 `integrations(type=feishu)`,并调用长连接管理器 `restart()`。
3. 应用启动时(`main.py` lifespan):
- 初始化并启动 `FeishuLongConnectionManager`。
- 启动 `feishu_outbox_drain_loop`,持续补偿发送 outbox。
补充:长连接重试策略来自环境变量:
- `FEISHU_LONG_CONNECTION_RETRY_BASE_SECONDS`(默认 1)
- `FEISHU_LONG_CONNECTION_RETRY_MAX_ATTEMPTS`(最大 3)
### 3.2 飞书事件接收(长连接)
1. 管理器线程内创建 `lark_oapi ws.Client`。
2. 仅业务事件 `message.receive_v1 / im.message.receive_v1` 进入主队列。
3. Worker 从队列取事件,调用 `FeishuIntegrationService.handle_message_event()`。
### 3.3 消息解析与预处理
在 `FeishuIntegrationService._handle_message_receive`:
1. 忽略机器人/应用发送者(`sender_type in {app, bot}`)。
2. 解析消息内容(支持 `text/post/image/file/media`),附件会归一化。
3. 记录 ingress trace 到 `ai_processing_logs`。
4. 无文本但被 @ 时,会回一条“请补充文字需求”的提示。
### 3.4 AI PMO 决策主链路
`ProactiveSignalCaptureService.capture_from_feishu` 会调用 `AIPMOKernelService.process_feishu_message`:
1. 清洗文本,先过滤空消息/纯噪音。
2. 生成 `source_message_id`,并写 `ingest_events` 做幂等去重。
3. 创建 `work_items`(状态机起点 `received`)。
4. 构建 world model(项目、预算、产能、技能、章程、任务、风险)。
5. Intent 识别:
- `query.read_only`
- `project.create`
- `signal.create`
- `signal_source.onboard`
- `followup.confirm / followup.continue`
- `ignore`
6. 三脑决策与仿真:战略、战术、执行前仿真 + policy gate。
7. 根据策略:
- 可自动执行:进入 typed executor。
- 不可自动执行:进入 `waiting_manual`,并推送站内待办通知。
8. 生成唯一回执(`reply_receipts`),避免同消息同 phase 重复回复。
### 3.5 Typed Executor 分支
- `query.read_only`:调用 `AdaptiveRAGService.answer_question`。
- `project.create`:调用 `AIStewardService.create_project_from_natural_language`。
- `signal.create`:直接创建 `signals`(可带 `project_id`)。
- `signal_source.onboard`:创建信号后,走 `SignalSourceDomainWorkflow`(底层编排 `SignalSourceOrchestrationService` / PMFlow 本地路由层)。
- `followup.*`:尝试恢复最近待确认工作项继续执行。
### 3.6 回复生成与发送
`FeishuIntegrationService` 会按 scene 路由回复:
- `execute`:优先固定执行回执模板(避免“教程式”回复)。
- `qa`:
- 若 `direct_reply_required=true`,直接回 `direct_reply_text`;
- 否则仅在明确 `@PMFlow` 时触发人设化回复。
- `error`:固定错误模板。
发送路径:
1. 先入 `feishu_reply_outbox(status=pending)`。
2. 异步立即派发一次;失败则指数退避重试。
3. 后台 drain loop 持续扫 `pending/retrying` 做补偿发送。
## 4. 可靠性与幂等设计
关键幂等点:
- `ingest_events`:`(tenant_id, channel, event_key)` 唯一。
- `work_items`:`(tenant_id, source_system, source_message_id)` 唯一。
- `reply_receipts`:`(tenant_id, source_system, source_message_id, receipt_phase)` 唯一。
关键可靠性点:
- 长连接断线自动重连(最多 3 次,指数退避)。
- Outbox 发送失败自动重试 + 后台补偿。
- 全链路 `ai_processing_logs` 留痕,便于回放排障。
## 5. 关键数据表(当前链路涉及)
- `integrations`:飞书配置。
- `ingest_events`:入站事件幂等账本。
- `work_items`:AI PMO 工作项与状态机。
- `decision_records` / `plan_bundles`:决策与计划快照。
- `reply_receipts`:回执唯一性控制。
- `feishu_reply_outbox`:发送队列与重试。
- `signals` / `project_signal_links`:落库信号与项目关联。
- `ai_processing_logs`:处理过程日志。
## 6. 运维排查入口
- `GET /feishu/config`:是否配置、当前模式、长连接状态。
- `POST /feishu/test-connection`:token + 长连接线程健康检查。
- `GET /feishu/long-connection/status`:运行态/错误码/重试窗口。
- `POST /feishu/long-connection/restart`:手动重启长连接。
常见失败定位:
- `auth_failed`:`app_id/app_secret` 或应用权限问题。
- `network_error`:后端到飞书网络/TLS 问题。
- `sdk_missing`:缺少 `lark-oapi` 依赖。
- outbox `failed`:下游发送失败,查看 `last_error`。
## 7. 现状说明(避免误判)
- `FeishuSignalPipelineService` 与 `feishu_items` 仍存在,但当前主入口未直接调用该服务。
- 现在线上主流程以 `AIPMOKernelService` 为统一决策中枢。
- 如果后续要彻底收敛,可考虑把历史队列链路标记为 deprecated 并逐步下线。
### 7.1 这套历史链路现在“还有什么用”
当前仍有 4 类明确用途:
1. 回归评测与回放:`backend/evals/feishu_replay_eval.py` 仍直接驱动 `FeishuSignalPipelineService`,用于离线评估路由/回执一致性。
2. 单元测试基座:多处测试直接依赖其工具函数与判定逻辑(例如 `backend/tests/test_inbox_queue_view.py`、`backend/tests/test_feishu_routing_receipts.py`)。
3. 历史数据兼容:`ai_logs`、`project_knowledge_graph` 仍会读取 `feishu_items` 做项目过滤和增量图谱事件。
4. 数据迁移与幂等治理:Alembic 与启动自检里仍有 `feishu_items` 去重/唯一索引修复逻辑,保障旧数据不炸库。
一句话:它对“新消息在线处理”不是主链路,但对“测试、历史数据、迁移兼容”仍有实际价值。
## 8. 阶段与 Agent(服务)映射
> 你问的“走到哪用哪个 agent”,按当前代码可对应为下表。
| 阶段 | Agent/服务 | 作用 |
| --- | --- | --- |
| 事件接入 | `FeishuLongConnectionManager` | 与飞书建立长连接,接收 `im.message.receive_v1` 事件并投递队列 |
| 渠道适配 | `FeishuIntegrationService` | 解析飞书消息、提取文本/附件、场景分流、触发回复 |
| 消息捕获 | `ProactiveSignalCaptureService` | 预清洗与噪音过滤,统一进入 AI PMO 内核 |
| 意图解析 | `IntentResolver`(内核组件) | 把文本收口为 `query/project.create/signal.create/...` |
| 组合决策 | `DecisionEngine` + `StrategicBrain` + `TacticalBrain` + `SimulationEngine` + `ExecutionPolicyBrain` | 做战略/战术/仿真/自动执行边界判定 |
| 执行落地 | `TypedExecutor` | 按 intent 进行 `RAG问答/立项/信号入库/信号源接入` |
| 结果复核 | `AIPMOReviewService` | 校验执行后状态与风险,生成 review summary |
| 回复渲染 | `ReplyRenderer` | 统一生成 `action/pending/error` 回执文本 |
| 回复幂等 | `ReplyReceipt`(账本) | 保证同消息同 phase 只发一次业务回执 |
| 消息投递 | `FeishuReplyOutbox` + dispatch worker | 发送到飞书并做失败重试/补偿 |
| 知识沉淀 | `AdaptiveRAGService.ingest_feishu_message_async` | 异步把飞书内容纳入检索知识域 |
### 8.1 具体 Agent 名称(字符串级)
下面是你要的“具体名称”。
1. 角色 Agent(`role_key`)
- `pm_dispatcher`(默认 active,角色名:产品经理(任务分派))
- `tech_architect`(角色名:技术架构师)
- `delivery_coach`(角色名:交付推进官)
2. 主链路实际会命中的 LLM Agent 名(`function_name`)
- `feishu_humanized_reply`:飞书被 @ 且需要人设化回复时使用。
- `signal_source_onboarding_plan`:识别到“新增信号源接入”时的规划器。
- `signal_source_ai_worker_execution`:信号源接入子 worker 执行器。
- `control_plane_command_dispatch`:PMFlow 本地路由层 指挥层把自然语言转操作计划。
- `rag_intent_classification`:RAG 问答意图分类(query/mixed/statement)。
- `rag_db_project_semantic_retrieval`:RAG 的项目语义检索快路由。
3. 历史链路 Agent 名(`FeishuSignalPipelineService`,非当前主入口)
- `feishu_level_classification`
- `feishu_signal_extraction`
- `feishu_project_prefill`
- `feishu_task_orchestration`
- `feishu_project_signal_classification`
- `feishu_new_project_brief`
说明:上面第 3 组名称仍在评测/历史链路中使用,但实时主入口不直接走这条链路。
### 8.2 `dashscope` / `minimax` 在哪一步、做什么
> 依据:`backend/.control_plane/pmflow-routing-rules.json`(当前默认 `CONTROL_PLANE_ROUTING_ENABLED=true`,`LLM_MIXED_ROUTING_ENABLED=false`)。
#### A. 当前飞书主链路(实时)
| 步骤 | function_name | 默认命中模型 | 具体作用 |
| --- | --- | --- | --- |
| 飞书 @ 人设回复 | `feishu_humanized_reply` | `zai/glm-4-flash` | 把执行结果转成短中文回复,控制语气与可执行建议 |
| RAG 意图判定 | `rag_intent_classification` | `zai/glm-4-flash` | 把用户输入判定为 question / mixed / statement |
| RAG 项目语义检索 | `rag_db_project_semantic_retrieval` | `openai-compatible/GLM-5` | 从项目索引中做语义命中与回答草案 |
| RAG 最终答案生成(normal/deep) | `adaptive_rag_answer_normal` / `adaptive_rag_answer_deep` | `openai-compatible/GLM-5` | 生成最终回答(结论+证据+不确定项) |
#### B. 主链路中的“信号源接入子流程”(命中时)
| 步骤 | function_name | 默认命中模型 | 具体作用 |
| --- | --- | --- | --- |
| 接入规划器 | `signal_source_onboarding_plan` | **active 引擎**(未在规则中显式绑定) | 判断是否应接入、产出 source 元数据与 worker 角色 |
| PMFlow 本地路由层 指挥计划 | `control_plane_command_dispatch` | **active 引擎**(未在规则中显式绑定) | 把自然语言转 typed operations |
| 子 worker 执行 | `signal_source_ai_worker_execution` | **active 引擎**(未在规则中显式绑定) | 各角色生成 deliverables/risks/next_actions |
说明:这 3 个函数名不在当前 PMFlow 本地路由层 规则文件中,因此在默认配置下走 active 引擎;若 active 仍是默认 PMFlow 本地路由层 low 模型,则通常表现为 `dashscope`。
#### C. 历史/评测链路(`FeishuSignalPipelineService`)
| 步骤 | function_name | 默认命中模型 | 具体作用 |
| --- | --- | --- | --- |
| 层级判断 | `feishu_level_classification` | `zai/glm-4-flash` | 判定 project-level 还是 signal-level |
| 信号抽取 | `feishu_signal_extraction` | `zai/glm-4-flash` | 抽取标题、类型、优先级、置信度 |
| 项目预填充 | `feishu_project_prefill` | `openai-compatible/GLM-5` | 生成建议项目名/描述/owner/timeline |
| 任务编排 | `feishu_task_orchestration` | `openai-compatible/GLM-5` | 生成任务拆解与分配建议 |
| 项目信号分类 | `feishu_project_signal_classification` | `openai-compatible/GLM-5` | 对新项目/已有项目/非需求做高层分类 |
| 新项目摘要 | `feishu_new_project_brief` | `openai-compatible/GLM-5` | 生成项目简报(brief) |