第 11 讲:洞见发现——DataSTORM

Agentic AI · Lecture 11。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应:Stanford CS224V Fall 2026 Lecture 13(11/9 Insight discovery)。 关于材料来源:这次课的幻灯片尚未公开。本讲依据:DataSTORM 论文(Liu、Jiang、Farook、Nicollier Sanchez、Castro Pena、Lam,DataSTORM: Deep Research on Large-Scale Databases using Exploratory Data Analysis and Data Storytelling,COLM 2026,arXiv 2604.06474);第一讲幻灯片对 DataSTORM 的介绍(“从数据库里自动得出洞见,例如国际冲突数据”);课程表和项目说明(“DataSTORM 和 GRILL:怎样把文献检索和数据分析结合起来?”)。 配套代码:code/lecture11/(只用 Python 标准库;04 号文件可选,需要 anthropic 包和 API 密钥) 预计阅读时间:3 小时左右(含运行代码)


0. 本讲导航

0.1 学完本讲,你应该能够

  1. 说明”在大型数据库上做深度研究”和”在网上做深度研究”、和”Text-to-SQL 回答一个问题”有什么不同,为什么现有的深度研究系统拿到了数据也很少用。
  2. 解释探索性数据分析(EDA)和数据叙事的三条原则——迭代地提出和检验假设、演绎和归纳结合、收敛到一个中心叙事——以及 DataSTORM 的每个部件分别对应哪一条。
  3. 描述 DataSTORM 的流程:网上研究热启动 → 多层的规划者—执行者探索(统计摘要、查询一致性、洞见库)→ 每隔几层生成 / 修正论点 → 分阶段写报告(大纲、分节起草、逐句核查、修改、润色)。
  4. 解释”查询一致性”问题:为什么独立的分支会悄悄地用不同的口径,怎样检测和统一,以及”一致”不等于”正确”。
  5. 说明怎样评估”洞见”:InsightBench、ACLED 数据集、参考文章的标准匹配、RACE、数据库使用比例、新闻工作者的人工评估;以及 LLM 评委和标注错误这两个陷阱。

0.2 先修知识

知识点用在哪里最低要求
第 2 讲第 1、3 节STORM / Co-STORM:多智能体在网上做研究、写长报告;评估长报告的难处
第 3 讲第 3 节上下文管理;子智能体在独立的上下文里工作
第 6、8 讲第 3 节Text-to-SQL;ReAct 式的查询智能体(执行者就是这样的智能体)
第 9 讲第 6 节SLIDERS:把长文档变成数据库再回答问题
第 5 讲第 5 节评委的偏差、标注错误、人工评估

0.3 本讲地图

第1节  动机:在数据库上做深度研究                                ← 代码 01
第2节  背景:探索性数据分析与数据叙事                            ← 代码 01
第3节  DataSTORM 的设计:热启动、规划者—执行者、统计摘要、
       洞见库、论点、写报告                                     ← 代码 03 演示 1、2
第4节  查询一致性                                               ← 代码 02
第5节  评估:InsightBench、ACLED、消融、人工评估、评估的陷阱      ← 代码 03 演示 3~6
第6节  讨论与边界                                               ← 代码 04(可选)
第7–11节 小结、与项目的关系、练习、延伸阅读、下一讲预告

0.4 本讲的玩具世界

代码 conflict_world.py 生成一个虚构的冲突事件数据库,仿照论文用的 ACLED(Armed Conflict Location & Event Data,一个由非营利组织维护的、人工标注的全球冲突与抗议事件库):

  • 四个虚构的国家(Veloria、Kestavia、Orundi、Pallasca),每个国家四个省,2020-01 到 2024-12,一共 14,162 件事件,每件一行:日期、月份、国家、省、事件类型(战斗、针对平民的暴力、爆炸 / 远程暴力、抗议、骚乱、战略发展)、三列行为者(actor1、assoc_actor_1、actor2)、死亡人数。真实的 ACLED 有 163 万行、31 列;
  • **7 条”标准洞见”**埋在数据里(G1~G7),例如:Veloria 在 2022 年 8 月”全面和平”政策之后战斗减少、针对平民的暴力却增加;Kestavia 的抗议在 2023 年 3 月激增;教师工会大多出现在”关联行为者”那一列;
  • 6 篇”网上的报道”,提供背景(政策从哪个月开始),其中一篇是误导性的(“自从和平政策以来,暴力全面下降”);
  • 4 个研究主题(T1~T4),仿照论文的做法写成中性的问题,例如 T1:“分析 Veloria 的全面和平政策及其对暴力的影响”(论文 ACLED 数据集第 2 个主题的虚构版)。

datastorm.py 是迷你的 DataSTORM 和两个基线。

关于本讲的数字:论文里的真实数字会注明出处;模拟实验的数字都来自 01~03 号代码的实际输出。特别注意:没有真实的 LLM。规划者按设定的规则挑问题,“读结果”按简单的阈值;但 SQL 是真实执行的,洞见里的每个数字都来自数据库。系统之间的差距说明的是机制,不是真实系统的成绩。


1. 动机:在数据库上做深度研究

1.1 关键的知识常常不在文本里

第 2 讲的 STORM / Co-STORM、GRILL 都在网上的文本里做研究:检索、阅读、综合、写报告。这个范式有一个隐含的假设:知识主要是用自然语言写下来的。

但在很多最需要深度研究的领域——金融、科学实验、政策分析——关键的知识在结构化的数据库里:它藏在数字之间的关系、实体、表结构里。一个冲突分析师想知道”和平政策有没有减少暴力”,网上有很多评论,但真正的证据是一张记录了每一件冲突事件的表。

论文的一个观察很能说明问题:即使是 OpenAI Deep Research,拿到了数据库,报告里也只有 23.3% 的论断来自数据库(直接给它 CSV 文件;通过 MCP 给它一个数据库智能体时是 30.4%)。它更习惯在网上找别人已经写好的结论。

1.2 为什么这比 Text-to-SQL 难

第 6、8 讲的智能体回答一个具体的问题:“2023 年有多少次抗议?“——有一条 SQL 能回答它。深度研究的问题是开放的:“这项政策对暴力有什么影响?“——没有一条 SQL 能回答它。需要:

  • 自己提出问题:哪些事件类型?和什么时候比?按地区分吗?行为者呢?
  • 对数量模式做推理:减少了 37% 算不算多?这个月的数字是不是异常?
  • 在反复探索中保持一致:第 3 步算”政策前”用的是哪个时间窗口,第 15 步还是同一个吗?
  • 收敛:几十个查询的结果,最后要讲成一个有中心论点的故事,而不是一堆数字的罗列。

搜索空间也大得多:163 万行 × 31 列,每一列都可以过滤、分组、和别的列交叉。

1.3 以往的做法

