用 Instructor 构建知识图谱:从非结构化文本到可迭代更新的结构化图谱
发布时间:2026/9/15 18:47:24来源:尧图网络
用 Instructor 构建知识图谱从非结构化文本到可迭代更新的结构化图谱【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor导读本文演示如何基于 Instructor 与 Pydantic将一段任意非结构化文本自动转化为结构化的知识图谱Knowledge Graph并进一步用 Graphviz 完成可视化。你会掌握三类核心能力用response_model约束 LLM 输出Node/Edge结构、把超长文本拆分成多段迭代式地更新同一张图谱以及把图谱导出为可读的图形文件。这套流程是知识管理、文档理解、RAG 前置处理等场景的基础设施相关配套示例可参见 Entity Resolution实体解析与 Document Segmentation文档分段。为什么用 LLM 构建知识图谱知识图谱以实体节点关系边的方式刻画一段文本的语义结构。传统做法依赖人工建模或规则抽取成本高、泛化差。而 LLM 天然擅长理解自然语言中的实体与关系只要我们用 Pydantic 把输出形状定义清楚Instructor 就能让模型直接返回一个合法的KnowledgeGraph对象而不是需要二次解析的裸 JSON。核心思路只有三步用 Pydantic 定义Node节点与Edge边用KnowledgeGraph聚合节点与边的列表作为response_model通过instructor.from_provider(...)创建的客户端发起调用模型输出会自动校验并实例化为 Pydantic 模型。定义图谱的数据结构节点表示关键概念或实体边表示它们之间的关系。下面是最基础的模型定义from typing import List from pydantic import BaseModel, Field import instructor class Node(BaseModel): id: int label: str color: str blue # 默认节点颜色为蓝色 class Edge(BaseModel): source: int target: int label: str color: str black # 默认边颜色为黑色 class KnowledgeGraph(BaseModel): nodes: List[Node] Field(default_factorylist) edges: List[Edge] Field(default_factorylist)要点说明Edge.source与Edge.target通过Node.id引用节点构成有向图color字段让后续可视化阶段无需再硬编码配色模型可自主为不同类型节点上色Field(default_factorylist)保证即使模型漏掉某个列表字段也不会抛校验错误而是得到空列表这对应 Instructor 文档中 Optional Fields 的容错思想节点与边均为嵌套模型列表嵌套正是 Nested Structures 指南中嵌套列表模式的直接应用。单次生成用 response_model 约束输出创建客户端并调用client.create把KnowledgeGraph作为response_model传入# Patch the OpenAI client to add response_model support client instructor.from_provider(openai/gpt-5-nano) def generate_graph(input_text: str) - KnowledgeGraph: Generates a knowledge graph from the input text. return client.create( modelgpt-4o-mini, messages[ { role: user, content: fHelp me understand the following by describing it as a detailed knowledge graph: {input_text}, } ], response_modelKnowledgeGraph, )这里有三处值得展开from_provider的作用它替代了旧式的instructor.from_openai(OpenAI())两步初始化旧写法仍保留在 examples/knowledge-graph/run.py 中。从 instructor/init.py 的懒加载表可以看到from_provider来自instructor.auto_client会根据传入的 provider 字符串自动选择合适的客户端并完成 patch因此下面的generate_graph同样适用于 Anthropic、Gemini、Mistral、Cohere 等其它 providerresponse_modelKnowledgeGraph这是 Instructor 的核心机制。它在底层把 Pydantic 模型转换为函数调用 schema 或 JSON Schema模型返回内容会经过 Pydantic 校验保证返回对象字段齐全、类型正确甚至能在校验失败时自动重试相关机制见 Response Models 与 Validation消息只含一条 user 指令单次生成场景足够简单无需 system 提示。执行入口与输出示例if __name__ __main__: input_text Jason is Sarahs friend and he is a doctor graph generate_graph(input_text) print(graph.model_dump_json(indent2))输出为符合KnowledgeGraphschema 的 JSON{ nodes: [ { id: 1, label: Jason, color: blue }, { id: 2, label: Sarah, color: blue }, { id: 3, label: Doctor, color: blue } ], edges: [ { source: 1, target: 2, label: is a friend of, color: black }, { source: 1, target: 3, label: is a, color: black } ] }可以看到模型把Jason is Sarahs friend解析为Jason --is a friend of-- Sarah把he is a doctor解析为Jason --is a-- Doctor实体与关系被完整地结构化。用 Graphviz 可视化图谱拿到结构化对象后用 Graphviz 的Digraph渲染即可。仓库 examples/knowledge-graph/run.py 给出了参考实现from graphviz import Digraph def visualize_knowledge_graph(kg: KnowledgeGraph): dot Digraph(commentKnowledge Graph) # Add nodes for node in kg.nodes: dot.node(str(node.id), node.label, colornode.color) # Add edges for edge in kg.edges: dot.edge(str(edge.source), str(edge.target), labeledge.label, coloredge.color) # Render the graph dot.render(knowledge_graph.gv, viewTrue) graph generate_graph(Teach me about quantum mechanics) visualize_knowledge_graph(graph)可视化时注意两点节点与边均使用Node.id而非 label作为 DOT 标识保证多节点重名时不会互相覆盖dot.render(knowledge_graph.gv, viewTrue)会生成同名文件可用任意 Graphviz 兼容工具打开查看。下图展示了用上述流程对 quantum mechanics 主题生成的图谱效果迭代更新把长文本分段逐批构建单次生成受限于提示词长度也无法在后续追加新信息。为此可以将update与draw两个辅助方法直接挂到 Pydantic 模型上让模型自带合并与绘制能力from pydantic import BaseModel, Field from typing import List, Optional class Node(BaseModel, frozenTrue): id: int label: str color: str class Edge(BaseModel, frozenTrue): source: int target: int label: str color: str black class KnowledgeGraph(BaseModel): nodes: Optional[List[Node]] Field(..., default_factorylist) edges: Optional[List[Edge]] Field(..., default_factorylist) def update(self, other: KnowledgeGraph) - KnowledgeGraph: Updates the current graph with the other graph, deduplicating nodes and edges. return KnowledgeGraph( nodeslist(set(self.nodes other.nodes)), edgeslist(set(self.edges other.edges)), ) def draw(self, prefix: str None): dot Digraph(commentKnowledge Graph) for node in self.nodes: # 遍历所有节点并加入图中 dot.node(str(node.id), node.label, colornode.color) for edge in self.edges: # 遍历所有边并加入图中 dot.edge( str(edge.source), str(edge.target), labeledge.label, coloredge.color ) dot.render(prefix, formatpng, viewTrue)与单次生成版本相比这里做了三个关键变化frozenTrueNode/Edge变为不可变模型从而获得稳定的哈希值list(set(...))才能对节点/边去重update方法用集合运算合并新旧图谱自动去重这是迭代不膨胀的前提draw方法将可视化逻辑收进模型prefix可传入文件名前缀配合formatpng直接输出 PNG。在此基础上改写generate_graph接收一个字符串列表逐段调用 LLM 抽取新节点与新边再合并进当前状态from typing import List def generate_graph(input: List[str]) - KnowledgeGraph: cur_state KnowledgeGraph() # 初始化空图谱零节点、零边 num_iterations len(input) for i, inp in enumerate(input): new_updates client.create( modelgpt-4o-mini, messages[ { role: system, content: You are an iterative knowledge graph builder. You are given the current state of the graph, and you must append the nodes and edges to it Do not provide any duplicates and try to reuse nodes as much as possible., }, { role: user, content: fExtract any new nodes and edges from the following: # Part {i}/{num_iterations} of the input: {inp}, }, { role: user, content: fHere is the current state of the graph: {cur_state.model_dump_json(indent2)}, # 把当前图谱状态回灌进提示词 }, ], response_modelKnowledgeGraph, ) # 合并新抽取的内容到当前状态 cur_state cur_state.update(new_updates) # 用模型返回信息更新节点与边并绘制新变化 cur_state.draw(prefixfiteration_{i}) return cur_state这个循环的巧妙之处在于状态回灌每一轮都把cur_state.model_dump_json(indent2)拼进用户消息让模型看得见已有节点和边system 提示要求不提供重复内容、尽量复用已有节点从提示词层面抑制重复抽取即使模型仍返回了重复项update的集合去重也会兜底。运行示例模拟必须分批处理的超长文本text_chunks [ Jason knows a lot about quantum mechanics. He is a physicist. He is a professor, Professors are smart., Sarah knows Jason and is a student of his., Sarah is a student at the University of Toronto. and UofT is in Canada, ] graph: KnowledgeGraph generate_graph(text_chunks) graph.draw(prefixfinal)每一步的产物对比如下。先看第 1 段文本抽取出的图谱Jason 及其职业、知识领域经过多轮合并后最终图谱加入了 Sarah、University of Toronto、Canada 等新实体以及 is a student of、is a student at、is in 等新关系源码佐证与扩展方向仓库中的可运行示例与本文代码一一对应可对照研读examples/knowledge-graph/run.py单次生成 visualize_knowledge_graph独立函数的完整版本使用旧式instructor.from_openai(OpenAI())初始化examples/knowledge-graph/run_stream.py迭代构建版本与本文的update/draw方案一致并额外为Node/Edge显式实现了__hash__见 run_stream.py同样是为了保证集合去重的正确性——这印证了frozenTrue与哈希实现是迭代去重的关键前提examples/knowledge-graph/ 目录下的iteration_0.png至iteration_3.png、final.png是上述示例逐轮运行的真实输出。在该模式之上还可以按需扩展与实体解析结合先抽取实体属性与依赖关系再构图见 Entity Resolution与文档分段结合超长文档先按概念分段再逐段构图见 Document Segmentation更换底层模型from_provider支持 Anthropic、Cohere、Gemini、Mistral 等多家 provider可查看 Integrations 列表同一套response_model代码无需改动即可切换校验强化若希望图谱抽取更严谨可在模型上追加 Pydantic validator利用 Reask Validation 让模型自动修正不合法的输出。总结本文完成了从一段文本到一张可迭代更新的知识图谱的完整闭环用 Pydantic 的Node/Edge/KnowledgeGraph定义输出形状用 Instructor 的response_model获得校验过的结构化对象用 Graphviz 渲染成图再用update 状态回灌实现分批、增量式构建。这套模式不依赖任何专有图数据库最小实现仅需一个 Pydantic 模型类适用于问答系统知识沉淀、长文档理解、课程笔记整理等各类需要把文本变图的场景。【免费下载链接】instructorstructured outputs for llms项目地址: https://gitcode.com/GitHub_Trending/in/instructor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网