79 lines
8.4 KiB
Markdown
79 lines
8.4 KiB
Markdown
# DATAFLOW
|
||
|
||
## PMFlow AI Agent OS Runtime Flow
|
||
1. User turns enter the product surface through `POST /space/pmflow-ai/threads` for the first message, `POST /space/pmflow-ai/threads/{thread_id}/messages` for continuation, or compatibility `POST /space/ai-concierge/ask`.
|
||
2. The product API persists `pmflow_ai_threads / pmflow_ai_messages` as the user-visible transcript. Each assistant turn creates a durable `pmflow_agent_runs` execution row before answer synthesis. QA records are transcript/history only.
|
||
3. `PMFlowAgentRuntimeService` creates the durable run first, then delegates execution to `PMFlowAIAgentRunService`.
|
||
4. `PMFlowAIAgentRunService` first builds a `GoalFrame`, records the user goal, desired output, object-binding candidates, evidence requirements, success criteria and customer-safe boundaries, then asks the LLM Step Planner for one next action at a time.
|
||
5. The planner can only choose tools from `AGENT_TOOL_CONTRACTS`, including `inspect_space_collections`, `inspect_project_operating_state`, `external_search`, saved-idea reads and pending-confirmation reads. It must not use old route plans, answer contracts or fixed business enums.
|
||
6. Each selected tool writes observations into the observation ledger, then `PMFlowAIAgentEvidenceNormalizer` converts raw observations into `source_quality`, claim ledger entries, boundary ledger entries and gaps. Raw snippets/tool payloads are not valid final-answer material.
|
||
7. `PMFlowAIAgentStateCritic` checks whether `GoalFrame + Claim Ledger + Boundary Ledger + Gap Ledger` satisfies the user goal. If not, it must state what is missing, whether another retry would change state, and whether to continue, narrow, ask the user or stop blocked.
|
||
8. `PMFlowAIAgentAnswerRuntime` builds terminal state only from the ledgers and answer intent plan, then composes the natural customer answer. The quality gate blocks internal terms, fixed templates, empty answers and missing lead claim/boundary.
|
||
9. `PMFlowAgentRuntimeService` projects those real goal/planner/tool/normalizer/critic/answer steps into `pmflow_agent_steps`, `pmflow_agent_observations`, `pmflow_agent_artifacts`, `pmflow_agent_verifications` and `pmflow_agent_memories`.
|
||
10. The thread API returns a customer-safe projection: `thread_id`, continuous `messages[]`, and the latest assistant message with `content`, `work_log`, inline `artifacts`, `actions` and `confirmations`.
|
||
11. `PMFlowAIWorkspace` at `/space/pmflow-ai` renders the durable thread list, continuous transcript and per-message work log. It must not render raw run ids, step ids, verification target refs or English status labels as the default user experience.
|
||
|
||
## PMFlow AI Compatibility Flow
|
||
1. `POST /space/ai-concierge/ask` remains for old clients, but it calls the same Agent OS runtime and returns the same projection.
|
||
2. Old Turn Runtime, EvidenceToolRegistry, CustomerAnswerPresentationService and Operating Runtime modules may be used as tool/rendering/compatibility assets.
|
||
3. They must not decide the main run, override final answer unconditionally, or expose internal verification labels such as `project_object_required_for_world_state`.
|
||
|
||
## 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.
|