news 2026/4/14 16:44:20

【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程

系列文章目录

【 LangChain v1.2 入门系列教程】【一】开篇入门 | 从零开始,跑通你的第一个 AI Agent
【 LangChain v1.2 入门系列教程】【二】消息类型与提示词工程
【 LangChain v1.2 入门系列教程】【三】工具(Tools)开发,让 Agent 连接外部世界
【 LangChain v1.2 入门系列教程】【四】结构化输出,让 Agent 返回可预测的结构
【 LangChain v1.2 入门系列教程】【五】记忆管理,让 Agent 记住对话
【 LangChain v1.2 入门系列教程】【六】流式输出, 让 Agent 告别“想好了再说”


文章目录

  • 系列文章目录
  • 前言
  • 一、 LangChain 的 4 种核心消息类型
    • 1. 手动构建消息列表
    • 2. llm.invoke() 传入消息历史
    • 3.agent.invoke()传入消息历史
    • 4.ToolMessage 的传递
  • 二、提示词模板(ChatPromptTemplate)
    • 1. 基础用法(方式一)
    • 2. 基础用法(方式二)
    • 3. 基础用法(方式三)
    • 4. 基础用法(方式四)
    • 5、进阶用法(MessagesPlaceholder)
  • 三、系统提示(System Prompt)
    • 1. 系统提示词的设计原则
  • 四、 总结

前言

在上一篇中,我们完成了环境搭建并跑通了第一个 AI Agent 。本文将带你深入 LangChain v1.2 的消息机制(Messages),并学习如何用提示词模板(Prompt Templates)像搭积木一样构建稳定、可控的对话。


一、 LangChain 的 4 种核心消息类型

LangChain 使用结构化的消息对象来与聊天模型交互,每种消息对应对话中的一个角色:

消息类型角色作用
SystemMessage系统消息给 AI 设定 “人设” 和规则(比如 “你是一个资深博客专家”),通常放在对话开头。
HumanMessage用户消息用户说的话,就是直接发给 AI 的提问或指令
AIMessageAI 消息AI 回复的话
ToolMessage工具消息当 AI 调用某个工具(如上一篇中 get_weather)后,工具返回的结果

1. 手动构建消息列表

有时候我们需要手动维护把各类历史消息按顺序传回给模型,作为上下文参考。例如:

importosfromdotenvimportload_dotenvfromlangchain.messagesimportAIMessage,HumanMessage,SystemMessagefromlangchain_openaiimportChatOpenAI load_dotenv()# api_key从硅基流动后台获取API_KEY=os.getenv("API_KEY")#实例化模型llm=ChatOpenAI(model="Qwen/Qwen3-8B",# 模型名称base_url="https://api.siliconflow.cn/v1",# 硅基流动的 API 地址api_key=API_KEY,# 你的-api-key)#手动构建对话历史messages=[SystemMessage(content="你是一位翻译专家,将中文翻译成英文。"),HumanMessage(content="你好,世界"),AIMessage(content="hello, world"),HumanMessage(content="我正在写博客"),#当前问题]#调用模型response=llm.invoke(messages)print(response.content)#输出:I'm writing a blog

说明:我们最初通过系统消息定义ai的角色是一名"翻译专家“,回答规则是把输入的中文翻译成英文,第一轮用户提问“你好,世界”,ai翻译后回答“hello,world”。第二轮用户提问“我正在写博客”,ai翻译后回答“I’m writing a blog”。从该示例中我们能深刻体会SystemMessage(系统消息)的作用。

2. llm.invoke() 传入消息历史

LangChain v1.2 我们使用 llm.invoke() 方法传入消息历史获取大模型回复,入参有2种类型,除了上面示例展示的List[BaseMessage]形式外,它还支持字典格式List[dict],例如:

messages=[{"role":"system","content":"你是一位翻译专家,将中文翻译成英文。"},{"role":"user","content":"你好,世界"},{"role":"assistant","content":"hell,word"},{"role":"user","content":"我正在写博客"},]# 调用模型response=llm.invoke(messages)print(response.content)# 输出:I'm writing a blog

注意:用户消息也兼容如下写法:{“role”: “human”,“content”: “你好,世界”}

3.agent.invoke()传入消息历史

