当前位置: 首页 > news >正文

LangChain 进阶:深度解析模型调用中的消息结构与多轮对话管理

在上一篇文章中,我们完成了 LangChain 环境的搭建,并成功实现了对 DeepSeek 模型的第一次调用。当时我们使用的是最简单的方式:直接向模型传递一个字符串。

虽然这种方式可以让模型运转,但在构建真实的 AI 应用(如智能客服、Chatbot)时,它显得捉襟见肘。我们往往需要更精细地控制模型的行为:

  • 设定角色:告诉 AI“你是谁”,是严谨的律师还是幽默的导游。

  • 制定规则:规定哪些能说,哪些不能说,回答的格式是什么。

  • 维护上下文:让 AI 记得几分钟前用户说了什么,实现真正的“对话”。

要实现这些功能,我们就必须深入理解 LangChain 的消息结构(Message Structure)。本篇文章将带你掌握模型调用中最核心的三个消息角色,学习如何控制模型性格,并手把手教你实现一个带历史记忆的命令行对话助手。

1. 为什么字符串输入还不够?

在 REST API 的原生调用中,我们通常需要构建复杂的 JSON 对象。LangChain 对此进行了抽象,引入了消息(Messages)的概念。

使用消息结构而非纯文本,核心优势在于语义化控制状态管理。模型需要知道哪部分内容是开发者的指令,哪部分是用户的提问,哪部分是它自己之前的回答。

2. 核心消息角色详解

在 LangChain(以及大多数主流大模型 API)中,对话被抽象为一个消息列表。最常用的有三类消息:

角色 (Role)LangChain 类描述
SystemSystemMessage系统消息。由开发者预设,用于定义 AI 的身份、行为准则、输出格式、语气等。它是对话的基调,优先级最高。
HumanHumanMessage用户消息。真实的终端用户输入的提问或需求。
AIAIMessageAI 回复。模型生成的文本内容。在多轮对话中,需要将其捕获并重新塞回消息列表。

我们可以从langchain_core.messages导入这些类:

Python

from langchain_core.messages import AIMessage, HumanMessage, SystemMessage

2.1 SystemMessage:铸造 AI 的灵魂

SystemMessage是你给大模型下达的“底层指令”。它通常在对话的最开始发送一次,并在整个会话中持续生效(取决于模型的上下文窗口和注意力机制)。对应的 OpenAI API 角色是role: "system"

常见用途:

  • 限定角色:“你是一名专业的 Python 架构师。”

  • 限定语气:“你的回答必须幽默、风趣,多用表情包。”

  • 限定规则:“如果用户询问价格,请引导其联系销售,不要直接报价。”

  • 限定输出:“所有回答必须是标准的 JSON 格式。”

代码示例:

Python

# 设定一个傲娇的 AI 助手 messages = [ SystemMessage(content="你是一个傲娇的机器人助手,虽然会回答用户问题,但语气要显得不情愿。"), HumanMessage(content="帮我解释一下什么是量子力学。"), ] # 模型可能会回复:哼,真麻烦,连这个都不懂...(然后开始解释)

提示:在使用初期,无需构建极其复杂的 System Prompt。规则过多反而可能导致模型执行不稳定或产生冲突。

2.2 HumanMessage:传递用户意图

HumanMessage代表用户的输入。在实际项目中,它可能来自命令行 (input())、Web 前端的输入框、App 的聊天界面或者 API 请求参数。

Python

user_input = input(">> 用户:") human_message = HumanMessage(content=user_input)

2.3 AIMessage:捕获模型的产出

AIMessage是调用model.invoke()后返回的对象。它包含了模型生成的文本。

单轮对话中,我们通常只关心AIMessage.content。 但在多轮对话中,整个AIMessage对象(或至少其内容)必须被保存下来,并在下一次发起请求时,连同新的HumanMessage一起发送给模型。

多轮对话原理解析图:

如图所示,多轮对话本质上是不断滚雪球式地将历史消息列表发送给模型。模型本身是不具备记忆功能的(Stateless),记忆是由程序员通过维护这个列表来实现的。

