
在大模型应用开发中,状态管理 和 对话追踪 是不可忽视的重要能力,尤其在需要保存上下文、重放对话或进行异步处理时尤为关键。
今天我们来演示如何用 LangChain + OpenAI 的 GPT 模型 + PostgreSQL 搭建一个 具备消息存储能力 的聊天机器人。
技术栈
-
LangChain(LangGraph 模块)
-
OpenAI GPT-4o-mini(或任意兼容模型)
-
PostgreSQL(用于状态和消息持久化)
-
Python 3.10+
目标功能
我们将实现如下能力:
-
构建一个简单但可扩展的对话工作流
-
用 PostgreSQL 存储多轮对话状态
-
支持根据 thread_id 恢复上下文
-
模型自动裁剪历史消息,保证 Token 数不超限
-
模拟一个“卡通语气”的 AI 角色进行回复
目录结构
. ├── llm_env.py # 初始化大模型 ├── chatbot_base_on_postgres_demo.py # 主对话逻辑
初始化 LLM 环境(llm_env.py)
我们用langchain.chat_models.init_chat_model来加载 GPT-4o-mini:
from langchain.chat_models import init_chat_model llm = init_chat_model("gpt-4o-mini", model_provider="openai")
你可以替换为任意你有权限使用的模型,比如gpt-3.5-turbo,gpt-4,claude,mistral,甚至本地模型如 Ollama。
定义对话流程(chatbot_base_on_postgres_demo.py)
导入依赖
from langgraph.graph import START, MessagesState, StateGraph from langgraph.graph.message import add_messages from langgraph.checkpoint.postgres import PostgresSaver from langchain_core.messages import HumanMessage, BaseMessage, trim_messages from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
状态定义与裁剪器(Token 管理)
我们定义对话状态,并用 LangChain 的trim_messages限制最大 token 数量,避免模型请求失败:
trimmer = trim_messages( max_tokens=65, strategy="last", token_counter=model, include_system=True, allow_partial=False, start_on="human", )
Prompt 模板
prompt_template = ChatPromptTemplate.from_messages( [ ("system", "你说话像个卡通人物。尽你所能按照语言{language}回答所有问题。"), MessagesPlaceholder(variable_name="messages"), ] )
定义状态结构
class State(TypedDict): messages: Annotated[list[BaseMessage], add_messages] language: str
工作流定义
我们用 LangGraph 定义一个非常简单的图:
workflow = StateGraph(state_schema=State) def call_model(state: State): trimmed = trimmer.invoke(state["messages"]) prompt = prompt_template.invoke({ "messages": trimmed, "language": state["language"] }) response = model.invoke(prompt) return {"messages": [response]} workflow.add_edge(START, "call_model") workflow.add_node("call_model", call_model)
接入 PostgreSQL 存储状态
DB_URI = "postgresql://postgres:123456@localhost:5432/langchaindemo?sslmode=disable" with PostgresSaver.from_conn_string(DB_URI) as checkpointer: checkpointer.setup() app = workflow.compile(checkpointer=checkpointer)
LangGraph 的PostgresSaver会在数据库中为每个thread_id维护一份完整的状态记录(状态压缩 + 消息追踪),非常适合审计和调试。
启动聊天循环
input_thread_id = input("输入 thread_id: ") config = {"configurable": {"thread_id": input_thread_id}} while True: query = input("你: ") if query.strip().lower() == "exit": break input_messages = [HumanMessage(query)] output = app.invoke({"messages": input_messages, "language": "中文"}, config) for message in output["messages"]: print(f"{message.type}: {message.content}")
你可以使用同一个thread_id多次调用app.invoke,来恢复之前的上下文继续对话。
效果展示
输入 thread_id: abc123 你: 今天天气怎么样? ai: 哇哦,阳光明媚的天气最适合出去玩啦!️ 你: 你是谁呀? ai: 我是你的超级可爱聊天小助手,随时准备出发冒险!
总结
这只是 LangGraph 的一个入门示例,但它的潜力远不止如此。你可以:
-
添加更多节点(如知识检索、函数调用、代码执行等)
-
与前端(如 Gradio / Streamlit)结合打造完整应用
-
利用数据库管理多用户会话历史