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