论文把相关工作分成两类:

  • 固定的流水线:例如定义四种”分析动作”,按固定的顺序调用。问题是不能根据中间的发现调整方向——不管数据显示了什么,都按预定的步骤走;
  • ReAct 式或多智能体的系统(例如 InsightBench 上之前最好的 AgentPoirot,用 Python 代码迭代地发现洞见):更灵活,但依赖 LLM 的一般能力,没有专门处理大型数据库特有的难点——结果被截断、口径不一致、洞见零散。

1.4 一个例子

论文 ACLED 数据集的第 2 个主题,中性的提示是”分析佩特罗的全面和平政策对哥伦比亚暴力和武装团体的影响”。ACLED 专家写的文章标题是:“‘全面和平’的悖论:佩特罗的政策减少了暴力,但武装团体变强了”。

注意这个标题的结构:一个中心论点(悖论),有数据支撑的两面(直接冲突减少了;武装团体扩张了)。好的研究报告不是”关于哥伦比亚冲突的 20 个事实”,而是这样一个论点。

本讲的 T1 是它的虚构版。代码 03 演示 1 里,迷你 DataSTORM 最后的论点是:“政策之后远程暴力每月增加了 79%;但是战斗减少了 37%“——同样是一个”悖论”式的论点(第 3.6 节)。


2. 背景:探索性数据分析与数据叙事

DataSTORM 的设计直接来自两个领域的原则。论文把它们归纳成三条性质,每个部件对应其中一条。

2.1 探索性数据分析:迭代地提出和检验假设

探索性数据分析(EDA)是统计学家 Tukey 在 1977 年提出的:在做正式的统计检验之前,先”看”数据——画图、汇总、变换——发现值得研究的模式。Wickham 和 Grolemund 把它描述成一个循环:

   提出问题 ──→ 变换、可视化、建模来回答 ──→ 根据看到的结果,提出新的问题 ──┐
      ↑                                                                    │
      └────────────────────────────────────────────────────────────────────┘

性质 1:迭代地提出和检验假设。DataSTORM 把”提出问题”和”找答案”分给两个智能体:规划者提问题,执行者写 SQL 找答案;每一轮的结果决定下一轮问什么。

2.2 演绎与归纳

EDA 的文献区分两种推理(Kirk 2016):

  • 演绎(自上而下):带着一个假设去问数据。“政策之后战斗减少了吗?”
  • 归纳(自下而上):不带假设地看数据,看会”冒”出什么。“这一列的最大值为什么是均值的四倍?”

只有演绎不够:规划者不可能把所有值得问的问题都问一遍;而且返回的表常常太长,只能截断地给规划者看。

代码 01 演示 1 是演绎:网上的报道说 Veloria 的政策从 2022 年 8 月开始,带着这条线索问数据:

How did monthly Battles in Veloria change before vs after 2022-08?
  结果:[('before', 29.39), ('after', 18.52)]
  → Monthly Battles in Veloria fell by 37% after 2022-08.
How did monthly Violence against civilians in Veloria change before vs after 2022-08?
  结果:[('before', 19.81), ('after', 26.28)]
  → Monthly Violence against civilians in Veloria rose by 33% after 2022-08.

注意演绎需要先知道分界点——这是 DataSTORM 先在网上做一轮研究的原因(第 3.2 节)。

演示 2 是归纳。Kestavia 每个月的抗议次数一共 60 行,只给规划者看前 5 行和后 5 行:

('2020-01', 29) ('2020-02', 32) ('2020-03', 13) ('2020-04', 20) ('2020-05', 29)
...
('2024-08', 29) ('2024-09', 30) ('2024-10', 47) ('2024-11', 28) ('2024-12', 37)
统计摘要(n 这一列):最小 13、最大 129(2023-03)、中位数 29.0、均值 31.1;不同值的比例 40%
→ 最大值是均值的 4.2 倍,追问:What happened with Protests in Kestavia in 2023-03?
没有统计摘要时:不能从显示的 10 行里发现异常

2023 年 3 月在第 39 行,被截掉了。看得见的 10 行里没有任何异常;统计摘要的”最大值”把它暴露了出来。这正是论文图 1 左下角的例子(真实的 ACLED 查询:“观察了 159 行,省略了 111 行”,月度计数的最大值 177,中位数 51、均值 64.38)。

性质 2:演绎和归纳的结合。DataSTORM 的执行者在每个答案里自动附上每一列的统计摘要。

2.3 数据叙事:一个中心的洞见

数据叙事(Segel & Heer 2010;Dykes 2019)强调:数字本身不会说服人,要”用数字讲一个故事”。Dykes 的原则是:每个数据故事都需要一个中心洞见。

性质 3:收敛到一个连贯的中心叙事。论文更进一步:不是等到写报告时才想故事,而是从探索一开始就围绕一个”工作中的论点”组织——先从数据里发现候选的论点,再通过反复的、跨来源的调查检验它,最后发展成一个分析叙事。

2.4 网上的说法 vs 数据

代码 01 演示 3:一篇网上的评论说”自从和平政策以来,Veloria 的暴力全面下降”。数据怎么说?

Battles                     政策前每月  29.4 件 → 政策后  18.5 件(-37%)
Violence against civilians  政策前每月  19.8 件 → 政策后  26.3 件(+33%)
Explosions/Remote violence  政策前每月   7.2 件 → 政策后  12.8 件(+79%)

“全面下降”是错的。只在网上做研究的系统会把这句话原样写进报告;以数据库为证据的系统能发现它不对。这也是为什么”报告里有多少论断来自数据库”是一个值得测的指标(第 5.3 节)。

2.5 同一个问题,不同的写法

代码 01 演示 4:“教师工会参与了多少次事件?”

看 actor1                               →  177 件
看 assoc_actor_1                        →  393 件
看 actor1 / assoc_actor_1 / actor2      →  570 件

ACLED 用好几列记录行为者:主要行为者、关联行为者、对方……只看 actor1 会少算三分之二。每种写法单独看都”说得通”;如果报告里的两个数字用了不同的写法,它们看起来互相矛盾,其实是不可比的。这是第 4 节的主题。


3. DataSTORM 的设计

3.1 总体流程

输入:一个关系数据库 D、一个网上的语料 I、一个用户的问题 q。输出:一份自由文本的研究报告 r。三个阶段(论文图 1):

① 热启动:Co-STORM 在网上做一轮研究 → 初步报告 r0、几条洞见 B0;论点 t0 = 空
                                   │
② 多层探索(最多 m 层),第 i 层:
     规划者:根据 B(i-1) 和 t(i-1)(第一层根据 r0)提出 ≤ n 个自然语言的问题(问数据库或问网上)
        → 执行者(各自独立的上下文):翻译成 SQL、执行,答案 + 每一列的统计摘要
        → 查询一致性模块:对比这一层的 SQL(参照洞见库里已有的),生成"统一口径"的追问,重新执行
        → 过滤、更新全局洞见库 B(i)(容量有限,弱的被强的替换)
     每 p 层:生成(第一次)/ 修正论点 t
                                   │