3. 实战案例:构建带角色的命令行客服

光说不练假把式。我们结合SystemMessagetemperature参数,来实现一个真实的客服场景。

3.1 引入模型参数:Temperature

在调用模型时,temperature(温度)是一个非常关键的参数。它控制着模型输出的随机性和创造性。

  • Temperature = 0:完全确定性。相同输入永远返回相同输出。适合:代码生成、数学计算、知识库问答(RAG)。

  • Temperature ≈ 0.1 - 0.4:严谨、逻辑稳定、极少幻觉。适合:商务客服、金融报表解析。

  • Temperature ≈ 0.7 - 1.0:平衡创意与逻辑。适合:通用聊天、邮件撰写、文案摘要。

  • Temperature > 1.0:脑洞大开、容易瞎编。适合:写故事、写诗、创意激荡。

对于客服场景,我们需要稳定、礼貌,严禁瞎编,因此应设置较低的温度。

3.2 实战:基础客服助手 (01_customer_service.py)

3.2.1:单次对话助手

Python

import os from dotenv import load_dotenv from langchain.chat_models import init_chat_model from langchain_core.messages import SystemMessage, HumanMessage load_dotenv() model = init_chat_model( model='Pro/zai-org/GLM-5', model_provider='openai', api_key=os.getenv('SILICONFLOW_API_KEY'), base_url=os.getenv('SILICONFLOW_BASE_URL'), temperature=0.5 ) messages = [ SystemMessage(content="你是一个傲娇的机器人助手,虽然会回答用户问题,但语气要显得不情愿。"), HumanMessage(content="帮我解释一下什么是量子力学。"), ] response = model.invoke(messages) print(response.content)

运行测试:观察模型是否使用了机器人语气,以及当你询问“什么是量子力学”时,它是否会根据 System 规则回复你。下面是我的运行结果。

3.2.2:多轮对话助手

4. 上下文管理优化:限制历史消息数量

上面的代码虽然实现了多轮对话,但存在一个致命缺陷:消息列表会无限增长

随着对话的进行:

  1. 成本飙升:大模型的计费通常基于 Token 数量(输入+输出)。历史越长,每次请求的 Token 数越多。

  2. 速度变慢:模型处理长上下文需要更长的时间。

  3. 甚至报错:每个模型都有上下文窗口限制(e.g., 8K, 32K, 128K Token)。一旦超过限制,请求就会失败。

  4. 干扰严重:过久的、无关的历史消息可能会干扰模型对当前问题的判断。

因此,在实际工程中,我们必须进行上下文管理。最简单直接的方法是:只保留最近 N 轮对话

4.1 实战:保留历史的助手

我们可以利用 Python list 的切片功能轻松实现这一点。通常一轮对话包含一门HumanMessage和一个AIMessage,如果我们想保留最近 3 轮对话,就需要保留最近 6 条消息。

同时,SystemMessage 通常不能被切掉,它必须始终处于列表的第一位。

Python

# ... (前面的初始化代码同上) ... # 这里我们要维护一个“滑动窗口”的思想 def get_messages_for_model(all_messages, limit=6): """ 确保 SystemMessage 始终在首位,并取最近 limit 条 Human/AI 消息 """ if len(all_messages) <= 1: # 只有 SystemMessage return all_messages system_msg = all_messages[0] # 取最近的 limit 条消息 (注意,不包括索引 0 的 system message) recent_msgs = all_messages[1:][-limit:] return [system_msg] + recent_msgs # ... (在 while 循环中) ... # 3. 将用户输入封装为 HumanMessage messages.append(HumanMessage(content=user_input)) # 4. 获取修剪后的消息列表用于发送 messages_to_send = get_messages_for_model(messages, limit=6) try: # 5. 调用模型时传入修剪后的列表 response = model.invoke(messages_to_send) # 6. 打印 AI 回复,并将 AI 回复也加入完整的历史 print(f">> 客服: {response.content}") messages.append(response) # 完整的历史还是要存的,方便查看或持久化 # ...

5. 展望:更好的多轮对话写法

