把知识图谱的三元组抽取交给大模型这事到底靠不靠谱我带着这个疑问折腾了三个月在一套真实业务数据上跑了规则模板、序列标注模型、通用大模型 API、开源模型本地部署四条路线中间踩了不少坑也拿到了一些意外的结论。这篇东西不打算做成学术报告而是把我实际测试的过程、数据、翻车案例和最终采用的工程方案完整摆出来给同样想用大模型做知识抽取的同行一个参考。文章会重点聊大模型抽取三元组在效果、成本、稳定性三个维度上的真实表现以及哪些场景适合直接上手、哪些场景建议趁早绕开。1. 先搞清楚知识图谱为什么需要能打的三元组抽取1.1 我为什么会盯上大模型来做抽取做知识图谱的都知道这个领域真正的瓶颈不在图数据库选型也不在 SPARQL 查询优化而在最前端的知识抽取环节。我最早做图谱用的是传统方案针对特定领域写规则模板或者训练 BERT 序列标注模型做实体识别和关系分类。规则模板的问题是维护成本极高新增一个实体类型就要写好几条正则换个语料风格就全线崩溃。序列标注模型效果确实比规则好但需要大量人工标注数据我当年在医疗领域标注了八千多条句子才把 F1 勉强推到 0.82换个疾病领域又得重新标。大模型出来之后我第一个想法就是能不能用它的少样本能力跳过标注环节直接通过指令让模型抽取三元组这个想法听起来很美好但作为工程决策不能凭感觉拍板。所以我去查了 OneKE、DeepKE 这些专门做知识抽取的框架也翻了各大模型厂商的技术文档。我的目标很明确搞清楚大模型在这件事上的能力边界到底在哪里哪些场景能替代传统方案哪些场景会翻车。1.2 三元组是知识图谱的最小可用单元再解释一下三元组的本质。一张知识图谱从逻辑上可以拆成无数个主体-关系-客体的单元比如华为技术有限公司-总部所在地-深圳这就是一条三元组。所有复杂的图谱查询、推理、问答最终都要落到这种最小单元上。三元组的质量直接决定图谱的天花板抽错了实体图谱就脏抽错了关系推理就歪。这里要特别注意一点三元组抽取不是单纯的命名实体识别它是实体识别和关系抽取的联合任务。你不仅要找出文本里的实体谁、什么、在哪里还要判断实体之间的语义关系是位于还是成立于还是控股。传统做法是把这两个步骤串成 pipeline——先做 NER 再做关系分类误差会层层累积第一个环节抽错实体第二个环节再准也没用。大模型做三元组抽取的方式和传统做法有本质区别我下一节详细拆解。2. 原理拆解大模型做三元组抽取的底层能力从哪来2.1 三元组抽取本质上是一个结构化信息转化问题如果把知识抽取抽象一下整个任务的定义是输入一段非结构化文本输出一组结构化的三元组。传统模型做这件事的路径是先识别再分类把任务拆成多个子模型而大模型的路径是一步到位——把输入的文本和抽取要求都拼进 prompt 里让大模型直接输出结构化的结果例如从以下文本中抽取主体, 关系, 客体三元组只抽取真实存在的信息 文本小米集团于2024年4月18日发布了小米汽车SU7由北京工厂负责生产。 输出{triples: [[小米集团, 发布, 小米汽车SU7], [小米汽车SU7, 由...生产, 北京工厂]]}这个能力来自大模型预训练阶段见过的海量文本模型在训练过程中学会了实体往往是名词短语关系往往由谓语动词或介词短语承载这类语言规律。所以哪怕你没给它提供任何领域标注数据它也能从一个句子里大致判断出谁对谁做了什么。2.2 生成式模型的模式迁移能力恰好踩中了抽取任务的需求我在实测中最直观的感受是大模型做抽取其实是在执行一种模式迁移。它不是靠记忆背下来某个实体的类别而是根据上下文的语义结构推断哪些词是实体、哪个词是关系。举例来说一个在电商数据上训练过的大模型你让它去抽医疗文本的三元组它虽然不懂医学但能根据某某药治疗某某疾病这样的句式结构猜出治疗的客体是疾病名。这种能力在传统模型上几乎不可能实现传统模型换个领域就得重新训练。有人可能觉得这没什么了不起但放在真实业务里非常关键。我评估过的很多图谱项目痛点恰恰在于领域数据量不足以支撑训练一个可靠的传统抽取模型。标注一万条句子需要两个标注员干一个月期间还要反复核对标注一致性。大模型的零样本/少样本能力直接把这一步省了这在项目冷启动阶段是最值钱的。2.3 输入输出映射决定了它能听懂你的抽取规则还有一层被很多人忽略的技术细节大模型本身是输入输出映射器。你可以把实体类型的定义写进 prompt比如客体只能是药物名称或疾病名称不能是剂量、服用方法模型能理解这个约束并据此调整输出。传统模型如果要加一个约束得重新设计标注规范和模型结构而大模型只需要改一句话。这意味着抽取规则的迭代周期从周缩短到分钟——这对我来说是很大的效率提升。理解了模型为什么能做这件事之后接下来的问题就现实了效果到底怎样成本能不能接受稳定性靠不靠谱下面是我实际测评过程的核心干货。3. 落地实测不同方案抽取效果与成本的真实对比3.1 我设计的评测方案数据、指标、对照先说明我的评测环境方便你复现或者根据自己的场景调整。我选了三组语料分别代表三种典型场景财经公告句式规范、实体密集、医疗科普口语化、术语多、技术博客中英混杂、长句多。每组随机抽取 100 个句子由我本人和另外一位同事各自标注三元组然后合并去重作为标准答案。指标用最经典的精确率、召回率、F1 值实体边界要求在字符级别完全一致才算对。关系判别要求关系类型必须和标准答案一致同义关系不算对。对照了四条路线方案A基于正则和词典的规则模板方案BBERT 序列标注模型3000 条标注数据训练方案C通用大模型 API用千问系列标准 prompt方案D本地部署的开源模型7B 参数级别同样 prompt3.2 让数据说话效果与成本对比这是我在三组语料上取平均之后的评测结果方案精确率召回率F1冷启动成本单条处理成本规则模板0.870.430.58高人工写规则最低BERT序列标注0.820.780.80高需标注3000条低大模型API0.790.740.76极低写prompt即可中本地部署7B模型0.750.680.71极低低仅需GPU看完你可能和我第一反应一样大模型并没有赢过精心训练的 BERT 模型。但注意几个关键点——BERT 模型的前提是已经烧了 3000 条标注数据而这个成本在真实项目里往往比 API 调用费贵一个数量级。规则模板的精确率最高但召回率惨不忍睹等于你拿了一个漏掉一半信息的准确图谱很多下游应用根本没法用。3.3 好看的平均分背后的三个失败场景平均分只能说明整体水平真实项目里真正杀伤力大的是那些系统性错误。我在评测中发现了三个非常典型的失败场景第一个是长文本被截断。大模型输入长度有限制一篇几千字的财报公告塞不进一个 prompt强行分段抽取会导致跨段信息丢失。比如公司董事会审议通过了上述议案这种指代句如果上述议案在上一段审议通过这个关系就抽不出来。第二个是实体过于稀疏的短句。大模型在华为与苹果在智能手机市场展开激烈竞争这样的句子上经常抽出一堆隐含关系比如华为-竞争-苹果。这个关系从语义上说得通但在业务规则里可能是噪音因为你的 schema 里根本没定义竞争这个关系。第三个是关系同义改写不一致。同一篇文档里小米收购了某公司和某公司被小米收购这两句话关系完全一样但大模型第一次输出收购第二次可能输出被收购。如果不做关系归一化图谱里会出现两条语义重复的边。3.4 成本对比API 调用 vs 本地部署 vs 人工标注成本可能是决定方案能不能落地的更关键因素。我按处理 10 万条文本的规模算了一笔账人工标注加训练的综合成本在 3 到 6 万取决于领域复杂度和标注员水平大模型 API 按 token 计费大约在 1.5 万到 2.5 万取决于 prompt 长度和模型档位本地部署的开源模型成本集中在硬件一次性投入用一张 24G 显存的消费级显卡跑 7B 模型单条成本几乎可以忽略但要牺牲一部分效果。所以如果你问大模型抽取三元组可不可行我的回答是效果上不是最优但在成本约束下往往是最优解。尤其当你的目标是从零快速搭建一个领域图谱的初版而不是追求 SOTA 精度的时候大模型的性价比非常突出。4. 最容易翻车的五个环节格式、幻觉、实体边界、关系爆炸、重叠语义4.1 输出格式不稳定直接拖垮下游解析这在真实工程里是第一个拦路虎。大模型的输出是自然语言你要求它输出 JSON它可能在前面加一句好的以下是抽取结果后面又附带一句希望这个回答对你有帮助。字符串解析直接失败整个 pipeline 卡住。我在项目里用的是two-pass 策略第一轮让模型严格按照 schema 输出 JSON第二轮专门写一个解析器如果 JSON 解析失败就把模型的原始输出重新丢给模型让它只输出 JSON 部分不要任何解释。实测这个办法能把格式成功率从 80% 拉到 96% 左右。还有一个更稳定的土办法在 prompt 里给出输入输出示例并限制模型严格按照给定格式逐字输出同时在后端做 JSON 容错解析——把非 JSON 的杂质部分剥离后再尝试json.loads。这两个方法叠加基本能解决大部分格式问题。4.2 实体幻觉让图谱出现本不存在的事实幻觉是最严重的坑。传统抽取模型不会无中生有但大模型为了理解你的指令偶尔会补充它觉得应该存在但实际上原文没有的信息。比如一篇新闻里只写了某公司发布了新品模型可能在客体位置补一个它从训练数据里记住的具体产品名这个产品名正确与否是概率性的。我处理幻觉的办法是加原文回指校验模型抽出的每个实体、每个关系关键词都必须能在原文中找到子串或同义片段。找不到的直接丢弃不进入图谱。这个规则粗暴但有效能把幻觉带来的错误率降低一半以上。当然缺点是有可能误杀正确的指代词比如华为在原文里写作该公司就匹配不上所以对指代词要做一层共指消解再校验。4.3 实体边界和嵌套实体破坏最小单元的原子性实体边界是抽取任务里的经典难点。把北京市朝阳区抽出成北京市和朝阳区确实不算全错但放进图谱里做地域查询时会非常痛苦。大模型在这方面的表现和训练数据的颗粒度强相关你让它抽地点它往往给出长尾完整名称你让它抽城市它往往会缩小边界。嵌套实体更麻烦。句子华为公司旗下的荣耀品牌发布了X10手机正确的三元组应该包含华为公司-旗下-荣耀品牌和荣耀品牌-发布-X10手机两层。大模型经常只抽到最外层华为公司-发布-X10手机中间的层级关系丢了。我现在会在 prompt 里明确要求如果句子中出现机构与其子品牌/子公司关系请同时抽出两层实体关系能在一定程度上提高嵌套关系的召回率。4.4 关系类型爆炸schema 没设计好会让模型无所适从关系类型的设计直接决定大模型的表现。如果你的 schema 定义了 200 种关系类型描述还写得含糊大模型就会频繁地把治疗输出成用于治疗把位于和坐落于当成两种不同关系。这本质上是关系分类的类别不平衡和语义重叠问题。我的经验是把关系类型控制在 30 到 50 种以内并给每种关系写一句描述和一个示例。比如located_in表示实体之间的位置从属关系示例北京的故宫。注意与 has_part 的区别has_part 表示组成部分关系。这样模型才能稳定地把坐落于、位于、地处归一化到同一个关系上。关系定义得越清晰模型的输出就越可控这一点大模型也不例外。4.5 重叠三元组的漏抽信息密度高的句子最容易丢一个句子里包含多个三元组时大模型的召回率会明显下降。比如该公司发布了新一代旗舰手机并宣布与三大运营商达成合作理想情况应该有四条三元组发布手机、宣布合作、与运营商合作、合作主体细化。实测中模型经常只抽出该公司-发布-旗舰手机和该公司-宣布-合作这两条粗粒度三元组具体跟谁合作、合作内容是什么的细粒度三元组丢了。对策是在 prompt 里加一条数量提示分析语句主干并尝试找出所有可能的主谓宾结构不要遗漏。同时可以在模型输出后用一个小模型或规则做完整性检查——把原句和三元组里的实体做一个对比如果句子中出现了明显的人名、机构名、产品名却没出现在任何三元组里就提示漏抽。我通常用 BGE-M3 这类嵌入模型辅助做实体对齐和补全判断。5. 工程化补位方案从能跑通到能上线5.1 给模型戴上紧箍咒Schema约束加输出校验层在前面这些坑基础上我最终形成了自己的大模型抽三元组工程框架。核心思想是不信任模型的格式绝对信任模型的能力。意思是不管模型输出什么我都会做过一道严格的校验和清洗但实体的识别、关系的判断尽量交给大模型来完成。校验层我维护了一个图谱合法性检查器职责有三个JSON 格式校验、实体边界校验、关系名称归一化。JSON 格式校验做的是解析和剥离杂质实体边界校验会把过长或过短的实体打回重抽关系名称归一化会维护一个同义关系映射表比如把位于地处坐落于全部映射成位于。这套校验层跑在模型之后凡是校验不过的三元组直接丢弃或进入人工复核队列。5.2 微调专属抽取模型用它来替代通用模型如果你的图谱是垂直领域的比如医疗、法律、金融并且你对召回率的要求很高零样本的通用大模型效果可能不够。我建议走基座模型加微调的路线。框架上比较推荐 OneKE 或基于 LlamaFactory 进行微调理由有三个第一它们对知识抽取任务做了专项优化把训练数据组织成了指令微调格式第二模型体积可控7B 到 13B 级别的底座在单张消费级显卡上就能跑第三领域化的微调能显著减少幻觉因为模型学会了你领域内的实体边界。微调数据的构造也有讲究。纯人工标注成本高我的办法是用通用大模型先生成一批候选三元组人工修正后再拿去做微调训练。相当于大模型先用零样本能力产出一版草稿人工只负责挑错和修改训练成本比全部人工标注低一个数量级。我在金融公告数据集上用这个方法微调了一个 7B 模型F1 从零样本的 0.76 提到了 0.84幻觉率下降了大概一半。这个提升幅度对垂直领域项目来说是决定性的。5.3 混合架构规则负责快模型负责准经过这些测试后我最终落地到生产环境的技术方案是混合架构先用规则模板做一次快速抽取得到高精确率但低召回率的初步三元组集合再让大模型做一轮全量抽取得到高召回率的结果用规则结果和大模型结果做实体对齐和合并保留两边一致的三元组以及大模型新抽到且通过合法性校验的三元组。这个方案的好处是兼顾了规则模板的稳定性和大模型的泛化能力。比如公司名称这种强规律性的实体规则模板几乎不会错就让它来抽但一篇文章里复杂的业务关系比如甲通过子公司间接持有乙 30% 股权只能靠大模型的语义理解能力。两者合并后F1 比任选一个单独方案都高我测试出来的数据是从 0.76 提升到了 0.85 左右。5.4 部署层面的工程注意点vLLM推理与并发如果走本地部署这条路工程上的坑也不比算法少。我一开始直接用 HuggingFace Transformers 库加载模型做推理速度完全没法看。后来换了vLLM做推理服务吞吐量提升了大概一个数量级单张 24G 显存的卡跑 7B 模型能做到每秒处理十几条文本。但要注意 vLLM 是按模型显存占用做连续批处理的prompt 越长单次批处理量越小。所以实际部署时我会把长文本切成短句每条控制在 200 字以内这样既能控制显存占用也能降低大模型漏抽的概率——因为句子短语义焦点更清晰。并发请求也值得注意不要一上来就开 100 路并发打自己的推理服务先用二三十路的并发压测观察 GPU 显存和响应时延找到吞吐量和延迟的平衡点。6. 可行性结论什么场景值得用大模型抽三元组6.1 我的决策框架规模、频率、复杂度、预算做了这么多测试和工程实践之后我对大模型抽取知识图谱三元组的可行性的结论可以浓缩成一张决策表场景特征推荐方案原因图谱规模小、一次性构建大模型 API 直接抽成本低、速度快不需要投入标注人力图谱规模大、需要持续更新本地部署开源模型 微调长期成本低数据不出内网安全问题可控关系类型非常简单少于10种规则模板优先稳定、可解释、几乎零成本关系类型复杂、长尾关系多大模型方案必选规则难以覆盖长尾语义传统模型标注成本过高精确率要求极高如医疗、法律大模型 人工复核大模型做初筛人工只复核置信度低的三元组实时抽取、低延迟本地部署 7B 以下模型API 延迟不可控本地模型可做到秒级响应这个表不是拍脑袋写出来的每一行背后都是我在这轮评估里的实测数据。你可以把自己的项目参数带进去对号入座。6.2 我的个人结论和建议如果回到标题的核心问题大模型抽取知识图谱三元组可行吗我的答案是可行但它不是银弹。可行是因为在成本敏感、冷启动快速、长尾语义多的场景里大模型提供了一个传统方案无法匹敌的起点你几乎不需要标注数据就能得到一个 0.76 左右 F1 的抽取器。它不是银弹是因为模型输出不稳定、幻觉问题客观存在、格式解析需要做大量工程兜底这些不会自动消失。根据我的经验最容易成功的落地方式是这样的先用通用大模型跑一遍零样本抽取把结果可视化到一个标注工具里让领域专家快速修正修正后的数据同时具备两个用途——成为最终图谱的一部分也作为微调数据集喂给底座模型。把迭代跑上两三轮你就能得到一套领域定制版的三元组抽取服务效果趋近甚至超过传统的全监督方案。一个建议是不要在模型选型上纠结太久先用 7B 级别的开源模型跑通全流程确认业务上可行再考虑换更强的模型或引入微调。毕竟用起来永远比选最优更能推进项目落地。