第一章:基于Docker环境快速搭建LangChain框架的智能对话系统:从langchain环境搭建到多轮对话代码实现(大语言模型加载)
文章目录
- 前言
- 一、langchain环境搭建
- 1、docker容器搭建
- 2、docker容器连接
- 修改密码
- 容器内容修改
- 物理机修改
- 3、langchain安装
- 二、langchain构建简单智能对话示例
- 1、基于deepseek的简单问答Demo
- 2、langchain的invoke、stream与astream生成方法
- 1、langchain的invoke、stream与astream含义
- invoke 含义
- stream 含义
- astream 含义
- 2、langchain的invoke、stream代码示例
- 三、构建历史对话方法
- 1、历史对话示例代码
- 2、HumanMessage示例说明
前言
在当今的技术发展中,大语言模型(LLMs)的出现极大地简化了智能对话系统的构建。LangChain作为一个强大的框架,为开发者提供了灵活且全面的工具集,使得即使是复杂的多轮对话系统也能轻松实现。
本指南将简要介绍如何使用Docker快速搭建LangChain环境,并通过实例展示从简单的问答到带有历史记录的多轮对话的构建方法。首先,我们会学习如何利用Docker部署一个支持GPU的环境,以加速应用运行。然后,我们将了解如何安装LangChain及通过API调用语言模型进行交互。最后,我们将探讨如何使用LangChain维护对话历史,创建自然流畅的人机对话体验。
无论你是想提升项目的智能化水平,还是打算开发新的AI助手,本文都将提供必要的指导和技术点拨。让我们一起探索LangChain,开启智能对话系统的新旅程。
一、langchain环境搭建
我采用docker容器方法来搭建环境,我将给出容器搭建与虚拟环境构建方法。
1、docker容器搭建
镜像构建容器:
docker run --gpus all -itd -p 9891:6861 --ipc=host --name agent -v /home:/home nvidia/cuda:12.1-ubuntu22.04 /bin/bash
启动容器:
docker exec -it dcee /bin/bash
ssh安装:
sudo apt update #更新数据
sudo apt upgrade #更新软件
sudo apt install openssh-server #下载安装ssh服务的服务器
sudo apt install openssh-client #下载安装ssh服务的客户端
2、docker容器连接
修改密码
passwd
容器内容修改
# 修改容器ssh命令
vim /etc/ssh/sshd_config
# 修改内容
# port值修改为6861
# PermitRootLogin prohibit-password 打开该命令,修改为:PermitRootLogin yes
# 重启服务
service ssh restart
物理机修改
ssh -p 9891 root@191.164.0.96
参考博客:点击这里
3、langchain安装
我也以为langchain安装较为复杂,结果只需一个命令即可搞定,命令如下:
pip install -U langchain
如果你需要安装其它库,通常直接使用pip命令即可。我也给出了一份参考资料:点击这里
二、langchain构建简单智能对话示例
1、基于deepseek的简单问答Demo
我们是将deepseek模型作为语言模型来构建的问答内容,我是调用API KEY的方式,而使用是OpenAI的接口。这里,key可以从各个大模型官网进行申请。当然,也可以本地通过ollma等框架构建本地大语言模型,再转换成openai模式的api key方式调用(至于不使用openai key方式调用,我后期内容会给出教程)。我给出一个简单问答demo,其代码如下:
from langchain_openai import ChatOpenAI
import os
os.environ["OPENAI_API_KEY"] = "sk-h7E1zMfVCiF8mYQ0Aa4fDb23E4Bb4f3fAc0aKf3dB57aC62"
os.environ["OPENAI_API_BASE"] = "http://146.191.235.17:18800/v1"llm = ChatOpenAI(model="deepseek")
res = llm.invoke("2+2等于多少")print(res) # 你的模型版本是什么
其结果如下:
2、langchain的invoke、stream与astream生成方法
既然涉及到大语言模型调用,我不得不给出生成方法,我只介绍2类方法,包含invoke与stream,并给出代码说明。
1、langchain的invoke、stream与astream含义
invoke 含义
invoke
是 LangChain 中最基础的同步调用方式,用于一次性获取语言模型生成的完整结果。它适用于快速生成短文本或测试模型输出效果的场景。使用 invoke
时,程序向语言模型发送请求并等待完整的响应,期间主线程被阻塞,直到获得包含整个生成内容的对象(如 AIMessage
)。此方法简单易用,适合开发和测试阶段,但由于其阻塞性质,不适合需要实时交互的应用。特别适用于生成问答、摘要等较短文本内容,以及无需逐步显示结果的场景。
stream 含义
stream
是 LangChain 中实现语言模型生成内容流式输出的同步方法,适用于需实时显示生成内容的应用场景。当调用 stream
时,程序向语言模型发送请求,并通过生成器逐步接收部分结果,直至生成完成。尽管是流式处理,但它是同步的,因此会阻塞主线程。这种方法支持逐步返回生成结果,非常适合提升用户体验,特别是在聊天应用或长文本生成中,可以分段显示内容,避免用户长时间等待。
astream 含义
astream
是 LangChain 中为异步编程设计的流式输出方法,允许在不阻塞主线程的情况下逐步获取语言模型生成的结果,非常适合高并发或异步框架中的应用。与同步的 stream
不同,astream
返回一个异步生成器,可以通过 async for
循环逐步获取结果。由于其非阻塞特性,astream
非常适合构建高效的异步Web服务或处理多用户同时请求的场景。这使得它成为追求高性能和良好用户体验的开发者的理想选择,尤其是在需要动态内容更新或实时数据处理的应用中。
2、langchain的invoke、stream代码示例
这里,我将给出langchain使用大语言模型推理生成的内容,我给出invoke与stream的代码示例,而astream与stream效果相差不大,不再给出。
同样,我使用api key的方式来调用,invoke与stream代码如下:
from langchain_openai import ChatOpenAI
import os
os.environ["OPENAI_API_KEY"] = "sk-h7E1zMfVCiF8mYQ0Aa4fDb23E4Bb4f3fAc0aKf3dB57aC62"
os.environ["OPENAI_API_BASE"] = "http://146.191.235.17:18800/v1"
llm = ChatOpenAI(model="deepseek")def invoke_output():res = llm.invoke("请用100字介绍 LangChain 的核心功能。使用中文回答。")print(res) # 你的模型版本是什么from langchain.schema import HumanMessage
# 定义流式输出处理函数
def stream_response(prompt: str):# 创建消息对象messages = [HumanMessage(content=prompt)]results = llm.stream(messages)# 调用 .stream 方法for chunk in results:print(chunk.content, end="", flush=True) # 逐块输出
def stream_output():prompt = "请用100字介绍 LangChain 的核心功能。使用中文回答。"stream_response(prompt)if __name__ == "__main__":invoke_output()stream_output()
其结果如下图所示:
上面红框是invoke结果,而下面是stream结果。
三、构建历史对话方法
为什么需要构建历史对话内容?因为,我们很多时候构建的大模型是多轮对话,因此有必要熟悉与构建具有历史的对话内容。而langchain中具有历史保存信息内容,我这里介绍三种,from langchain.schema import HumanMessage, AIMessage, SystemMessage
。
1、历史对话示例代码
我们构建了如下代码,代码中有注解,我不在介绍了,其代码如下:
from langchain.schema import HumanMessage, AIMessage, SystemMessage
from langchain_openai import ChatOpenAI # 假设这是您的语言模型模块def get_language_model():# 定义API密钥,用于访问语言模型的API服务api_key = "sk-h7E1zMfVCiF8mYQ0Aa4fDb234Bb4f3fAc0aFfdB57aC260"# 定义API的基础URL,即语言模型API服务的主机地址和端口api_base = "http://164.120.215.17:18800/v1"# 创建一个ChatOpenAI对象,指定使用的模型为"deepseek",并传入API密钥和API基础URLllm_model = ChatOpenAI(model="deepseek", openai_api_key=api_key, openai_api_base=api_base)# 返回创建的语言模型对象return llm_modelif __name__ == "__main__":# 构建对话历史messages = [SystemMessage(content="你是一个乐于助人的助手,总是提供友好和有建设性的回答。"),HumanMessage(content="你好!"),AIMessage(content="你好,有什么可以帮你的?"),HumanMessage(content="请介绍一下 LangChain。")]# 获取语言模型实例llm = get_language_model()# 使用stream方法获取并打印AI生成的回答print("AI:", end="", flush=True)for chunk in llm.stream(messages):print(chunk.content, end="", flush=True)
其结果如下:
注:上面SystemMessage内容也可屏蔽,历史对话可以一直添加。这个好处在于,在多轮对话中我们不管输出内容,直接添加即可。
2、HumanMessage示例说明
好了,上面介绍了HumanMessage, AIMessage, SystemMessage。这里,以HumanMessage作为示例,给出langchain的源码内容,其源码如下:
class HumanMessage(BaseMessage):"""Message from a human.HumanMessages are messages that are passed in from a human to the model.Example:.. code-block:: pythonfrom langchain_core.messages import HumanMessage, SystemMessagemessages = [SystemMessage(content="You are a helpful assistant! Your name is Bob."),HumanMessage(content="What is your name?")]# Instantiate a chat model and invoke it with the messagesmodel = ...print(model.invoke(messages))"""example: bool = False"""Use to denote that a message is part of an example conversation.At the moment, this is ignored by most models. Usage is discouraged.Defaults to False."""
其代码示例如下:
messages = [HumanMessage(content="你好!"),AIMessage(content="你好,有什么可以帮你的?"),HumanMessage(content="请介绍一下 LangChain。")
]
for chunk in llm.stream(messages):print(chunk.content, end="", flush=True)