使用 BAML 模糊解析改进 LangChain 知识图谱提取:成功率从25%提升到99%

在构建基于知识图谱的检索增强生成(RAG)系统或智能代理时,从非结构化数据中准确提取节点和关系是一项核心挑战。特别是在使用经过量化处理的小型本地大语言模型(LLM)时,这一问题尤为突出,往往导致整体系统性能显著下降。

LangChain 提取框架的主要限制在于其对严格 JSON 解析的依赖,即使采用大规模模型或精心设计的提示模板,解析失败的情况仍然频繁发生。

相比之下,BAML(Basically, A Made-up Language)采用模糊解析策略,能够在 LLM 输出格式不完全符合 JSON 标准的情况下仍然成功提取结构化数据。
本文将深入分析小型量化模型在 LangChain 提取任务中的性能限制,并展示 BAML 技术如何将知识图谱提取成功率从约 25% 显著提升至 99% 以上。

评估数据集的构建与初始化
为了系统性地分析问题并验证解决方案的有效性,本研究构建了一个标准化评估数据集,以便在多个测试场景中评估 BAML 对 LangChain 知识图谱构建的改进效果。

实验使用的数据来源于 Tomasonjo 在 GitHub 上公开的博客数据集,首先进行数据加载操作。

导入 pandas 库用于数据操作和分析

import pandas as pd

从 GitHub 上托管的 CSV 文件加载新闻文章数据集到 pandas DataFrame

news = pd.read_csv(
"https://raw.githubusercontent.com/tomasonjo/blog-datasets/main/news_articles.csv"
)

数据集结构相对简单,包含文章标题和正文内容。为了后续的性能分析和评估,需要添加一个新列来记录每篇新闻文章对应的 token 总数。

此处采用 OpenAI 的

tiktoken
库进行 token 计算,通过循环遍历的方式为整个数据集计算 token 数量。

导入 tiktoken 库以从文本计算令牌数

import tiktoken

定义一个函数来计算给定字符串中特定模型的令牌数

def num_tokens_from_string(string: str, model: str = "gpt-4o") -> int:
"""返回文本字符串中的令牌数。"""
# 获取指定模型的编码
encoding = tiktoken.encoding_for_model(model)
# 将字符串编码为令牌并计算它们
num_tokens = len(encoding.encode(string))
# 返回令牌总数
return num_tokens

在 DataFrame 中创建一个新列 'tokens'

它为每篇文章的 'title' 和 'text' 组合计算令牌数

news["tokens"] = [
num_tokens_from_string(f"{row['title']} {row['text']}")
for i, row in news.iterrows()
]
数据集的 token 计算过程耗时较短,完成后得到包含 token 信息的增强数据集。

显示 DataFrame 的前 5 行以显示新的 'tokens' 列

news.head()
token 信息将在后续的评估和分析阶段发挥重要作用,这是数据预处理的关键步骤。

量化 LLaMA 模型的部署与配置
为了模拟生产环境中的实际场景,本文采用低精度量化模型进行严格的性能评估。在实际生产部署中,开源 LLM 通常以量化形式运行,以降低计算成本和推理延迟。本研究选择 LLaMA 3.1 作为测试模型。

实验平台选择 Ollama,但需要注意的是,LangChain 框架支持多种 API 和本地 LLM 提供商,可根据具体需求选择合适的部署方案。

ChatOllama 是 Ollama 语言模型的接口

from langchain_ollama import ChatOllama

定义要使用的模型名称

model = "llama3"

初始化 ChatOllama 语言模型

'temperature' 参数控制输出的随机性。

低值(例如 0.001)使模型的响应更具确定性。

llm = ChatOllama(model=model, temperature=0.001)
系统环境配置需要在本地安装 Ollama,该工具支持 macOS、Windows 和 Linux 操作系统。安装步骤包括访问官方网站,下载相应操作系统的安装程序并按照说明完成安装。

安装完成后,Ollama 将作为后台服务运行。在 macOS 和 Windows 系统中,应用程序会自动启动并在后台运行,用户可在菜单栏或系统托盘中看到相应图标。在 Linux 系统中,可能需要通过

systemctl start ollama
命令手动启动服务。

服务状态检查可通过终端或命令提示符执行以下命令:

检查可用模型

ollama list

OUTPUT

[ ] <-- 尚无模型
如果服务正常运行但尚未安装模型,将显示空的模型列表,这在初始阶段是正常现象。若出现"命令未找到"错误,需要检查 Ollama 安装状态;若出现连接错误,则表明服务未正常启动。

模型下载使用 pull 命令完成。由于模型文件较大,此过程需要较长时间和充足的磁盘空间。

下载 llama3 模型

ollama pull llama3
下载完成后,再次执行

