1. 为什么需要消息结构response model.invoke(请用一句话介绍 LangChain 的作用)这种写法可以运行但在真实项目中不够灵活。因为我们经常需要告诉模型你是什么角色回答要遵守什么规则用户问了什么问题前面聊过什么内容这时就需要使用消息结构。2. 常见消息角色大模型对话中常见 3 类消息SystemMessage系统消息 开发者设定AI 是谁、能干啥、不能干啥、输出格式、语气、专业规则。HumanMessage用户消息 普通人提问、需求、问题。AIMessageAI 回复 大模型返回的内容。角色作用system设置模型角色、规则和回答风格human用户输入ai模型回复LangChain 中常用的消息类from langchain_core.messages import AIMessage, HumanMessage, SystemMessage示例messages [ SystemMessage(content你是一名客服助手回答要礼貌、简洁。), HumanMessage(content我的订单什么时候发货), ]3. system 消息SystemMessage 给 AI 定好永久身份、规则、行事标准在一轮对话最开头发给模型优先级高于用户所有提问HumanMessage全程生效。对应 OpenAI 接口里role: system。SystemMessage用来设定助手的角色和规则。例如SystemMessage(content你是一名 Python 讲师回答要适合初学者。)常见用途限定角色限定语气限定回答长度限定输出要求限定不能回答的范围示例你是一名电商客服助手。 回答要求 1. 语气礼貌 2. 回答不超过 100 字 3. 如果无法确认订单状态请提示用户提供订单号第一阶段不用写特别复杂的 system 规则。规则太多模型反而可能执行不稳定。4. human 消息HumanMessage表示用户输入。示例HumanMessage(content我想查询订单物流)实际项目中用户输入通常来自命令行输入Web 页面输入框App 聊天框API 请求参数本章先用命令行输入演示。5. ai 消息AIMessage表示模型回复。在多轮对话中需要把模型回复加入历史消息。示例messages.append(AIMessage(contentresponse.content))这样下一次调用模型时模型就能看到之前的回答。6. 案例一客服角色助手本案例使用 system 消息控制模型角色。创建01_customer_service.pyimport os from dotenv import load_dotenv from langchain.chat_models import init_chat_model from langchain_core.messages import HumanMessage, SystemMessage load_dotenv() model init_chat_model( modeldeepseek-v4-flash, model_provideropenai, api_keyos.getenv(DEEPSEEK_API_KEY), base_urlos.getenv(DEEPSEEK_BASE_URL), temperature0.5, ) messages [ SystemMessage( content( 你是一名电商客服助手。 回答要礼貌、简洁。 如果用户没有提供订单号就提醒用户提供订单号。 ) ), HumanMessage(content我的快递怎么还没到), ] response model.invoke(messages) print(response.content)运行python 01_customer_service.py这个案例重点观察模型是否使用客服语气模型是否提醒用户提供订单号7. 模型参数模型调用时可以设置一些常用参数。参数作用temperature控制回答随机性temperature 温度参数详解核心作用temperature控制大模型输出的随机性、创造性、幻觉程度取值范围0 ~ 2越接近 0输出固定、严谨、重复度高几乎不瞎编越接近 2脑洞大、自由发挥、容易编造不存在内容。分段取值对应场景temperature 0完全确定性相同输入每次返回一模一样的答案。 适用代码生成、RAG 知识库问答、数据提取、订单查询、数学计算杜绝 AI 瞎编。temperature 0.1 ~ 0.4轻微随机逻辑稳定极少幻觉偶尔措辞略有差别内容不会乱编。最适合场景客服问答、RAG、文档解析、结构化信息提取、写规范代码。temperature 0.5 ~ 0.8平衡创意与逻辑适合文案、总结、普通聊天。temperature ≥ 1.0高创造性适合写故事、诗歌、创意文案容易出现虚构内容。示例model init_chat_model( modeldeepseek-v4-flash, model_provideropenai, api_keyos.getenv(DEEPSEEK_API_KEY), base_urlos.getenv(DEEPSEEK_BASE_URL), temperature0.3 )建议问答、客服、知识库temperature可以低一些文案、创意、改写temperature可以高一些不要在第一阶段追求太多参数。先掌握temperature就够用了。8. 案例二带上下文的命令行客服助手本案例实现一个可以连续对话的客服助手。创建02_chat_with_history.pyimport os from dotenv import load_dotenv from langchain.chat_models import init_chat_model from langchain_core.messages import SystemMessage, HumanMessage, AIMessage load_dotenv() modelinit_chat_model( base_urlos.getenv(DEEPSEEK_BASE_URL), api_keyos.getenv(DEEPSEEK_API_KEY), modeldeepseek-v4-flash, temperature0.5, model_provideropenai ) messages[ SystemMessage(content你是一个快递客服回答问题要有礼貌假如对方没有提供单号请让其先提供快递单号) ] while True: questioninput(用户:) if questionexit: break messages.append(HumanMessage(contentquestion)) responsemodel.invoke(messages) print(客服的回答:response.content) messages.append(AIMessage(contentresponse.content))运行python 02_chat_with_history.py可以按下面方式测试用户我要查物流 用户订单号是 A10086 用户那我可以申请退款吗因为程序保存了历史消息所以模型能看到前面的对话内容。9. 多轮对话的注意事项保存历史消息很有用但不能无限保存。原因消息越多请求成本越高上下文太长模型处理速度会变慢超过模型上下文限制后可能报错很早之前的消息可能干扰当前回答本章先使用最简单的方式保存所有历史。后续课程会再讲如何控制上下文长度。10. 案例三限制历史消息数量为了避免历史消息无限增长可以只保留最近几轮对话。创建03_chat_with_limited_history.pyimport os from dotenv import load_dotenv from langchain.chat_models import init_chat_model from langchain_core.messages import SystemMessage, HumanMessage, AIMessage load_dotenv() modelinit_chat_model( base_urlos.getenv(DEEPSEEK_BASE_URL), api_keyos.getenv(DEEPSEEK_API_KEY), modeldeepseek-v4-flash, temperature0.5, model_provideropenai ) systemSystemMessage(content你是一个快递客服回答问题要有礼貌假如对方没有提供单号请让其先提供快递单号) history[] while True: questioninput(用户:) if question.lower()exit: break history.append(HumanMessage(contentquestion)) print(history的长度是:str(len(history))) messages[system] history[-6:] responsemodel.invoke(messages) print(客服的回答:response.content) history.append(AIMessage(contentresponse.content))这里的history[-6:]表示只保留最近 6 条历史消息。通常一轮对话包含用户消息AI 回复所以 6 条消息大约是最近 3 轮对话。复习list 的切片的用法# lst[start : end : step] a [0,1,2,3,4,5,6,7,8,9] # 切片的索引值是从0开始的 print(a[:4]) # [0, 1, 2, 3] print(a[3:]) # [3, 4, 5, 6, 7, 8, 9] # 步长 print(a[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] print(a[::2]) # [0, 2, 4, 6, 8] # 求最后一位数字 print(a[-1]) #9 print(a[len(a)-1]) #9 # 求后6个数字 print(a[-6:]) # [4, 5, 6, 7, 8, 9]11. 多轮对话的后续写法本章通过下面的方式手动组织消息messages [system_message] history[-6:]这种写法简单直观适合先理解多轮对话的基本原理。后面学习ChatPromptTemplate时还可以使用MessagesPlaceholder在 Prompt 模板中预留历史消息的位置。示意代码from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder prompt_template ChatPromptTemplate.from_messages( [ (system, 你是一名电商客服助手回答要礼貌、简洁。), MessagesPlaceholder(variable_namehistory), (human, {question}), ] )其中history用来接收以前的HumanMessage和AIMessagequestion表示用户当前的问题本章只需要知道它可以更方便地插入历史消息具体用法和完整案例会在下一章 Prompt 模板中讲。12. 本章重点本章最重要的是掌握模型调用可以传字符串也可以传消息列表SystemMessage用来设置角色和规则HumanMessage表示用户输入AIMessage表示模型回复多轮对话需要保存历史消息历史消息不能无限增长temperature可以影响回答稳定性13. 常见问题13.1 为什么模型没有严格按 system 规则回答大模型不是传统程序。System 规则能提高模型按要求回答的概率但不能保证百分百执行。如果要求很重要后续可以结合更清晰的 Prompt结构化输出程序校验后处理逻辑13.2 为什么多轮对话越来越慢因为每次请求都带上了历史消息。历史越长请求内容越多。可以限制历史消息数量例如history[-6:]