③ 写报告:大纲 → 分节起草 → 逐句核查引用 → 修改 → 润色

论文在 InsightBench 上的设置:m = 5 层,第一层 2 个问题,之后每层 5 个。本讲的迷你版用同样的设置,论点每 2 层生成 / 修正一次(PARAMS)。

3.2 热启动:先在网上做一轮研究

热启动用第 2 讲的 Co-STORM:几个 LLM 智能体围绕主题讨论、检索网上的证据,写出一份结构化的初步报告。目的不是深入研究,而是广泛地覆盖主题、指出值得调查的方向。

为什么需要它?因为没有背景,规划者不知道该问什么。代码 03 演示 1 的第一步:

热启动:读了 3 篇网上的报道,得到线索 {'Veloria': {'date': '2022-08'}}

有了”政策从 2022 年 8 月开始”这条线索,第一层的问题才能是”2022-08 前后的变化”。人类分析师也是这样:先读背景材料,再打开数据。

3.3 规划者—执行者的分工

规划者只提出高层的、自然语言的探索问题;执行者负责把问题翻译成查询并执行。论文的执行者是一个 ReAct 式的数据库智能体(附录 B),可用的动作:

动作作用
get_tables()列出所有表和简短的说明
retrieve_tables_details([...])查看指定表的详细信息
execute_sql(sql)执行 SQL,返回结果
execute_python_from_sql(sql, code)在 SQL 的结果上执行 Python 代码
stop()把最近一条 SQL 作为最终答案,结束

最多 15 轮。这就是第 6、8 讲的智能体:在复杂的数据库里,写对一条查询常常需要先看表结构、试探性地查几次、根据反馈修改。

为什么要分开?

  • 上下文管理(第 3 讲):执行者在独立的上下文里摸索表结构、试错,只把答案和最终的 SQL 交回给规划者。规划者的上下文里只有”问题—答案”,不会被几十轮试错淹没;
  • 可替换:执行者可以换成任何一个 Text-to-SQL 系统;
  • 对应 EDA 的循环:提问和找答案是两件不同的事。

3.4 自下而上的统计摘要

执行者在每个答案里,对返回的表的每一列自动计算:

  • 不同值的比例(不同值的个数 / 行数)、出现最多的 5 个值;
  • 数值列再加:最小值、最大值、中位数、均值。

代码 datastorm.py 的 summarize 就是这么做的。迷你版里,规划者”读结果”时(read_insight),如果最大值 ≥ 3 倍均值,下一层就追问那个月。代码 03 演示 2,主题 T2(“2023 年 Kestavia 的动荡是什么驱动的?”):

有统计摘要:
  种子 0:第 3 层 monthly → 第 4 层 spike(2023-03)
  种子 1:第 3 层 monthly → 第 4 层 spike(2023-03)
  种子 2:第 3 层 monthly → 第 4 层 spike(2023-03)
没有统计摘要:
  种子 0:第 3 层 monthly
  ...

三次都问了月度序列;有统计摘要时都追问了激增的那个月,没有时都错过了。

为什么是这几个统计量? 它们便宜(不需要 LLM)、通用(任何表、任何列都能算)、对”异常”敏感(最大 / 最小值、出现最多的值)。它们不替规划者下结论,只是让被截断的部分可见。练习 1 讨论了”怎样判断异常”的阈值问题。

3.5 洞见库

每一层结束时,DataSTORM 把新的答案和洞见库里已有的洞见放在一起,留下最多 k 条:新的、更强的发现可以替换旧的、弱的(论文 Prompt 11)。迷你版的 _add:同一个结构化描述只留一条,按”强度”排序,超过容量(8 条)时去掉最弱的。

洞见库有两个作用:给规划者看”已经知道了什么”(避免重复问);作为写报告的证据。

3.6 论点驱动的探索

只让 LLM 自由探索,常常得到一堆零散的洞见,没有中心主题。

DataSTORM 在第 p 层之后调用论点生成模块(Prompt 12),根据当前的洞见库提出一个初始论点;之后每 p 层修正一次(Prompt 13),在三个动作里选一个:

动作含义
sharpen(深化)加上具体的条件、限制、附加说明
pivot(转向)新证据指向别处,换掉主线
confirm(确认)证据支持原来的论点,不变

论点又反过来引导规划者:之后的问题要支撑、检验或修正论点。

一个担心:论点会不会让系统只找支持自己的证据(确认偏误)? 论文附录 E.2 做了两项检查:

  • ACLED 上一共 40 次修正:sharpen 34、pivot 3、confirm 1、“confirm 并 sharpen” 2——论点很少原封不动;
  • 论点生成之后加入报告的 342 条证据里:267 条支持、59 条加上了限制或例外、3 条反驳、13 条混合——21.9% 不是单纯的确认。

代码 03 演示 1 是一次完整的研究(主题 T1,种子 5)。摘录关键的几步:

第 1 层(2 个问题)
  问:How did monthly Battles in Veloria change before vs after 2022-08?
      → Monthly Battles in Veloria fell by 37% after 2022-08.
  问:What share of Violence against civilians in Pallasca happen in December to March?   ← 还没有论点,探索是"散"的
      → (没有值得写进报告的)
第 2 层(5 个问题,其中 3 个问的是别的国家)
★ 论点(generate):Monthly Battles in Veloria fell by 37% after 2022-08.
第 3 层:Veloria 的年度趋势、季节、骚乱、远程暴力的前后对比……           ← 检验论点:别的暴力类型也减少了吗?
      → Monthly Explosions/Remote violence in Veloria rose by 79% after 2022-08.
第 4 层
      → Monthly Violence against civilians in Veloria rose by 33% after 2022-08.
★ 论点(pivot):Monthly Explosions/Remote violence in Veloria rose by 79% after 2022-08;
                 but monthly Battles in Veloria fell by 37% after 2022-08.
第 5 层
      → Yearly Explosions/Remote violence in Veloria went from 65 (2020) to 169 (2024).

报告:
  [数据库] Yearly Explosions/Remote violence in Veloria went from 65 (2020) to 169 (2024).
  [数据库] Monthly Explosions/Remote violence in Veloria rose by 79% after 2022-08.
  [数据库] Monthly Battles in Veloria fell by 37% after 2022-08.
  [数据库] Monthly Violence against civilians in Veloria rose by 33% after 2022-08.
  [网上] Veloria's new government announced a 'total peace' policy, opening talks with armed groups.
  [网上] Observers report increasing use of drones and explosives by armed groups in Veloria.