ollama list
命令应能看到已安装的模型。

向本地 Ollama API 发送请求以生成文本

curl http://localhost:11434/api/generate \
# 设置 Content-Type 标头以指示 JSON 负载
-H "Content-Type: application/json" \
# 为请求提供数据
-d '{
"model": "llama3",
"prompt": "Why is the sky blue?"
}'

OUTPUT

{
"model": "llama3",
"created_at": "2025-08-03T12:00:00Z",
"response": "The sky appears blue be ... blue.",
"done": true
}
成功的测试请求将返回 JSON 格式的响应流,确认服务器正常运行并能够为模型提供推理服务。

完成评估数据和 LLM 的准备工作后,下一步将进行数据转换,以深入理解 LangChain 框架中存在的问题。
基于 LLMGraphTransformer 的传统方法分析
在 LangChain 或 LangGraph 框架中,将原始或结构化数据转换为知识图谱的标准方法是使用官方提供的转换工具。其中最为常用的是

langchain_experimental
库中的

LLMGraphTransformer
组件。

该工具采用一体化解决方案设计理念:用户只需提供文本数据和 LLM 实例,工具会自动处理提示构建和结果解析,最终返回结构化的图数据。

首先验证该方法在本地

llama3
模型上的性能表现。实验开始前需要导入必要的组件。

从 Langchain 的实验库导入主要图转换器

from langchain_experimental.graph_transformers import LLMGraphTransformer

导入图和文档的数据结构

from langchain_community.graphs.graph_document import GraphDocument, Node, Relationship
from langchain_core.documents import Document
转换器初始化需要配置之前创建的

llm
对象(即

llama3
模型)。同时需要指定希望为节点和关系提取的附加属性信息。在本实验中,仅要求提取

description
属性。

使用我们的 llama3 模型初始化 LLMGraphTransformer

我们指定我们希望节点和关系都有一个 'description' 属性

llm_transformer = LLMGraphTransformer(
llm=llm,
node_properties=["description"],
relationship_properties=["description"]
)
为了确保实验的可重复性和代码的整洁性,需要构建一个辅助函数。该函数接受文本字符串作为输入,将其封装为 LangChain 的

Document
格式,然后传递给

llm_transformer
进行图结构提取。

导入 List 类型以进行类型提示

from typing import List

定义一个函数来处理单个文本字符串并将其转换为图文档

def process_text(text: str) -> List[GraphDocument]:
# 从原始文本创建一个 Langchain Document 对象
doc = Document(page_content=text)
# 使用转换器将文档转换为 GraphDocument 对象列表
return llm_transformer.convert_to_graph_documents([doc])
完成配置后开始实验。为了保持实验的可控性并突出核心问题,选择数据集中 20 篇文章作为测试样本。
weibo.com/ttarticle/p/show?id=2309405199201524383850
weibo.com/ttarticle/p/show?id=2309405199201700282593
weibo.com/ttarticle/p/show?id=2309405199201880899693
weibo.com/ttarticle/p/show?id=2309405199202056798340
weibo.com/ttarticle/p/show?id=2309405199202237153371
weibo.com/ttarticle/p/show?id=2309405199202413314261
weibo.com/ttarticle/p/show?id=2309405199202593931356
weibo.com/ttarticle/p/show?id=2309405199202770092248
weibo.com/ttarticle/p/show?id=2309405199202946253096
weibo.com/ttarticle/p/show?id=2309405199203126608015
weibo.com/ttarticle/p/show?id=2309405199203302768894
weibo.com/ttarticle/p/show?id=2309405199203482861644
weibo.com/ttarticle/p/show?id=2309405199203663478808
weibo.com/ttarticle/p/show?id=2309405199203839639716
weibo.com/ttarticle/p/show?id=2309405199204015800497
weibo.com/ttarticle/p/show?id=2309405199204196155453
weibo.com/ttarticle/p/show?id=2309405199204372054171
weibo.com/ttarticle/p/show?id=2309405199204552671269
weibo.com/ttarticle/p/show?id=2309405199204728832120
weibo.com/ttarticle/p/show?id=2309405199204904992985
weibo.com/ttarticle/p/show?id=2309405199205085347926
weibo.com/ttarticle/p/show?id=2309405199205261508804
weibo.com/ttarticle/p/show?id=2309405199205525749947
weibo.com/ttarticle/p/show?id=2309405199205706104950
weibo.com/ttarticle/p/show?id=2309405199205882265743
weibo.com/ttarticle/p/show?id=2309405199206058164352
weibo.com/ttarticle/p/show?id=2309405199206238781493
weibo.com/ttarticle/p/show?id=2309405199206414680160
weibo.com/ttarticle/p/show?id=2309405199206591103211