关注我~第一时间学习如何更好地使用AI。
重要的不是我们是否会被AI替代,
而是我们要比被替代的人更懂AI。
大家好,上一期我们初步学习了如何利用LangChain的Chat Model来使用DeepSeek(从零开始学LangGraph(1):Chat Model --- 如何通过代码与模型对话(上))。本期我们将继续探索LangChain中与“模型使用”相关的一些细节,涉及的核心概念包括Message和Template。
Message 概述
上一期末尾,我们使用invoke方法生成了一个AIMessage,这就引出了一个与Chat Model使用相关的重要知识点,Message 。
事实上,Chat Model的定义就是一种以一个消息(Message)列表 作为输入,并将一段消息(如AIMessage)作为输出的接口。
换言之,Message是Chat Model中进行信息交流的基本单位,它用于表示聊天模型的输入与输出,以及与对话可能相关的任何额外上下文或元数据。
Message的类型
在LangChain中,Message对象包括三个要素:
- • 角色(Role) :定义Message的类型,常见角色如系统、用户;
- • 内容(Content) :代表Message的实际内容,可以是字符串、图片、视频、文档等等;
- • 元数据(Metadata) :可选项,包括根据聊天模型提供商而异的各种额外元数据,如messsage IDs、token用量等等。
【Role】Message(content="消息的内容")
根据role的不同,Message分又为了4种主要类型,包括:
- • SystemMessage :对应的角色是系统,用来设定模型的基本身份、行为模式,属于一种系统Prompt。
- • HumanMessage :对应的角色是用户,代表用户输入的信息。
- • AIMessage :对应的角色是助手(assistant),代表模型回复的消息。
- • ToolMessage :对应的角色是工具,它包含的内容主要是工具的调用。
事实上,看过我前面使用Cherry Studio进行各种MCP整活,或者在Coze中搭建智能体的教程的朋友应该会很熟,在设定智能体时,我们首先会给模型设一个系统提示,以定义它的“灵魂”,然后再去对话框中输入具体的任务需求。这样,模型就会在系统提示(对应SystemMessage )的背景下,去理解和处理用户输入的内容(对应HumanMessage )。
三种等价的Prompt格式
看到这里,有的朋友可能会疑惑,上期的示例里面,我们可没有写什么复杂的HumanMessage,不是直接就llm.invoke("hello")了吗?
这是因为,对于用户输入信息,除了前述标准格式,LangChain也支持直接以字符串的形式输入(text prompts) ,或者用OpenAI格式输入(Dictionary format) 。这意味着下列三种消息输入方式是等价的:
model.invoke("Hello")
model.invoke([{"role": "user", "content": "Hello"}])
model.invoke([HumanMessage("Hello")])
Message的基本使用方法
使用Message的最简单方法,就是将不同role的message放到一个列表中,然后将这个列表传递给model进行invoke。参考代码如下:
from langchain\_core.messages import HumanMessage, SystemMessage
messages = [
SystemMessage(content="将用户输入翻译为中文"),
HumanMessage(content="hello world!"),
]
model.invoke(messages)
可以看到,模型成功地将“hello world”翻译成了中文。
换言之,LangChain中,如果你向Chat Model传入一个包含SystemMessage和HumanMessage的列表,Chat Model就能够明白SystemMessage是在设定模型的基本行为,而HumanMessage是用户的具体输入。
关于Chat Prompt Templates
事实上,熟悉Prompt编写的朋友可能会意识到,把SystemMessage和HumanMessage的组合起来,其实就能构成一套比较完整的Prompt。
于是,在LangChain中,为了让这个作为Prompt的message列表的生成过程更加灵活、便捷,可以使用ChatPromptTemplates组件对Prompt的关键要素进行预设,形成Prompt模板。
这样,当我们向模版输入数据(这些数据可以是用户的原始输入,也可以是程序的查询结果等等),这些数据能够与Prompt模版相结合(比如为用户输入增加一个SystemMessage,或者将用户输入整理为预设的格式),从而自动构造出最终真正传递给模型的消息列表。
但需要说明的是,目前LangChain1.0版文档中似乎并没有将template作为一个核心组件来讲了。考虑到template有时还是很有用的,这里也还是补充一下相关的基本用法,感兴趣的朋友可以去探索探索。
Chat Prompt Templates的基本用法
Step 1.设置Prompt 模板
这里我使用LangChain0.3版本官方文档中的参考代码为例,完整内容如下:
from langchain\_core.prompts import ChatPromptTemplate
system\_template = "将用户输入翻译为 {language}"
prompt\_template = ChatPromptTemplate(
[
("system", system\_template),
("user", "{text}")
]
)
我们直接看第三段代码,这是构造Prompt模版的核心:
prompt\_template = ChatPromptTemplate(
[ ("system", system\_template), ("user", "{text}") ]
)
可以看到,构造模板的方法非常简单,就是向ChatPromptTemplate传递一个列表类型的参数,该列表中的每个元素是一个元组(即方括号[]内的两个圆括号()包裹的数据),而每个元组内包含的元素又依次为角色(role)和对应的内容模板。
system角色对应的模板内容,又引用了一个变量system\_template,根据第二段代码,这个变量的值为字符串"将用户输入翻译为 {language}",其中{language}是一个使用花括号的占位符,将在实际使用时被具体的语言名称替换(例如“英语”、“法语”)。同理,user角色对应的模板内容{text}也是一个占位符。
Step 2.使用Prompt 模版
我们使用ChatPromptTemplate构造出的模板对象prompt\_template,也可以使用invoke方法来生成最终用来传给大模型的提示词,代码如下:
prompt = prompt\_template.invoke({"language": "中文", "text": "hello world!"})
其中,向invoke方法传入的是一个字典结构的数据,这个字典中包含了两个键值对,其“键”分别对应着我们前面在设置模版时提前占位的{language}和{text}。
这时,我们如果打印prompt,就会发现它其实就是一个message对象的列表。
换言之,我们使用prompt\_template.invoke(),可以将一个与我们提示词模板相对应的字典结构的数据,转化为标准的LangChain消息格式,以作为提示词传递给大模型。
好了,以上就是本期的主要内容,请大家尽情探索,祝大家玩得开心!
—— END——
往期精华:
1.LangGraph学习笔记
从零开始学LangGraph(0):如何搭建基本的AI应用开发学习环境
从零开始学LangGraph(1):Chat Model --- 如何通过代码与模型对话(上)
2.COZE教程
AI工作流编排手把手指南之一:Coze智能体的创建与基本设置
AI工作流编排手把手指南之二:Coze智能体的插件添加与调用
Agent | 工作流编排指南4:萌新友好的Coze选择器节点原理及配置教程
Agent | 工作流编排指南5:长文扩写自由 — Coze循环节点用法详解
Coze工作流编排指南6:聊天陪伴类智能体基本工作流详解-快来和玛奇玛小姐姐谈心吧~
PPT自由!Coze工作流 X iSlide插件-小白也能看懂的节点参数配置原理详解
3.MCP探索
Excel-MCP应用 | 自动提取图片数据到Excel的极简工作流手把手教程
markitdown-mcp联动Obsidian-mcp | 一个极简知识管理工作流
【15合1神器】不会代码也能做高级图表!这个MCP工具让我工作效率翻了不止三倍!
【效率翻倍】Obsidian自动待办清单实现:MCP联动Prompt保姆级教程(萌新3分钟上手)
萌新靠MCP实现RPA、爬虫自由?playwright-mcp实操案例分享!
高德、彩云MCP全体验:让Cherry Studio化身私人小助理的喂饭版指南!
4.Prompt设计
干货分享 | Prompt设计心法 - 如何3步做到清晰表达需求?
