Dify.AI 关系抽取实战:三块拼图搭好文本到知识图谱的最短路径,附质量兜底清单
发布时间:2026/8/28 12:43:20 作者:尧图编辑部 阅读量:1,286

Dify.AI 关系抽取实战三块拼图搭好文本到知识图谱的最短路径附质量兜底清单【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify客服组每天收 2000 条工单想自动把产品模块—功能点—报错码串成依赖链靠人工整理一轮要 3 天。用 Dify.AI 把这条链路跑起来Dify.AI 关系抽取加图存储的组合能在几小时内把工单文本变成一组可查询的三元组支撑知识图谱构建与下游问答。先把三个概念钉死关系抽取整条链路上最容易混淆的是三个词。每个按三层说清类比、定义、Dify 里对应的组件。实体识别。类比在聊天记录里给人名、产品名画荧光笔。技术定义从文本中定位出有名字的东西及其类型。Dify 里这一步通常交给工作流中的 LLM 节点完成提示词里写清楚实体类型清单平台自身不内置 NER 模型抽取能力由你指定的 LLM 提供。关系抽取。类比给画了荧光笔的词之间连线写上报错于依赖这样的动词。技术定义判定两个实体之间是否存在预定义的关系类型。Dify 对应工作流引擎里的节点编排节点源码在api/core/workflow/nodes/LLM 节点实现见api/core/workflow/llm_node.py。知识图谱落库。类比把画完线的便签钉进档案柜之后按任意一个词都能反查出所有连线。技术定义把头实体关系尾实体三元组写入结构化存储供多跳查询。这里要泼一盆冷水Dify 源码里没有现成的图数据库适配器落库这一跳要你自己接 Neo4j。跑通一条最小链路只需要三块拼图把 Dify 的 RAG 管线和工作流引擎各取一块拼起来就是最短路径。三块拼图输入侧、引擎侧、输出侧。缺任何一块链路都会在某个环节空转。输入侧文本从哪来chunk 怎么切做什么把原始文档变成 LLM 能吃进去的一段段文本。为什么这样设计LLM 的上下文窗口有限长文档必须先切片切太小会切碎实体 A 依赖实体 B这种成对出现的表述切太大又浪费 token、拉低精度所以 overlap 要留一点余量。Dify 的入口是api/core/rag/extractor/extract_processor.py里的ExtractProcessor按文件扩展名路由到 PDF、Word、Markdown 等具体抽取器切片用api/core/rag/splitter/text_splitter.py的TextSplitter系列。下面这段展示文件 → Document → chunk的完整输入侧from core.rag.extractor.extract_processor import ExtractProcessor from core.rag.extractor.entity.extract_setting import ExtractSetting # 多格式文档统一转成 Document 列表自动识别编码 documents ExtractProcessor.extract(ExtractSetting(datasource_typeDatasourceType.FILE, upload_filef)) # 递归字符切片默认先按换行再按空格chunk 间保留重叠 chunks RecursiveCharacterTextSplitter(chunk_size500, chunk_overlap50).split_text(doc.page_content)引擎侧用 JSON Schema 约束 LLM 输出做什么让 LLM 按固定形状吐出实体和关系。为什么这样设计自由文本输出解析起来像在拆盲盒字段名、类型随时可能漂移把输出钉死成 JSON 结构后处理代码才能放心跑。Dify 的 LLM 节点支持在系统提示词里贴 schema并在节点配置中勾选 JSON 输出约束失败时节点报错而不是静默产出脏数据。这份 schema 可以直接贴进 LLM 节点的提示词{ type: object, properties: { entities: { type: array, items: { type: object, properties: { text: {type: string}, type: {enum: [module, feature, error_code]} }, required: [text, type] } }, relations: { type: array, items: { type: object, properties: { head: {type: string}, rel: {enum: [throws, depends_on]}, tail: {type: string} }, required: [head, rel, tail] } } }, required: [entities, relations] }输出侧三元组校验再写图做什么过滤无效三元组然后批量写入图数据库。为什么这样设计LLM 偶尔会编出不存在的实体引用或自环关系直接入库就是往知识图谱里灌水写之前做一次引用完整性检查成本几毫秒省掉的是下游所有查询的脏结果。Dify 的工作流里这一步通常接在 LLM 节点后面用代码节点或 HTTP 节点完成图数据库连接由你自己维护。这段是 Neo4j 批量写入的核心逻辑def write_triples(driver, triples): with driver.session() as s: s.run(UNWIND $t AS x # 一次性写整批三元组 MERGE (h:Entity {name: x.head}) MERGE (n:Entity {name: x.tail}) MERGE (h)-[r:REL {name: x.rel}]-(n), ttriples)抽得准只是及格线兜底才是分水岭抽取准确率 90% 听起来不错但三元组是乘法累积的每错一条下游的问答、统计、告警都在错上加错。三个兜底策略按投入从低到高排。用 schema 约束输出格式就是上一节贴的那份 JSON。它拦掉的是解析失败和字段漂移这类低级错误属于免费收益。置信度阈值 人工回流。让 LLM 对每条关系附带 confidence 字段低于阈值的样本不直接丢弃而是写进待审队列KEEP, REVIEW 0.85, 0.6 for r in relations: c r.get(confidence, 0.0) if c KEEP: store.write(r) # 高置信直接入库 elif c REVIEW: store.enqueue_human_review(r) # 灰区进人工队列 # 低于阈值的直接丢弃并记日志增量更新时做冲突检测。新三元组和库里已有边矛盾比如同一对实体的依赖方向反了时触发告警而不是静默覆盖def check_conflict(driver, t): q (MATCH (a:Entity {name:$h})-[r]-(b:Entity {name:$n}) RETURN r.name AS rel) rows driver.session().run(q, ht.head, nt.tail).data() return any(r[rel] ! t.rel for r in rows) # 旧边和新边方向不一致不做兜底和做了兜底差别在三个维度上维度无兜底有兜底准确率脏三元组直接入库错误随查询放大灰区样本进人工队列入库即高置信维护成本图谱越滚越大坏数据难定位每次入库可追溯到 chunk 和 prompt 版本上线风险下游问答被脏关系带偏返工重抽冲突告警先于用户发现问题 冲突检测是增量场景的刚需文档一更新旧三元组和新三元组就可能打架没有告警机制等于盲改图谱。什么规模该用什么姿势先说清 Dify 当前版本的能力边界再谈工程取舍。适合的姿势千级到万级 chunk 的单领域文档、schema 收敛在几个实体类型和关系类型内、要求一两天内出原型。这套组合下Dify 的ExtractProcessor 分片 工作流 LLM 节点够用瓶颈通常在 LLM 调用量而不是平台本身。不适合的姿势中英混合语料schema 和提示词都要重做抽取质量明显掉、图片加文本的多模态抽取Dify 的 RAG 管线以文本为主、以及要求百毫秒级延迟的在线服务——工作流引擎是为离线批处理设计的单次执行链路里还有持久化、事件层等开销实时服务不该走这条链。数据量上万 chunk 时一个关键取舍是分片并行还是结果缓存def run(chunks, llm, store): cache {} for i in range(0, len(chunks), 50): # 按 50 个 chunk 一批投给 celery worker batch chunks[i:i50] triples [llm.extract(c) if hash(c) not in cache else cache[hash(c)] for c in batch] store.write_triples(filter_triples(triples))按内容哈希做结果缓存增量跑批时没变过的 chunk 不重复烧 token这是万级场景下最划算的一刀。分片并行则直接把批次投递给 Celery workerDify 的 Celery 基础设施开箱就有。源码想深入时看这两处工作流节点在api/core/workflow/nodes/RAG 数据源与向量适配层在api/core/rag/datasource/vdb/BaseVector抽象出了 create、search_by_vector、delete_by_ids 这套接口图存储适配照这个模式自己实现一份即可。规模与诉求推荐姿势千级 ~ 万级 chunk单领域 schemaDify 内置链路ExtractProcessor 分片 LLM 节点万级以上周期性增量上表链路 内容哈希缓存 Celery 分片并行跨语言混合语料 / 多模态 / 百毫秒级在线外挂自定义抽取模型入口是工作流 LLM 节点更换模型或用插件机制注册自定义节点下一步往哪走 三个值得往下挖的方向每个都对应一个具体动作图谱与 RAG 检索融合把用户问题先转成子图查询再用图上的实体约束向量检索的范围能显著压掉答非所问。动作把知识检索节点和图查询节点串成一条新工作流。跨语言实体对齐中英文语料里的同一产品模块要先归一到一个 canonical id否则图谱会裂成两半。动作在实体表加一个 alias 字段入库前做一次归一。窄 schema 先闭环从 3 种实体、3 种关系起步跑通抽取—校验—入库—查询一整圈再扩类型。你现在能做的一个动作拿 20 条真实工单按本文三块拼图把链路跑一遍统计一次抽取的实体召回率——这个数字会直接告诉你你的 schema 该收窄还是该放宽。【免费下载链接】difyBuild Agentic workflows, RAG pipelines, with rich AI model and tool support on one collaborative workspace. Deploy on cloud, VPC, or self-hosted, so teams move from prototype to production without rebuilding the stack.项目地址: https://gitcode.com/GitHub_Trending/di/dify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考