核查时删掉了被数据反驳的网上说法:Commentators claim violence in Veloria has fallen across the board ...
评判:对上了 ['G1', 'G2', 'G6'](召回率 100%);数据库论断占 67%;一共 22 次查询

几个值得注意的地方:

  1. 初始论点”战斗减少了”——这是网上流行的说法,也是数据最先支持的说法;
  2. 有了论点之后,规划者按”检验论点”的思路去问:别的暴力类型也减少了吗?结果发现远程暴力、针对平民的暴力都增加了;
  3. 论点转向:主线从”政策减少了暴力”变成”暴力的形式变了”;原来的发现没有丢,成了”但是”后面的附加条件;
  4. 报告只写和论点有关的洞见(第 2 层问到的别国的发现没有写进去),删掉了被数据反驳的网上说法。

迷你版的论点规则见 DataSTORM._thesis:主论断 = 洞见库里和主题相关的最强的一条;主论断没变而有新证据 → sharpen;主论断换了、方向相反(或者旧的被挤出了洞见库)→ pivot。这是对 LLM 行为的粗略模仿。

3.7 写报告:分阶段的编辑流水线

即使是推理能力很强的 LLM,一次写成的长报告也常有问题:论断没有引用支撑、堆砌长长的引用列表、缺少把证据逐步引向论点的叙事结构(第 2 讲的 STORM 也遇到过)。DataSTORM 分五步(论文图 2):

步骤做什么
A 大纲每一节写明:叙事上的目的、需要哪些证据(洞见库的子集)、要点
B 分节起草每一节只根据分给它的证据独立起草
C 逐句核查引用按引用的边界把一节切成小块,让 LLM 标出”引用的来源不足以支撑”的论断
D 修改根据核查的意见修改每一节
E 润色合并、润色成最终的报告

C 步很关键:没有它,LLM 写的”相关工作”里会有大量编造的引用。迷你版的 _write 做了两件事:报告只写和论点相关的洞见;以 80% 的概率发现”数字和查询结果不符”的论断(执行者把 SQL 写错了),删掉被数据反驳的网上说法。04 号文件(可选)里,Claude 写报告,程序做最简单的逐句核查:句子里的每个数字都必须出现在它引用的洞见里。

数字准不准? 论文附录 E.3 从 18 份报告里随机抽了 50 条有 SQL 支撑的数字论断,人工检查:86% 忠实于引用的结果表、10% 不忠实、4% 不确定;SQL 本身 94% 正确、6% 不确定、没有发现实质性错误的。也就是说,剩下的错误主要出在”把表里的数字写进句子”这一步——这正是 C 步要继续加强的地方。

3.8 迷你版和论文的对应

论文的部件迷你版(datastorm.py)模拟的地方
Co-STORM 热启动warm_start:读同一个国家的网上报道,得到线索和网上的论断不是真的多智能体讨论
规划者(LLM)plan:先做”题目指向的”分析;有论点时集中在论点上;追问统计摘要暴露的异常规则代替 LLM
执行者(ReAct Text-to-SQL)Executor.run:模板生成真实执行的 SQL;在”可以有不同写法”的地方随机选;6% 的概率写错不是真的 ReAct
统计摘要summarize:和论文相同的统计量一致
查询一致性模块统一的写法 {"actor": "all", "window": "2020-01"};02 号文件有一个”检测 + 统一”的教学版简化
洞见库_add:容量 8,强的替换弱的一致
论点_thesis:generate / sharpen / pivot / confirm规则代替 LLM
写报告_write:只写切题的洞见;核查;删掉被反驳的网上说法没有真的写文字

4. 查询一致性

4.1 问题:独立的分支悄悄地用了不同的口径

规划者一层提出好几个问题,交给各自独立的执行者——这正是规划者—执行者分工的好处(独立的上下文),也带来了一个检索式的流水线不会遇到的问题:不同的分支可能悄悄地用了不同的分析口径(时间窗口、过滤条件),得出的数字看起来矛盾,其实不可比。

论文的例子:ACLED 有 actor1、assoc_actor_1、actor2、assoc_actor_2 几列记录行为者。分析”抗议者”时,一个执行者只查 actor1 和 actor2,另一个把两列关联行为者也算上——聚合出来的数字完全不同。

代码 02 演示 1:

问题:How many events in Kestavia involved Teachers' Union of Kestavia?
  看 actor1                             →  177 件
  看 actor1 / actor2                    →  177 件
  看 actor1 / assoc_actor_1 / actor2    →  570 件

问题:Veloria 的各类暴力,政策(2022-08)前后每月的变化
                              前一段从 2020-01 起      前一段从 2020-08 起
  Battles                                     -37%                -38%
  Violence against civilians                  +33%                +30%
  Explosions/Remote violence                  +79%                +67%

时间窗口的影响小一些,但远程暴力本身有上升的趋势,“前一段”从哪里算起,变化就从 79% 变成 67%。

4.2 查询一致性模块

论文的模块(Prompt 10):

  • 输入:这一层所有”问数据库”的(问题, SQL)对;洞见库里已有的(问题, SQL)对作为参照——它们不会被修改,只用来引导这一层的统一(全局一致);
  • 输出:一致性的追问 q’(例如”请把关联行为者也算上,和其他查询保持一致”);
  • 追问连同原来的 (q, s) 一起交给执行者,写出新的 SQL s’、新的答案 a’。

代码 02 的 detect / pick_standard / standardize 是一个教学版:先按”维度 + 概念”分组,找出写法不止一种的组;统一的写法优先沿用洞见库里的,否则选”最完整”的;只重新执行写法不同的那几条。演示 2:一层 4 个问题,4 个独立的执行者:

统一之前:
  {'actor': 'all'}  Teachers' Union of Kestavia was involved in 570 events in Kestavia, mostly Protests.
  {'actor': 'a1'}  10% of Protests in Kestavia involved Teachers' Union of Kestavia.
  {'window': '2020-08'}  Monthly Battles in Veloria fell by 38% after 2022-08.
  {'window': '2020-01'}  Monthly Explosions/Remote violence in Veloria rose by 79% after 2022-08.
一致性模块生成的追问:
  [actor] What share of Protests in Kestavia involved Teachers' Union ...?  写法 a1 → 统一为 all
  [temporal] How did monthly Battles in Veloria change before vs after 2022-08?  写法 2020-08 → 统一为 2020-01
统一之后:
  ... 570 events ...
  31% of Protests in Kestavia involved Teachers' Union of Kestavia.
  Monthly Battles in Veloria fell by 37% after 2022-08.
  ...

统一之前,报告会同时写”工会参与了 570 件事件”和”只有 10% 的抗议有工会参与”——读者会以为至少有一个数字错了。

4.3 一致不等于正确

