如何用LangGraphRAG为?

摘要:在本系列的开篇,我们利用create_agent工厂函数编写了一个RAG例子,这是一个将指定博文内容作为上下文的QA应用。现在我们使用LangGraph的编程模式重现实现它,并添加如下两个功能: 查询和上下文相关性评估:在利用查询文本从Ve
在本系列的开篇,我们利用create_agent工厂函数编写了一个RAG例子,这是一个将指定博文内容作为上下文的QA应用。现在我们使用LangGraph的编程模式重现实现它,并添加如下两个功能: 查询和上下文相关性评估:在利用查询文本从VectorStore检索出相关内容之后,我们利用LLM评估它们之间是否具有相关性; 重新生成查询:如果没有通过相关性评估,我们会利用LLM重新生成具有更高质量的查询文本,并重启QA流程; 整个流程如下图所示:入口节点“retrieve_context”利用查询文件检索博文内容,并将其作为上下文;如果通过了上述的相关性评估,直接转入“generate_response”节点生成回答,否则转入“regenerate_query”节点重新生成更高质量的查询文本。“regenerate_query”节点完成后再次转向入口节点重启流程。接下来我们分步骤介绍整个应用的实现。 步骤一: 检索上下文 我们首先通过如下的步骤创建作为上下文检索器的Retriever对象:我们利用WebBaseLoader加载博文内容并转换成Document列表,后者被RecursiveCharacterTextSplitter切割之后生成的切片被添加到创建的InMemoryVectorStore中,最后调用InMemoryVectorStore的as_retriever方法得到所需的检索器。 loader = WebBaseLoader( web_paths=("https://www.cnblogs.com/artech/p/inside-asp-net-core-framework.html",), bs_kwargs={"parse_only": SoupStrainer(class_=("postBody"))}, ) documents = loader.load() splitter = RecursiveCharacterTextSplitter( chunk_size=1000, chunk_overlap=200, add_start_index=True, ) retriever = ( InMemoryVectorStore.from_documents( documents=splitter.split_documents(documents), embedding=OpenAIEmbeddings(model="text-embedding-3-small"), ).as_retriever() ) 我们定义了如下的State作为整个执行流程的状态Schema类型。为了让大家了解整个流程的执行情况,我们会将每个步骤的执行信息以日志的形式写入log变量表示的列表。 log =[] class State(TypedDict): query: str context: str result:str generate_times: Annotated[int,operator.add] State类型具有如下四个成员: query:查询文本,可以是用户输入的原始查询文本,也可以是在相关性评估失败后重新生成的查询; context: 根据查询文本检索得到的作为上下文的文本; result:最终的回答; generate_times:如果评估一直失败,“检索-评估-查询"循环将会一直持续下去,generate_times对查询再生成进行计数; 如下所示的retrieve_context为“上下文检索”节点函数,只需要直接调用Retriever对象,将格式化后的检索内容用于更新状态的context成员。在方法返回之前,我们将检索信息写入日志。
阅读全文