0基础知识图谱实战:本地大模型+Langchain节点匹配
利用本地LLM构建知识图谱与高级RAG:从原始数据到语义关联的完整实施路径
新年伊始,先聚焦数据这一核心议题。
数据始终是AI落地的根基。无论是HR筛选简历、法务审查合同、电商分析客户评价,还是个人知识管理,只有将数据结构化且可检索,才能释放真实价值。
上一篇我们完成了私有文档的预处理与文本分块。本篇继续推进:使用本地大语言模型,从文本中识别并匹配概念及其语义关系,构建知识图谱。本系列覆盖从数据预处理到高级RAG应用的完整链路,本篇为第四步。
鉴于企业对数据安全与隐私的严格需求,本次操作全程本地执行,不依赖云端服务。项目以医疗数据为例,完整代码与数据已整理就绪,可随时查看。
专注力有限,直接上干货。
第一部分:全局策略与顶层设计,授人以渔
庄子云:“纵横不出方圆,万变不离其宗。”知识图谱构建亦然——先厘清问题域,目标明确则事半功倍。
先看常见需求统计表:
目标确定后,必须制定技术工程计划与资源分配方案。知识图谱构建是系统工程,需开发人员、数据分析师、领域专家协同。此外还需项目管控角色,确保资源合理分配、环节有序衔接。
1.1 技术工程计划制定
技术选型:选对技术栈是成功基础。包括数据存储(如Neo4j、JanusGraph)、数据处理(如Apache Spark、Kafka)、前端可视化(如D3.js、Sigma.js)。本文第二部分将详细说明本次项目所用工具。
数据源确认:根据目标确定需整合的数据源——公开数据集、内部数据库、爬虫数据等。此阶段还需评估数据质量、可用性与合规要求。
架构设计:设计完整系统架构,覆盖数据采集、处理、存储、查询与展示层,确保可扩展性、稳定性与安全性。
开发计划:分阶段制定目标、时间线与职责分工。推荐迭代式开发,灵活应对变化需求。
1.2 资源分配策略
手上有哪些资源——人力、时间、预算、技术积累,必须心中有数。
团队组建:构建跨学科团队,除技术人员外,必须有领域专家支撑。每位成员需明确职责与协作方式。
时间管理:合理分配时间,确保关键里程碑达成。敏捷方法(Scrum、Kanban)可提升效率。
资金预算:明确投入方向,重点倾斜技术研发、数据获取与人才培养。
知识传递:团队内部定期组织技术分享、工作坊与培训,持续提升整体能力。
第二部分:具体实现方案——工具选型与使用方式
整个项目分为四步,后续逐一详解。
① 文本分块:将语料库切分为若干块,每块分配唯一ID。前置步骤已完成,未执行的可回看历史内容。
工具:langchain、llama_index、Unstructured等
② 关系抽取:对每个文本块,使用LLM提取概念及其语义关系,并为关系赋予权重W1。同一对概念间可存在多条关系,每条对应一条边。
工具:ollama、zephyr、df2Graph、graph2Df等
③ 相关性计算:同一文本块内的概念,通过上下文邻近性产生关联,分配权重W2。同一对概念可能出现在多个块中。
工具:Pandas、NumPy
④ 可视化输出:将相似关系对分组,权重求和后连接。最终每对不同概念仅保留一条边,附带权重与关系名称,形成可视化概念图,以网页形式输出。
工具:Seaborn、Pandas、NetworkX、Pyvis等
第三部分:实例运行——边操作边剖析细节
说实话,很多人会直接跳到这里。但建议先回头阅读心法部分,磨刀不误砍柴工。
今天重点完成数据处理与关系抽取,下一篇进行连线与可视化。开始实操!
主要分为两块内容:
#A 搭建AI实操环境:miniconda + jupyter-notebook
#B 运行知识图谱构建,输出html网页文件
3.1 搭建实操AI环境
首先在ollama上部署zephyr大模型,也可替换其他LLM。若未部署过,可参考之前的部署指南。
打开WSL,输入指令回车启动。首次部署会自动下载模型,占用显存约6G。
ollama run zephyr
保持窗口后台运行,后续代码将连接该模型。LLM的作用是根据文本块生成概念关系,效果如下:
启动miniconda,创建新环境用于数据处理与概念图生成。未搭建环境的,请参考之前的环境配置指南。
创建新环境,在miniconda命令窗口输入:
conda create --name kg python=3.10
环境名设为“kg”,指定Python 3.10。务必新建环境,避免污染全局,养成良好习惯。
激活环境:
conda activate kg
安装依赖包:
pip install pandas numpy networkx seaborn langchain pypdf2 pyvis tqdm yachalk unstructured "unstructured[pdf]"
安装jupyter:
pip install jupyter
启动jupyter:
jupyter-notebook
处理下载的文件
将会员盘中的文件下载后放置到纯英文路径下,切换到该目录,然后双击打开"yiyiai-kg"这个notebook。
简单说明jupyter操作:右上角圆圈表示内核运行状态,空白则需重启。运行中圆圈变灰。选中代码块按Ctrl+回车执行,或点击上方小三角。按顺序运行即可。每个模块的核心操作已说明,仔细阅读即可理解。
至此,环境搭建完成。
3.2 运行知识图谱构建,输出html网页文件
边执行边讲解核心代码。
设置默认输入与输出目录
数据统一存放在"F:/data/03"路径下,可直接修改绝对路径。输出目录在同一文件夹内,自动创建"output"子文件夹。
## 定义输入数据的路径
data_dir = "F:/data/03"
inputdirectory = Path(f"./data_input/{data_dir}")
## 定义数据输出路径
out_dir = data_dir
outputdirectory = Path(f"./data_output/{out_dir}")
加载数据与文本分块
使用PDF加载器,结合langchain的递归拆分方法,将文件夹下所有PDF拆分为文本块。每块大小1500字符,重叠150字符。
loader = PyPDFDirectoryLoader(r"F:/data/03")
documents = loader.load()
splitter = RecursiveCharacterTextSplitter(
chunk_size=1500,
chunk_overlap=150,
length_function=len,
is_separator_regex=False,
)
pages = splitter.split_documents(documents)
print("Number of chunks = ", len(pages))
print(pages[3].page_content)
运行后返回拆分总数。样例中拆出8个块,数据量越大块数越多,处理时间相应增加。
创建数据框并分配块ID
from helpers.df_helpers import documents2Dataframe df = documents2Dataframe(pages) print(df.shape) df.head()
调用LLM抽取主体关系
8个文本块保存为"chunks.csv",传给LLM处理后返回"graph.csv"。
if regenerate:
concepts_list = df2Graph(df, model='zephyr:latest')
dfg1 = graph2Df(concepts_list)
if not os.path.exists(outputdirectory):
os.makedirs(outputdirectory)
dfg1.to_csv(outputdirectory/"graph.csv", sep="|", index=False)
df.to_csv(outputdirectory/"chunks.csv", sep="|", index=False)
else:
dfg1 = pd.read_csv(outputdirectory/"graph.csv", sep="|")
dfg1.replace("", np.nan, inplace=True)
dfg1.dropna(subset=["node_1", "node_2", 'edge'], inplace=True)
dfg1['count'] = 4
print(dfg1.shape)
dfg1.head()
提示词文件用于指导LLM如何抽取及返回格式。若效果不佳,可修改提示词或更换模型。
相似度计算与数据框合并
同一份数据中可能包含语义相同的关系,需计算相似度后合并,才能准确呈现关系网络。
dfg = pd.concat([dfg1, dfg2], axis=0)
dfg = (dfg.groupby(["node_1", "node_2"]).agg({"chunk_id": ",".join, "edge": ','.join, 'count': 'sum'}).reset_index())
dfg
核心逻辑至此完成。但知识图谱的价值在于可视化“图”本身。下一篇将把这些数据转化为HTML格式,生成交互式网络图,可部署至公司内网供全员使用。













