在LangChain中实现数据检索与RAG

概要

在许多应用场景中,用户提供的输入只是一个问题,而答案需要从已有的数据库或文档中检索出来。这种情况下,单纯依靠大模型的生成能力是不够的,我们需要结合外部知识源来增强模型的回答准确性。LangChain 提供了多种工具来实现这一点,其中包括检索增强生成(RAG)技术。本文将介绍如何在 LangChain 中使用 RAG 技术来增强模型的回答能力,并通过具体的代码示例展示其实现过程。

技术名词解释

数据检索
在进行数据检索时,我们通常需要一个检索器来帮助我们从外部知识源中查找相关信息。LangChain 支持多种检索器,本节将介绍如何使用向量数据库生成检索器。

RAG 技术简介
检索增强生成(RAG)是一种前沿的技术,它允许基础大模型无需额外训练即可调用特定领域的知识。RAG 可以视为给大模型装上了一个“知识外挂”,让模型能够在回答问题时利用外部数据源提供的上下文信息。

技术细节

步骤一:创建向量数据库
首先,我们需要创建一个向量数据库来存储我们的文档。这里我们使用 FAISS 和 Hugging Face 的 Embeddings 模块来生成向量表示。

from langchain_community.vectorstores import FAISS
from langchain_community.embeddings.huggingface import HuggingFaceEmbeddings

embeddings_path = "D:\\ai\\download\\bge-large-zh-v1.5"
embeddings = HuggingFaceEmbeddings(model_name=embeddings_path)

# 创建向量数据库
vectorstore = FAISS.from_texts(
    ["小明在华为工作", "熊喜欢吃蜂蜜"],
    embedding=embeddings
)

步骤二:生成检索器
有了向量数据库之后,我们可以创建一个检索器来从数据库中检索相关文档。

# 使用向量数据库生成检索器
retriever = vectorstore.as_retriever()

# 测试检索器
retriever.invoke("熊喜欢吃什么?")

retriever.invoke(“熊喜欢吃什么?”)
步骤三:集成检索器与模型
接下来,我们将检索器与一个语言模型结合起来,以便在回答问题时能够利用检索到的上下文信息。

from langchain_openai import ChatOpenAI
openai_api_key = "EMPTY"
openai_api_base = "http://127.0.0.1:1234/v1"
model = ChatOpenAI(
    openai_api_key=openai_api_key,
    openai_api_base=openai_api_base,
    temperature=0.3,
)

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 创建提示模板
template = """
只根据以下文档回答问题:
{context}

问题:{question}
"""
prompt = ChatPromptTemplate.from_template(template)

# 创建请求链
setup_and_retrieval = RunnableParallel(
    {
        "context": retriever,
        "question": RunnablePassthrough()
    }
)

chain = setup_and_retrieval | prompt | model | StrOutputParser()

# 测试请求链
chain.invoke("小明在哪里工作?")

完整链式请求
我们也可以使用链式的方式组织请求流程,这使得代码更简洁易懂。

# 完整链式请求
chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

# 测试完整链式请求
chain.invoke("小明在哪里工作?")

添加个性化元素
为了使回答更具个性化,我们可以在提示模板中加入用户的称呼。

from operator import itemgetter

# 创建带有称呼的提示模板
template = """
只根据以下文档回答问题:
{context}

问题:{question}
回答问题请加上称呼"{name}"。
"""
prompt = ChatPromptTemplate.from_template(template)

# 创建请求链
chain = (
    {
        "context": itemgetter("question") | retriever,
        "question": itemgetter("question"),
        "name": itemgetter("name"),
    }
    | prompt
    | model
    | StrOutputParser()
)

# 测试带有称呼的请求链
chain.invoke({"question":"小明在哪里工作?","name":"主人"})

加载目录中的文档
最后,如果我们要处理的是目录中的多个文档,可以使用 DirectoryLoader 来加载这些文档。

from langchain_community.document_loaders import DirectoryLoader

# 加载目录中的文档
loader = DirectoryLoader('./txt')
docs = loader.load()

小结

通过上述步骤,我们展示了如何在 LangChain 中实现数据检索与 RAG 技术。RAG 不仅能够增强模型的回答能力,还能让我们有效地利用外部数据源来提供更准确的答案。希望这篇博客能够帮助大家更好地理解和应用 LangChain 的 RAG 功能。

  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值