自托管 Cognee:LLM 性能测试
使用本地LLM测试Cognee - 实际效果
Cognee 是一个 Python 框架,用于使用 LLM 从文档中构建知识图谱。 但它能与自托管模型一起使用吗?
我用多个本地 LLM 进行了测试,以找出答案。

那是我尝试处理的价格清单 PDF 页面。
TL;DR
Cognee 可能与具有数百亿参数的智能 LLM 配合良好,但对于预期自动从 PDF 中提取数据的 自托管 RAG 设置(例如价格清单),在我的硬件上,它未能达到预期。该框架对结构化输出的依赖使较小的本地模型难以可靠地运行。
什么是 Cognee?
Cognee 是一个开源 Python 框架,旨在使用 LLM 从非结构化文档中构建知识图谱。与仅对文档进行分块和嵌入的传统 RAG 系统不同,Cognee 尝试通过提取实体、关系和概念到图数据库中来创建语义理解。这种方法与 GraphRAG 等高级 RAG 架构一致,后者承诺更好的上下文检索。
该框架支持多种后端:
- 向量数据库:LanceDB(默认),支持其他向量存储
- 图数据库:Kuzu(默认),允许复杂的关系查询
- LLM 提供商:OpenAI、Anthropic、Ollama 等
- 结构化输出框架:BAML 和 Instructor 用于受限生成
对于自托管爱好者来说,Cognee 与 Ollama 的兼容性使其在本地部署中具有吸引力。然而,细节才是魔鬼——正如我们将看到的,结构化输出要求为较小的模型带来了重大挑战。
为什么结构化输出很重要
Cognee 严重依赖结构化输出,以一致的格式从文档中提取信息。处理文档时,LLM 必须返回包含实体、关系和元数据的正确格式的 JSON。这就是许多较小模型难以应对的地方。
如果你在自己的项目中使用结构化输出,理解这些限制至关重要。我在 Cognee 上遇到的挑战反映了在使用本地模型时,LLM 生态系统中更广泛的问题。
配置设置
这是我使用 Ollama 的 Cognee 的工作配置。请注意启用本地操作的关键设置:
TELEMETRY_DISABLED=1
# STRUCTURED_OUTPUT_FRAMEWORK="instructor"
STRUCTURED_OUTPUT_FRAMEWORK="BAML"
# LLM 配置
LLM_API_KEY="ollama"
LLM_MODEL="gpt-oss:20b"
LLM_PROVIDER="ollama"
LLM_ENDPOINT="http://localhost:11434/v1"
# LLM_MAX_TOKENS="25000"
# 嵌入配置
EMBEDDING_PROVIDER="ollama"
EMBEDDING_MODEL="avr/sfr-embedding-mistral:latest"
EMBEDDING_ENDPOINT="http://localhost:11434/api/embeddings"
EMBEDDING_DIMENSIONS=4096
HUGGINGFACE_TOKENIZER="Salesforce/SFR-Embedding-Mistral"
# BAML 配置
BAML_LLM_PROVIDER="ollama"
BAML_LLM_MODEL="gpt-oss:20b"
BAML_LLM_ENDPOINT="http://localhost:11434/v1"
# 数据库设置(默认)
DB_PROVIDER="sqlite"
VECTOR_DB_PROVIDER="lancedb"
GRAPH_DATABASE_PROVIDER="kuzu"
# 认证
REQUIRE_AUTHENTICATION=False
ENABLE_BACKEND_ACCESS_CONTROL=False
关键配置选择
结构化输出框架:我测试了 BAML,它相比基本提示提供了更好的输出模式控制。BAML 特别为结构化 LLM 输出而设计,使其成为知识图谱提取任务的自然选择。
LLM 提供商:使用 Ollama 的 OpenAI 兼容 API 端点(/v1)使 Cognee 能够将其视为任何其他 OpenAI 风格的服务。
嵌入模型:SFR-Embedding-Mistral 模型(4096 维)提供了高质量的嵌入。有关嵌入模型选择和性能的更多信息,Qwen3 的嵌入模型提供了出色的替代方案,具有强大的多语言能力。
数据库:SQLite 用于元数据,LanceDB 用于向量,Kuzu 用于知识图谱,可在不依赖外部组件的情况下保持所有内容本地化。
安装 Cognee
使用 uv(或 pip)安装 Cognee 非常简单。我建议使用 uv 以加快依赖项解析速度:
uv venv && source .venv/bin/activate
uv pip install cognee[ollama]
uv pip install cognee[baml]
uv pip install cognee[instructor]
uv sync --extra scraping
uv run playwright install
sudo apt-get install libavif16
[ollama]、[baml] 和 [instructor] 附加项会安装本地 LLM 操作和结构化输出所需的依赖项。scraping 附加项添加了网络爬取功能,而 Playwright 启用 JavaScript 渲染页面处理。
示例代码和使用
以下是使用 Cognee 处理文档的基本工作流程。首先,我们添加文档并构建知识图谱:
msy-add.py:
import cognee
import asyncio
async def main():
# 为 cognee 创建一个干净的起点 —— 重置数据和系统状态
await cognee.prune.prune_data()
await cognee.prune.prune_system(metadata=True)
# 添加示例内容
await cognee.add(
"/home/rg/prj/prices/msy_parts_price_20251224.pdf",
node_set=["price_list", "computer_parts", "2025-12-24", "aud"]
)
# 使用 LLM 处理以构建知识图谱
await cognee.cognify()
if __name__ == '__main__':
asyncio.run(main())
node_set 参数提供语义标签,有助于在知识图谱中对文档进行分类。cognify() 方法是魔法(或问题)发生的地方 —— 它将文档片段发送给 LLM 进行实体和关系提取。
msy-search.py:
import cognee
import asyncio
async def main():
# 查询知识图谱
results = await cognee.search(
query_text="价格清单中有哪些产品?"
# query_text="32GB RAM(2x16GB 模块)的平均价格是多少?"
)
# 打印
for result in results:
print(result)
if __name__ == '__main__':
asyncio.run(main())
与传统 RAG 系统中的向量搜索不同,Cognee 查询知识图谱,理论上可以实现更复杂的基于关系的检索。这类似于高级 RAG 架构的工作方式,但需要初始图构建成功。
测试结果:LLMs 性能
我用一个实际用例测试了 Cognee:从计算机零件价格清单 PDF 中提取产品信息。这似乎是一个理想的情景 —— 结构化数据以表格形式呈现。以下是每种模型的表现:
测试的模型
1. gpt-oss:20b(200亿参数)
- 结果:因字符编码错误失败
- 问题:返回了格式错误的结构化输出,字符代码不正确
- 备注:尽管专门设计用于开源兼容性,但它无法保持一致的 JSON 格式
2. qwen3:14b(140亿参数)
- 结果:未能生成结构化输出
- 问题:模型会生成文本,但不在所需的 JSON 架构中
- 备注:Qwen 模型通常表现良好,但此任务超出了其结构化输出能力
3. deepseek-r1:14b(140亿参数)
- 结果:未能生成结构化输出
- 问题:与 qwen3 相似,无法满足 BAML 架构要求
- 备注:推理能力未能帮助格式合规
4. devstral:24b(240亿参数)
- 结果:未能生成结构化输出
- 问题:即使有更多参数,也无法持续生成有效的 JSON
- 备注:专为编码设计的模型仍然难以遵守严格的架构要求
5. ministral-3:14b(140亿参数)
- 结果:未能生成结构化输出
- 问题:Mistral 的较小模型无法处理结构化输出需求
6. qwen3-vl:30b-a3b-instruct(300亿参数)
- 结果:未能生成结构化输出
- 问题:视觉能力在此上下文中未能帮助 PDF 表格提取
7. gpt-oss:120b(1200亿参数)
- 结果:在 2 小时以上仍未完成处理
- 硬件:消费级 GPU 设置
- 问题:模型太大,即使最终可能运行,也不适合实际自托管使用
关键发现
分块大小限制:Cognee 使用 4k token 分块来处理与 Ollama 的文档。对于复杂文档或具有更大上下文窗口的模型,这似乎过于限制。该框架没有提供调整此参数的简便方法。
结构化输出要求:核心问题不是模型智能,而是格式合规。这些模型可以理解内容,但在提取过程中保持一致的 JSON 架构证明具有挑战性。这与获取本地模型尊重输出约束的更广泛挑战一致。
硬件考虑:即使足够大的模型可能工作(如 gpt-oss:120b),硬件要求使其在大多数自托管场景中不切实际。你需要大量的 GPU 内存和处理能力。
与结构化输出最佳实践的比较
这次经历强化了在不同 LLM 提供商中使用结构化输出的经验教训。OpenAI、Anthropic 和 Google 的商业 API 通常有内置机制来强制执行输出架构,而本地模型需要更复杂的方法,如基于语法的采样或多次验证。
对于选择适合 Cognee 的 LLM 以在 Ollama 上运行,包括不同模型大小和性能特征的详细比较,有全面的指南可以帮助你做出明智的决定。
自托管 RAG 的替代方法
如果你坚持自托管并需要从文档中提取结构化数据,请考虑以下替代方法:
1. 传统 RAG 与简单提取
与其提前构建复杂的知识图谱,不如使用传统 RAG 进行文档分块和向量搜索。对于结构化数据提取:
- 使用
pdfplumber或tabula-py等库直接解析表格 - 使用不需要严格架构遵循的简单提示
- 在 Python 中实现后处理验证,而不是依赖 LLM 输出格式
2. 专用嵌入模型
嵌入的质量显著影响检索性能。考虑使用在本地表现良好的高性能嵌入模型。现代嵌入模型如 Qwen3 提供了出色的多语言支持,可以显著提高 RAG 系统的准确性。
3. 重排序以获得更好的结果
即使使用简单的 RAG 架构,添加重排序步骤也能显著提高结果。在初始向量搜索检索后,重排序模型可以更好地评估相关性。这种两阶段方法通常优于更复杂的单阶段系统,尤其是在受限硬件上工作时。
4. 混合搜索策略
将向量搜索与传统关键字搜索(BM25)结合使用,通常比单独使用任何一种方法效果更好。许多现代向量数据库原生支持混合搜索。
5. 考虑向量存储的替代方案
如果你从头开始构建 RAG 系统,请根据你的需求评估不同的向量存储。选项范围从轻量级嵌入式数据库到专为生产规模设计的分布式系统。
Docker 部署考虑
在生产自托管中,容器化你的 RAG 设置简化了部署和扩展。当使用 Cognee 或类似框架与 Ollama 时:
# 在容器中运行 Ollama
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
# 拉取你的模型
docker exec -it ollama ollama pull gpt-oss:20b
# 配置 Cognee 以连接到容器端点
确保正确配置 GPU 传递和卷挂载以实现模型持久化。
学到的经验
1. 工具与硬件匹配:Cognee 是为云规模 LLM 设计的。如果你在消费级硬件上自托管,更简单的架构可能更实用。
2. 结构化输出很困难:从本地 LLM 获取一致的架构合规性仍然具有挑战性。如果您的应用程序严重依赖结构化输出,要么使用商业 API,要么实现强大的验证和重试逻辑。
3. 早期测试:在承诺使用框架之前,用特定的用例和硬件进行测试。演示中起作用的东西可能在大规模或使用您的文档时不起作用。
4. 考虑混合方法:对于复杂的提取任务使用商业 API,对于简单的查询使用本地模型,以平衡成本和能力。
相关阅读
LLM 的结构化输出
理解结构化输出对于框架如 Cognee 来说至关重要。这些文章深入探讨了如何从 LLM 获取一致、符合架构的响应:
- 为 Cognee 选择合适的 LLM:本地 Ollama 设置
- LLM 的结构化输出:Ollama、Qwen3 与 Python 或 Go
- 流行 LLM 提供商的结构化输出比较:OpenAI、Gemini、Anthropic、Mistral 和 AWS Bedrock
- Ollama GPT-OSS 的结构化输出问题
RAG 架构与实现
对于知识提取和检索的替代或补充方法:
嵌入和重排序
通过更好的嵌入和重排序提高检索质量: