OA0
OA0 是一个探索 AI 的社区
现在注册
已注册用户请  登录
OA0  ›  代码  ›  GraphRAG Local Search 的替代思路:nano-graphrag — 轻量图谱 RAG 实现

GraphRAG Local Search 的替代思路:nano-graphrag — 轻量图谱 RAG 实现

 
  bronze ·  2026-04-10 11:00:22 · 2 次点击  · 0 条评论  
显示 MemoDB 徽标

一个简单、易于修改的 GraphRAG 实现

😭 GraphRAG 功能强大,但官方的实现难以阅读或修改

😊 本项目提供了一个更小、更快、更简洁的 GraphRAG,同时保留了核心功能(参见性能基准已知问题)。

🎁 排除 tests 和提示词,nano-graphrag 大约只有 1100 行代码

👌 小巧但可移植(支持 faiss、neo4j、ollama...),异步且完全类型化。

如果你正在寻找一个用于长期用户记忆的多用户 RAG 解决方案,可以看看这个项目:memobase :)

安装

从源码安装(推荐)

# 先克隆此仓库
cd nano-graphrag
pip install -e .

从 PyPi 安装

pip install nano-graphrag

快速开始

[!TIP]

请在环境中设置 OpenAI API 密钥:export OPENAI_API_KEY="sk-..."

[!TIP]
如果你使用 Azure OpenAI API,请参考 .env.example 设置你的 Azure OpenAI 环境变量。然后通过 GraphRAG(...,using_azure_openai=True,...) 启用。

[!TIP]
如果你使用 Amazon Bedrock API,请确保你的凭证已正确设置(例如通过 aws configure 命令)。然后通过类似这样的配置启用:GraphRAG(...,using_amazon_bedrock=True, best_model_id="us.anthropic.claude-3-sonnet-20240229-v1:0", cheap_model_id="us.anthropic.claude-3-haiku-20240307-v1:0",...)。参考示例脚本

[!TIP]

如果你没有任何 API 密钥,可以查看这个示例,它使用 transformersollama。如果你想使用其他 LLM 或嵌入模型,请查看高级用法

下载查尔斯·狄更斯的《圣诞颂歌》副本:

curl https://raw.githubusercontent.com/gusye1234/nano-graphrag/main/tests/mock_data.txt > ./book.txt

使用以下 Python 代码片段:

from nano_graphrag import GraphRAG, QueryParam

graph_func = GraphRAG(working_dir="./dickens")

with open("./book.txt") as f:
    graph_func.insert(f.read())

# 执行全局 GraphRAG 搜索
print(graph_func.query("这个故事的主要主题是什么?"))

# 执行局部 GraphRAG 搜索(我认为这是更好、更具扩展性的方式)
print(graph_func.query("这个故事的主要主题是什么?", param=QueryParam(mode="local")))

下次从相同的 working_dir 初始化 GraphRAG 时,它将自动重新加载所有上下文。

批量插入

graph_func.insert(["TEXT1", "TEXT2",...])
增量插入 `nano-graphrag` 支持增量插入,不会添加重复的计算或数据:
with open("./book.txt") as f:
    book = f.read()
    half_len = len(book) // 2
    graph_func.insert(book[:half_len])
    graph_func.insert(book[half_len:])