演示 3:洞见库里已经有一条”只看 actor1”的查询(177 件),新的一层又问到了工会,执行者这次把三列都算上了(570 件)。按”全局一致”的规则,新的查询向洞见库看齐:

追问:[actor] How many events in Kestavia involved Teachers' Union of Kestavia?  写法 all → 统一为 a1
统一之后:... 177 events ... —— 前后一致,但真实的数字是 570

一致性模块保证的是可比,不保证正确。统一成哪种口径仍然需要判断——论文让 LLM 结合上下文决定;在真实的项目里,口径常常应该由领域专家事先定下来(ACLED 的编码手册就规定了每一列的含义)。练习 2 让你在完整的系统里试试”统一成错的口径”。

4.4 怎样度量一致性

论文为此设计了一个专门的指标(附录 E.1):

  1. 从一份报告里取出所有有 SQL 支撑的证据,每条表示成(问题, SQL, 结果的预览),去掉重复的 SQL;
  2. 交给 GPT-5,在六个维度里分别做两步:分组(找出指向同一个概念的两条以上的查询;连接条件这类纯结构的谓词不算)、判断(每组的过滤条件在语义上是否等价,不等价时记下冲突的谓词);
  3. 一个维度的得分 = 写法一致的组的比例;没有可比较的组时记 1.0(不可能不一致);总分是六个维度的平均。
维度检查什么例子(不一致)
行为者 / 实体同一个行为者是否用同样的方式匹配一条只在 actor1、actor2 里找某个武装团体,另一条还查了关联行为者和备注
地理同一个地方是否用同样的方式规范化一条只写省名,另一条写”国家 + 省”
时间同一个时期是否用同一个日期窗口一条”2023-04-01 之后”没有上限,另一条到 2024-12-31 为止
事件类别同一个事件概念是否定义一致“政治暴力”一条用 disorder_type 定义,另一条用 event_type
计数 / 聚合同一个量是否用同样的方式计算同一个”规模”的论断,一条数事件、一条加总死亡人数
人群范围同一个基础人群是否同样过滤同一个地区性的论断,一条限定了国家,另一条没有

结果(论文表 4b,10 个 ACLED 主题):

总分人群事件行为者计数地理时间
DataSTORM0.5490.680.530.250.500.500.83
去掉一致性模块0.4060.250.360.100.450.450.83

完整的系统在六个维度里的五个上更一致(时间维度持平)。注意即使有一致性模块,总分也只有 0.55:LLM 做的检测和统一并不完美,“行为者”这个维度尤其难。

代码 02 演示 4 用迷你版的指标(只有行为者和时间两个维度),三种系统各做 80 次研究(4 个主题 × 20 个随机种子):

系统                        行为者    时间    总分   工会的数字有两种口径   G5 发现率
ReAct 基线                    0.95    0.62    0.79           3 / 20           35%
DataSTORM 去掉一致性模块      0.94    0.57    0.76           5 / 20           35%
DataSTORM                     1.00    1.00    1.00           0 / 20          100%

迷你版的 DataSTORM 一致性是 1.00,因为统一的写法是规定死的——这是模拟的边界,真实的 LLM 模块做不到这么完美(论文 0.549)。更值得看的是最后一列:G5(“教师工会大多是关联行为者”)只有在口径是”三列都算上”时才能对上,没有一致性模块的系统只有约三分之一的时候碰巧用对了口径。


5. 评估

评估深度研究系统很难:任务是开放的,没有唯一的正确答案。论文在一个已有的基准和一个新建的数据集上评估,用了多种自动指标和一次人工评估。

5.1 InsightBench

InsightBench 是一个评估商业分析智能体的基准:100 个实例,每个包括一个自然语言的目标(例如”找出事件在各个类别上分布的差异和不平衡”)、一个数据库、一组标注好的”标准洞见”。评估用 LLM 当评委:

  • 洞见级:每条标准洞见的得分 = 它和所有预测洞见的最高匹配分;
  • 摘要级:系统把自己的洞见总结成一段摘要,和标注的参考摘要比较。

一个评估的陷阱:原论文用 Llama-3 当评委,但 DataSTORM 的作者发现它几乎总是给 7/10——这个分数是从评估提示词的示例里原样抄来的,即使洞见明显对不上。他们改用 Qwen3-30B(开源)和 GPT-4o(闭源)两个评委。

结果(论文表 1,召回率 %):

系统洞见级(GPT-4o 评委)洞见级(Qwen3 评委)摘要级(GPT-4o)摘要级(Qwen3)
AgentPoirot(gpt-5)47.149.946.651.5
DataSTORM(gpt-5)61.969.352.558.7

AgentPoirot 是之前最好的系统:ReAct 式,用 Python 代码迭代地发现洞见,3 次并行运行。两个系统用同一个底层模型,差距来自框架。

错误分析:随机抽 20 条最高匹配分只有 0.5 的标准洞见,45% 是数据集的标注错误——例如提到数据里根本没有的”打印机”、没有证据就把东京或伦敦标成”高留存”的城市、图和标签对不上。剩下 55% 是模型真的没有探索到相关的方向,其中 45% 涉及时间序列的趋势分析。

5.2 ACLED 数据集

已有的基准没有反映”同时用网上的资料和本地的大型数据库做研究”的真实复杂度。作者在 ACLED 上建了一个新的数据集:

  • 数据:ACLED 网站公开的事件数据(有一年的延迟),1,630,187 行、31 列,2020-01-01 到 2025-01-02;
  • 主题:2024 年下半年 ACLED 专家发表的 20 篇分析文章;文章标题常常透露结论,作者为每篇手工写了一个中性的提示作为研究问题;
  • 防止”作弊”:基线和 DataSTORM 都不能访问 ACLED 的网站(自建的搜索服务屏蔽了这个域名),而且只能搜到文章发表之前的网页;
  • 基线:OpenAI Deep Research(o3-deep-research),两种接入数据库的方式——直接上传 CSV(按地区切分,实际上简化了任务),或通过 MCP 使用和 DataSTORM 相同的数据库智能体;
  • DataSTORM 用 gpt-5 做探索,gpt-5.1 写报告。

5.3 自动指标

  1. 参考文章的标准匹配:让 LLM 从专家文章里归纳出一组评价标准(例如”全面和平”那篇,有一条是”指出降低国家与武装团体的对抗,可能伴随着团体之间暴力的上升这一悖论”),再用每条标准给系统的报告打分(0、0.25、0.5、0.75、1),取平均;
  2. RACE:一个已有的、以参考报告为基准的评估框架,按任务动态加权,四个维度:全面性、深度、遵循指令、可读性;50 分表示和参考报告持平;
  3. 数据库使用比例:把报告拆成原子论断,判断每条来自 ACLED 数据库还是一般的网上资料。

结果(论文表 2,GPT-5 评判):

