Skip to content

[Deep Research] Add claim–evidence verification and bidirectional citation traceability #13

Open

Description

@helsome

Background

Deep Research 的报告产出需要做到 claim-level 可审计:报告中的事实、归纳结论以及根因/因果结论,都应能逐条回到实际来源证据,并能从原始证据反查哪些摘要/结论引用了它。

这里的“一对一校验”指 每个 atomic claim 都必须独立完成证据校验,而不是把数据模型强制设计成数据库层面的 1:1。实际关系需要支持 many-to-many:一个结论可能需要多个 evidence span 才能支撑,同一段事实也可能支撑多个结论。

Requirements

  • 在研究报告 synthesis 阶段,为每个可验证的事实性、因果性、根因性结论生成稳定的 claim_id。
  • Evidence 必须定位到原始 source 的具体 passage/span,而不是只保存 URL 或文档级引用;至少保留足以恢复原文位置的 source/document identity、excerpt 和 location metadata。
  • 对每个 claim 单独执行 evidence verification,至少输出:
    • supported
    • contradicted
    • insufficient_evidence
  • 持久化双向关系:
    • claim -> evidence_refs
    • evidence_ref -> claim_ids
  • 上述映射需要跨越 streaming、report assembly、持久化、重新加载以及导出过程,不能只存在于单次 Agent runtime 内存中。
  • 报告 UI / 输出支持:
    • 点击摘要、结论或 citation,可跳转到对应原始引用 passage,并高亮对应证据;
    • 在原始 evidence passage 处可以反查引用它的摘要/结论。
  • unsupported / contradicted 的 claim 不允许无提示地作为“已证实结论”进入最终报告;需要明确实现标记、降级或阻断策略。
  • verification 结果需要提供 machine-readable 结构,供后续 Gold Case / Langfuse evaluation 使用。

Acceptance Criteria

  • 测试报告中的每个事实性/因果性 claim 都有 evidence link,或明确标记为 unsupported / contradicted。
  • claim -> evidence 的跳转在报告重新加载后仍然有效,并定位到具体原始 passage,而非只打开来源首页。
  • evidence -> claim 的反向绑定可用。
  • 支持 multi-source claim,以及一个 evidence 被多个 claims 引用的场景。
  • 构造一个“看似合理但来源并不支持”的根因结论,系统能够识别为 insufficient_evidence 或 contradicted,不能自动放行。
  • 覆盖必要的 unit / integration tests。
  • 至少完成 1 次真实 Deep Research E2E 测试,走真实模型 + 实际 retrieval/search 路径;只跑 mock / fixture 不算完成。
  • PR 中附上真实测试 query、最终 report、claim-evidence mapping、verifier 输出,以及前端双向跳转的截图或录屏。

Notes / Non-goals

  • 不要求强制 1:1 relational schema;重点是“每个 claim 必须被独立校验”。
  • Verifier 自己生成的解释不能替代 source evidence。
  • 不要只做 citation UI;后端必须存在稳定、可持久化、可供评测消费的 claim/evidence 数据关系。

