导航栏:首页 / AI教程目录 / AI创客项目开发教程目录 / 第1篇 基础知识篇 / AID101-1-2-04–Assistant Role详解
本节内容简介
本节将详细讲解 Assistant Role(助手角色)在 ESP32 开发板上调用 AI 平台 API 实现具有上下文的交互。通过本节课程,您将理解 如何利用Assistant Role 来存储 AI 的回答,如何通过携带与AI模型的对话历史实现上下文感知的连续对话,以及如何在实际应用中动态管理多轮对话。
Assistant Role(助手角色)详解
什么是 Assistant Role?
Assistant Role(助手角色)是 AI 大语言模型 API 调用中用于存储 AI 回答的角色。在多轮对话中,每一轮 AI 的回答都会被记录为 Assistant Role,并携带在下一轮请求的 messages 数组中,从而使 AI 能够理解对话的上下文,实现连贯的交互体验。
核心作用:
- 💬 回答存储:记录 AI 在每一轮对话中的回答内容
- 🔄 上下文传递:将历史对话信息传递给 AI,使其理解对话脉络
- 🧠 连续对话:支持多轮问答,让对话更加自然连贯
- 📝 对话管理:帮助程序跟踪和管理对话历史
为什么需要 Assistant Role?
与人类对话一样,与 AI 的连续对话也需要”记忆”。当用户与AI交流时,如果没有上下文,AI 无法理解用户在之前的对话中的交流内容,通过 Assistant Role,我们将 AI 每一轮的回答都记录下来,并在下一轮请求时一同发送,这样 AI 就能理解完整的对话上下文。
Assistant Role 与 System Role、User Role 的关系
三种角色的协作分工
| 角色 | 作用 | 内容来源 | 变化频率 |
|---|---|---|---|
| System Role | 设定 AI 的行为规则和身份 | 开发者预设 | 通常固定 |
| User Role | 用户的提问和指令 | 用户输入 | 每次对话都可能变化 |
| Assistant Role | AI 的回答记录 | AI 自动生成 | 每轮对话都会新增 |
messages 数组中三种消息的顺序
messages 数组中的消息顺序非常重要,AI 模型按照消息出现的顺序来理解对话上下文。因此,必须严格按照时间顺序排列消息:
正确顺序:
1. system (最先)
2. user (第一轮用户问题)
3. assistant (第一轮AI回答)
4. user (第二轮用户问题)
5. assistant (第二轮AI回答)
6. user (第三轮用户问题)
...以此类推
示例程序:带有上下文的单轮对话
注意
本程序需要配合my_info.h代码使用,否则程序将无法正常编译。
请点击以下链接前往该代码页面,复制下载该代码:
http://ai.taichi-maker.com/index.php/homepage/ai-tutorial-index/ai-maker-project-tutorial-index/my_info_h-code-description/
/*
* ESP32 AI平台调用 Assistant角色示例
*
* 功能描述:
* 本程序演示如何在 ESP32(特别是 ESP32-S3)开发板上,通过 HTTPS 协议向 AI 平台
* 发送带有上下文的对话请求,展示如何使用 assistant role 实现多轮对话功能。
*
* 本程序仅执行一次对话请求,但这次请求中包含了完整的对话历史,
* 模拟了多轮对话中的"第二轮"场景,演示 assistant role 如何传递上下文。
*
* 对话场景:
* - User(第一轮): 帮我计算2的2次方
* - AI(第一轮回答): 2的2次方等于4。计算方法是:2 × 2 = 4。
* - User(第二轮/本程序请求点): 那3呢
*
* 通过本程序,初学者可以清晰理解:当 AI 需要理解上下文时,
* 需要在请求中携带之前的对话历史(通过 assistant role)。
*
* 作者:Taichi-Maker
* 作者官网:http://ai.taichi-maker.com
* 创建日期:2026年03月27日
* 版本:1.0.1
*
* 硬件要求:
* - 支持 Wi-Fi 的 ESP32 开发板(推荐使用 ESP32-S3-DevKitC-1,因其性能更好、内存更大)
*
* 所需软件库:
* - ArduinoJson 库(版本 7.0.0 或更高)——用于处理 JSON 数据(虽然本例中请求体为硬编码,但响应解析通常需要它)
* 官网:https://arduinojson.org/
*
* 配置说明:
*
* 1. 在 my_info.h 文件中填写您的 Wi-Fi 名称(ssid)和密码(password)。
* 2. 在 my_info.h 文件中将 ai_api_key 替换为您从 AI 平台获取的有效 API 密钥(切勿泄露!)。
* 3. 确保开发板已正确连接到电脑,并选择正确的开发板型号与端口。
*
* 使用方法:
* 将本程序上传至 ESP32 后,打开串口监视器(波特率设置为 115200),
* 程序会自动连接 Wi-Fi 并向 AI 平台发送两次请求,每次请求都会包含之前的对话历史,
* 从而实现上下文感知的多轮对话。
*
* 注意事项:
* - 本例使用 client.setInsecure() 跳过了 SSL 证书验证,仅适用于测试环境;
* 在生产环境中应使用有效证书以确保通信安全。
* - 请求仅在 setup() 中执行两次,loop() 为空,不会重复发送。
*
* 兼容性说明:
* 本程序已在 ESP32-S3-DevKitC-1 开发板上测试通过。
*
* 许可证:MIT License
*
* 程序源:
* 本程序源自太极创客团队精心开发的《AI创客项目开发教程》。该教程专为热爱科技创新、热衷于动手实践 * 创客爱好者与初学者量身打造,是一套完全免费、开源且注重实战的AIoT(人工智能物联网)入门学习资源。
*
* 通过本教程,您可以系统地掌握从项目构思、方案设计、软硬件选型,到实际搭建、系统集成与调试优化的 * 整开发流程。
* 您可以通过以下链接获得更多关于本教程的详细信息:
* http://ai.taichi-maker.com/index.php/homepage/ai-tutorial/
*/
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <HTTPClient.h>
#include "my_info.h"
// 创建一个安全的 Wi-Fi 客户端(用于 HTTPS 连接)
WiFiClientSecure client;
// 创建一个 HTTP 客户端对象,用于发送请求
HTTPClient https;
/*
* -------------- 带有上下文的对话请求体 --------------
*
* 此处使用 C++11 的原始字符串字面量(Raw String Literal)语法 R"rawliteral(...)rawliteral"
* 来定义一个多行 JSON 字符串,避免手动转义双引号和换行符。
*
* 该 JSON 符合 OpenAI API 兼容格式,包含以下关键字段:
* - model: 指定要调用的 AI 模型名称
* - messages: 对话历史,包含 system、user、assistant、user 四条消息
*
* 本请求体模拟了多轮对话中的"第二轮"场景:
* - system: 设定 AI 的身份
* - user(第一轮): 帮我计算2的2次方
* - assistant(第一轮回答): 2的2次方等于4。计算方法是:2 × 2 = 4。
* - user(第二轮): 那3呢
*
* 通过携带前面对话历史,AI 能够理解"那3呢"是指"3的2次方等于几"。
*/
const char* request_payload = R"rawliteral({
"model": "qwen-flash",
"messages": [
{
"role": "system",
"content": "你是一个智能助理"
},
{
"role": "user",
"content": "帮我计算2的2次方"
},
{
"role": "assistant",
"content": "2的2次方等于4。计算方法是:2 × 2 = 4。"
},
{
"role": "user",
"content": "那3呢"
}
]
})rawliteral";
void setup() {
// 初始化串口通信,波特率为 115200
Serial.begin(115200);
delay(1000); // 短暂等待串口稳定
Serial.println();
Serial.println("---------- AI Platform Config ----------");
Serial.print("AI Platform API Endpoint: ");
Serial.print(ai_host);
Serial.println(ai_endpoint);
Serial.println();
Serial.println("---------- Procedures ----------");
Serial.println("Step 1: Connecting WiFi...");
// 开始连接 Wi-Fi
WiFi.begin(ssid, password);
// 循环等待直到成功连接
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("Step 2: WiFi Connected!");
Serial.println("Step 3: Initialize HTTPS Connection...");
// 【重要】跳过 SSL 证书验证(仅用于开发测试!)
// 在真实产品中应加载有效证书以防止中间人攻击
client.setInsecure();
// 设置SSL连接超时时间
client.setTimeout(15); // 15秒超时
Serial.println("Step 4: Send Request to AI Platform...");
Serial.println();
// 发送带有上下文的请求
sendAIRequest(request_payload, "带有上下文的对话请求");
Serial.println();
Serial.println("Step 5: Task Completed!");
}
// 主循环留空,因为本例只需发送一次请求
void loop() {
// 空
}
/*
* -------------- 向 AI 平台发送 HTTPS 请求的核心函数 --------------
*
* 该函数完成以下步骤:
* 1. 构造完整的 HTTPS 请求 URL(基于 my_info.h 中定义的主机、端口和路径)
* 2. 设置请求头:Content-Type 为 application/json,Authorization 为 Bearer + API 密钥
* 3. 发送 POST 请求,携带上述 JSON 请求体
* 4. 接收并打印 HTTP 响应状态码和响应内容
*
* 参数:
* - payload: 要发送的 JSON 请求体
* - description: 请求的描述名称,用于输出显示
*/
void sendAIRequest(const char* payload, const char* description) {
// 构造 Authorization 请求头:格式为 "Bearer <your-api-key>"
String auth = "Bearer ";
auth += ai_api_key;
// 初始化 HTTPS 连接(使用 client、主机名、端口、API 路径)
if (https.begin(client, ai_host, ai_port, ai_endpoint)) {
// 设置超时时间(毫秒)- 增加超时时间以处理更复杂的请求
https.setTimeout(20000); // 20秒超时
https.setConnectTimeout(10000); // 10秒连接超时
// 添加必要的 HTTP 请求头
https.addHeader("Content-Type", "application/json");
https.addHeader("Authorization", auth);
// 发送 POST 请求,并获取 HTTP 状态码
int httpCode = https.POST(payload);
Serial.println("---------- " + String(description) + " Response ----------");
if (httpCode > 0) {
// 打印 HTTP 响应状态码(如 200 表示成功)
Serial.print("HTTP Response Code: ");
Serial.println(httpCode);
// 如果响应成功(HTTP 200 OK)
if (httpCode == HTTP_CODE_OK) {
// 获取完整的响应字符串
String resp = https.getString();
Serial.println("AI Response : ");
Serial.println(resp); // 打印 AI 返回的完整 JSON(含模型生成的回答)
}
} else {
// 打印 HTTP 错误信息(如连接失败、超时等)
Serial.print("HTTP error: ");
Serial.println(https.errorToString(httpCode).c_str());
Serial.print("Error code: ");
Serial.println(httpCode);
}
Serial.println("========================================");
// 结束本次 HTTP 会话,释放资源
https.end();
} else {
// 如果无法建立 HTTPS 连接,打印错误提示
Serial.println("Unable to connect to server");
}
}
/*
* ========================================================================
* 【附录】本程序实际发送的 HTTP 请求内容(供参考)
* ========================================================================
*
* 请求内容:
* POST /api/v3/chat/completions HTTP/1.1
* Host: ark.cn-beijing.volces.com
* Content-Type: application/json
* Authorization: Bearer [你的API密钥]
*
* {
* "model": "qwen-flash",
* "messages": [
* {
* "role": "system",
* "content": "你是一个智能助理"
* },
* {
* "role": "user",
* "content": "帮我计算2的2次方"
* },
* {
* "role": "assistant",
* "content": "2的2次方等于4。计算方法是:2 × 2 = 4。"
* },
* {
* "role": "user",
* "content": "那3呢"
* }
* ]
* }
*
* 说明:
* - 本程序请求包含完整的对话历史,模拟多轮对话中的"第二轮"场景
* - messages 数组中包含:
* 1. system: 设定 AI 身份
* 2. user(第一轮): 第一轮用户提问
* 3. assistant(第一轮回答): 第一轮 AI 回答
* 4. user(第二轮): 第二轮用户提问"那3呢"
* - AI 通过理解完整上下文,能够正确理解"那3呢"是指"3的2次方"
* - 通过这种方式,可以实现具有上下文感知能力的多轮对话
* ========================================================================
*/程序说明:
本程序演示了如何通过 assistant role 实现带有上下文的对话。
本程序仅执行一次请求,这次请求模拟了多轮对话中的”第二轮”场景,包含完整的对话历史:
- User: 帮我计算2的2次方
- AI: 2的2次方等于4。计算方法是:2 × 2 = 4。
- User: 那3呢
关键特点:
- 程序只发送一次请求,但请求中包含了完整的对话历史
- 通过 assistant role 携带 AI 的历史回答
- AI 能够理解上下文,正确理解”那3呢”是指”3的2次方等于几”
关键代码:带有上下文的请求体定义
const char* request_payload = R"rawliteral({
"model": "qwen-flash",
"messages": [
{
"role": "system",
"content": "你是一个智能助理"
},
{
"role": "user",
"content": "帮我计算2的2次方"
},
{
"role": "assistant",
"content": "2的2次方等于4。计算方法是:2 × 2 = 4。"
},
{
"role": "user",
"content": "那3呢"
}
]
})rawliteral";这段代码定义了带有上下文的请求体,包含完整的对话历史,模拟多轮对话中的”第二轮”场景。
关键结构解析:
role: "system"– 设定 AI 的身份role: "user"(第一轮) – 第一轮用户提问role: "assistant"– 第一轮 AI 的回答role: "user"(第二轮) – 第二轮用户提问”那3呢”
为什么这样做?
- 通过携带历史对话,AI 才能理解”那3呢”是追问”3的2次方”
- 这种方式实现了上下文感知的连续对话
对话流程
以下展示的是示例程序请求和AI平台响应流程,请留意:请求中携带了之前的对话历史,使 AI 能够理解上下文
┌─────────────────────────────────────────────────────────────────┐
│ 带有上下文的对话请求 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ESP32 ──────► messages: │
│ [ │
│ {role: "system", content: "你是一个智能助理"}, │
│ {role: "user", content: "帮我计算2的2次方"}, │
│ {role: "assistant", content: "2的2次方等于4。"},│
│ {role: "user", content: "那3呢"} │
│ ] │
│ ▼ │
│ AI 平台理解上下文以及用户提问然后推理回应 │
│ ▼ │
│ ESP32 ◄────── AI 回答: │
│ { │
│ role: "assistant", │
│ content: "3的2次方等于9。" │
│ } │
│ │
└─────────────────────────────────────────────────────────────────┘带有上下文的AI交流关键机制解析
1. 历史记录累积
每完成一轮对话,新的 assistant role 就会被添加到 messages 数组中。随着对话轮次的增加,messages 数组会不断增长,包含越来越多的历史对话。
2. 上下文理解
AI 模型通过读取完整的 messages 数组,理解对话的完整脉络。如,在本示例中,当用户提到”那3呢”时,AI 会结合第一轮的”2的2次方”,理解用户是想问”3的2次方”。
3. 动态消息构建
在实际应用中,每一轮请求都需要重新构建 messages 数组,包含:
- System Role(固定不变)
- 所有的历史对话(User + Assistant)
- 当前的新问题(User)
思考题:
如果我们想要继续以上示例程序中的对话,实现新的一轮与AI交流,在这一轮里,我们需要问AI的问题是“那5呢”,也就是问AI“5的2次方等于几”。为了实现这一请求,我们该如何编写新一轮交流的请求体?
请先不要看以下答案,试着自己思考一下,并且尝试改写以上示例程序,验证你的请求体内容是否正确。
思考题答案:
const char* request_payload = R"rawliteral({
"model": "qwen-flash",
"messages": [
{
"role": "system",
"content": "你是一个智能助理"
},
{
"role": "user",
"content": "帮我计算2的2次方"
},
{
"role": "assistant",
"content": "2的2次方等于4。计算方法是:2 × 2 = 4。"
},
{
"role": "user",
"content": "那3呢"
},
{
"role": "assistant",
"content": "3的2次方等于9。计算方法是:3 × 3 = 9。"
},
{
"role": "user",
"content": "那5呢"
}
]
})rawliteral";思考题请求体说明:
本请求体内容在两轮对话的基础上增加了一轮,演示更复杂的多轮对话场景:
- 第一轮对话:用户询问”2的2次方是多少”,AI 回答”2的2次方等于4。”
- 第二轮对话:用户追问”那3呢”,AI 回答”3的2次方等于9。计算方法是:3 × 3 = 9。”
- 第三轮对话:用户再追问”那5呢”,AI 回答”5的2次方等于25。计算方法是:5 × 5 = 25。”
关键特点:
- 三轮对话形成完整的上下文链
- 每轮请求都携带之前所有的对话历史
- AI 能够追踪多轮对话的脉络
总结
Assistant Role 的核心价值
- 实现上下文理解:通过携带对话历史,AI 能够理解多轮对话的完整脉络
- 支持连续对话:用户无需重复说明背景信息,对话更加自然流畅
- 构建智能应用:为客服、调试、控制等场景提供连贯的交互体验
Assistant Role 的使用要点
- 历史累积:每轮对话后,将 assistant 的回答添加到 messages 数组
- 顺序重要:严格按照时间顺序排列消息
- 成本控制:注意 token 消耗,避免对话过长
- 动态管理:在实际应用中,需要动态构建请求体
基础知识篇目录
第〇章 (AID101-1-0) 序言
第一章 (AID101-1-1) 准备工作
第二章 (AID101-1-2) AI大模型API交互基础
- AID101-1-2-01 – 使用ESP32调用AI大模型API的基本操作
- AID101-1-2-02 – System Role详解
- AID101-1-2-03 – User Role 详解
- AID101-1-2-04 – Assistant Role详解
- AID101-1-2-05 -大模型API交互基础知识总结及练习
第三章 (AID101-1-3) AI大模型工具调用(tools call)
- AID101-1-3-01 – AI大模型工具调用(tools call)基础
- AID101-1-3-02 – 单工具定义实例
- AID101-1-3-03 – 多工具定义实例
- AID101-1-3-04 – 后续工具调用(follow-up tools call)实例
- AID101-1-3-05 – 并行多工具调用(parallel tool calls)实例
- AID101-1-3-06 – 应用开发实例: 可用自然语言控制的人工智能LED
附录