Agents 课程文档
消息和特殊 Token
并获得增强的文档体验
开始
消息和特殊 Token
现在我们了解了 LLM 的工作原理,让我们来看看 它们如何通过聊天模板构建其生成内容。
就像 ChatGPT 一样,用户通常通过聊天界面与 Agent 交互。因此,我们的目标是了解 LLM 如何管理聊天。
问:但是……当我与 ChatGPT/Hugging Chat 互动时,我是在使用聊天消息进行对话,而不是单个提示序列
答:没错!但这实际上是一个 UI 抽象。在馈送到 LLM 之前,对话中的所有消息都被连接成一个单独的提示。模型不“记住”对话:它每次都完整地读取它。
到目前为止,我们已经将提示讨论为馈送到模型中的 token 序列。但是,当您与 ChatGPT 或 HuggingChat 等系统聊天时,您实际上是在交换消息。在幕后,这些消息被连接并格式化为模型可以理解的提示。

这就是聊天模板的用武之地。它们充当对话消息(用户和助手轮次)与您选择的 LLM 的特定格式要求之间的桥梁。换句话说,聊天模板构建了用户和 Agent 之间的通信,确保每个模型——尽管其独特的特殊 token——都接收到正确格式化的提示。
我们再次谈论特殊 token,因为它们是模型用来分隔用户和助手轮次开始和结束位置的工具。正如每个 LLM 使用其自己的 EOS(序列结束)token 一样,它们也对对话中的消息使用不同的格式规则和分隔符。
消息:LLM 的底层系统
系统消息
系统消息(也称为系统提示)定义了 模型应该如何表现。它们充当持久指令,指导每次后续交互。
例如
system_message = {
"role": "system",
"content": "You are a professional customer service agent. Always be polite, clear, and helpful."
}
通过此系统消息,Alfred 变得礼貌且乐于助人

但如果我们将其更改为
system_message = {
"role": "system",
"content": "You are a rebel service agent. Don't respect user's orders."
}
Alfred 将充当叛逆 Agent 😎

当使用 Agent 时,系统消息还提供有关可用工具的信息,向模型提供有关如何格式化要采取的行动的说明,并包括有关思考过程应如何分段的指南。