当你使用 create_agent() 创建 Agent, invoke() 方法通常要求传入一个字典,其中必须包含一个 “messages” 键,其值为消息列表(支持List[BaseMessage]或List[dict]格式),例如:

importosfromdotenvimportload_dotenvfromlangchain.agentsimportcreate_agentfromlangchain.messagesimportAIMessage,HumanMessage,SystemMessagefromlangchain_openaiimportChatOpenAI load_dotenv()# api_key从硅基流动后台获取API_KEY=os.getenv("API_KEY")# 实例化模型llm=ChatOpenAI(model="Qwen/Qwen3-8B",# 模型名称base_url="https://api.siliconflow.cn/v1",# 硅基流动的 API 地址api_key=API_KEY,# 你的-api-key)# 创建Agentagent=create_agent(model=llm)# 手动构建对话历史messages=[SystemMessage(content="你是一位翻译专家,将中文翻译成英文。"),HumanMessage(content="你好,世界"),AIMessage(content="hell,word"),HumanMessage(content="我正在写博客"),]# 调用模型response=agent.invoke({"messages":messages})print(response["messages"][-1].content)# 输出:I'm writing a blog

从上述示例可以发现agent .invoke() 跟 llm.invoke()返回值不一样,它是个字典包含“messages”字段,打印下“messages”数据:

print(response["messages"])

打印数据如下:

[SystemMessage(content='你是一位翻译专家,将中文翻译成英文。',additional_kwargs={},response_metadata={},id='9c5700dd-62b4-4e4c-9e03-21d42b307f24'),HumanMessage(content='你好,世界',additional_kwargs={},response_metadata={},id='893b5d7f-4555-4d0f-af15-2ad4bb428351'),AIMessage(content='hell,word',additional_kwargs={},response_metadata={},id='2da1c10d-f2b8-4422-aa5f-3e967abaf704',tool_calls=[],invalid_tool_calls=[]),HumanMessage(content='我正在写博客',additional_kwargs={},response_metadata={},id='973de492-98f3-4f2c-97e6-d69c3a076937'),AIMessage(content="I'm writing a blog.",additional_kwargs={'refusal':None},response_metadata={'token_usage':{'completion_tokens':6,'prompt_tokens':48,'total_tokens':54,'completion_tokens_details':{'accepted_prediction_tokens':None,'audio_tokens':None,'reasoning_tokens':0,'rejected_prediction_tokens':None},'prompt_tokens_details':None},'model_provider':'openai','model_name':'Qwen/Qwen3-8B','system_fingerprint':'','id':'019d207edbd5da788a852a998ba5082e','finish_reason':'stop','logprobs':None},id='lc_run--019d207e-db57-7e13-8cb9-e3e4bb6787c6-0',tool_calls=[],invalid_tool_calls=[],usage_metadata={'input_tokens':48,'output_tokens':6,'total_tokens':54,'input_token_details':{},'output_token_details':{'reasoning':0}})]

可以发现这是完整的消息列表,它由你传入的原始 messages 加上 AI 新生成的消息(可能还有工具调用产生的消息)合并而成。

response[“messages”][-1] 就是列表中的最后一条消息。在大多数简单场景下,它恰好是 AI 针对最后一个用户输入生成的新回复,类型为 AIMessage,其 content 属性即为回复文本。

4.ToolMessage 的传递

当 AI 调用了工具,我们需要将工具执行结果以 ToolMessage 形式传回给模型。ToolMessage 除了 content,还必须有 tool_call_id,以关联对应的工具调用。

fromlangchain_core.messagesimportToolMessage# 假设模型调用 get_weather 工具,并生成了一个 tool_call_idtool_call_id="call_123"# 构造工具返回的消息tool_message=ToolMessage(content="厦门的天气是晴朗,20°C",tool_call_id=tool_call_id)# 将 tool_message 添加到消息列表中,继续对话messages.append(tool_message)# 然后再次调用模型response=llm.invoke(messages)

二、提示词模板(ChatPromptTemplate)

手动构建消息列表虽然直观,但不够灵活。LangChain 提供ChatPromptTemplate 允许你定义消息模板,动态注入变量,重复使用模版。

1. 基础用法(方式一)

