PMFlow/mdproject/PLAN.md

116 lines
5.9 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.

# External Query 独立主链升级计划
## 摘要
把外部查询从通用 AdaptiveRAG 回答链里拆出来,做成一条独立的“外部事实链”:`规划 -> 取证 -> 验证 -> 呈现`。这次升级的目标是让 `route_mode=external` 后只依赖外部证据作答,不再落到 `industry_trend / external_trend` prompt,也不再混入 `project manifest / system snapshot / 内部检索上下文`。
## 关键改动
### 1. 外部链路边界固定
- 保留现有 `Query Route Gateway` 作为上游拍板;一旦 `effective_source_policy=external`,后续回答链默认只走外部主链,不再回到通用 scene prompt 选择。
- `ExternalQueryPlanner` 只负责产出结构化 `ExternalQueryPlan`;planner 的 fallback 改成保守模式:
- 仅复用上游 `query_semantics`
- 不再用硬性词语、对象词表或正则去猜 `query_kind / time_range / location`
- 结构化 planner 失败时,默认 `query_kind=generic_web`、`answer_contract=summary_with_sources`、`search_queries=[原问题]`
- `ExternalQueryGateway` 只做 provider 选择与证据收集;`verifier` 只判断证据是否足够支撑回答,不再承担语义重判或 internal/external 二次裁决。
### 2. 能力选路替代固定顺序
- 在 `backend/app/services/external_query_service/` 内把 adapter 能力声明收紧为受控合同:
- `provider_type`: `fact_api | live_search | doc_search`
- `supported_query_kinds`
- `supports_freshness`
- `supports_page_fetch`
- gateway 排序固定为“能力优先”而不是“注册顺序优先”:
- `fact_api` 优先处理天气/汇率/股价等结构化事实
- `live_search` 处理实时网页事实
- `doc_search` 只处理文档/说明类问题
- 当前没有专用天气 API 时,天气类默认优先 `live_search`;MCP 文档型 adapter 不再先占坑。
- MCP 和 live search 都保留“搜索结果 -> 抓目标页正文 -> chunk 打分 -> best snippet”这套正文取证链。
### 3. 外部证据与呈现彻底分层
- 在 `schemas.py` 新增 `ExternalContextPacket`,作为 external-only 的回答输入,字段固定为:
- `question`
- `plan`
- `adapter_attempts`
- `verified_evidence`
- `verifier`
- `uncertainties`
- 新增 `ExternalAnswerPresenter`,替代 `_generate_answer()` 里对 external route 走通用 `_select_scene_prompt()`。
- presenter 只按 `answer_contract` 选 3 类 prompt,不再使用 `industry_trend / external_trend`:
- `direct_fact`
- `summary_with_sources`
- `compare_with_sources`
- presenter 默认只喂:
- 用户问题
- 外部证据片段
- 来源摘要
- 时间/范围/不确定项
- presenter 明确禁止喂:
- `manifest_text`
- `project_context`
- `system_snapshot`
- `user_snapshot`
- 内部 retrieval block
### 4. verifier 改成“证据校验器”,不是“语义裁判”
- 把当前 `gateway.py` 里的 bundle 校验拆成独立 verifier 组件,职责只保留:
- 外部来源合法性
- 目标对象一致性
- 时间范围一致性
- 多来源是否足以支撑回答
- 对象一致性继续走通用归一化和 bundle 评分,但不允许回退到硬编码对象词表、关键词探针或正则模式。
- 证据不足时统一返回 `clarify / insufficient_evidence`,不再误落到“行业趋势回答”这种假阳性路径。
### 5. 与现有 AdaptiveRAG 的接缝
- `mixin_answer_retrieval.py` 保留 `_execute_external_query_gateway()`,但返回值从“retrieved rows + meta”扩成 `ExternalContextPacket` 所需信息。
- `mixin_deep_guard_answer.py` 在 `effective_source_policy=external` 时直接走 `ExternalAnswerPresenter`,绕过:
- `_resolve_answer_scene_semantics()` 对 external 的 `industry_trend/external_trend` 映射
- `_generate_answer()` 里默认注入 manifest 的逻辑
- `Answer Presentation Policy` 保持现有客户可见合同:
- 正文前缀仍是 `外部实时查询:`
- 来源只显示中文化展示字段,不暴露内部 source label/raw metadata
## 主要接口与类型
- `ExternalQueryPlan` 保留现有字段,语义收紧为“planner 产出的结构化取证计划”,不再依赖正则推断补字段。
- 新增 `ExternalContextPacket` 作为 external presenter 的唯一输入。
- adapter 注册合同新增能力字段,供 gateway 统一排序。
- external presenter 输出仍是最终中文正文,不改上层 API 响应包络。
## 测试与验收
- planner:
- 结构化 planner 失败时,不使用正则或硬词表补 `weather/news/company`
- fallback 仍能产出可执行 `search_queries`
- gateway:
- 天气 query 优先 `live_search`
- 文档 query 优先 `mcp/doc_search`
- MCP/live_search 都能抓目标页正文,而不是只用标题摘要
- verifier:
- `湛江市 / 湛江` 这类归一化对象不再误杀
- 时间范围不匹配时明确 `insufficient_evidence`
- 证据不足时返回 `clarify`,不生成假结论
- presenter:
- external route 不再命中 `industry_trend / external_trend`
- prompt 输入中不包含 `[M] 项目画像`、模块规模、知识图谱、system snapshot
- 最终回答只基于外部 evidence 生成
- 端到端:
- 从飞书入口发“湛江市未来五天的天气”,整条链应表现为:
- `route_mode=external`
- provider 选中 `live_search`
- verifier 通过
- presenter 输出 `外部实时查询:...`
- 回答内带来源摘要且无内部上下文污染
## 假设与默认
- 这期只改“纯 external route”的主链,不在本期实现“外部事实 + 内部能力判断 + plan_mode 动作”的完整混合编排。
- 当前没有专用天气 API 时,实时公开事实默认靠 `live_search + 网页正文抓取` 承担。
- 若后续接入专用事实 API,只需要新增 adapter,不改 planner/verifier/presenter 的边界。
- 文档同步纳入本期:至少更新 `docs/architecture/RUNTIME_GUARDRAILS.md` 与 `docs/architecture/CODE_REFERENCE_INDEX.md`,明确 external-only 上下文和 presenter 边界。