PMFlow/mdproject/PLAN.md

7.3 KiB
Raw Blame History

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 响应包络。

测试与验收

本期验收不绑定固定问句、固定 provider、固定 prompt 名或固定内部实现路径。 验收只看 route_mode=external 后,external-only 主链是否满足行为合同。

验收要求

  • 一旦进入 external 主链,最终回答只能基于 external evidence 生成,不能混入 manifest_text / project_context / system_snapshot / user_snapshot / 内部 retrieval block。
  • external 证据不足时,必须明确返回 insufficient_evidence 或 clarify,不能假装已经查实。
  • 对同一 external 问题的后续追问,只要语义上仍是在继续核实,就必须继续留在 external query.answer 主链,不能误跳到 requirement-plan、draft confirm 或内部执行链。
  • external source filtering 在过滤后若无合格来源,必须按空来源或证据不足处理,不能把内部来源重新塞回 external answer。
  • 当前实现可以按 adapter 能力选择不同 external 取证方式,但验收不把某一种具体 provider 顺序写死为长期真源。
  • 运行时必须保留清晰审计信息,至少能看出:planner 如何产出计划、gateway 如何取证、verifier 为何通过或失败、presenter 如何生成最终回答。

覆盖范围

  • planner:
    • 结构化 planner 失败时,不使用正则或硬词表补 weather/news/company
    • fallback 仍能产出可执行 search_queries
  • gateway:
    • 不同类型的 external 问题都能进入受控 adapter 取证,而不是回退到旧 scene prompt 混答
    • external adapter 返回搜索结果后,仍需尽量抓取目标页正文,而不是长期只依赖标题摘要
  • verifier:
    • 湛江市 / 湛江 这类归一化对象不再误杀
    • 时间范围不匹配时明确 insufficient_evidence
    • 证据不足时返回 clarify,不生成假结论
  • presenter:
    • external route 不再命中 industry_trend / external_trend
    • prompt 输入中不包含 [M] 项目画像、模块规模、知识图谱、system snapshot
    • 最终回答只基于 external evidence 生成
  • 端到端:
    • 覆盖带时间范围或地点的公开事实问题
    • 覆盖一般性的外部事实或动态问题
    • 覆盖证据不足后的继续核实
    • 覆盖 external 来源被过滤为空的情况
    • 覆盖某一种 external 取证方式不可用、需要切换备选方式的情况
    • 覆盖需要多个来源交叉支撑的对比问题

假设与默认

  • 这期只改“纯 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 边界。