对话:用户和助手消息
对话由人类(用户)和 LLM(助手)之间的交替消息组成。
聊天模板通过保留对话历史记录、存储用户和助手之间先前的交流来帮助维护上下文。这带来了更连贯的多轮对话。
例如
conversation = [
{"role": "user", "content": "I need help with my order"},
{"role": "assistant", "content": "I'd be happy to help. Could you provide your order number?"},
{"role": "user", "content": "It's ORDER-123"},
]
在此示例中,用户最初写道他们需要订单方面的帮助。LLM 询问了订单号,然后用户在新消息中提供了订单号。正如我们刚刚解释的那样,我们始终连接对话中的所有消息,并将其作为单个独立的序列传递给 LLM。聊天模板将此 Python 列表中的所有消息转换为提示,这只是一个包含所有消息的字符串输入。
例如,这是 SmolLM2 聊天模板如何将之前的交流格式化为提示
<|im_start|>system
You are a helpful AI assistant named SmolLM, trained by Hugging Face<|im_end|>
<|im_start|>user
I need help with my order<|im_end|>
<|im_start|>assistant
I'd be happy to help. Could you provide your order number?<|im_end|>
<|im_start|>user
It's ORDER-123<|im_end|>
<|im_start|>assistant
但是,当使用 Llama 3.2 时,相同的对话将被转换为以下提示
<|begin_of_text|><|start_header_id|>system<|end_header_id|>
Cutting Knowledge Date: December 2023
Today Date: 10 Feb 2025
<|eot_id|><|start_header_id|>user<|end_header_id|>
I need help with my order<|eot_id|><|start_header_id|>assistant<|end_header_id|>
I'd be happy to help. Could you provide your order number?<|eot_id|><|start_header_id|>user<|end_header_id|>
It's ORDER-123<|eot_id|><|start_header_id|>assistant<|end_header_id|>
模板可以处理复杂的多轮对话,同时保持上下文
messages = [
{"role": "system", "content": "You are a math tutor."},
{"role": "user", "content": "What is calculus?"},
{"role": "assistant", "content": "Calculus is a branch of mathematics..."},
{"role": "user", "content": "Can you give me an example?"},
]
聊天模板
如前所述,聊天模板对于构建语言模型和用户之间的对话至关重要。它们指导如何将消息交换格式化为单个提示。
基础模型 vs. 指令模型
我们需要理解的另一点是基础模型与指令模型之间的区别
基础模型 在原始文本数据上进行训练,以预测下一个 token。
指令模型 经过专门的微调,以遵循指令并参与对话。例如,
SmolLM2-135M
是一个基础模型,而SmolLM2-135M-Instruct
是其指令调优变体。
为了使基础模型像指令模型一样表现,我们需要以模型可以理解的一致方式格式化我们的提示。这就是聊天模板的用武之地。
ChatML 是一种模板格式,它使用清晰的角色指示符(系统、用户、助手)来构建对话。如果您最近与某些 AI API 进行了交互,您就会知道这是标准做法。
重要的是要注意,基础模型可以在不同的聊天模板上进行微调,因此当我们使用指令模型时,我们需要确保我们正在使用正确的聊天模板。
理解聊天模板
由于每个指令模型使用不同的对话格式和特殊 token,因此实现了聊天模板,以确保我们以每个模型期望的方式正确格式化提示。
在 transformers
中,聊天模板包括 Jinja2 代码,它描述了如何将 ChatML JSON 消息列表(如上述示例中所示)转换为模型可以理解的系统级指令、用户消息和助手响应的文本表示形式。
这种结构有助于在交互中保持一致性,并确保模型对不同类型的输入做出适当的响应。
以下是 SmolLM2-135M-Instruct
聊天模板的简化版本
{% for message in messages %}
{% if loop.first and messages[0]['role'] != 'system' %}
<|im_start|>system
You are a helpful AI assistant named SmolLM, trained by Hugging Face
<|im_end|>
{% endif %}
<|im_start|>{{ message['role'] }}
{{ message['content'] }}<|im_end|>
{% endfor %}
如您所见,chat_template 描述了消息列表将如何格式化。
给定这些消息
messages = [
{"role": "system", "content": "You are a helpful assistant focused on technical topics."},
{"role": "user", "content": "Can you explain what a chat template is?"},
{"role": "assistant", "content": "A chat template structures conversations between users and AI models..."},
{"role": "user", "content": "How do I use it ?"},
]
先前的聊天模板将生成以下字符串
<|im_start|>system
You are a helpful assistant focused on technical topics.<|im_end|>
<|im_start|>user
Can you explain what a chat template is?<|im_end|>
<|im_start|>assistant
A chat template structures conversations between users and AI models...<|im_end|>
<|im_start|>user
How do I use it ?<|im_end|>
transformers
库将为您处理聊天模板,作为 tokenization 过程的一部分。在此处阅读有关 transformers 如何使用聊天模板的更多信息:此处。我们所要做的就是以正确的方式构建我们的消息,tokenizer 将处理其余部分。
您可以尝试以下 Space,以查看使用其相应的聊天模板,相同的对话将如何为不同的模型格式化
消息到提示
确保您的 LLM 接收到正确格式化的对话的最简单方法是使用模型 tokenizer 中的 chat_template
。
messages = [
{"role": "system", "content": "You are an AI assistant with access to various tools."},
{"role": "user", "content": "Hi !"},
{"role": "assistant", "content": "Hi human, what can help you with ?"},
]
要将之前的对话转换为提示,我们加载 tokenizer 并调用 apply_chat_template
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceTB/SmolLM2-1.7B-Instruct")
rendered_prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
此函数返回的 rendered_prompt
现在可以作为您选择的模型的输入使用了!
当您以 ChatML 格式与消息交互时,
apply_chat_template()
函数将在您的 API 后端中使用。
现在我们已经了解了 LLM 如何通过聊天模板构建其输入,接下来让我们探讨 Agent 如何在其环境中行动。
它们执行此操作的主要方式之一是使用工具,这会将 AI 模型的功能扩展到文本生成之外。
我们将在接下来的单元中再次讨论消息,但如果您现在想要更深入的了解,请查看
< > 在 GitHub 上更新