云原生 API 网关 APISIX 入门教程
零基础构建基于LangChain的聊天机器人
你可能已经与大型语言模型(LLMs)互动过,比如OpenAI的ChatGPT背后的模型,它们能够回答问题、总结文档、编写代码等,功能非常出色。虽然LLMs本身就很了不起,但如果有一点编程知识,你可以利用像LangChain这样的库来创建自己的LLM驱动的聊天机器人,几乎可以做任何事情。
在企业环境中,创建LLM驱动的聊天机器人最受欢迎的方法之一是通过检索增强生成(RAG)。当你设计一个RAG系统时,使用一个检索模型来检索相关信息,通常是从数据库或语料库中,将这些检索到的信息提供给LLM以生成与上下文中相关的响应。
在本教程中,将针对一家大型医院系统,构建一个基于LangChain的RAG聊天机器人,使用Neo4j检索有关患者、就医体验、医院位置、询问、费用支付和医生等有关数据。
在本教程中,将学习如何:
- 使用LangChain构建自定义聊天机器人
- 根据对业务需求和医院系统数据的理解设计聊天机器人
- 使用图数据库
- 设置Neo4j AuraDB实例
- 构建一个从Neo4j检索结构化和非结构化数据的RAG聊天机器人
- 使用FastAPI和Streamlit部署聊天机器人
★
点击下面的链接下载本项目的完整源代码和数据:
https://github.com/realpython/materials/tree/master/langchain-rag-app/
预期成果:一个带有LangChain和Neo4j的LLM RAG聊天机器人
到本教程结束时,你将拥有一个为你的LangChain聊天机器人提供服务的REST API。你还将拥有一个Streamlit应用程序,为你的API提供了一个不错的聊天界面。
在幕后,Streamlit应用程序将消息发送给聊天机器人API,聊天机器人生成并发送响应回Streamlit应用程序,然后显示给用户。
在本教程中,你将学习如何处理每个步骤,从理解业务需求和数据到构建Streamlit应用程序。教程中还有很多内容需要消化,但不会让你感到不知所措,因为教程中会对每个引入的概念提供足够的背景知识,以及可以为加深理解而提供的外部资源链接。
现在,是时候深入学习了!
前置条件
本教程最适合希望获得创建自定义聊天机器人实践经验的中级Python开发人员。
★
如果没有达到Python中级开发者的要求,请学习课程《Python自学教程》,此课程从基础开始,但是能直接引导学习者达到中级开发者水平。课程地址链接:https://yantucs.com/series/XL100116xxxxxx ,且在该网站上学习,还能使用 AI 智能问答服务。
除了中级Python知识外,还需要对以下概念和技术有必要的理解:
上述列表中没有硬性前提条件,所以如果对它们中的任何一个不太了解,也不用担心,在学习过程中会逐步介绍每个概念和技术。此外,在本教程中你还可以通过自己的实践操作,掌握这些技术,没有比这更好的学习方法了。
项目概览
在整个教程中,将创建几个目录,这些目录构成了最终的聊天机器人。以下是每个目录的详细说明:
langchain_intro/
建演示聊天机器人所需的工具,但不包括在最终的聊天机器人中。data/
存储以CSV文件形式存储的原始医院系统数据。在步骤 2 中使用这些数据。在步骤 3 中,将把这些数据移动到 Neo4j 数据库中,聊天机器人将查询该数据库以回答问题。hospital_neo4j_etl/
包含一个脚本,该脚本从data/
中加载原始数据到 Neo4j 数据库中。在构建聊天机器人之前,必须运行此脚本,在步骤 3 中会了解到有关设置 Neo4j 实例的所有方法。chatbot_api/
是 FastAPI 应用程序,它作为REST终端为聊天机器人提供服务,并且是这个项目所交付的产品。chatbot_api/src/agents/
和chatbot_api/src/chains/
子目录包含组成聊天机器人的LangChain对象,稍后会了解代理和链是什么,但现在只需要知道,聊天机器人实际上是由链和函数组成的LangChain代理。tests/
包括两个脚本,用于测试聊天机器人回答一系列问题的速度。这将让你感受到通过向像OpenAI这样的LLM提供商发出异步请求来节省多少时间。chatbot_frontend/
是Streamlit应用程序,它与chatbot_api/
中的聊天机器人终端交互,这是在最终产品中看到的UI,将在步骤 5 中构建它。
构建和运行聊天机器人所需的所有环境变量存储在.env
文件中,并使用Docker容器部署hospital_neo4j_etl/
、chatbot_api
和chatbot_frontend
中的代码,这些容器由Docker Compose创建。
有了项目概览和前提条件,下面就开始第一步——熟悉LangChain。
第1步:熟悉LangChain
在设计和开发聊天机器人之前,需要知道如何使用LangChain。在本节中,将通过构建医院系统聊天机器人的初步版本来了解LangChain的主要内容和功能。
创建一个虚拟环境,确保安装了Python 3.10或更高版本。
★
创建虚拟环境的方法,请参考:https://lqpybook.readthedocs.io/en/latest/chapter11.html#id8
或者参考视频教程:https://yantucs.com/series/XL100116xxxxxx
激活虚拟环境并安装以下库:
(venv) $ python -m pip install langchain==0.1.0 openai==1.7.2 langchain-openai==0.0.2 langchain-community==0.0.12 langchainhub==0.1.14
还需要安装 python-dotenv
来管理环境变量:
(venv) $ python -m pip install python-dotenv
python-dotenv
从.env
文件中加载环境变量到 Python 环境中,这在开发聊天机器人时非常方便。然而,最终将使用 Docker 部署聊天机器人,Docker 可以处理环境变量,就不再需要 python-dotenv
了。
然后从本教程的材料或GitHub仓库下载reviews.csv
文件。
接下来,打开项目目录并添加以下文件夹和文件:
./
│
├── data/
│ └── reviews.csv
│
├── langchain_intro/
│ ├── chatbot.py
│ ├── create_retriever.py
│ └── tools.py
│
└── .env
data/
中的reviews.csv
文件是刚刚下载的,目录中的其余文件应该是空的。
现在已经准备好使用 LangChain 开始构建第一个聊天机器人了!
聊天模型
LangChain 的核心组件是 LLM。LangChain 为使用 LLM 提供商(如OpenAI、Cohere、HuggingFace、Anthropic、Together AI等)提供了一个模块化接口。在大多数情况下,只需要从LLM提供商那里获得一个API密钥,就可以开始使用LangChain中的LLM了。LangChain还支持托管在自己机器上的LLM或其他语言模型。
本教程中使用OpenAI,但请记住,有许多优秀的开源和闭源提供商。可以根据应用程序的需求和成本限制测试不同的提供商并进行优化。在继续之前,请确保已经注册了OpenAI账户,并且拥有一个有效的API密钥。
一旦有了OpenAI API密钥,就将其添加到的.env
文件中:
OPENAI_API_KEY=<YOUR-OPENAI-API-KEY>
虽然可以直接与LangChain中的LLM对象交互,但更常见的抽象是聊天模型。聊天模型在底层使用LLM,它们专为对话而设计,并且它们与聊天消息而不是原始文本交互。
通过聊天消息,向LLM提供了关于你要发送的消息类型的额外详细信息。所有消息都具有角色和内容属性。角色告诉LLM谁在发送消息,内容就是消息本身。以下是最常用的消息类型:
HumanMessage
:与语言模型交互的用户的一条消息。AIMessage
:来自语言模型的消息。SystemMessage
:告诉语言模型如何表现的消息。并非所有提供商都支持SystemMessage。
还有其他类型的消息,如 FunctionMessage
和 ToolMessage
,当构建代理时,将了解更多关于它们的内容。
在LangChain中开始使用聊天模型很简单。要实例化一个OpenAI聊天模型,到langchain_intro
子目录并添加以下代码到chatbot.py
中:
# langchain_intro/chatbot.py(这一行说明的是文件路径,不是该文件中的代码内容。下同。)
import dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
chat_model = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
首先导入 dotenv
和 ChatOpenAI
。然后调用 dotenv.load_dotenv()
,它读取并存储来自.env
的环境变量。默认情况下,dotenv.load_dotenv()
假定.env
位于当前工作目录中,但如果.env
位于其他位置,你可以传递其他目录的路径。
然后,使用 GPT 3.5 Turbo 作为基础LLM实例化一个 ChatOpenAI
模型,并将温度(temperature
)设置为 0
。OpenAI提供了具有不同价格和性能的模型,GPT 3.5 turbo 对初学者比较合适,因为它在许多用例中表现良好,而且比GPT 4 更便宜。
打开项目目录后,启动一个Python解释器(在 Python 交互模式中),并运行以下代码,即可以使用 chat_model
:
>>> from langchain.schema.messages import HumanMessage, SystemMessage
>>> from langchain_intro.chatbot import chat_model
>>> messages = [
... SystemMessage(
... content="""You're an assistant knowledgeable about
... healthcare. Only answer healthcare-related questions."""
... ),
... HumanMessage(content="What is Medicaid managed care?"),
... ]
>>> chat_model.invoke(messages)
AIMessage(content='Medicaid managed care is a healthcare delivery system
in which states contract with managed care organizations (MCOs) to provide
healthcare services to Medicaid beneficiaries. Under this system, MCOs are
responsible for coordinating and delivering healthcare services to enrollees,
including primary care, specialty care, hospital services, and prescription
drugs. Medicaid managed care aims to improve care coordination, control costs,
and enhance the quality of care for Medicaid beneficiaries.')
在这段代码块中,导入了 HumanMessage
和 SystemMessage
,以及 chat_model
。然后定义了一个包含一个SystemMessage
和一个HumanMessage
的列表,并通过chat_model.invoke()
运行。在底层,chat_model
向OpenAI的服务端发出请求,该服务端提供gpt-3.5-turbo-0125
,并将结果作为AIMessage
返回。
正如上述操作所见,聊天模型回答了HumanMessage
中提供的“What is Medicaid managed care?”,如果想知道聊天模型在这种情况下对SystemMessage
做了什么。注意观察问以下问题时会发生什么:
>>> messages = [
... SystemMessage(
... content="""You're an assistant knowledgeable about
... healthcare. Only answer healthcare-related questions."""
... ),
... HumanMessage(content="How do I change a tire?"),
... ]
>>> chat_model.invoke(messages)
AIMessage(content='I apologize, but I can only provide assistance
and answer questions related to healthcare.')
正如前面所述,SystemMessage
告诉模型怎么做,上面的示例中,告诉模型只回答与医疗保健相关的问题。这就是为什么它拒绝回答如何换轮胎的原因(“How do I change a tire?”)。通过文本指令控制LLM与用户的关系,也就是通过提示工程(prompt engineering)是创建定制聊天机器人的基础。
聊天消息是一个很好的抽象,并且有助于确保向LLM提供了正确类型的消息,当然, 也可以将原始字符串输入到 chat_model
中:
>>> chat_model.invoke("What is blood pressure?")
AIMessage(content='Blood pressure is the force exerted by
the blood against the walls of the blood vessels, particularly
the arteries, as it is pumped by the heart. It is measured in
millimeters of mercury (mmHg) and is typically expressed as two
numbers: systolic pressure over diastolic pressure. The systolic
pressure represents the force when the heart contracts and pumps
blood into the arteries, while the diastolic pressure represents
the force when the heart is at rest between beats. Blood pressure
is an important indicator of cardiovascular health and can be influenced
by various factors such as age, genetics, lifestyle, and underlying medical
conditions.')
在这个代码块中,将字符串“What is blood pressure?”直接传递给chat_model.invoke()
。如果想在没有SystemMessage
的情况下控制LLM的行为,可以在输入字符串中包含 prompt。
接下来,将学习一种模块化的方法来指导模型响应,就像用SystemMessage
做的那样,这使得定制个性化的聊天机器人更容易。
文章转自微信公众号@CS创新实验室