LangGraph-agent 系列之2——持久化
·
1. 导入必须的包
from typing import TypedDict,List,Union
from langchain_core.messages import HumanMessage,AIMessage
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
from langgraph.graph import StateGraph,START,END
-
from typing import TypedDict, List, Union- 导入 Python 类型提示工具,用于定义结构化的数据类型:
TypedDict:用于创建具有明确键和值类型的字典结构(如对话状态的定义)。List:标注列表类型,指定列表中元素的类型(如消息列表)。Union:标注 “联合类型”,表示一个变量可以是多种类型中的一种(如消息列表可包含人类消息或 AI 消息)。
- 导入 Python 类型提示工具,用于定义结构化的数据类型:
-
from langchain_core.messages import HumanMessage, AIMessage- 导入 LangChain 核心模块中定义的消息类型:
HumanMessage:封装人类用户输入的消息(如用户的提问)。AIMessage:封装 AI 生成的回复消息(如模型返回的回答)。
这两种类型是构建对话历史的基础,确保消息在流程中被正确识别和处理。
- 导入 LangChain 核心模块中定义的消息类型:
-
from langchain.chat_models import init_chat_model- 导入 LangChain 提供的通用聊天模型初始化工具,用于便捷地创建不同厂商的聊天模型实例(如 OpenAI、DeepSeek、Anthropic 等)。
通过统一的接口初始化模型,简化了不同模型之间的切换成本。
- 导入 LangChain 提供的通用聊天模型初始化工具,用于便捷地创建不同厂商的聊天模型实例(如 OpenAI、DeepSeek、Anthropic 等)。
-
from dotenv import load_dotenv- 导入
python-dotenv库的核心函数,用于从.env文件中加载环境变量(如 API 密钥、配置参数等),避免敏感信息硬编码在代码中,提升安全性。
- 导入
-
from langgraph.graph import StateGraph, START, END- 导入 LangGraph 框架的核心组件,用于构建状态流转图:
StateGraph:状态图构建器,用于定义智能体的流程节点和节点间的连接关系。START/END:系统内置的起始节点和结束节点,标记流程的起点和终点。
- 导入 LangGraph 框架的核心组件,用于构建状态流转图:
2. 加载大模型,定义消息类型
load_dotenv()
llm = init_chat_model("deepseek:deepseek-chat")
class State(TypedDict):
message:List[Union[HumanMessage,AIMessage]]
1. load_dotenv()
- 作用:调用
python-dotenv库的核心函数,从项目根目录的.env文件中加载环境变量(如 API 密钥、配置参数等)。 - 实际效果:假设
.env文件中有DEEPSEEK_API_KEY=your_api_key,执行后会将该密钥注入系统环境变量,供后续模型调用时自动读取,避免在代码中硬编码敏感信息。 - 注意:需确保
.env文件与脚本在同一目录,或通过load_dotenv(dotenv_path="路径")指定文件位置。
2. llm = init_chat_model("deepseek-chat",temperature=0.7 )
- 作用:初始化 DeepSeek 聊天模型实例,用于后续生成 AI 回复。
- 细节说明:
init_chat_model是 LangChain 提供的通用模型初始化工具,支持多种厂商的模型(通过模型名称区分)。- 可补充参数如
temperature=0.7控制回复随机性(0-1 之间,值越高回复越灵活)。 - 模型会自动从环境变量中读取
DEEPSEEK_API_KEY(由load_dotenv()加载),无需手动传入。
3. class State(TypedDict): message:List[Union[HumanMessage,AIMessage]]
- 作用:定义对话系统的状态结构,用于在流程中统一管理对话数据。
- 细节说明:
3. 定义处理信息函数
State(TypedDict):通过TypedDict定义一个结构化字典,明确规定状态中必须包含的字段及类型,确保数据格式一致。message:List[Union[HumanMessage,AIMessage]]:- 字段名
message表示 “对话消息列表”(建议用复数messages,更符合列表语义)。 List[Union[HumanMessage, AIMessage]]表示该列表可包含两种消息类型:HumanMessage(用户输入)和AIMessage(AI 回复),完整记录对话历史。
- 字段名
- 该状态会在 LangGraph 的节点间传递,确保各节点能获取完整的对话上下文。
def process(x:State)->State:
"""该节点处理用户输入的请求"""
response = llm.invoke(x["message"])
#将AI回复信息添加到状态字典中
x["message"].append(AIMessage(content=response.content))
#打印AI回复的内容
print(f"\n {response.content}")
# 打印x中当前的信息
print("CURRENT STATE:", x["message"])
return x
-
response = llm.invoke(x["message"])x["message"]是当前的对话历史(包含用户之前的输入和 AI 的回复),作为完整上下文传递给模型。llm.invoke(...)调用初始化好的 DeepSeek 模型,生成针对当前上下文的回复(response包含回复文本content)。
-
状态更新机制
x["message"].append(AIMessage(content=response.content))- 将 AI 回复的文本(
response.content)包装成 LangChain 标准的AIMessage类型(标记为 “AI 发送的消息”)。 - 把新消息添加到
x["message"]列表中,更新对话历史。由于列表是可变对象,这一修改会直接反映到整个流程的状态中,确保后续对话能基于完整历史上下文进行。
- 将 AI 回复的文本(
3. 核心价值
这个节点函数通过简洁的逻辑实现了对话系统的核心能力:
- 上下文感知:基于完整的对话历史生成回复,支持多轮对话。
- 状态自动维护:无需手动管理对话历史,通过修改
State对象实现自动更新。
4. 多轮对话
conversation_history = []
user_input = input("Enter:")
while user_input != 'exit':
conversation_history.append(HumanMessage(content=user_input))
result = app.invoke({"message":conversation_history})
conversation_history=result['message']
user_input=input('Enter:')
核心优势
- 上下文连贯性:每次调用智能体时都会传入完整的
conversation_history,确保 AI 能基于所有历史消息生成回复(支持多轮对话)。 - 状态自动同步:通过
result['message']更新对话历史,保证本地存储的消息与智能体处理后的状态完全一致,避免数据不一致问题。
5. 写入日志文件
# 将对话内容写入日志中
with open("logging.txt","w",encoding="utf-8") as file:
file.write("Your conversation log:\n")
for msg in conversation_history:
if isinstance(msg,HumanMessage):
file.write(f"you:{msg.content} \n")
elif isinstance(msg,AIMessage):
file.write(f"AI:{msg.content} \n\n")
file.write("End of Conversation")
print("Conversation saved to logging.txt")
更多推荐
所有评论(0)