Agent 3 面试题与答案
每道题分三部分:一句话(先抛结论)→ 详细回答(被追问时展开)→ 可能的追问。
数字来自agent3.md和google_docs_assisant/benchmarks/reports/agent3_test.md。
先看:口径统一(这份最重要)
⚠️ 1. 我做的不是「实体-三元组知识图谱」
这套题是按传统知识图谱出的(实体、关系类型、三元组、实体消歧)。你做的是「知识树 + 关联边」:
| 传统知识图谱 | 你的项目 |
|---|---|
| 节点 = 实体(人名、方法名) | 节点 = 问答(一个知识点)和主题 |
| 边 = 预定义的关系类型(属于、提出、使用…) | 边 = 无向的「相关」;另外用 same 判断去重 |
| 三元组(头实体,关系,尾实体) | 问答 =(问题,答案,原文证据) |
| 存图数据库 | 存一个 JSON 文件 |
每道题先用一句话把题目「翻译」到你的设计上,再回答。不要顺着说「我做了实体抽取」,一追问就露馅。面试时说「知识树 + 关联边」,少说「知识图谱」。
2. 其他口径
| 项目 | 口径 |
|---|---|
| 技术栈 | 全套谷歌:教师 Gemini,学生 Gemma 3 27B;参考答案由旗舰教师从原文抽取;评测判断由 LLM 裁判完成 |
| 「关系边正确 0.25 → 0.90」 | 两个数不是同一个标准:0.25 是有向「依赖」,0.90 是无向「相关」。不能说「提升了 3 倍多」,见 Q4 |
| GRPO | 3 轮,测试集上和 SFT 持平(差距在 ±0.012 以内);主要收获是训练中无效输出从 21% 降到 2% |
| 两个 LoRA | 抽取 LoRA(SFT + GRPO 3 轮)+ 关系判断 LoRA(只做 SFT),挂在同一个 27B 基座上 |
关键数字速查(37 篇测试文档)
| 方案 | 召回率 | 准确率 | 问题自足 | 归属主题 | 关系边正确 | 不连正确 | 问答数 / 篇 | 小主题比例 |
|---|---|---|---|---|---|---|---|---|
| Gemma 27B 未训练 | 0.319 | 0.915 | 0.958 | 0.817 | — | — | 78 | 0.44 |
| 教师 Gemini | 0.691 | 0.965 | 0.985 | 0.858 | — | — | 102 | 0.36 |
| SFT 第一版(只训抽取) | 0.680 | 0.925 | 0.942 | 0.743 | 0.25(有向) | — | 195 | 0.27 |
| SFT 第二版(抽取 + 关系判断) | 0.692 | 0.934 | 0.950 | 0.841 | 0.897 | 0.754 | 201 | 0.27 |
| SFT + GRPO 3 轮(最终) | 0.697 | 0.928 | 0.947 | 0.836 | 0.899 | 0.766 | 211 | 0.28 |
「—」:当时用的是有向依赖的定义,和现在的无向「相关」不可比。
模块一:项目架构与设计思路
Q1:请介绍 Agent 3 的核心任务、输入输出和完整工作流程。它与 Agent 2 的关系是什么?
一句话
Agent 3 把 Agent 2 切好的块逐块抽成「主题 → 问答」,再用「程序找候选、模型判断、程序合并」的方式去重、连无向的相关边,建成一篇文档的知识树,最后并入用户已有的知识库;Agent 2 负责把文本修干净、切成 Agent 3 一次读得下的块。
详细回答
输入:Agent 2 的块(每块 ≤ 4096 token、话题完整、格式干净)。
输出:一棵两级知识树 + 关联边
1 | 文档:GRPO 论文 |
| 组成 | 作用 |
|---|---|
| 主题 | 像章节小标题,给问答分组 |
| 问答 | 最小知识单位:问题 + 答案 + 一句原文证据 |
| 相关边 | 两条问答之间的无向连线,可以跨主题、跨文档 |
树负责分类,边负责关联。
每条问答的三个要求:
- 问题自足:脱离原文也能看懂(不写「本文」「该方法」)
- 答案忠实原文:不补充、不编造,用原文的语言
- 带原文证据:原样摘录一句,方便核对
完整流程:
1 | Agent 2 的块 |
和 Agent 2 的关系:
- Agent 2 切块是为了 Agent 3:一篇论文几万 token 一次放不下,太长也会漏抽中间内容
- 4096 的上限由 Agent 3 的预算倒推:输入 4096 + 提示词 + 输出上限 12000,正好放进 20480 的上下文
- Agent 2 必须「只修格式不改内容」:Agent 3 照着它的输出抽问答,Agent 2 改错一个数字,错误就进了知识库
- 跨块的关联不靠 Agent 2 的重叠,而是由 Agent 3 的合并步骤处理
Q2:为什么要将文档转换成知识图谱?相比直接使用文本块进行检索或问答,知识图谱能解决什么问题?
一句话
先纠正一下:我做的是「知识树 + 关联边」,不是实体三元组图谱;它解决的不是检索,而是复习:把一篇文档变成去重后、分好类、互相关联的知识点,用户能像看思维导图一样系统地复习,而文本块只能被动地等人搜索。
详细回答
产品定位:个人知识库,用户上传文档后得到思维导图式的知识整理,用来学习和复习。
直接用文本块(检索增强)的问题:
| 问题 | 文本块 | 知识树 + 边 |
|---|---|---|
| 怎么用 | 用户要先想到问题才能搜 | 直接浏览,知道这篇文档有哪些知识点 |
| 重复 | 引言、方法、结论各讲一次,检索会返回三段 | same 合并成一条 |
| 跨文档重复 | 两篇文档讲同一个概念,各存一份 | 并入知识库时合并 |
| 结构 | 一段文字里混着多个知识点 | 一条问答只讲一个知识点,按主题分组 |
| 关联 | 看不出「这个和那个值得对照看」 | 相关边,可以跨主题、跨文档 |
| 可核对 | — | 每条问答带原文证据 |
为什么是「树 + 边」,不是纯图谱:
- 只有一串问答:一篇论文一两百条平铺,没法复习
- 树解决分类:每条问答只属于一个主题,对应思维导图的分支
- 边解决跨分类的关联:比如「PPO 的截断」和「GRPO 的相对优势」在不同分支,但值得一起看
为什么不做实体三元组:用户要复习的是「概念、原理、方法步骤、结论、关键数据」这类知识点,一个三元组(GRPO,使用,组内优势)承载不了「怎么算、为什么」。问答形式更接近复习的使用方式。
可能的追问
- 那能不能也支持检索问答? 可以,问答本身就带向量,天然适合做检索;而且检索结果已经去重、带证据,比原始文本块更干净。
模块二:实体与关系抽取(对应:问答抽取与关系判断)
Q3:如何从文本块中抽取实体和实体之间的关系?你的抽取流程是什么?
一句话
在我的设计里,「实体」对应主题和问答,「关系」对应 same / related;抽取分两段:抽取 LoRA 逐块生成主题和问答,关系不在抽取时定,而是合并阶段由程序找候选对、关系判断 LoRA 逐对判断。
详细回答
第一段:逐块抽取问答(agents/knowledge/extract.py)
模型看到的输入:
1 | 文档标题:DeepSeekMath: ... |
- 加目录是为了让主题名起得具体(「GRPO 的优势估计」而不是「方法」)
- 目录只是每块标题的前 40 字,不含其他块内容,所以还能并行
输出:
1 | {"topics": [{"id": "t1", "name": "GRPO 的优势估计"}], |
第二段:关系判断(agents/knowledge/merge.py)
1 | 所有问答(例如 180 条) |
为什么关系不在抽取时定:
- 抽取时每块只看得到自己,跨块的关系它根本看不到
- 两两比较 200 条问答约 2 万对,太贵,所以先用便宜的方法筛候选
- 一个有意思的发现:抽取输出里的
relations最终不使用,但提示词里要求标关系的那段不能删。删掉后召回率从 0.60 掉到 0.41。推测是要求标关系时,模型会更仔细地拆分知识点
为什么分成两个 LoRA:抽取输出几千 token,关系判断只输出约 8 个 token。混在一起训练时 loss 按 token 平均,判断样本只能分到约 1% 的训练信号。
Q4:如何定义实体类型和关系类型?如何避免大模型生成不符合要求的实体或关系?
一句话
「实体」只有两类(主题、问答),关系只有三类(same、related、none),类型刻意定得很少;关系类型最初设计成有向的「前置依赖」,但连教师都只有 0.32~0.65 的正确率,查文献发现方向需要外部信号,于是改成无向的「相关」;不合规的输出靠提示词规则、程序整理和训练数据清洗三层把关。
详细回答
类型定义:
| 类型 | 定义 |
|---|---|
| 主题 | 像章节小标题,≤ 20 字,写出具体对象;一个主题下几个到十几个问答 |
| 问答 | 一个知识点:概念、定义、原理、方法步骤、结论、关键数据 |
| same | 同一个知识点,问法不同也算 → 合并 |
| related | 看懂一个后另一个值得一起看:同一概念的不同方面、对比、因果、问题与解法、定理与应用、举例 |
| none | 只是同一篇、同一章、同一话题下并列,或只是字面上有相同的词 |
拿不准就选 none:连错一条边比漏连一条更糟,会误导用户。
最重要的决策:从「有向依赖」改成「无向相关」
原设计:有向的「前置依赖」(要懂 A 必须先懂 B),可以生成学习路径。
问题:连教师的依赖边正确率都只有 0.32~0.65。试过四种办法:
| 尝试 | 结果 |
|---|---|
| 更严格的提示词、更多反例 | 只到 0.43 |
| 成环检查(依赖不该成环,有环就删边) | 只能去掉矛盾的边,单独一条错边发现不了 |
| RefD 引用检查(天然有方向) | 能多找候选,方向准确度提升有限 |
| 改成逐对单独判断 | 最好 0.65 |
查概念前置关系学习的文献(RefD、基于教材顺序的方法、LectureBank)后确认:方向需要外部信号(教材章节顺序、课程大纲、引用结构),语义相似度是对称的,只能说「有关系」,说不出谁是谁的前提。数据也印证:真正有依赖的对,平均相似度反而比「看起来像但无关」的对还低。
决定:先做无向的「相关」,以后有外部信号再加回有向依赖。不是放弃,是推迟。
⚠️「0.25 → 0.90」要讲清楚:两个数不是同一个标准,0.25 是有向依赖(方向也要对),0.90 是无向相关。如果被问「是不是换了道简单题刷指标」:
对,这两个数不在同一个标准下。它说明的是有向依赖在没有外部信号时本身就做不好,连教师都只有 0.32 到 0.65。为了证明不是在刷指标,我同时看了「不连正确」:把最像但没连的对拿出来检查是不是真的无关,这一项是 0.77。如果模型只连最有把握的几条,这一项就会掉。
怎么避免不符合要求的输出(三层):
| 层 | 做法 |
|---|---|
| 提示词 | 写清什么抽、什么不抽(导航、参考文献、致谢、版权声明不抽);问题自足;主题要具体 |
| 程序整理 | 不合法 JSON 记为失败;缺问题或答案的丢掉;没主题的放进兜底主题;关系只能三选一 |
| 训练数据清洗 | 教师答错的问答删掉;语言不对的翻译回原文语言;挂错主题的改挂;小主题合并 |
Q5:如果文本中存在代词、省略、同名实体或者隐含关系,你如何处理?
一句话
代词和省略靠「问题自足」的硬要求解决:问题里必须写出具体对象,不许写「该方法」;同名靠「问答内容」而不是「名字」判断是否合并;隐含关系靠 RefD 引用检查补充候选,因为真正相关的对往往字面并不像。
详细回答
| 情况 | 怎么处理 |
|---|---|
| 代词 | 提示词要求问题自足,必须把「该方法」「它」替换成具体名称,比如「GRPO 相比 PPO 的优势是什么?」。评测里有「问题自足」这一项,最终 0.947(教师 0.985) |
| 省略 | 同上;并且给模型提供文档标题和全文目录,它知道「本文的方法」指的是什么 |
| 同名不同义 | 合并时不看名字,看问题 + 答案的内容由模型判断 same。比如「GRPO 的优势怎么算」和「PPO 的优势怎么算」字面很像、相似度很高,但模型会判为不同 |
| 同名主题 | 两个都叫「实验设置」的主题可能讲完全不同的事。所以主题合并时用「主题名 + 下面前 5 个问题」一起判断 |
| 不同名同义 | 「GRPO 的优势估计」和「组内相对优势」是同一个主题:向量能召回,模型判 same 后合并 |
| 隐含关系 | 向量相似度只能找「看起来像的」。补充 RefD 引用检查:A 的答案里大量出现 B 问题里的关键概念,说明 A 用到了 B 讲的东西。比如 A「GRPO 的损失函数是什么?」答案里用到了「相对优势」,B「相对优势怎么算?」,两者字面不像,但应该相关 |
RefD 的具体做法:
- 找每条问答问题里在本文档中有区分度的词(英文单词、中文二字词、公式符号)
- 超过 30% 的问答都出现的词不算(比如方法名「GRPO」)
- 统计 A 的答案里出现了多少 B 的关键概念
- 每条问答再加上引用最多的 3 条作为候选
可能的追问
- 跨句的代词消解做了吗? 没有单独做共指消解,而是让模型在生成问题时直接写出具体对象,评测「问题自足」来检查。
模块三:知识图谱构建与融合(对应:合并建树与知识库融合)
Q6:你如何将抽取结果转换成知识图谱?节点、边及其属性分别如何设计?
一句话
节点有三层:文档、主题、问答,用一个 parent 字典组织成两级树;边只有一种:问答之间的无向「相关」边,按 id 排序存储,同一对只存一次;所有数据存在一个 JSON 文件里。
详细回答
数据结构(agents/knowledge/types.py):
1 | KnowledgeDocument / KnowledgeBase |
节点属性:
| 节点 | 属性 | 设计考虑 |
|---|---|---|
| 问答 | 问题、答案、证据、来源块号 | 证据用于核对和归因;来源块号让 Agent 4 定位 |
| 问答 | merged_from |
被合并掉的问答记在这里,不丢信息 |
| 问答 / 主题 | 全局 id:文档id:c块号:q序号 |
合并时不冲突 |
边的设计:
- 只有一种类型:无向
related - 存储时两个端点按 id 排序,同一对只存一次
- 无向边不存在成环问题,不需要去环
scope区分文档内的边和跨文档的边
为什么不用图数据库:这是个人知识库,几十到几百篇文档,问答最多几万条,一个 JSON 文件足够,也方便查看和调试。规模变大再换(见 Q14)。
Q7:不同文本块可能抽取出同一个实体,你如何进行实体对齐、去重和消歧?
一句话
程序先用向量相似度和 RefD 筛候选对,关系判断 LoRA 逐对判断是不是同一个知识点,再用并查集处理传递合并,保留最先出现的那条;主题也按同样流程合并,消歧靠「看内容不看名字」。
详细回答
为什么需要:
- 同一文档内:引言提一次、方法讲一次、结论又总结一次
- 主题重复:「GRPO 的优势估计」和「组内相对优势」其实是一回事
- 跨文档:GRPO 论文和一篇 RLHF 综述都讲了相对优势
流程:
① 找候选对(避免 2 万对两两比较)
- 向量:每条问答(问题 + 答案)用
paraphrase-multilingual-MiniLM-L12-v2编码,取最像的 3 条,相似度低于 0.6 不要;小模型,中英文都能用,本机 CPU 就能跑 - RefD:再加引用最多的 3 条
② 模型判断:关系判断 LoRA 输出 same / related / none
③ 并查集传递合并
1 | A same B,B same C,D same E |
结果里没有直接写「A same C」,要靠传递推出来,并查集专门处理这种情况。
④ 合并后修边:连到 B、C 的边改连到 A;自环和重复边删掉
⑤ 主题合并:用「主题名 + 前 5 个问题」做向量找最像的 3 个,模型判断是不是同一主题,并查集合并,问答改挂到保留的主题上,空主题删掉
消歧:靠模型看完整的问题和答案判断,不靠名字。字面相同但讲两回事的(「GRPO 的优势」vs「PPO 的优势」)判为不同。
并入知识库时的两条规则:
- 合并时保留已有的那条:用户已经看过的不会突然变样
- 同一文件重复上传:文件 id 是内容哈希,先删旧的再并入
可能的追问
- same 的训练样本很少怎么办? 关系判断数据里 same 只有 33 对(related 1269、none 1277)。我按自然比例训练,没有配平:早期把依赖类上采样后,模型预测依赖的比例从教师的 5% 涨到 11%,一半是错的。分类任务的训练比例要和实际使用时一致。
- 并查集有没有误合并的风险? 有:一次错误的 same 会通过传递把一串都合并掉。可以加约束,比如同一块里的问答不判 same,或者合并后检查组内的两两相似度。
Q8:如果一个实体关系跨越多个文本块,你如何发现并建立跨块关系?如何避免错误连接?
一句话
抽取时每块只看自己,所以跨块关系统一在合并阶段处理:所有块的问答放在一起找候选对,同一块内的也比,由关系判断模型逐对判断;防错连靠「拿不准就选 none」的保守策略,并用「关系边正确」和「不连正确」两个指标同时监控。
详细回答
怎么发现跨块关系:
- 合并时把全文所有块的问答放在一起找候选,块与块之间不设边界
- 同一块内的问答也要比较,关系统一在这一步判断
- 向量找「看起来像的」,RefD 找「实际用到的」,两种候选互补
- 跨文档也一样:并入知识库时,新文档的问答和库里已有的问答比较,连跨文档的边
怎么避免错误连接:
| 手段 | 做法 |
|---|---|
| 候选门槛 | 相似度低于 0.6 不进候选;每条最多取 3 + 3 个 |
| 保守判断 | 提示词明确「拿不准就选 none」,连错比漏连更糟 |
| 明确的反例 | 只是同一篇、同一章、同一话题下并列、字面有相同的词,都不算相关 |
| 训练数据 | 关系判断数据按自然比例,不人为抬高「有关系」的比例 |
| 输入一致 | 训练和推理用同一个 link_message() 构造输入;A、B 顺序随机交换,避免位置偏好 |
双指标监控:
| 关系边正确高 | 关系边正确低 | |
|---|---|---|
| 不连正确高 | 判断准 | 乱连 |
| 不连正确低 | 太保守,漏连 | 都不行 |
结果:关系边正确 0.899,不连正确 0.766。说明偏保守:最像但没连的对里约四分之一其实相关。
可能的追问
- 0.899 可信吗? 可能偏高。做 Agent 4 时发现有 575 条边被二次复核确认是错的,但在 Agent 3 评测时被判为正确。已记录待办:用同样的二次复核方式把所有方法重算一遍。
模块四:提示词与模型优化
Q9:你如何设计实体与关系抽取的提示词?如何约束大模型输出结构化结果?
一句话
提示词给模型文档标题和全文目录,写清主题和问答的规则(问题自足、忠实原文、带证据、只抽讲解过的知识);输出用固定的 JSON 格式,再由程序做三层兜底:LaTeX 反斜杠转义、字段补齐、输出长度上限。
详细回答
抽取提示词的规则(agents/knowledge/prompts.py 的 EXTRACT_PROMPT):
| 规则 | 为什么 |
|---|---|
| 主题像章节小标题,≤ 20 字,写具体对象 | 不要「本文方法」这种泛泛的名字 |
| 一个主题下几个到十几个问答 | 不要一问一主题,也不要整块塞进一个主题 |
| 一个问答只讲一个知识点 | 方便复习 |
| 问题自足,不用「本文」「该方法」「作者」 | 复习时原文不在手边 |
| 答案忠实原文,不补充,用原文语言 | 不能编造 |
| 证据:原样摘录本块里的一句话(≤ 200 字) | 方便核对,评测时能检查证据是否真的在原文里 |
| 导航框、链接列表、目录、参考文献、作者单位、致谢、版权声明不抽 | 这些不是知识 |
| 本块没有值得记的知识就返回空列表 | 不要硬抽 |
| 公式用 LaTeX | 和 Agent 2 保留的公式一致 |
关系判断提示词:输入两条问答(问题 + 答案),输出 {"relation": "same" / "related" / "none"};写清三类的定义和反例,「拿不准就选 none」。
结构化输出的约束:
| 问题 | 处理 |
|---|---|
| LaTeX 反斜杠弄坏 JSON | \mathbb 直接报错;更危险的是 \tau 被当成制表符、\beta 被当成退格,解析成功但公式已经坏了。解析前把「反斜杠 + 两个以上字母」当成 LaTeX 命令补上转义 |
| 不合法 JSON | 这块记为抽取失败 |
| 缺问题或答案 | 丢掉这条 |
| 没写主题或主题不存在 | 不丢,放进以「本块标题」命名的兜底主题 |
| 局部 id(t1、q1) | 换成全局 id |
| 未训练模型停不下来 | 偶尔重复输出同一段,一直生成到超时。设输出上限 12000 token(教师最长约 8900) |
训练也在约束格式:GRPO 里不合法 JSON 整条记 −1,训练中无效输出从 21% 降到 2%。
每个问题都记进 problems,给 Agent 4 和调试用。
Q10:为什么选择当前的模型抽取方案?是否考虑过传统命名实体识别、关系抽取模型或者微调方案?
一句话
传统命名实体识别和关系抽取需要固定的类型体系,而我要抽的是「概念、原理、步骤、结论」这类开放的知识点,还要生成自足的问题和答案,只有生成式模型能做;微调是做了的:抽取和关系判断各训了一个 LoRA,未训练时召回只有 0.319,训练后 0.697,追平教师。
详细回答
为什么不用传统方法:
| 传统命名实体识别 / 关系抽取 | 我的需求 | |
|---|---|---|
| 输出 | 文本里的实体片段、预定义关系 | 生成「问题 + 答案」,问题要自足 |
| 类型 | 固定类型体系,要标注数据 | 开放领域(论文、维基各种学科) |
| 粒度 | 词和短语 | 一个完整知识点 |
| 语言 | 通常单语 | 中英文都有,要用原文语言 |
| 关系 | 句内或相邻句 | 跨块、跨文档 |
为什么微调而不是直接用大模型:
| 方案 | 召回率 | 问题 |
|---|---|---|
| 未训练 Gemma 27B | 0.319 | 抽得太少(每篇 78 条,教师 102) |
| 直接调教师 Gemini | 0.691 | 成本、数据隐私、调用限制 |
| 微调 Gemma 27B | 0.697 | 追平教师,本地部署 |
训练怎么做的:
抽取 LoRA:
- 教师在训练集 63 篇上逐块抽取
- 拒绝采样:LLM 裁判拿来源块原文判断每条问答,答错的删掉;错得太多的块整块丢掉
- 整理数据:英文论文 63%、英文维基 40% 的问答被教师写成了中文(受中文提示词影响),翻译回原文语言;挂错主题的改挂;小主题合并;空块只保留一部分(近三成是空块,太多会让学生「拿不准就不抽」)
- 最终 282 块、7255 条问答
- 整理前后:召回 0.680 → 0.692,归属主题 0.743 → 0.841
关系判断 LoRA:
- 用和推理时完全一样的方法生成候选对,教师判断
- 2989 对(related 1269、none 1277、same 33、主题对 410),按自然比例
- 关系边正确 0.897
GRPO:3 轮,3 项奖励(召回、准确、结构),测试集和 SFT 持平,训练中无效输出 21% → 2%
两个踩过的坑:
- loss 要按 token 平均:答案从 20 token(空块)到 3400 token 不等,按样本平均时空块权重是正常样本的上百倍,模型塌缩成总输出空列表。改成按 token 平均后正常
- 类别不要配平:见 Q7
模块五:质量评估与实验指标
Q11:如何评估知识图谱的构建质量?实体准确率、关系准确率、召回率和 F1 分别如何计算?
一句话
分抽取、关系、结构三类评:召回率对照参考答案(向量找候选 + LLM 判断是否覆盖),准确率对照原文判断,关系看「连了的对不对」和「没连的是不是真无关」;我没有算 F1,因为召回和准确对照的不是同一个标准。
详细回答
难点:没有现成的标准答案。Agent 1、2 的标准答案是原文本身,但「这篇文档有哪些知识点」原文里不会写。
参考答案怎么来:旗舰教师按同样流程,从标准答案原文(LaTeX 源码 / 维基正文)抽取,不是从 Agent 2 的输出抽。这样 Agent 1、2 丢了内容,会体现在 Agent 3 的召回上。37 篇只需要 17 份参考答案(同一篇论文的 PDF 和扫描版内容一样)。人工通读 3 篇共 147 条,没发现内容错误。
指标(每篇先算,再对 37 篇平均):
| 类别 | 指标 | 计算 |
|---|---|---|
| 抽取 | 召回率 | 每条参考问答:向量在学生问答里找最像的 3 条 → LLM 判断有没有一条覆盖同一知识点(问的同一件事、关键信息一致,措辞详略可不同)。召回 = 被覆盖的参考问答数 / 参考问答总数 |
| 抽取 | 准确率 | 每条学生问答,拿它来源块的原文让 LLM 判断答案是否正确、有原文依据。准确率 = 正确数 / 学生问答总数 |
| 抽取 | 问题自足 | 同一次判断,问题能否脱离原文看懂 |
| 关系 | 归属主题 | 问答连同所在主题名和主题下其他几个问题,判断属不属于这个主题 |
| 关系 | 关系边正确 | 学生连的每条边,判断是否真的相关 |
| 关系 | 不连正确 | 按相似度挑出和边数一样多的「最像但没连」的对,判断是否真的无关 |
| 结构 | 问答数 / 篇、小主题比例 | 规则统计;小主题 = 问答数 ≤ 2 |
为什么准确率对照原文,不对照参考答案:参考答案不可能穷尽所有知识点,学生抽到了原文有、参考里没有的知识,不应该算错。
为什么没有 F1:召回对照参考答案,准确率对照原文,分母不是同一个集合,算 F1 没有意义。
评测本身的两个问题(做 Agent 4 时发现,要主动说):
- 召回率可能被低估:复核「漏抽」时发现约一半其实抽到了。参考答案一条塞了 3 个事实,学生拆成 3 条,每条只覆盖一部分,被判为没覆盖。学生每篇 211 条、教师 102 条,拆得更细,受影响更大
- 关系边正确可能偏高:575 条边被二次复核确认是错的,当时被判为正确
- 已记待办:用同样的二次复核方式把所有方法重算。目前报告里都是原始口径
Q12:如果大模型抽取出了原文不存在的关系,你如何检测和减少这种幻觉?
一句话
检测靠两条:证据必须逐字出现在原文里(规则检查),答案要被来源块原文支持(LLM 判断);减少靠训练数据只保留通过检查的问答、GRPO 的准确奖励直接惩罚,关系则由单独的判断模型保守地逐对确认,抽取时模型自己标的关系一律不用。
详细回答
问答层面的幻觉:
| 环节 | 做法 |
|---|---|
| 生成时 | 提示词要求答案忠实原文、不补充;每条必须带原文证据 |
| 检测(规则) | 证据是否逐字出现在来源块里 |
| 检测(LLM) | 拿来源块原文判断答案是否正确、有依据 |
| 训练数据 | 教师答错的问答删掉,错得多的块整块丢掉 |
| GRPO 奖励 | 准确 = 0.7 × LLM 判断有原文依据 + 0.3 × 证据逐字出现在块里 |
| 评测 | 准确率 0.928(教师 0.965) |
关系层面的幻觉:
- 抽取时模型自己标的
relations一律不用,因为它只看到一块,容易编造 - 关系只由合并阶段的关系判断模型逐对判断,输入是两条问答的完整内容
- 「拿不准就选 none」
- 有向依赖改成无向相关:有向依赖本身就是幻觉的重灾区(教师 0.32~0.65),是在没有依据的情况下判断方向
一个具体的幻觉来源:网页残留
- 维基网页上准确率只有 0.847(教师 0.972),每篇抽 347 条(教师 142)
- 原因:模型把导航、参考文献这类网页残留也抽成了问答
- 改进:抽取数据里加「残留不抽」的负样本;或者让 Agent 2 多删残留
防止为了召回而编造:GRPO 结构奖励里有「问答数不超过教师 1.3 倍」,制衡召回奖励。否则模型会把一个知识点拆成很多条来刷分。
Q13:你如何设计实验验证 Agent 3 的有效性?会选择哪些基线方法和消融实验?
一句话
基线有未训练模型和教师;消融已经做了三组:SFT 第一版 vs 第二版(数据整理的作用)、SFT vs GRPO(强化学习的作用)、有向依赖的四种做法对比(证明任务定义要改);还有一个意外发现:删掉提示词里的依赖说明,召回从 0.60 掉到 0.41。
详细回答
基线:
| 基线 | 回答的问题 |
|---|---|
| 未训练 Gemma 27B | 不训练能做到多好?(召回 0.319) |
| 教师 Gemini | 学生要追的水平(召回 0.691) |
已经做过的对照:
| 对照 | 结果 | 结论 |
|---|---|---|
| 未训练 vs SFT 第一版 | 召回 0.319 → 0.680 | 训练解决了「抽得太少」 |
| SFT 第一版 vs 第二版 | 归属主题 0.743 → 0.841 | 数据整理(改挂主题、合并小主题)有效 |
| SFT 第二版 vs GRPO 3 轮 | 各项差距 ±0.012 以内;逐篇比较 GRPO 更高的有 12~22 / 37 篇 | 测试集上持平;训练中无效输出 21% → 2%,长文本上更不容易失控 |
| 有向依赖:提示词 / 成环检查 / RefD / 逐对判断 | 最好 0.65 | 任务本身需要外部信号 |
| 提示词保留 vs 删掉依赖说明 | 召回 0.60 vs 0.41 | 要求标依赖时模型拆知识点更仔细 |
| 关系数据:配平 vs 自然比例 | 配平后依赖预测比例 5% → 11%,一半是错的 | 分类任务要按自然比例 |
| loss:按样本平均 vs 按 token 平均 | 按样本平均时塌缩成输出空列表 | 长度差异大时必须按 token 平均 |
GRPO 为什么只是持平(诚实说):
- 只跑了 3 轮(为了控制费用),只证明流程跑通
- 召回奖励以教师为标准,而 SFT 已经追平教师,提升空间本来就不大
- 要超过 SFT,需要更多轮次,并且奖励不能只以教师为标准(比如准确率直接对照原文)
还应该补做的消融:
| 消融 | 想回答的问题 |
|---|---|
| 候选对只用向量 / 只用 RefD / 两者都用 | RefD 的贡献 |
| 候选数 3 / 5 / 10,相似度门槛 0.5 / 0.6 / 0.7 | 召回和成本的平衡 |
| 抽取时给 / 不给全文目录 | 目录对主题命名和召回的作用 |
| 用二次复核重算所有方法的召回和关系边正确 | 修正评测口径 |
| 跨文档合并的专门测试集 | 现在只评单篇,跨文档去重和连边没有单独评测 |
模块六:工程异常与系统协同
Q14:如果文档很长,包含大量重复实体和复杂关系,你如何控制图谱规模、构建成本和处理耗时?
一句话
长文档靠 Agent 2 切块后并行抽取;重复靠 same 合并控制规模;最贵的关系判断不做两两比较,而是每条问答只取向量前 3 + RefD 前 3 个候选,把成本从平方级降到线性;知识库再变大就换成向量索引。
详细回答
构建成本:
| 环节 | 做法 | 效果 |
|---|---|---|
| 抽取 | 每块单独抽,6 块并行 | 耗时随块数线性增长,可并行 |
| 抽取输出 | 上限 12000 token | 截断失控的重复输出 |
| 候选对 | 每条只取向量前 3 + RefD 前 3,相似度低于 0.6 不要 | 200 条问答从约 2 万对降到最多约 1200 对 |
| 关系判断 | 单独的小任务 LoRA,输出约 8 个 token | 每次判断很便宜,可以批量 |
| 向量模型 | 小的多语言模型,本机 CPU 就能跑 | 不占 GPU |
| 部署 | 两个 LoRA 挂在同一个 27B 基座上 | 部署成本不增加 |
图谱规模:
- same 合并:同一知识点只保留一条
- 主题合并 + 小主题合并:避免主题碎片化
- GRPO 结构奖励「问答数不超过教师 1.3 倍」:防止拆得过碎
- 每条问答最多 3 + 3 个候选,边的数量天然受限
知识库变大时的问题:
- 现在每次并入都要把知识库所有问答重新算向量
- 到几十万条时应换成向量索引(如 FAISS),增量更新
- 存储可以从 JSON 换成数据库
其他已知局限:
- 删除文档时可能丢知识:B 的问答合并到 A 上,删掉 A 时那条会一起删掉。更完整的做法是删除时把
merged_from里来自其他文档的问答恢复出来 - 跨文档去重和连边没有专门的测试集
Q15:如果 Agent 4 检查发现知识图谱缺少关系或者出现错误,你如何区分是 Agent 1 解析、Agent 2 切分还是 Agent 3 抽取的问题?
一句话
沿着数据流逐级往回追:看这个知识点在标准答案原文里有没有、在 Agent 1 的输出里有没有、在 Agent 2 的块里有没有、在 Agent 3 的问答里有没有,第一个丢掉它的环节就是责任方;训练 Agent 4 时这个追查由程序沿标准答案自动完成,生成归因标签。
详细回答
逐级追查(benchmarks/agent4/labels.py、scripts/label_agent4.py):
1 | 一个知识点(来自参考答案) |
错误类型和归属:
| 错误类型 | 归给谁 |
|---|---|
| 整篇解析不完整 | Agent 1 |
| 解析时丢了知识点 | Agent 1 |
| 修复时删了知识点 | Agent 2 |
| 块对不上原文 | Agent 2 |
| 漏抽、答案错、问题不自足 | Agent 3 |
| 归错主题、连错边、漏连边 | Agent 3 |
「缺少关系」的特殊情况:如果两个知识点被 Agent 2 切到了不同的块,是不是 Agent 2 的错?
- 不一定。跨块关系本来就由 Agent 3 的合并阶段负责
- 判断方法:两条问答都抽出来了 → 关系没连上是 Agent 3 合并或判断的问题;如果因为切点把一个推导劈开,导致其中一条问答没抽出来或答案不完整 → 才是 Agent 2 的问题
- 反事实验证:把相邻两块合成一块重新抽,如果关系或问答出现了,就确认是切块导致的
Agent 4 在部署时怎么做(没有标准答案时):按块读取上游三个 Agent 的输入和输出,先写推理,再列出问题、归因到出错的 Agent、给修改意见。依据是:
- Agent 3 的问答证据能不能在 Agent 2 的块里找到
- Agent 2 的块和 Agent 1 的输出比,正文有没有被删
- 每一步都存了
trace,可以逐层回放
前车之鉴:Agent 2 清晰度卡住时,归因发现一半以上的问题在上游(公式被拆碎、表格丢结构)。所以出错时不要先假设是 Agent 3 的问题,要逐层验证。
这个归因机制还反过来发现了评测问题:复核漏抽标签时发现约一半其实抽到了(颗粒度不同);575 条边被确认是错的,但 Agent 3 评测时被判为正确。
附:30 秒版本(面试开场用)
Agent 3 把 Agent 2 切好的块逐块抽成问答,每条问答问题自足、带原文证据,再合并成「文档 → 主题 → 问答」的知识树,相关的问答之间连无向边,并和已有知识库去重。合并用的是「程序找候选、模型判断、程序合并」:向量相似度和 RefD 引用检查筛候选对,关系判断 LoRA 逐对判同一知识点、相关还是无关,并查集合并去重。关系最初设计成有向的前置依赖,但连教师的正确率都只有 0.32 到 0.65,查文献发现方向需要教材顺序这类外部信号,于是改成无向的「相关」。训练上抽取和关系判断各一个 LoRA,未训练时召回只有 0.319,训练后 0.697,追平教师,准确率 0.93。