Activity

  1. KKK-keria commented on Sep 11, 2026

    @KKK-keria
    Contributor

    /claim

  2. github-actions commented on Sep 11, 2026

    @github-actions

    @KKK-keria 已认领该 Issue,并已自动设为 Assignee。提交 PR 时请在描述中写 Closes #13。

  3. eric7h commented on Sep 11, 2026

    @eric7h

    按 CONTRIBUTING 里「大 Issue 可以拆成多个可独立合入的小 PR」,先提交这个 Issue 的第一步,不一次覆盖全部验收项:

    PR #67 — claim 身份 + claim ↔ evidence 双向映射(数据关系层)
    #67

    覆盖范围:

    • 为报告中每个 section 的 claim 生成稳定 claim_id;EvidenceRef 增加稳定 id 与反向指针 claimId
    • 持久化 claim -> evidence_refs 与 evidence_ref -> claim_ids 双向关系,并保证跨组装、持久化、重新加载、导出之后能重建出同一份映射
    • 一个 claim 可由多条 evidence 支撑、一条 evidence 可被多个 claim 引用(many-to-many,不强行 1:1 schema)
    • 没有 evidence 的 claim 显式暴露出来,不再默认按「已证实结论」混进正文
    • 向后兼容:新增字段均为可选,历史报告按 section key + 位置派生 id

    本 PR 明确不覆盖,留给后续 PR:

    • evidence 定位到原始 source 的具体 passage / span(目前仍指向 capability run)
    • claim 级 verifier,输出 supported / contradicted / insufficient_evidence
    • 报告 UI 的 claim → passage 跳转,以及 evidence → claim 的反查交互
    • 走真实模型 + 真实 retrieval 的 Deep Research E2E 验证与截图 / 录屏

    先把稳定、可持久化、可被评测消费的 claim / evidence 数据关系落下来(Notes 里也提到「不要只做 citation UI」),后续几项在此基础上继续。如果对拆分粒度或顺序有别的偏好,我按维护者的意见调整。

  4. github-actions commented on Sep 21, 2026

    @github-actions

    @KKK-keria 这个 Issue 已认领超过 7 天,目前没有发现关联的 open PR,也没有看到最近 7 天的进度更新。

    如果仍在推进,请在 3 天内 留一条简短进度说明(包括正在等待的前置依赖也可以);如果已经有 PR,请贴出链接。若 3 天内没有回应,认领会自动释放,方便其他贡献者接手。

  5. removed
    claimedClaimed by a contributor and currently in progress
    on Sep 25, 2026
  6. github-actions commented on Sep 25, 2026

    @github-actions

    @KKK-keria 在提醒后 3 天内没有进度回应,且仍未发现关联的 open PR;本次认领已自动释放。Issue 保持开放,可以重新认领。

  7. nanhanq1 commented on Sep 28, 2026

    @nanhanq1
    Contributor

    /claim

  8. github-actions commented on Sep 28, 2026

    @github-actions

    @nanhanq1 已认领该 Issue,并已自动设为 Assignee。提交 PR 时请在描述中写 Closes #13。

  9. nanhanq1 commented on Sep 28, 2026

    @nanhanq1
    Contributor

    按 CONTRIBUTING「大 Issue 可以拆成多个可独立合入的小 PR」,这里再落一块独立子能力,不一次覆盖全部验收项:

    PR #251 — 证据的 passage/span 级定位(定位数据层)
    #251

    覆盖范围:

    • SourcePassage / PassageLocation 契约:source/document identity(documentId、canonicalUrl)+ 逐字 excerpt + location(start/end 字符偏移、1-based line/column),即 issue 要求的「source/document identity、excerpt 和 location metadata」三件套
    • 确定性定位器:只容忍空白差异,其余字符逐字匹配;定位不到返回 undefined(fail-closed),不回退到相近偏移——避免造出「看着对、实际指错位置」的引用
    • 重载后按当前文本重新推导位置;来源已变则如实返回不可解析,不复用可能已失效的旧偏移
    • 报告组装时从 run outcome 派生并随报告持久化(ResearchReport.evidencePassages),因此位置不可能由模型正文编造
    • 一条 evidence(一个 run)→ 多条 passage;passage 自带 runId + capabilityId,反向天然成立

    本 PR 明确不覆盖,留给后续:

    • claim 身份与 claim ↔ evidence 双向映射 —— PR feat: 为研究报告引入 claim 身份与 claim↔evidence 双向映射 #67 已覆盖,本 PR 未复制其类型、也未与之重叠
    • claim 级 verifier 接线 —— core 已由 feat(research): 增加 claim verifier 核心 #90 合入,聚合接线见 feat(research): 基于统一证据 bundle 聚合研报 Claim 核验 #155
    • 报告 UI 的 claim → passage 跳转与高亮、passage → claim 反查(验收项里「跳转在重新加载后仍然有效」「反向绑定可用」的 UI 部分):本 PR 只提供后端数据。issue 的 Notes 也写明「不要只做 citation UI;后端必须存在稳定、可持久化、可供评测消费的 claim/evidence 数据关系」,先把这一层落下来
    • 非文本来源(filing / 研究文档)的 passage 抽取:buildCapabilityPassages 目前只认 research.news,其余返回空,不为结构化数据硬造位置
    • 真实模型 + 实际 retrieval 的 Deep Research E2E 与截图/录屏(验收项 7/8):本地没有可用模型与 Longbridge 凭据,本 PR 的集成验证止于「真实 runner + 真实组装 + 真实持久化/重载」,provider 调用是替身。这一项如实标注为未完成,不当作已交付

    关于验收项「claim → evidence 的跳转在报告重新加载后仍然有效,并定位到具体原始 passage」:本 PR 负责其中「定位到具体原始 passage」与「重载后仍可复算位置」两半,并在 runner.test.ts 里用真实持久化 + 新 store 实例重载做了集成断言;claim → evidence 那段链接本身取决于 #67。

    如果对拆分粒度、命名或字段位置有别的偏好,我按维护者的意见调整。

  10. nanhanq1 commented on Sep 28, 2026

    @nanhanq1
    Contributor

    进度更新:passage 定位切片的真实 E2E 已跑通

    承接上一条评论:PR #251 补上了「evidence 定位到原始 source 的具体 passage/span」。现补上验收项 7 要求的真实模型 + 实际 retrieval E2E。

    本次真实跑的是什么(链路上没有任何 fixture):

    • 模型:deepseek-v4-pro,真实流式 API(2068 prompt + 2635 completion tokens)
    • 检索:49 条实时新闻,真实 HTTPS 抓取
    • 链路:真实 AgentKernel → 生产 createAgentSynthesizer → 生产 research.news 能力(只注入 getNews fetcher)→ 生产 ResearchService / ResearchRunner / assembleReport → 真实 ResearchReportRepository

    结果:

    断言 结果
    真实 retrieval 产出 evidencePassages 49 条(一篇来源一条)
    每条 offset 可重定位到同一位置 全部通过
    sourceText.slice(start, end) 等于记录的 excerpt 全部通过
    evidence → passage 可解析 全部通过
    换全新 repository 实例重载后仍成立 全部通过

    产物与报告见 PR #251:docs/acceptance/evidence-passage/(verification / final-report / retrieved-news / model-usage)、docs/evidence-passage-test-report.md。

    如实说明三点:

    1. 只覆盖 passage 定位这一段。验收项 7/8 里的 claim 身份与双向映射(feat: 为研究报告引入 claim 身份与 claim↔evidence 双向映射 #67 仍 OPEN)、verifier 输出(feat(research): 增加 claim verifier 核心 #90 只合了库,全仓库零调用方)、报告 UI 双向跳转与录屏(无人认领)目前都还没有代码。所以整条链路的 E2E 现在没有任何单 PR 能完成——缺的是代码,不是凭据。
    2. 检索源换成了公开 RSS。验收环境没有 Longbridge CLI 与凭据,因此只替换了生产能力的 getNews fetcher;生产 Longbridge fetcher 仍是该能力的默认值,由 feat: 为 Deep Research 增加持久化检查点与崩溃恢复 #80 的 research-recovery-kernel.ts 端到端覆盖。
    3. 顺带发现一个既有问题(未在本 PR 修改,仅记录):createResearchNewsCapability 把 provenance.provider 写死为 'longbridge',一旦注入别的 fetcher,该字段就会失真——实测 checkpoint 里 provider: "longbridge" 而数据实际来自 NYT RSS。

    PR #251 CI 全绿(Typecheck / Focused tests / Secret scan),mergeable。

  11. nanhanq1 commented on Sep 30, 2026

    @nanhanq1
    Contributor

    请求查看是否有问题

  12. nanhanq1 commented on Sep 30, 2026

    @nanhanq1
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

claimedClaimed by a contributor and currently in progress

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions