人大 EvoOntology 深度拆解:Agent 与数据之间,该不该插一层「会自己长大的本体」?
做 Data Agent 有个越来越明显的病:模型越聪明,Agent 却还是要一遍遍重新理解数据。接上数据库、Excel、PDF、API 之后它理论上什么都能查,可真跑起来还在不断找表、猜字段、试 SQL、看结果、再改路径。大量 Token 和 Tool Call,不是花在解决问题上,而是花在重复做 Schema D…
做 Data Agent 有个越来越明显的病:模型越聪明,Agent 却还是要一遍遍重新理解数据。接上数据库、Excel、PDF、API 之后它理论上什么都能查,可真跑起来还在不断找表、猜字段、试 SQL、看结果、再改路径。大量 Token 和 Tool Call,不是花在解决问题上,而是花在重复做 Schema Discovery。
人民大学团队给这个病起了个名字:agent–data gap。他们的药方不是塞更多提示词,也不是继续堆记忆,而是在 Agent 和数据之间插一层会自己长大的地图——EvoOntology。
我把论文(arXiv:2609.15779)全文逐表回读了一遍,又把开源仓库 264 个文件通读了一遍。结论十二个字:方向对、工程实、证据虚、溯源缺。四句并列,不可互相抵消。以下逐条坐实。
一、先把病人说清楚
论文对病灶的描述相当准(原文第 117 行):数据在 Agent 之外,Agent 只能透过通用工具(SQL 接口、文件读取器)触达,于是结构与内容都无先验。结果是 Agent 只能盲目试探——反复发探测查询、猜概念落在哪、读进一堆无关内容。
它还抓到一个别人少谈的点:现有 semantic layer 是手工维护的,且与下游轨迹脱节——没人知道哪条语义记录影响了哪个下游决策。
这个诊断是对的。而对照组设计也干净:
Baseline:纯 ReAct,无本体层,每个任务都要重新发现 schema;Baseline + SL:把 builder 产出的语义层当静态 Prompt 片段前置;ReAct + Memory:把历史轨迹当可检索片段,取 top-k 注入 Prompt。
这是本文最干净的一组对照:「静态塞入」不如「按需查询」。
二、它是什么:三层 + 五类记录
本体状态记为 ℒ =(Schema Γ / Content 𝒮 / Tool ℛ),把「知识的形状」「知识」「知识的取用方式」三者分开。
- Schema Layer Γ:定义四类节点的字段、允许的关系类型、允许的引用模式;
- Content Layer 𝒮:领域知识与数据映射,真正的「地图内容」;
- Tool Layer ℛ:两个 MCP 工具 + 一份 session manifest。
- 四类节点:Term(概念,五型可选:concept/metric/entity/dimension/category)、Mapping(落到物理列)、Constraint(限正确用法)、Evidence(探测之证);
- 两类边:Semantic Relation(连接 Term,受控五值)、Structural Reference(由对象引用隐含)。
affects、belongs_to 之流):| 关系类型 | 含义 |
|---|---|
association | 泛业务关联(兜底型) |
hierarchy | is-a,子域 ⊆ 父域 |
composition | part-of,子记录不可独立存在 |
equivalence | 跨源同义 |
derivation | 目标由源算出 |
Relation 本质是边不是节点。把一张图说成一份清单,丢掉的恰是本设计的要点。设计里最值得学的一条:无证据不入库。只有探测结果支持的候选才准进本体:𝒞⁺ = { c ∈ 𝒞 | verify(probe(c, 𝒟)) = 1 }。幻觉被挡在本体之外。
三、闭环四步:诊断 → 归因 → 补丁 → 门控
- Diagnose:从历史轨迹里提取复现的失败签名;
- Attribute:把签名判给 Content / Tool / Schema 三层之一;
- Patch:生成只改一层的候选,同一假设涉及多个相互依赖对象时可一并改动;
- Gate:候选与其父版本在同一验证集、同一预算下评测,只有当提升达到 margin τ 才保留。
| 变体 | 得分 | Δ |
|---|---|---|
| Full loop | 89.5 | – |
| w/o Gate | 78.3 | −11.2 |
| w/o Attribution | 83.2 | −6.3 |
| w/o Diagnose | 84.7 | −4.8 |
| w/o Patch(改自由改写) | 87.8 | −1.7 |
四、数字逐表还原
先排一个乱子。摘要说「four LLM backbones」,实验设置节说「six LLM backbones」,Table 2 标题说 four,Table 3 的分析段里同一段话先说 six 再说 four。而第 724 行给出了「四强」的确切名单:GPT-5.5、GPT-5.6-sol、Claude-Sonnet-5、Claude-Opus-4.8。
真相是:实验跑了六个,分析与消融只报四个。被剔除的 DeepSeek-V4-Flash 与 Qwen3.5-Flash,恰是两个最弱的(Baseline Traj-Wise 分别只有 30.3 与 14.3)。算术坐实:
| 口径 | Baseline 均值 | Evolved 均值 | 增益 |
|---|---|---|---|
| 六 backbone | 53.80 | 71.57 | +17.77(≈正文的 +17.8) |
| 四 backbone | 69.55 | 89.50 | +19.95(≈表里的 +20.0) |
主结果(EvoOntology 相对同 backbone Baseline,Traj-Wise):
| Backbone | Baseline | EvoOntology | Δ |
|---|---|---|---|
| GPT-5.5 | 64.2 | 90.9 | +26.7 |
| GPT-5.6-sol | 68.5 | 93.5 | +25.0 |
| Claude-Sonnet-5 | 72.5 | 81.3 | +8.8 |
| Claude-Opus-4.8 | 73.0 | 92.3 | +19.3 |
| DeepSeek-V4-Flash | 30.3 | 52.3 | +22.0 |
| Qwen3.5-Flash | 14.3 | 19.1 | +4.8 |
这里说句公道话:BIRD 是文本到 SQL,且用了 Oracle Knowledge——该设定本就向模型提供了表/列提示。在「schema 提示已给」的场景下还能涨 +7.4,说明本体层提供的是超越 schema 的语义(口径、枚举含义、跨表关系、派生指标)。这是对论文有利的解读,应该说出来。
谁的功劳?
论文把 Baseline → Evolved 拆两段:
| 基准 | builder 之劳 | 自进化之劳 |
|---|---|---|
| DDR-Bench Traj-Wise | +12.3 | +7.7 |
| InsightBench Insight | +0.8 | +0.2 |
| BIRD EX | +5.1 | +3.7 |
全篇最硬的一笔账
Appendix B 的 Table 8,恰恰证明了「多数 Token 花在重复 Schema Discovery」这句话不是修辞:
| 指标 | Baseline | Initial | Evolved |
|---|---|---|---|
| 输入 token / 轮 (K) | 3.2 | 4.1 | 4.6 |
| 轮数 / 任务 | 14.6 | 11.2 | 8.4 |
| 总 token / 任务 (K) | 52.6 | 50.4 | 42.0 |
| Traj-Wise (%) | 69.5 | 81.8 | 89.5 |
(须注意:Table 8 只统计了使用期的推理开销,未计入 Build 与 Evolve 本身的成本——Build 要发大量探测查询,Evolve 每轮都要在验证集上跑 Parent 与 Candidate 两遍。这是半份成本表。)
五、八处审查
1)门控:论文写了 margin τ,代码里没有 τ
这是全案最硬的一处「论文宣称 vs 代码交付」落差。论文式(2)写得清清楚楚:候选被保留,only when its improvement reaches margin τ。
而代码 evoontology/evaluation/evaluation.py:28-39 实为:
"accept": candidate_avg > parent_avg
判据是 >,不是 >= τ。整个内核目录 grep margin | tau | min_delta——零命中(唯一命中是 HTML 模板里的 CSS margin)。
更要紧的是,README.md:67 的设计原则写着:*Publish a Candidate only when paired evaluation shows a reproducible improvement*. 「可复现」一词赫然在目,但一个基于点估计、无 margin、无检验、无多次采样的判据,无法提供任何可复现性保证——哪怕候选只高 0.0001 分,也会被发布为新版本并切为 active。
必须公允地补充两点:
- 作者是知情的,且写在了文档里。
evaluation-protocol.md:72原文:「第一版不叠加 swap 消偏(已匿名)、分维度判、多采样、confidence 字段。」 - 作者知其险,却只用了软约束。
evo-evolve/SKILL.md:219-220:「When the validation set is small, re-run the evaluation to confirm the improvement is not single-trial luck.」——补救措施写进了交给 LLM 执行的 skill 提示语,而非内核强制。提示语无法保证被执行,而门控是自动化的、每轮都跑的。
2)统计:零方差、零样本量
全文 grep p-value | significan | confidence interval | standard deviation | error bar | multiple run | variance——零命中。全文亦未披露任何一个基准的实际题数/样本量。
这意味着:读者手里没有任何工具去判断这些百分点是效应还是噪声。
我做了敏感性反算(假设声明:论文未披露 N,故取若干候选值;各 case 独立伯努利;取对作者最有利的单尾方向;真实方差只会更大,故下列 p 为下界):
| 场景 | 增益 | N | Fisher p | 判读 |
|---|---|---|---|---|
| DDR 总增益 | +20.0pp | 100 | 0.00033 | 显著 |
| DDR 自进化增益 | +7.7pp | 100 | 0.0764 | 不显著 |
| DDR 自进化增益 | +7.7pp | 200 | 0.0223 | 显著 |
| BIRD 自进化增益 | +3.7pp | 200 | 0.2605 | 不显著 |
| BIRD 自进化增益 | +3.7pp | 500(minidev 口径) | 0.1114 | 不显著 |
| Insight 自进化增益 | +0.2pp | 任意 | — | 不足一道题的分量 |
- 大增益是可信的。DDR 的 +20pp、BIRD 的 +7.4pp(相对 Baseline)在任何合理样本量下都显著。不能因为「没报显著性」就否定效应本身。
- 自进化的小增益不可信。BIRD 上 +3.7pp 若按 minidev(500 题,代码
run_evaluation.py:436确有此档)计,p=0.111,未达显著,而论文仍以此支撑「自进化不可或缺」。InsightBench 的 +0.2pp 更是任何统计都无法判真的量级。 - 门控缺统计纪律(见上)。
3)血脉:代码文档六处自认师承,论文正文零提及
- 证据 A:仓库
docs/architecture.md明写「EvoOntology 借鉴了 SkillOpt 的方法论:把「本体层」当成 Agent 的可训练状态……SkillOpt 训练的是 skill 文档,EvoOntology 演化的是本体层记录」,且逐项对标其目录契约(dataloader.py→data/、rollout.py→run_agent.py、EnvAdapter→EvolutionAdapter、skills/initial.md→evo-buildskill)。 - 证据 B:论文全文 grep
SkillOpt——零命中。无致谢、无 Related Work 提及、无脚注。 - 证据 C:
github.com/microsoft/SkillOpt是微软官方仓库(466 commits),自述「Train agent skills like you train neural networks... validation gates」,核心判据「a candidate edit is accepted only when it strictly improves a held-out validation score」——与 EvoOntology 的门控严丝合缝。时间线:v0.1.0 2026-05-22 → v0.2.0 07-02 → 微软研究院官方报道 07-24 → 末次提交 08-12;EvoOntology 提交 2026-09-14。
公允判词:方向对、迁移有价值、溯源不实。
4)交付:「自进化」在开源代码里没有端到端驱动
- 三个基准的
evolution_adapter.py全部是 subprocess 外壳,不 importevoontology任何东西; - 在整个
benchmarks/目录 grepEvolutionSession | EvaluationGate | decide_gt:零命中; benchmarks/README.md:71明说:仓库不提供原始大型数据、预构建ontology_v0与预构建 evolved ontology;- 唯一驱动内核的是一个离线构建脚本,且只覆盖 BIRD 的 formula_1 最小示例(
train_count: 33 / test_count: 33)。
(公允补充:不提供预构建产物,也可能是故意的学术诚信选择——避免他人直接拿去刷榜。且 README 明确交代了。问题是「复现门槛极高」,而非「故意隐瞒」。)
5)语义:Tool 层才是主杠杆,不是「地图内容」
三张消融表指向同一个结论:
- Table 6:Tool-only 演化 = +13.2(全血 +20.0 的 66%);Schema-only 只值 +3.6。
- Table 7:
w/o Mappings−13.4(最大)、w/o Evidence−8.7、w/o Constraints−3.5、w/o Relations仅 −2.1;而 Terms 无法单独屏蔽(所以「五类对象」实际只验证了四类)。 - Appendix C:Tool 层编辑占累积增益 57%、Content 34%、Schema 仅 9%。
换句话说:地图画得多细是次要的,能不能按需只翻当前要的那一格,才是主要的。若要自建类似方案,第一优先是把按需查询接口做对,而不是急着填本体条目。
6)另一条被低估的结论:本体是「每模型一本」
Figure 5:接受编辑后的 Term 标识 Jaccard 重叠最高仅 0.62,两个 Claude 之间(0.55)甚至低于两个 GPT 之间(0.61);跨 backbone 迁移掉 6.6~10.9 分。
换一个模型,本体要重训一遍。所谓「通用本体层」在数据上站不住——至少目前是「每模型一本」。对工程落地的含义很直接:成本不是一次性的,而是随模型数量线性增长。
7)工程瑕疵
USAGE.md:76在fixed_split模式下规定「优先复用官方划分,不额外生成随机 Fold」,而论文宣称采用自造两折的 Reciprocal Two-Fold Evaluation——口径冲突之处恰落在实验方法上;- 版本号三处互不相干:
pyproject.toml= 1.1.0 / claude-codeplugin.json= 1.0.2 / codexplugin.json= 1.1.1+codex.…; - 双命名空间:citation 指
ruc-datalab/EvoOntology,插件安装指令指MeiduoChong/EvoOntology; - 命名债:三个基准目录下的
tceo/代号仓库无全称可查,benchmark/*/config.py注释至今仍称「Static TCEO ontology layer runtime」; - 文档与代码取值漂移:schema 文档规定
severity取值为block / warning / info,代码却归一化为warn。
8)值得称赞处(同样是证据)
只挑毛病的报告等于没做报告。这个仓库有几处做得很好:
- 核心包零依赖:
pyproject.tomldependencies =[],不拖任何外部库; - 只读约束:
execute_ontology_query明令「bounded read-only SQL」; - 禁止伪造观察:
record_ontology_task_event原文「Do not submit fabricated observations or hidden reasoning」; - 防基准污染:
prepare_ontology_workload原文「Never reads global chat history or reserved benchmark data」; - 严格评测:BIRD 用执行式精确比对(结果集严格相等)产出 EX,非模糊 LLM 打分;
- 反早停状态机:只有 Accept 或合法 Incomplete 是终态;reject 不足 2 次时,不许以
missing_data/unreliable_evaluation为由收兵; - 原子写盘:先写
.tmp再replace; - 诚实标注:构建脚本里主动写入 3 条
rejected_candidates与 4 条known_limitations,逐条说明建模取舍(如「drivers.code 缺失 757/840」「最快圈速以文本存储需数值转换」)。
六、落地四改
若你要照搬这套,先改四处:
- 给门控加 margin τ:
decide_gt(parent, candidate, margin=τ),判据改>= τ(一行代码,且完全对齐论文式(2)); - 用配对检验:门控已要求
case_ids唯一对齐,说明数据本就配对——但判定只用了两个均值,白白浪费方差缩减的功效。改用 McNemar 或 bootstrap 配对 CI; - 软约束改硬约束:把 skill 里「小验证集请重跑」写进内核,别只写在提示语里;
- 补齐成本核算:当前只算使用期,Build 与 Evolve 的账欠着。
七、勘误与未证实
勘误清单(摘):
- 四 vs 六 backbone 混用(第 100/231/430/585/724/1295 行);
- 式(2) 的 margin τ 在代码中不存在(
evaluation.py:28-39); - 「reproducible」一词(
README.md:67)与点估计判据不符; - 「self-evolution loop is essential」用在 InsightBench 的 +0.2 上过重;
- 五类对象中 Terms 无法单独屏蔽,「五类」实际只验证四类;
- 「Tool Layer exposes two MCP tools」——代码实暴露约 29 个(查询期 2 + 确定性操作 17 + 宿主工作流 10),读者只读论文会严重低估工程体量;
- 转述版「五元组」应为「四类节点 + 两类边」。
- 三个基准的实际样本量——论文未披露。本报告的 p 值建立在假设的 N 上,不能当作对论文的证伪,只能当作「显著性不可复核」的证据;
- 「TCEO」全称——仓库无定义,不臆测;
- 论文的 Evolved 数字如何产出——仓库无端到端脚本,推测为作者私有编排 + 人工跑插件,未证实;
- BIRD 用的是 minidev(500) 还是 dev(1534)——代码两档皆存,论文未说明;
- benchmark 是否曾在 adapter 层实现 margin——内核无 margin,adapter 为 subprocess 外壳,不能 100% 排除,但未见任何证据;
- SkillOpt 与 EvoOntology 作者间是否有私下交流——无证据,不作推断。
gh repo clone 264 文件 + arXiv HTML 全文转纯文本 5.7 万字符)→ 主帅亲读内核 + 两路探子侦察(军报须附 文件:行号)→ 论文宣称与代码交付逐项对账 → 统计反算 → 口径四问。所有数字直接 grep/Read 自原文,不引二手转述。本文未实跑,代码结论均为读码推断。结语 · 四句
- 它给 Agent 的不是更多提示词,也不是更多记忆,而是一张会自己长大的地图——但真正的杠杆不在图画得多细,而在能不能只翻你要的那一格。
- 每轮多看 44% 的上下文,换来少走 42% 的弯路,总账省下 20% 的 token 且准确率涨 20 个点——这笔账,是这篇论文最漂亮的地方。
- 论文公式里写着「improvement ≥ τ」,代码里写着
candidate_avg > parent_avg。τ 不在了。 - 代码文档六处承认师承微软 SkillOpt,论文正文一字不提——方向对、迁移有价值、溯源不实。
原物:arXiv:2609.15779v1(2026-09-14)· github.com/ruc-datalab/EvoOntology(MIT,末次提交 2026-09-23)
对照:github.com/microsoft/SkillOpt(v0.1.0 2026-05-22;微软研究院官方报道 2026-07-24)
核查边界:未实跑;代码结论均附 文件:行号;p 值建立在假设样本量之上,不作证伪之用。