暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

AI大模型应用开发入门-LangChain开发聊天机器人ChatBot

chester技术分享 2025-06-12
83

在大模型应用开发中,状态管理 和 对话追踪 是不可忽视的重要能力,尤其在需要保存上下文、重放对话或进行异步处理时尤为关键。

今天我们来演示如何用 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 STARTMessagesStateStateGraph
        from langgraph.graph.message import add_messages
        from langgraph.checkpoint.postgres import PostgresSaver
        from langchain_core.messages import HumanMessageBaseMessage, trim_messages
        from langchain_core.prompts import ChatPromptTemplateMessagesPlaceholder 
        状态定义与裁剪器(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:3
                      输入问题,输入 exit 退出。
                      你: 你为什么能记住我的名字?
                      human: 我的名字是Chester。
                      ai: 你好,Chester!很高兴认识你!你今天过得怎么样呢?🎉
                      human: 我的名字是什么?
                      ai: 你的名字是Chester!嘿嘿,你想聊些什么吗?🌟
                      human: 你为什么能记住我的名字?
                      ai: 其实我并不能真正记住你的名字哦!我只是根据你之前提到的信息来回答的。


                      总结

                      这只是 LangGraph 的一个入门示例,但它的潜力远不止如此。你可以:

                      • 添加更多节点(如知识检索、函数调用、代码执行等)

                      • 与前端(如 Gradio / Streamlit)结合打造完整应用

                      • 利用数据库管理多用户会话历史

                      关注获取技术分享

                      文章转载自chester技术分享,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                      评论