自然语言处理:第四十六章 GraphRAG 快速入门

项目链接:microsoft/graphrag: A modular graph-based Retrieval-Augmented Generation (RAG) system (github.com)

实现过程:



写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!!

写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!!

写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!!

GraphRAG 是微软提出来的复合RAG,有关于GraphRAG的细节介绍和实现过程可以参考我之前的文章: 自然语言处理:第四十五章 GraphRAG 实现过程 。 这次就跟着我一起去看看如何将GraphRAG应用到实战里。

官网其实给了三种GraphRAG的方式:

  1. 从pypi包安装
  2. 源码部署
  3. 利用GraphRAG加速

要求: python >= 3.10 & <= 3.12



一. python部署

1. 新建环境

conda create -n GraphRAG python=3.11
conda activate GraphRAG

2. 环境安装

pip install graphrag

3. 初始化项目

mkdir -p ./ragtest/input   # 建立一个ragtest/input 文件夹用于存放查询文件 , ragtest 是工作目录
curl https://www.gutenberg.org/cache/epub/24022/pg24022.txt > ./ragtest/input/book.txt # 目前只支持txt和csv文件解析
python -m graphrag.index --init --root ./ragtest # 初始化项目文件夹, root后面输入的是项目文件夹,

然后在ragtest的文件夹下面会生成两个文件: .env 和 setting.yaml 文件


4. 修改配置文件

4.1 在.env文件里配置apikeys

改成你sk开头的apikeys就可以了

GRAPHRAG_API_KEY=sk-xxxxxxxxxxxxxxxxxxx


4.2 在setting.yaml文件修改url和model

由于配置文件里需要对应的修改对话模型和embedding模型,所以对应的有几个内容需要修改,下面这5个是比较常见需要修改的地方,如果其他的需要修改的可以参考官网Configuring GraphRAG Indexing (microsoft.github.io)

llm:
  model: deepseek-chat
  model_supports_json: false # recommended if this is available for your model.
  api_base: https://api.agicto.cn/v1  #  https://<instance>.openai.azure.com

embeddings:
  llm:
    model: text-embedding-3-small
    api_base: https://api.agicto.cn/v1



5. 构建GraphRAG的图谱

python -m graphrag.index --root ./ragtest

比较耗时,取决于你文件大小,运行成功后应该是这样:
在这里插入图片描述



6. 查询问题

GraphRAG提供了两种查询机制:

  1. Global: 问题的回答要基于所有文档的理解

    python -m graphrag.query \
    --root ./ragtest \
    --method global \
    "What are the top themes in this story?"
    
  2. Local: 问题的回答基于某篇文档就能直接回答

    python -m graphrag.query \
    --root ./ragtest \
    --method local \
    "Who is Scrooge, and what are his main relationships?"
    

官网解释:

在这里插入图片描述




二、源码部署

1. 新建环境

同上


2.下载源码

git clone https://github.com/microsoft/graphrag.git   
cd graphrag

3. 下载依赖并初始化

3.1 安装poetry资源包管理工具及相关依赖:
pip install poetry 
poetry install


3.2 初始化

poetry run poe index --init --root .

同样的也会生成会生成两个文件: .env 和 setting.yaml 文件


3.3 放入文件夹
mkdir ./input
curl https://www.xxx.com/xxx.txt > ./input/book.txt  #示例,可以替换为任何的txt文件


4. 修改配置文件

同上


5. 构建GraphRAG的图谱

poetry run poe index --root .

成功后截图:

⠋ GraphRAG Indexer
├── Loading Input (InputFileType.text) - 1 files loaded (0 filtered) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% 0:00:00 0:00:00
├── create_base_text_units
├── create_base_extracted_entities
├── create_summarized_entities
├── create_base_entity_graph
├── create_final_entities
├── create_final_nodes
├── create_final_communities
├── join_text_units_to_entity_ids
├── create_final_relationships
├── join_text_units_to_relationship_ids
├── create_final_community_reports
├── create_final_text_units
├── create_base_documents
└── create_final_documents
🚀 All workflows completed successfully.