系统标准匹配RACE 总分全面性深度遵循指令可读性数据库论断的比例
OpenAI DR(MCP)48.5%46.145.642.849.349.330.4%
OpenAI DR(CSV)51.2%46.846.943.949.449.523.3%
DataSTORM61.8%52.652.552.253.552.566.4%

注意 MCP 那一行:OpenAI DR 用的是和 DataSTORM 一样的数据库智能体,数据库论断的比例仍然只有 30%——差距不在接口,在研究框架。

5.4 消融

论文在 10 个主题上分别去掉三个部件(表 4a):

标准匹配RACE 总分数据库论断的比例
DataSTORM62.3%51.067.8%
去掉论点48.8%48.671.9%
去掉统计摘要56.9%50.170.9%

去掉论点损失最大(13.5 个点),去掉统计摘要损失 5.4 个点。一个有意思的现象:去掉部件之后,数据库论断的比例反而更高——数据库用得多不等于报告好,零散的数字堆得越多,比例越高。查询一致性的消融见第 4.4 节。

5.5 人工评估

ACLED 的主题和报道的视角很接近调查性新闻,作者招募了 10 位有调查报道经验的评估者(平均 13.3 年新闻从业经验)。20 个主题,每个主题两位评估者;先看中性的主题,再读 ACLED 专家的文章(了解专家怎样选择视角和论点),然后匿名地评价 DataSTORM 和 OpenAI DR(CSV)的报告(两人看的顺序相反,抵消顺序效应)。

评分表改编自经典的”新闻价值”标准(Galtung & Ruge 1965),七项,1~5 分(论文表 3):

项目OpenAI DR(CSV)DataSTORMDataSTORM 胜 / 负
公众影响3.583.6025.0% / 20.0%
公众兴趣3.303.5032.5% / 20.0%
制度上的重要性3.453.5830.0% / 17.5%
冲突与利害3.433.8345.0% / 22.5%
原创性2.213.05(显著,p < 0.05)61.5% / 10.3%
对人的影响2.752.8837.5% / 35.0%
后续报道的潜力3.383.3827.5% / 27.5%

两两比较的偏好(论文图 3):DataSTORM vs OpenAI DR,57.5% 偏好 DataSTORM;DataSTORM vs 专家文章,47.5% 偏好 DataSTORM(接近持平);OpenAI DR vs 专家文章,只有 30.0% 偏好 OpenAI DR。

自由评论的编码:32.5% 的评论称赞 DataSTORM 有清晰、独特的分析角度;40.0% 的评论批评基线论点弱、只是被动地总结文献。但是:27.5% 的评论指出 DataSTORM 的可读性、易懂性不足;20% 的评论称赞基线提供了有用的背景、读起来顺畅。论点驱动的研究能力和易读的写作风格怎样结合,是论文留下的问题。

5.6 模拟实验

代码 03 演示 3,三种系统各做 80 次研究:

系统                召回率  T1    T2    T3    T4    数据库论断  切题  错误论断/份  一致性  查询数
只做网上研究为主    0.09  0.08  0.03  0.15  0.10       12%   100%       0.25      1.00     3.0
ReAct 基线          0.70  0.73  0.17  1.00  0.90       63%    88%       0.00      0.79    22.0
DataSTORM           0.96  0.98  0.90  1.00  0.95       62%    98%       0.01      1.00    21.7
  • 只做网上研究为主(仿 OpenAI DR 拿到 CSV 的行为:主要用网上的资料,只做 3 次查询):数据库论断只有 12%,标准洞见几乎都没对上;T1 的报告每一份都写进了误导性的说法(“错误论断/份”0.25 = 4 个主题里有 1 个);
  • ReAct 基线(同样多的查询,但没有论点、统计摘要、一致性模块):T3、T4 研究问题直接指向答案,做得不错;T2 几乎失败(激增被截断、工会的口径不对);报告里一成多的论断和主题无关;
  • DataSTORM:召回率最高、报告切题、没有误导性的网上说法。

注意”数据库论断的比例”这一列:ReAct 基线用的是同一个数据库,比例和 DataSTORM 差不多。这个指标说明论断从哪里来,不说明报告好不好。

演示 4 是消融:

系统                召回率  T1    T2    T3    T4    数据库论断  切题  一致性
DataSTORM           0.96  0.98  0.90  1.00  0.95       62%    98%    1.00
去掉论点            0.91  0.80  0.90  1.00  0.95       66%    87%    1.00
去掉统计摘要        0.86  0.98  0.50  1.00  0.95       61%    98%    1.00
去掉一致性模块      0.85  0.93  0.57  1.00  0.90       61%    98%    0.76

三个部件各管一件事:

  • 论点 → T1:三条标准洞见都在 Veloria,论点把探索集中在 Veloria 的各种暴力上;去掉论点,报告也变”散”了(切题 98% → 87%),而数据库论断的比例更高(66%)——多出来的是别的国家的数据。这和论文表 4a 的现象一样;
  • 统计摘要 → T2 的激增(G3);
  • 一致性模块 → T2 的工会(G5);
  • T3、T4 只有一条洞见、研究问题直接指向它,三个部件都不太重要。

这说明了什么、没说明什么:模拟里每个部件起作用的”位置”是我们设计数据时埋进去的(截断的激增、多列的行为者)。它说明了机制:为什么统计摘要、一致性模块、论点会有用,在什么样的数据和问题上有用。部件在真实数据上各有多大作用,要看论文的消融。

演示 5 是论点的修正动作(80 次研究):

T1:generate 20、sharpen 11、pivot 7、confirm 2
T2:generate 19、sharpen 14、pivot 0、confirm 0
T3:generate 20、sharpen 0、pivot 0、confirm 20
T4:generate 18、sharpen 0、pivot 0、confirm 6

有多条洞见的主题(T1、T2)上,大多数修正是 sharpen,少数是 pivot——和论文附录 E.2 的分布相似。只有一条洞见的主题上只能 confirm:没有新证据,论点也就没有可修正的地方。

5.7 评估的两个陷阱

代码 03 演示 6 复现了论文提到的两个问题:

1. 总是给 7 分的评委
  只做网上研究为主  程序化的评判 0.09    偷懒的评委 0.70
  ReAct 基线        程序化的评判 0.70    偷懒的评委 0.70
  DataSTORM         程序化的评判 0.96    偷懒的评委 0.70

2. 标准答案里有一条标错了(T4 加上 "G8:Pallasca 的骚乱在 2021 年增加到三倍" —— 数据里没有)
  只做网上研究为主  T4 的召回率 0.10 → 0.05
  ReAct 基线        T4 的召回率 0.90 → 0.45
  DataSTORM         T4 的召回率 0.95 → 0.47
  1. 一个总给同一个分的评委,三种系统的分数一样——分数没有区分度。偷懒的评委”看起来”在工作(给了一个合理的分数),只有拿明显很差的系统去测它,才会发现它坏了。这是第 2、5 讲反复出现的教训:评委本身要先验证;
  2. 一条标错的标准洞见,把所有系统的召回率压到一半以下。系统的排序没变,但绝对数字失去了意义——“DataSTORM 只发现了一半的洞见”是错误的结论。所以论文在报告分数的同时做了错误分析:把得分低的标准洞见拿出来一条条看,才发现 45% 是标注的问题。

