PMFlow/docs/architecture/DATAFLOW.md

61 lines
5.3 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.

# DATAFLOW
## Signal Planner Flow (Post-Commit Async)
1. `AIPMOKernelService` creates signal (`signal.create`) in transaction.
2. Transaction commits.
3. Background task triggers `SignalPlannerService.analyze(signal_id, tenant_id, ...)`.
4. Planner service opens isolated `AsyncSessionLocal` and loads context:
- signal content/project context
- project members (`user_projects -> users -> user_workloads -> user_skill_bindings -> skill_tags`)
5. Planner calls `llm_service.generate_structured_object(function_name="signal_planner_analyze")` with hard wait timeout (`25s`).
6. Structured success:
- `SignalStrategicAnalysisService.merge_and_save(...)`
- update `signals.planner_status=completed`
- write planner payload into `strategic_analysis.ai_planner`
7. Structured invalid / timeout fallback:
- build degraded planner payload (`fallback_mode=true`)
- still `merge_and_save(...)` and mark `signals.planner_status=completed`
8. Hard failure (DB write / unexpected exception):
- `SignalStrategicAnalysisService.mark_failed(...)`
- update `signals.planner_status=failed`
- try enqueue compensate reply via `FeishuOutboxService.enqueue(...)`
## Model Routing / Route Lab Flow
1. Hidden frontend `ModelRoutingConfigPage` at `/platform/route-lab` reads function-level routing diagnostics from `/model-routing/functions/{function_name}`.
2. The visible UI is read-only: platform operators can inspect rule source, tier, recent execution and historical override traces, but cannot save function-level overrides from the page.
3. Backend `PUT /model-routing/functions/{function_name}` remains a platform-protected compatibility/internal write API and persists overrides into `integrations(type='model_routing')`.
4. `LLMService` resolves function-level override at runtime before default control-plane rules.
## Query Route Gateway Flow
1. `AIPMOKernelService.process_ingress()` 先完成 `plan_mode` gate;命中 `reply/thread`、`work_item_id`、active requirement context、draft/workspace lock 时继续留在 requirement/draft 主链。
- 若已绑定 active requirement context 且用户显式说 `退出需求模式`,必须先把当前带 active draft 的 live requirement topic 挂起,再回到普通 `query.answer`;同 scope 下后续 idle query topic 不得抢走这次绑定。
2. 非 `plan_mode` 的 `query.answer` 进入 `TypedExecutor._execute_query_intent()`,在调用 `AdaptiveRAG.answer_question()` 前先执行 `preview_query_route_decision(...)`。
3. `AdaptiveRAGQueryRouteGatewayMixin` 产出单次结构化 `query_profile`(`needs_private_context / needs_freshness / referenced_objects`),并分别运行:
- `InternalProbe`:`config_hit_count / private_object_hit_count / private_scope_hit / vector_top1_score / vector_topk_support / graph_fact_hit_count`
- `ExternalProbe`:`freshness_required / trusted_domain_hit_count / answerable_page_hit_count / cross_source_agreement / external_entity_hit`
4. Gateway 结合 `query_route_memories` 的相似样本先验,输出 `route_mode / effective_source_policy / decision_origin / reply_contract / probe_snapshot`。
5. 若 `route_mode=internal`,内部只读查询必须先生成 `Query DSL Plan`:统一收口 `query_type=existence/count/list/status/explain/diagnose/compare/unknown`、`entity_type`、`answer_contract`、`filters`、`scope` 与 `retrieval_policy`;协议短回复、模式控制、执行动作必须在此之前就被 gate 掉,不得混入 DSL 规划。
6. `Bounded Executor` 只按白名单模板执行内部查询:
- 优先查 `semantic_facts`
- facts 不足时再做 `db/graph/doc/config` 的受控 fallback retrieval
- 全程自动绑定 `tenant_id`
- 不接收自由 SQL
7. `Answer Verifier` 在出站前检查“问法合同、证据合同、来源合同”是否一致;若发现 existence/status/compare 被答成 total count、或证据与结果不符,必须重试或显式失败。
8. `AdaptiveRAG.answer_question()` 只消费已经收口好的 route 决策和对应结果:`internal` 只走受控内部查询主链;`external` 统一走 `External Query Planner -> External Query Gateway -> External Provider Registry -> MCP adapter 优先(当前已接通 Microsoft Learn backend-direct runtime)-> bounded fallback live search -> external answer verifier -> ExternalContextPacket -> ExternalAnswerPresenter`,禁止再直接混入内部检索结果,也禁止回流旧的 `industry_trend/external_trend` scene prompt;`uncertain` 仅允许 `external-first` 或 clarification。
9. external presenter 只读取 external-only 输入:
- question
- plan summary
- verified external evidence
- source summaries
若 verifier 未通过或 evidence 为空,则直接返回“证据不足/需澄清”,不得混入 `system_snapshot / user_snapshot / project_context / internal retrieval` 补答案。
10. 回答完成后:
- `QARecord.routing_snapshot`、`citations`、`sources_used` 继续落盘
- `query_route_memories` 追加或更新该次样本
- `QAFeedback` / `FeedbackCenterRecord` 后续会把 route feedback 回写到 `query_route_memories.feedback_outcome`
## Task Brief Flow
1. Frontend chooses template / trigger generate.
2. Backend `task_brief_service` stores template and run records in `integrations(type='task_briefs')`.
3. Generation run writes summary + artifact path.
4. `/task-briefs/center` aggregates latest generated cards for sidebar center.