6. 查询问题

同样的也分为两种查询方式global 和local:

1Global: poetry run poe query --root . --method global "本文主要讲了什么"

  1. Local: poetry run poe query --root . --method local "本文主要讲了什么"

三. 利用GraphRAG加速

可以参考这一篇note: graphrag-accelerator/notebooks/1-Quickstart.ipynb at main · Azure-Samples/graphrag-accelerator (github.com)

<think>好的,我现在需要帮助用户解决在生成文本嵌入时出现的'NoneType'对象不可迭代的错误。这个问题通常发生在尝试迭代一个值为None的变量时。首先,我需要回忆一下用户提供的引用内容,特别是引用[1]和[2]。 根据引用[1],当函数返回None而不是预期的可迭代对象时,比如返回元组或列表,就会引发这个错误。例如,如果函数没有显式返回任何值,Python默认返回None,而当用户试图将None解包到多个变量时,就会报错。引用[2]中的例子也说明了类似的情况,函数在条件不满足时返回None,导致赋值失败。 现在,用户的问题出现在生成文本嵌入的GraphRAG回调文件工作流中。可能的场景是,某个函数在生成嵌入后没有正确返回结果,或者在某些条件下返回了None。接下来我需要考虑常见的导致此错误的原因和解决方法。 首先,检查相关函数是否在所有路径都有返回值。例如,在生成嵌入的函数中,是否有条件分支(如异常处理或特定条件判断)导致函数没有执行到return语句,从而返回None。需要确保所有可能的代码路径都返回可迭代对象,如列表或元组。 其次,检查是否有外部API调用或库函数返回了None。例如,如果使用第三方库生成嵌入,而该库在某些情况下(如网络错误、无效输入)返回None,那么后续的迭代操作就会失败。此时需要添加错误处理,确保即使返回None,程序也能妥善处理,比如提供默认值或抛出明确的异常。 另外,还要查看变量是否正确初始化。例如,可能在某个步骤中,变量未被正确赋值,仍然保持None,随后被传递到需要迭代的地方。例如,在回调函数中,某个中间步骤的变量未被正确更新,导致后续处理失败。 接下来,按照用户提供的解决步骤,逐步分析可能的解决方案: 1. **检查函数返回值**:确保生成嵌入的函数在所有条件下都返回可迭代对象,比如列表或字典,而不是None。例如,在引用[1]的例子中,函数需要返回list(set(...)),如果没有正确处理输入,可能返回None。 2. **异常处理**:在调用可能返回None的函数时,使用try-except块捕获异常,或者在赋值前检查返回值是否为None。例如,在解包返回值之前,先判断是否为None,避免直接解包。 3. **调试与日志**:添加打印语句或日志记录,跟踪函数返回值,确认在出错时的返回值是否为None。这有助于定位问题发生的具体位置。 4. **初始化变量**:确保所有变量在使用前都被正确初始化,避免在未赋值的情况下被使用。例如,在回调函数中,某些变量可能在未正确初始化时被传递到下游处理。 5. **第三方库检查**:如果使用了外部库生成嵌入,查阅其文档,确认在错误情况下返回的值,并据此调整代码逻辑,处理可能的None返回值。 结合用户提供的代码示例,比如在引用[1]中的merge_two_list函数,正确的做法是确保函数返回一个列表,而不是None。类似地,在生成嵌入的函数中,可能存在类似的问题,需要确保所有代码路径都有正确的返回语句。 此外,用户的问题可能出现在回调函数中,当处理文件工作流时,某些步骤未能正确传递数据,导致后续处理接收到None。例如,在GraphRAG的处理流程中,某个回调函数在处理文件时未能正确生成嵌入,返回了None,导致下一个步骤尝试迭代该结果时出错。 总结可能的问题点: - 生成嵌入的函数存在未处理的异常,导致返回None。 - 函数在某些条件下(如空输入、错误状态)未返回有效值。 - 变量在传递过程中被意外设置为None。 - 第三方库或API调用返回了None,未做检查。 解决步骤建议: 1. **审查相关函数**:检查生成嵌入的函数,确保所有分支都有返回语句,并返回适当的可迭代对象。例如,添加默认返回空列表或元组,避免返回None。 2. **添加条件检查**:在调用函数后,检查返回值是否为None,再进行后续操作。例如: ```python result = generate_embeddings(text) if result is None: # 处理错误情况 else: # 正常处理 ``` 3. **异常捕获**:使用try-except块来捕获可能的错误,并处理异常情况,避免程序崩溃。 4. **日志记录**:在关键步骤添加日志,记录函数输入输出,帮助定位问题发生的位置。 5. **单元测试**:编写测试用例,模拟可能出错的场景,验证函数在各种情况下的返回值是否符合预期。 通过以上步骤,应该能够定位并解决'NoneType'对象不可迭代的问题。</think>要解决生成文本嵌入时出现的`'NoneType' object is not iterable`错误,需重点关注**函数返回值**和**变量初始化**问题。以下是具体步骤分析: --- ### 一、错误原因分析 1. **函数未返回有效值** 若生成嵌入的函数存在条件分支未覆盖的情况(如异常处理未返回默认值),可能导致返回`None`。例如: ```python def generate_embeddings(text): if not text: # 空文本直接返回None return None # 正常处理逻辑... ``` 当`text`为空时返回`None`,后续迭代操作会触发错误。 2. **变量传递异常** 在回调函数中,若中间步骤未正确传递数据(如文件读取失败未初始化变量),可能导致下游操作接收`None`。 3. **第三方库返回异常值** 若使用的嵌入生成库在输入无效或网络错误时返回`None`,需捕获并处理此类情况。 --- ### 二、解决方案 #### 步骤1:检查生成嵌入的函数返回值 确保函数**所有代码路径**均返回可迭代对象(如列表、元组): ```python def generate_embeddings(text): if not text: return [] # 返回空列表而非None # 正常逻辑 return embeddings_list # 确保此处是可迭代对象 ``` #### 步骤2:添加返回值类型检查 在调用生成嵌入的函数后,验证返回值是否为`None`: ```python embeddings = generate_embeddings(text) if embeddings is None: raise ValueError("生成嵌入失败:返回值为None") # 正常处理embeddings ``` #### 步骤3:异常捕获与日志记录 使用`try-except`捕获潜在错误,并记录上下文信息: ```python try: embeddings = generate_embeddings(text) for item in embeddings: # 若embeddings为None会触发TypeError process(item) except TypeError as e: print(f"错误:尝试迭代None对象 - {e}") # 回退逻辑(如加载默认嵌入) except Exception as e: print(f"未知错误:{e}") ``` #### 步骤4:初始化变量并设置默认值 在回调函数中,强制初始化关键变量: ```python def file_workflow_callback(file_data): embeddings = [] if file_data is not None: embeddings = generate_embeddings(file_data) # 确保embeddings始终是列表 return {"embeddings": embeddings or []} # 若为None则返回空列表 ``` #### 步骤5:检查第三方库行为 查阅嵌入生成库的文档,确认其返回值策略。例如,若库在失败时返回`None`: ```python from embedding_library import get_embedding def safe_generate_embeddings(text): try: result = get_embedding(text) return result if result is not None else [] except ConnectionError: return [] # 网络错误时返回空列表 ``` --- ### 三、代码示例修正 假设原始问题代码类似于: ```python def get_text_embeddings(text): if len(text) < 10: # 假设对短文本不处理 return None return [compute_embedding(text)] # 调用时直接解包 embeddings = get_text_embeddings("short") for emb in embeddings: # 若embeddings为None则报错 print(emb) ``` **修正后:** ```python def get_text_embeddings(text): if len(text) < 10: return [] # 返回空列表 return [compute_embedding(text)] embeddings = get_text_embeddings("short") for emb in embeddings: # 安全迭代 print(emb) ``` --- ### 四、相关问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曼城周杰伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值