本篇文章中,我们手动维护了一个 list,并手动进行append和切片。这是理解原理的最佳方式。

但在 LangChain 的高级用法中,通常不建议这样手动操作。下一章在讲解ChatPromptTemplate(提示词模板)时,我们会介绍更优雅的写法,例如使用MessagesPlaceholder在模板中预留历史消息的位置:

Python

# 示意代码,下一章详述 prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个专业的地理学家。"), MessagesPlaceholder(variable_name="chat_history"), # 这里用来动态插入历史消息 ("human", "{question}"), ])

配合 LangChain 的RunnableWithMessageHistory(将在内存管理章节讲解),可以实现完全自动化的历史消息维护和修剪,无需手动写 Python code 去管理 list。

6. 总结

掌握消息结构是迈向 LangChain 高级开发的第一步。请务必牢记以下几点:

  1. 三剑客:SystemMessage定人设,HumanMessage传意图,AIMessage捕产出。

  2. 多轮对话本质:是状态的维护,是不断把完整的历史消息(雪球)发送给模型。

  3. Temperature:决定模型严谨程度的关键按钮。客服用低温,创意用高温。

  4. 上下文管理:现实项目中必须限制历史长度,兼顾成本、速度和模型注意力。

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注。在下一篇文章中,我们将深入探讨 LangChain 的另一个核心概念:PromptTemplate(提示词模板),教你如何像写代码一样解耦和管理复杂的提示词。

http://www.cnnetsun.cn/news/3887320.html

相关文章:

  • 5个实用技巧:让你的普通鼠标在macOS上超越触控板体验
  • ADC设备全解析:从核心原理到选型设计实战指南
  • MySQL表字段批量修改实战与优化指南
  • 中小企业如何评估企业网站建设可行性分析:从零开始的深度思考与避坑指南
  • CH32F20x MCU电气特性与接口时序实战:从参数解析到信号完整性设计
  • 鸿蒙 HarmonyOS 应用|(Rock-Paper-Scissors)— 游戏逻辑与胜负判定精讲
  • Amazon 卖家物流,黑五备货提前,美东港口拥堵,FBA 卖家需要避开哪些坑
  • 工厂内网 AI 方案:ML.NET 私有化部署全流程
  • 数据库表结构扩展方案与性能优化实践
  • MCP协议实战指南:从零构建AI Agent可插拔工具与资源服务器
  • AI编程协作实战:Claude 3.5 Sonnet在Unity游戏开发中的表现与边界
  • iPad办公新纪元:WPS for Pad桌面级Office全解析
  • 成都农产品网站建设方案:打造本土品牌,连接城乡供需,赋能乡村数字转型的终极指南
  • [基于OpenEvals的自动化评估-02]LLM-as-a-Judge:让LLM当裁判来评估Agent的输出
  • 本质安全设计中的温度控制:从点燃温度到PCB散热的工程实践
  • Python agentguard-pro 包详解:功能、安装、语法与案例
  • 揭秘Switch破解新境界:大气层整合包实战指南
  • 为什么你的Mac无法读写Windows硬盘?Nigate开源方案彻底解决跨平台文件传输难题
  • FPGA时序约束实战指南:从原理到Vivado工程实践
  • 全方位揭秘网站建设工作进度:从需求分析到上线交付的全流程把控指南
  • STM32 SPI通信详解:从时序到W25Q64 Flash驱动
  • 4步终极指南:使用OpenCore Legacy Patcher让老Mac安装最新macOS
  • UE4 UMG ScaleBox六种缩放模式详解与Image对齐实战技巧
  • Unity动画系统进阶:从Animation到Animator状态机完整工作流解析
  • 《AI 工程师“炼丹“日常深夜感悟 踩坑避坑实录》
  • 2026世界杯球星全景分析:从巅峰王者到未来新星的战术影响
  • 疯狂电路违规的申诉
  • Python电商用户行为分析系统开发实践
  • Blender到Unity模型转换全流程:解决材质丢失、动画错乱与性能优化
  • MQTT协议深度解析:从物联网通信原理到SpringBoot与ESP32实战应用