> `nano-graphrag` 使用内容的 md5 哈希值作为键,因此不会有重复的文本块。 > > 但是,每次插入时,图的社区都会重新计算,社区报告也会重新生成。
朴素 RAG `nano-graphrag` 也支持朴素 RAG 的插入和查询:
graph_func = GraphRAG(working_dir="./dickens", enable_naive_rag=True)
...
# 查询
print(rag.query(
      "这个故事的主要主题是什么?",
      param=QueryParam(mode="naive")
)

异步

对于每个同步方法 NAME(...),都有一个对应的异步方法 aNAME(...)

await graph_func.ainsert(...)
await graph_func.aquery(...)
...

可用参数

GraphRAGQueryParam 是 Python 中的 dataclass。使用 help(GraphRAG)help(QueryParam) 查看所有可用参数!或者查看高级用法部分了解一些选项。

组件

以下是你可以使用的组件:

类型 功能 实现位置
LLM OpenAI 内置
Amazon Bedrock 内置
DeepSeek 示例
ollama 示例
嵌入模型 OpenAI 内置
Amazon Bedrock 内置
Sentence-transformers 示例
向量数据库 nano-vectordb 内置
hnswlib 内置,示例
milvus-lite 示例
faiss 示例
图存储 networkx 内置
neo4j 内置(文档
可视化 graphml 示例
文本分块 按 token 大小 内置
按文本分割器 内置
  • 内置 表示我们在 nano-graphrag 内部已有该实现。示例 表示我们在 examples 文件夹下的教程中有该实现。
  • 查看 examples/benchmarks 了解组件之间的比较。
  • 欢迎贡献更多组件。

高级用法

一些设置选项 - `GraphRAG(...,always_create_working_dir=False,...)` 将跳过目录创建步骤。如果你将所有组件都切换到非文件存储,可以使用此选项。
仅查询相关上下文 `graph_func.query` 直接返回最终答案,不进行流式输出。 如果你想在你的项目中集成 `nano-graphrag`,可以使用 `param=QueryParam(..., only_need_context=True,...)`,这将只返回从图中检索到的上下文,类似于:
# 局部模式
-----报告-----
```csv
id, 内容
0,  # FOX 新闻以及媒体和政治中的关键人物...
1, ...
```
...

# 全局模式
----分析师 3----
重要性分数:100
唐纳德·J·特朗普:经常被讨论与其政治活动相关...
...
你可以将这些上下文整合到你自定义的提示词中。
提示词 `nano-graphrag` 使用 `nano_graphrag.prompt.PROMPTS` 字典对象中的提示词。你可以修改并替换其中的任何提示词。 一些重要的提示词: - `PROMPTS["entity_extraction"]` 用于从文本块中提取实体和关系。 - `PROMPTS["community_report"]` 用于组织和总结图集群的描述。 - `PROMPTS["local_rag_response"]` 是局部搜索生成的系统提示词模板。 - `PROMPTS["global_reduce_rag_response"]` 是全局搜索生成的系统提示词模板。 - `PROMPTS["fail_response"]` 是当用户查询与任何内容都不相关时的备用回复。
自定义分块 `nano-graphrag` 允许你自定义分块方法,查看[示例](./examples/using_custom_chunking_method.py)。 切换到内置的文本分割器分块方法:
from nano_graphrag._op import chunking_by_seperators

GraphRAG(...,chunk_func=chunking_by_seperators,...)
LLM 函数 在 `nano-graphrag` 中,我们需要两种类型的 LLM:一个性能强大的和一个成本低廉的。前者用于规划和响应,后者用于总结。默认情况下,强大的模型是 `gpt-4o`,成本低廉的模型是 `gpt-4o-mini`。 你可以实现自己的 LLM 函数(参考 `_llm.gpt_4o_complete`):
async def my_llm_complete(
    prompt, system_prompt=None, history_messages=[], **kwargs
) -> str:
  # 如果有缓存 KV 数据库,则弹出
  hashing_kv: BaseKVStorage = kwargs.pop("hashing_kv", None)
  # 其余 kwargs 用于调用 LLM,例如 `max_tokens=xxx`
    ...
  # 调用你的 LLM
  response = await call_your_LLM(messages, **kwargs)
  return response
替换默认的 LLM 函数:
# 如果需要,调整最大 token 数或最大异步请求数
GraphRAG(best_model_func=my_llm_complete, best_model_max_token_size=..., best_model_max_async=...)
GraphRAG(cheap_model_func=my_llm_complete, cheap_model_max_token_size=..., cheap_model_max_async=...)
你可以参考这个[示例](./examples/using_deepseek_as_llm.py),它使用 [`deepseek-chat`](https://platform.deepseek.com/api-docs/) 作为 LLM 模型。 你可以参考这个[示例](./examples/using_ollama_as_llm.py),它使用 [`ollama`](https://github.com/ollama/ollama) 作为 LLM 模型。 #### JSON 输出 `nano-graphrag` 将使用 `best_model_func` 并附带参数 `"response_format": {"type": "json_object"}` 来输出 JSON。但一些开源模型可能产生不稳定的 JSON。 `nano-graphrag` 为你提供了一个后处理接口,用于将响应转换为 JSON。此函数的签名如下:
def YOUR_STRING_TO_JSON_FUNC(response: str) -> dict:
  "将字符串响应转换为 JSON"
  ...
并通过 `GraphRAG(...convert_response_to_json_func=YOUR_STRING_TO_JSON_FUNC,...)` 传递你自己的函数。 例如,你可以参考 [json_repair](https://github.com/mangiucugna/json_repair) 来修复 LLM 返回的 JSON 字符串。
嵌入函数 你可以将默认的嵌入函数替换为任何 `_utils.EmbedddingFunc` 实例。 例如,默认的嵌入函数使用 OpenAI 嵌入 API:
@wrap_embedding_func_with_attrs(embedding_dim=1536, max_token_size=8192)
async def openai_embedding(texts: list[str]) -> np.ndarray:
    openai_async_client = AsyncOpenAI()
    response = await openai_async_client.embeddings.create(
        model="text-embedding-3-small", input=texts, encoding_format="float"
    )
    return np.array([dp.embedding for dp in response.data])
替换默认的嵌入函数:
GraphRAG(embedding_func=your_embed_func, embedding_batch_num=..., embedding_func_max_async=...)
你可以参考这个[示例](./examples/using_local_embedding_model.py),它使用 `sentence-transformer` 在本地计算嵌入向量。
存储组件 你可以将所有与存储相关的组件替换为你自己的实现,`nano-graphrag` 主要使用三种存储: **`base.BaseKVStorage` 用于存储键值对数据(值为 JSON 格式)** - 默认我们使用磁盘文件存储作为后端。 - `GraphRAG(.., key_string_value_json_storage_cls=YOURS,...)` **`base.BaseVectorStorage` 用于索引嵌入向量** - 默认我们使用 [`nano-vectordb`](https://github.com/gusye1234/nano-vectordb) 作为后端。 - 我们也有一个内置的 [`hnswlib`](https://github.com/nmslib/hnswlib) 存储,查看此[示例](./examples/using_hnsw_as_vectorDB.py)。 - 查看此[示例](./examples/using_milvus_as_vectorDB.py),它实现了 [`milvus-lite`](https://github.com/milvus-io/milvus-lite) 作为后端(在 Windows 上不可用)。 - `GraphRAG(.., vector_db_storage_cls=YOURS,...)` **`base.BaseGraphStorage` 用于存储知识图谱** - 默认我们使用 [`networkx`](https://github.com/networkx/networkx) 作为后端。 - 我们有一个内置的 `Neo4jStorage` 用于图存储,查看此[教程](./docs/use_neo4j_for_graphrag.md)。 - `GraphRAG(.., graph_storage_cls=YOURS,...)` 你可以参考 `nano_graphrag.base` 查看每个组件的详细接口。

常见问题

查看 FQA

路线图

查看 ROADMAP.md

贡献

nano-graphrag 欢迎任何形式的贡献。在贡献之前请阅读此文档

性能基准

使用 nano-graphrag 的项目

  • Medical Graph RAG:用于医疗数据的 Graph RAG
  • LightRAG:简单快速的检索增强生成
  • fast-graphrag:能够智能适应你的用例、数据和查询的 RAG
  • HiRAG:具有分层知识的检索增强生成

如果你的项目使用了 nano-graphrag,欢迎提交 Pull Request,这将帮助其他人信任这个仓库 ❤️

已知问题

  • nano-graphrag 没有实现 GraphRAGcovariates 功能。
  • nano-graphrag 的全局搜索实现与原版不同。原版使用类似 map-reduce 的风格将所有社区信息填入上下文,而 nano-graphrag 只使用前 K 个重要且核心的社区(使用 QueryParam.global_max_consider_community 控制,默认为 512 个社区)。
2 次点击  ∙  0 人收藏  
登录后收藏  
0 条回复
关于 ·  帮助 ·  PING ·  隐私 ·  条款   
OA0 - Omni AI 0 一个探索 AI 的社区
沪ICP备2024103595号-2
耗时 36 ms
Developed with Cursor