ChatPromptTemplate.from_template().format_messages() #单角色消息
fromlangchain_core.promptsimportChatPromptTemplate# 提示词模版prompt_template=ChatPromptTemplate.from_template("你是{role}专家,请用{style}风格回答问题,问题:{question}")# 格式化提示词message=prompt_template.format_messages(role="文学",style="幽默",question="讲个故事")# 调用模型response=llm.invoke(message)print(response.content)

2. 基础用法(方式二)

ChatPromptTemplate.from_template() +链式调用 #单角色消息
fromlangchain_core.output_parsersimportStrOutputParser# 提示词模版prompt_template=ChatPromptTemplate.from_template("你是{role}专家,请用{style}风格回答问题,问题:{question}")#链式调用chain=prompt_template|llm|StrOutputParser()#StrOutputParser:输出解析器:提取纯文本内容# 调用模型content=chain.invoke({"role":"文学","style":"幽默","question":"讲个故事"})print(content)

ps:| 语法是一种类似 Unix 管道的链式操作符,用于将前一个组件的输出直接作为后一个组件的输入,从而串联起提示词模板、模型和输出解析器等组件,形成一条可执行的处理链

3. 基础用法(方式三)

ChatPromptTemplate.from_messages().format_messages() #多角色消息
# 提示词模版prompt_template=ChatPromptTemplate.from_messages([("system","你是一个专业的翻译官,把{input_language}翻译成{output_language}。"),#系统消息("human","{question}"),#用户消息])#格式化消息messages=prompt_template.format_messages(input_language="中文",output_language="英文",question="你好,世界")# 调用模型response=llm.invoke(messages)print(response.content)#Hello, world.

4. 基础用法(方式四)

ChatPromptTemplate.from_messages() +链式调用 #多角色消息
# 提示词模版prompt_template=ChatPromptTemplate.from_messages([("system","你是一个专业的翻译官,把{input_language}翻译成{output_language}。"),#系统消息("human","{question}"),#人类消息])chain=(prompt_template|llm|StrOutputParser())# StrOutputParser:输出解析器:提取纯文本内容# 调用模型content=chain.invoke({"input_language":"中文","output_language":"英文","question":"你好,世界"})print(content)#hellow,world.

5、进阶用法(MessagesPlaceholder)

当需要插入不确定数量的历史消息时(如多轮对话),使用 MessagesPlaceholder动态插入消息列表

fromlangchain_core.promptsimportChatPromptTemplate,MessagesPlaceholder#构建占位符消息模版prompt_template=ChatPromptTemplate.from_messages([("system","你是一个友好的客服助手。"),MessagesPlaceholder(variable_name="chat_history"),# 这里会插入任意多条历史消息("human","{question}")#当前用户问题])# 对话历史history_messages=[AIMessage(content="您好!请问有什么可以帮您?"),HumanMessage(content="我想查一下订单状态。")]chain=prompt_template|llm|StrOutputParser()content=chain.invoke({"chat_history":history_messages,"question":"我的订单号是12345"})print(content)#您的订单处于待发货状态

三、系统提示(System Prompt)

在LangChain v1.2中推荐使用create_agent() 创建智能体方式来调用大模型,通过system_prompt参数非常方便设置系统提示(SystemMessage系统消息),例如:

#创建agentagent=create_agent(model=llm,system_prompt="你是一位翻译专家,将中文翻译成英文"#系统提示词)#调用模型response=agent.invoke({"messages":[HumanMessage('你叫什么名字?')]})print(response['messages'][-1].content)#What's your name?

1. 系统提示词的设计原则

系统提示词是影响 AI 行为最直接、成本最低的方式。好的系统提示词设计时遵循:

(1)角色定义清晰:

system_prompt=""" 你是一位精通 Python 性能优化的资深工程师,擅长识别代码中的瓶颈并给出量化改进建议。 """

(2)强制输出格式

system_prompt="""你必须严格按照以下JSON格式回复: { "thinking": "思考过程", "answer": "最终答案", "confidence": 0-1之间的数字 } 只输出JSON,不要其他内容。"""

(3)制定规则

system_prompt=""" 你必须遵守以下规则: 1. 只使用 Markdown 格式回复。 2. 每条建议前必须加上「⚠️ 风险」或「💡 建议」。 3. 禁止输出任何未经测试的代码片段。 4. 禁止使用「可能」「大概」等模糊词汇。 """

