# 安装必要的库
! pip install langchain_community tiktoken langchain-openai langchainhub chromadb langchain langgraph
自主RAG (Self-RAG)
自主RAG是最近的一篇论文,介绍了一种用于主动RAG的有趣方法。
该框架训练单个任意的语言模型(如LLaMA2-7b, 13b)来生成控制RAG过程的标记:
-
是否从检索器检索 -
Retrieve- 标记:
Retrieve - 输入:
x (问题)或x (问题),y (生成的回答) - 决定何时使用
R检索D个片段 - 输出:
yes, no, continue
- 标记:
-
检索到的片段
D是否与问题x相关 -ISREL- 标记:
ISREL - 输入:(
x (问题),d (片段)) 对于每个d在D中 d提供解决x的有用信息- 输出:
relevant, irrelevant
- 标记:
-
每个片段
D生成的LLM回答是否与片段相关(如幻觉等) -ISSUP- 标记:
ISSUP - 输入:
x (问题),d (片段),y (生成的回答)对于每个d在D中 - 在
y (生成的回答)中所有需要验证的陈述都由d支持 - 输出:
fully supported, partially supported, no support
- 标记:
-
每个片段
D生成的LLM回答是否对x (问题)有用 -ISUSE- 标记:
ISUSE - 输入:
x (问题),y (生成的回答)对于每个d在D中 y (生成的回答)是否对x (问题)有用- 输出:
{5, 4, 3, 2, 1}
- 标记:
我们可以将其表示为一个图:

论文链接:https://arxiv.org/abs/2310.11511
让我们使用LangGraph从头开始实现这个过程。
检索器 (Retriever)
让我们索引三个博客文章。
from langchain.text_splitter import RecursiveCharacterTextSplitter # 从LangChain导入递归字符文本分割器
from langchain_community.document_loaders import WebBaseLoader # 从LangChain Community导入网页基础加载器
from langchain_community.vectorstores import Chroma # 从LangChain Community导入Chroma向量存储
from langchain_openai import OpenAIEmbeddings # 从LangChain OpenAI导入OpenAI嵌入
# 定义需要索引的博客文章URL列表
urls = [
"https://lilianweng.github.io/posts/2023-06-23-agent/",
"https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/",
"https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/",
]
# 加载每个URL的文档内容
docs = [WebBaseLoader(url).load() for url in urls]
# 将嵌套的文档列表展开为单个列表
docs_list = [item for sublist in docs for item in sublist]
# 使用递归字符文本分割器将文档分割成大小为250字符的块,且块之间没有重叠
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
chunk_size=250, chunk_overlap=0
)
doc_splits = text_splitter.split_documents(docs_list)
# 将分割后的文档添加到向量数据库
vectorstore = Chroma.from_documents(
documents=doc_splits, # 输入分割后的文档
collection_name="rag-chroma", # 指定集合名称
embedding=OpenAIEmbeddings(), # 使用OpenAI嵌入
)
# 将向量存储转化为检索器
retriever = vectorstore.as_retriever()
状态
我们将定义一个图。
我们的状态将是一个字典。
我们可以从任何图节点访问它,使用 state[‘keys’]。
from typing import Dict, TypedDict
from langchain_core.messages import BaseMessage
class GraphState(TypedDict):
"""
Represents the state of an agent in the conversation.
Attributes:
keys: A dictionary where each key is a string and the value is expected to be a list or another structure
that supports addition with `operator.add`. This could be used, for instance, to accumulate messages
or other pieces of data throughout the graph.
"""
keys: Dict[str, any]
节点和边
每个节点将简单地修改状态。
每条边将选择下一个要调用的节点。
我们可以将自助RAG表示为一个图:

import json
import operator
from typing import Annotated, Sequence, TypedDict
from langchain import hub
from langchain.output_parsers import PydanticOutputParser
from langchain.output_parsers.openai_tools import PydanticToolsParser
from langchain.prompts import PromptTemplate
from langchain_community.vectorstores import Chroma
from langchain_core.messages import BaseMessage, FunctionMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_core.runnables import RunnablePassthrough
from langchain_core.utils.function_calling import convert_to_openai_tool
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langgraph.prebuilt import ToolInvocation
### 节点 ###
def retrieve(state):
"""
检索文档
参数:
state (dict): 代理当前的状态,包括所有键。
返回:
dict: 向状态添加新键,documents,包含检索到的文档。
"""
print("---RETRIEVE---")
state_dict = state["keys"]
question = state_dict["question"]
documents = retriever.invoke(question

最低0.47元/天 解锁文章
918

被折叠的 条评论
为什么被折叠?