6. 讨论与边界

6.1 深度研究的三种”原料”

把这门课的几个深度研究系统放在一起看:

系统原料核心难点讲次
STORM / Co-STORM / GRILL网上的文本、论文覆盖面、组织、引用第 2 讲
SLIDERS一大批长文档上下文装不下 → 先变成数据库第 9 讲
DataSTORM大型数据库 + 网上的文本提出好问题、口径一致、收敛到一个论点本讲

DataSTORM 用了 Co-STORM 做热启动,执行者是第 6、8 讲的查询智能体。课程项目的一个方向是把 DataSTORM 和 GRILL 结合:文献检索和数据分析一起做。

6.2 论文承认的局限

  • 数据清洗(EDA 文献里叫”数据整理”)不在范围内:DataSTORM 假设输入的数据已经干净;
  • 规划者继承了底层 LLM 提出假设的偏差:选择偏差(问什么)、框架偏差(怎样表述);需要更多样的探索策略;
  • 时间序列推理:占真正失败的 45%;
  • 可读性:人工评估里被批评得最多的一点。

6.3 什么是”好的洞见”

一条洞见要同时满足两类要求:

  • 有趣:新、出乎意料、有后果——新闻价值的七项标准是一种表述(原创性、冲突与利害、对人的影响……);论点驱动让报告有一个”角度”;
  • 可靠:数字来自正确的查询(附录 E.3)、口径一致(第 4 节)、经得起反例的检验(论点的 sharpen / pivot)、不被网上的说法带偏。

只追求”有趣”会得到耸人听闻的、经不起检验的结论;只追求”可靠”会得到一堆正确但无聊的数字(“Kestavia 五年里一共有 1,863 次抗议”)。DataSTORM 的设计是让两者互相约束:论点提供方向和角度,数据库和一致性提供约束。

6.4 本讲模拟的边界

  • 没有真实的 LLM。规划者”读题”的能力(p_relevant)、“跟着论点问”的倾向(p_focus_thesis)、看到异常就追问的规则、论点的修正规则,都是设定的。04 号文件让真实的 Claude 当规划者,可以观察它是否真的会从统计摘要里注意到异常;
  • 7 条标准洞见是我们埋进去的,每条都能被一条模板 SQL 发现。真实的洞见常常需要多步推理、跨来源(网上 + 数据库)的综合,评判也需要 LLM 或人;
  • 程序化的评判(matches)按结构化的描述和数值比较,比 LLM 评委严格、可复现,但只能评判”有没有发现埋好的模式”,评判不了原创性、叙事质量。

7. 本讲小结

  1. 在数据库上做深度研究和在网上做不同:要自己提出可执行的问题、对数量模式做推理、在反复探索中保持口径一致、最后收敛到一个论点。现有的深度研究系统即使拿到了数据也很少用(OpenAI DR 的报告只有 23.3%~30.4% 的论断来自数据库)。
  2. DataSTORM 的设计来自探索性数据分析和数据叙事的三条原则:迭代地提出和检验假设(规划者—执行者);演绎和归纳结合(执行者自动附上统计摘要,让被截断的异常可见);收敛到中心叙事(论点驱动探索,sharpen / pivot / confirm;分阶段写报告、逐句核查)。另有网上研究热启动提供背景、洞见库积累证据。
  3. 查询一致性:独立的执行者会悄悄地用不同的口径(行为者看哪几列、时间窗口),得出看起来矛盾、其实不可比的数字。一致性模块对比同一层和洞见库里的查询,生成统一口径的追问。一致不等于正确:统一成哪种口径仍然需要判断。
  4. 评估:InsightBench 上洞见级召回率 61.9 / 69.3(两个评委)vs AgentPoirot 47.1 / 49.9;ACLED 上标准匹配 61.8% vs 51.2%,RACE 52.6 vs 46.8,数据库论断 66.4% vs 23.3%;新闻工作者 57.5% 偏好 DataSTORM,原创性显著更高;可读性仍是弱点。消融:去掉论点损失最大。
  5. 评估的陷阱:总给 7 分的评委没有区分度;标注错误让召回率失去意义(InsightBench 上低分的标准洞见 45% 是标注错误);“数据库论断的比例”高不等于报告好。

8. 与项目的关系

  • 如果你的项目要从数据里”找洞见”,先写下研究问题和口径(每个概念怎样用 SQL 表达:行为者看哪几列、时间窗口、计数方式),再让智能体探索。口径最好和领域专家一起定。
  • 给你的查询智能体的答案附上统计摘要,而不是只给截断的表——这是成本最低、收益最明显的一步。
  • 让探索围绕一个可修正的论点,并记录每次修正的动作和理由;检查加入的证据里有多少是”加限制、反驳”的,防止确认偏误。
  • 评估时:(1) 先拿明显很差的输出测一测你的 LLM 评委;(2) 把得分最低的样例一条条看,区分”系统的错”和”标注的错”;(3) 不要只看一个”数据库使用比例”这样的过程指标。
  • 项目方向:DataSTORM + GRILL——怎样把文献检索和数据分析结合起来?

9. 练习

练习 1(动手:怎样判断”异常”)。read_insight 用”最大值 ≥ 3 倍均值”决定是否追问。对 4 个国家 × 6 种事件类型的 24 条月度序列,阈值分别取 3、2.5、2,各有几条会被追问?被追问的都是真正的异常吗?设计一个更好的规则。

参考答案

实测:阈值 3 时只有 1 条(Kestavia 的抗议,4.2 倍,真正的激增);2.5 时 7 条;2 时 16 条。多出来的大多是计数很小的序列,例如 Pallasca 的”战略发展”每月平均 2.4 件、最多 7 件(2.9 倍)——这只是小数字的随机波动。

问题在于”倍数”没有考虑计数本身的波动:平均 2.4 件的序列,偶尔出现 7 件很正常;平均 31 件的序列出现 129 件极不寻常。计数数据近似泊松分布,标准差约为 √均值,可以用 z = (最大值 − 均值) / √均值:

序列z
Kestavia 抗议(2023-03)17.6
Pallasca 战斗(2021-02)6.8
Kestavia 针对平民的暴力3.9
Kestavia 骚乱3.7
其余≤ 3.2

