构建LangChain应用程序的示例代码:38、自主RAG的概念及其实现方法,使用LangChain和OpenAI工具从头开始构建一个结合检索和生成的系统

# 安装必要的库
! pip install langchain_community tiktoken langchain-openai langchainhub chromadb langchain langgraph

自主RAG (Self-RAG)

自主RAG是最近的一篇论文,介绍了一种用于主动RAG的有趣方法。

该框架训练单个任意的语言模型(如LLaMA2-7b, 13b)来生成控制RAG过程的标记:

  1. 是否从检索器检索 - Retrieve

    • 标记:Retrieve
    • 输入:x (问题)x (问题), y (生成的回答)
    • 决定何时使用R检索D个片段
    • 输出:yes, no, continue
  2. 检索到的片段D是否与问题x相关 - ISREL

    • 标记:ISREL
    • 输入:(x (问题), d (片段)) 对于每个dD
    • d提供解决x的有用信息
    • 输出:relevant, irrelevant
  3. 每个片段D生成的LLM回答是否与片段相关(如幻觉等) - ISSUP

    • 标记:ISSUP
    • 输入:x (问题), d (片段), y (生成的回答) 对于每个dD
    • y (生成的回答)中所有需要验证的陈述都由d支持
    • 输出:fully supported, partially supported, no support
  4. 每个片段D生成的LLM回答是否对x (问题)有用 - ISUSE

    • 标记:ISUSE
    • 输入:x (问题), y (生成的回答) 对于每个dD
    • 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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hugo_Hoo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值