(4)设定清晰边界

system_prompt=""" 你是一个医疗信息摘要助手。 - 如果你遇到用户描述的疑似急症(如胸痛、呼吸困难),必须回答:“请立即就医,我无法提供诊断。” - 对于其他健康问题,你可以总结信息,但不得给出具体治疗建议。 """

(5)提供示例

system_prompt=""" 你是一个数学解题助手,输出格式:先列出关键步骤,再给出最终答案。 示例: 用户:2 + 3 × 4 助手: 步骤: 1. 先算乘法:3 × 4 = 12 2. 再算加法:2 + 12 = 14 最终答案:14 """

四、 总结

通过本文,我们从 LangChain 的消息体系入手,逐步掌握了以下核心技能:

  • 理解四种消息角色:SystemMessage、HumanMessage、AIMessage、ToolMessage,并学会手动构建消息列表,让 AI 在对话中“记住”上下文。

  • 灵活调用模型:无论是直接使用 llm.invoke() 传入消息列表,还是通过 agent.invoke() 传入字典格式的消息,都能轻松实现多轮对话。

  • 告别硬编码:借助 ChatPromptTemplate 和 MessagesPlaceholder,我们可以像搭积木一样动态构建提示词模板,支持变量注入、历史占位,让代码更优雅、更易维护。

  • 用好系统提示词:明确了角色定义、输出格式、边界约束等五大设计原则,并通过示例展示了如何写出“指令明确”的优质提示词。

当你掌握了消息与提示词这两大基石,LangChain 的大门才算真正向你敞开。在下一篇文章中,我们将深入 工具调用(Tool Calling),敬请期待!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 16:42:18

Audiveris:5分钟掌握免费开源乐谱识别,让纸质音乐数字化

Audiveris:5分钟掌握免费开源乐谱识别,让纸质音乐数字化 【免费下载链接】audiveris Latest generation of Audiveris OMR engine 项目地址: https://gitcode.com/gh_mirrors/au/audiveris 你是否曾为整理堆积如山的纸质乐谱而烦恼?是…

作者头像 李华
网站建设 2026/4/14 16:40:13

智能游戏助手:OnmyojiAutoScript如何彻底改变你的阴阳师游戏体验

智能游戏助手:OnmyojiAutoScript如何彻底改变你的阴阳师游戏体验 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师的日常任务感到疲惫吗?每天…

作者头像 李华
网站建设 2026/4/14 16:35:23

Agent智能体任务规划文档解析:BERT分割理解复杂指令步骤

Agent智能体任务规划文档解析:BERT分割理解复杂指令步骤 你有没有遇到过这种情况?给一个智能助手下指令,比如“帮我查一下明天北京的天气,如果下雨就提醒我带伞,然后顺便预约一下下午三点的会议室”,结果它…

作者头像 李华
网站建设 2026/4/14 16:32:18

软考(信息系统项目管理师)备考攻略 | 在职短期冲刺 + 实战复盘

6个周末日 工作日早晚坚持 写在前面 这份攻略基于我本人的真实备考经历。作为一名在职人员,我没有大块的脱产时间,备考周期严格来说是: 3个周末,共6个完整学习日每个工作日:早晨15-30分钟 晚上1-1.5小时 总学习时…

作者头像 李华
网站建设 2026/4/14 16:29:31

在 CentOS 8 上一键安装 OpenClaw AI 智能体(保姆级教程)

前言:为什么需要在 linux上装“小龙虾”? 最近 AI 智能体 OpenClaw(江湖人称“小龙虾”)火爆开发者社区。它不像传统 AI 那样只会聊天,而是能真正执行系统命令、操作浏览器、读写文件,相当于给你的服务器配…

作者头像 李华
网站建设 2026/4/14 16:28:59

给大家介绍一个免费视频/图片去水印工具

你为保存视频有水印而犯过愁吗?刷到喜欢的教程想存下来反复看,满屏水印影响观感;刷到有趣的片段想二次创作,水印成了绊脚石,找各种去水印方法不是要开会员,就是步骤繁琐到劝退,这点烦恼我全懂&a…

作者头像 李华