取 z ≥ 5,正好标出两条:Kestavia 的激增(G3),和 Pallasca 的战斗——后者是旱季的规律(G7),也是真实的模式。注意论文的执行者只报告统计摘要,判断交给规划者(LLM);LLM 也可能被小数字的波动骗到,所以在摘要里同时给出均值和样本量是有帮助的。

练习 2(动手:统一成错的口径)。把 DataSTORM.research 里统一的写法 {"actor": "all", ...} 改成 {"actor": "a1", ...}(只看主要行为者),运行 03 号文件的消融。一致性得分和召回率怎样变化?

参考答案

实测:一致性得分仍然是 1.00,T2 的召回率从 0.90 降到 0.40,总召回率从 0.958 降到 0.833。所有和工会有关的查询口径完全一致——一致地少算了三分之二,G5 一次都没对上(T2 的两条洞见里只剩 G3 可能被发现,所以召回率不超过 0.5)。

这就是第 4.3 节”一致不等于正确”的完整版:一致性指标只检查”同一个概念的写法是否相同”,不检查”写法是否符合概念的定义”。要防止这类错误,口径本身需要验证:读数据的编码手册(ACLED 的手册说明了关联行为者的含义)、和领域专家确认、或者对比几种口径的结果并在报告里说明选择的理由。

练习 3(动手:规划者”读题”)。把 PARAMS["p_relevant"] 分别改成 0(规划者不”读题”,只在候选问题里随机挑)和 0.6,分别运行完整的 DataSTORM 和”去掉论点”。结果说明了什么?

参考答案

实测(总召回率;括号里是 T1 / T2 / T4):

p_relevantDataSTORM去掉论点
00.82(0.90 / 0.57 / 0.80)0.77(0.67 / 0.60 / 0.80)
0.3(默认)0.96(0.98 / 0.90 / 0.95)0.91(0.80 / 0.90 / 0.95)
0.60.94(0.97 / 0.90 / 0.90)0.88(0.73 / 0.88 / 0.90)

(1) “读题”——根据研究问题想到该做什么分析——是最基本的能力,没有它,三个部件也救不回来(0.82)。(2) 不读题时,论点的作用更明显(T1:0.90 vs 0.67):论点把”碰巧发现的第一条洞见”变成了探索的方向。(3) 读题太多也不好:总在”题目直接指向”的十几个问题里挑,挤掉了追问和检验论点的问题。这对应 EDA 的两种推理:题目给出的方向是演绎,追问异常是归纳,两者都需要。

练习 4(思考:数据库论断的比例)。论文表 4a 里,去掉论点、去掉统计摘要之后,数据库论断的比例都升高了。代码 03 演示 4 也有同样的现象。为什么?如果让你设计一个”报告用好了数据库”的指标,你会怎样设计?

参考思路

比例只看”论断从哪里来”。去掉论点之后,报告失去了中心,规划者问到的各种零散的数字(迷你版里是别的国家的发现)都被写进去,数据库论断变多,比例就升高了——但报告变”散”了(迷你版的切题比例从 98% 降到 87%)。

更好的指标要同时考虑:(1) 相关性:数据库论断和研究问题、论点有没有关系(迷你版的”切题”);(2) 必要性:哪些关键结论只能从数据库得到(例如数据反驳了网上的说法),报告有没有用数据库支撑它们;(3) 正确性:数字是否忠实于查询结果、查询是否正确(附录 E.3 的两个维度);(4) 一致性:第 4 节的指标。也可以像”参考文章的标准匹配”那样,从专家文章里提取”应该用数据支撑的论断”,检查覆盖了多少。

练习 5(思考:怎样验证一个 LLM 评委)。InsightBench 原来的 Llama-3 评委几乎总是给 7/10。如果你要用 LLM 当评委评估一个洞见发现系统,在正式使用之前,你会做哪些检查?

参考思路

(1) 看分数的分布:所有样例的分数是否集中在一两个值上?和提示词里的示例分数是否一样?(2) 负对照:拿明显错误的洞见(随机的、和标准洞见无关的、数字错的)给它评,分数应该很低;拿标准洞见本身给它评,分数应该很高(代码 03 演示 6 的”偷懒的评委”在第一步就会暴露)。(3) 和人工标注对比:抽几十对,请人打分,计算一致率;看评委在哪类样例上和人分歧。(4) 换评委:像论文那样用两个不同的评委,结论应该一致(DataSTORM 在 GPT-4o 和 Qwen3 两个评委下都领先)。(5) 检查偏差:位置偏差(先给的更容易得高分)、长度偏差(更长的更容易得高分)——第 15 讲会专门讨论。最后,评委给低分时要回头看标准答案本身对不对(InsightBench 的低分样例里 45% 是标注错误)。


10. 延伸阅读

课程相关

  • Liu、Jiang、Farook、Nicollier Sanchez、Castro Pena、Lam. DataSTORM: Deep Research on Large-Scale Databases using Exploratory Data Analysis and Data Storytelling. COLM 2026. arXiv 2604.06474. 代码:github.com/stanford-oval/DataSTORM
  • Jiang 等. Into the Unknown Unknowns: Engaged Human Learning through Participation in Language Model Agent Conversations(Co-STORM). EMNLP 2024.
  • Sahu 等. InsightBench: Evaluating Business Analytics Agents through Multi-Step Insight Generation. 2025.
  • Raleigh 等. Introducing ACLED: An Armed Conflict Location and Event Dataset. Journal of Peace Research, 2010.

背景

  • Tukey. Exploratory Data Analysis. 1977.
  • Wickham & Grolemund. R for Data Science(探索性数据分析一章). 2017.
  • Segel & Heer. Narrative Visualization: Telling Stories with Data. IEEE TVCG 2010.
  • Dykes. Effective Data Storytelling: How to Drive Change with Data, Narrative and Visuals. Wiley 2019.
  • Du 等. DeepResearch Bench: A Comprehensive Benchmark for Deep Research Agents(RACE 评估框架). 2025.
  • Galtung & Ruge. The Structure of Foreign News. Journal of Peace Research, 1965.

11. 下一讲预告

到这里,这门课已经搭起了一整套”可靠的智能体”:不幻觉的问答、可问责的决策、文本 + 数据库 + 知识图谱上的查询、长文档和大型数据库上的深度研究、可控的任务型对话。每一个系统里,harness(提示词、工具、流程、检查)都是人精心设计的。

第 12 讲换一个角度:编程智能体。Claude Code、Codex 这样的智能体为什么能独立完成复杂的编程任务?它们由哪些部分组成(LLM、工具、harness)?编程为什么特别适合智能体——因为代码可以执行、可以测试,反馈是现成的。更进一步:既然 harness 这么重要,能不能让智能体自动优化 harness 本身?我们会讨论提示词的自动优化(DSPy、OPRO、TextGrad、GEPA)和智能体的自动设计(ADAS、AFlow)。

← 返回课程目录