【ESP32接入国产大模型之豆包升级版】

    • 前言
    • 1. 豆包大模型
      • 1.1 方舟定位
      • 1. 极速体验
      • 1.3 深度思考
    • 2.1 环境配置
    • 2.2 所需零件
    • 3. 核心代码
      • 3.1 源码分享
      • 3.2 源码解析
    • 4. 上传验证
      • 4.1 platformio.ini
      • 4.2 对话测试
      • 4.3 错误码
    • 5. 总结

前言

通过 ESP32 接入豆包大模型 API,实现单轮 / 多轮对话、流式输出、联网搜索四大核心功能,打造可流式、联网搜索切换的智能对话终端。这个是基于【ESP32接入国产大模型之豆包】升级的哦!😘😘😘💕💕💕
四大对话模式:单轮/多轮/流式/联网自由切换
完整上下文:支持5轮对话历史记忆
实时流式输出:逐字打印的打字机效果
联网搜索:实时获取天气/新闻等最新信息

首先声明没有恰饭广告,源代码已经匿名处理,制作细节非常完善,方便大家复刻才会提供快捷的相关链接跳转!!!😘😘😘

本文将重点介绍如何通过ESP32S3接入国产大模型之豆包升级版。

上一篇博客已经分享了:
【ESP32接入国产大模型之腾讯混元】
【ESP32接入国产大模型之豆包】
【ESP32接入国产大模型之星火】
【ESP32接入国产大模型之MiniMax】
【ESP32接入语言大模型之智谱清言】
【ESP32接入国产大模型之文心一言】
【ESP32接入语言大模型之通义千问】
【ESP32接入国产大模型之kimi】
【ESP32接入国产大模型之Deepseek】
【ESP32接入国产大模型之阿里Deepseek】

下面是不标准测评,参考而已:

模型响应时间内容质量免费token次数地址
豆包2s9分50万https://www.volcengine/product/doubao
讯飞星火4s8分1亿https://www.xfyun/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html
MiniMax3s8分500万https://www.minimaxi/
智谱清言7s7分300万https://open.bigmodel/
文心一言10s7分500万https://cloud.baidu/doc/WENXINWORKSHOP/s/Nlks5zkzu
通义千问8s7分800万https://tongyi.aliyun/qianwen/
Kimi2s9分50万https://platform.moonshot/docs/guide/start-using-kimi-api
混元6s8分50万https://cloud.tencent/document/product/1729/105701
Deepseek12s9分50万https://api-docs.deepseek/
Deepseek10s9分50万https://help.aliyun/zh/model-studio/developer-reference/deepseek?spm=a2c4g.11186623.help-menu-search-2400256.d_1#2048aa1f92x46

这一次还是采用Platformio编程就会轻松许多开发。这样就可以把大模型装进口袋啦🤣🤣🤣


1. 豆包大模型

豆包火山注册地址:https://t.vncps/5LOve

豆包与火山方舟、火山引擎之间的关系主要体现为技术同源、产品定位互补,三者均隶属于字节跳动旗下。具体联系如下:

🛠️ 1. 火山引擎:底层技术基座

定位:字节跳动推出的企业级云服务平台,提供云计算、大数据、AI 中台、容器服务等基础技术能力。 功能:为火山方舟提供算力支持(GPU
集群)、模型训练 / 推理框架、数据存储等基础设施。 关系:是豆包和火山方舟的技术底层支撑。

🤖 2. 豆包:AI 产品化终端应用

定位:面向公众的AI 对话助手(类似 ChatGPT),可提供问答、写作、编程等能力。 技术来源:依赖于火山引擎的算力资源及自研大模型(如
Skywork 天工、Cloud 系列模型)。 产品形态:直接向用户提供服务的 C 端应用(网页 / App),如 doubao。

🔧 3. 火山方舟:AI 模型开发与服务平台

定位:聚焦于企业级 AI 模型的开发、部署与管理平台(类似百度文心千帆)。 核心功能:
模型接入:支持集成第三方大模型(如百川、MiniMax)。 工具链:提供模型精调(Fine-tuning)、评测、API 部署等工具。
场景方案:针对企业需求定制客服、营销等 AI 解决方案。 与豆包的联系: 技术同源:共用火山引擎的 AI 训练框架和推理加速技术。
能力互补:企业可通过火山方舟训练模型,再以 SDK/API 形式接入自身产品(如集成类似豆包的聊天功能)。
模型共享:豆包的底层模型可能通过火山方舟向企业客户开放定制。

产品简介:https://www.volcengine/docs/82379/1099455

1.1 方舟定位

为您提供大模型服务的开发平台,提供功能丰富、安全以及具备价格竞争力的模型调用服务,同时提供模型数据、精调、推理、评测等端到端功能,全方位保障您的 AI 应用开发落地。

1. 极速体验

您可以访问火山方舟大模型体验中心,免登录极速体验模型能力。
点击页面中心的模型切换按钮,可以切换体验Doubao或DeepSeek系列模型能力。
未登录状态下可以体验部分模型。如果您需要体验所有模型能力,建议您登录火山引擎账号,选择并开通模型。

点击开启MCP服务器,可以连接使用更多火山云产品与三方工具。
您也可以尝试选择下方的图片理解任务进行尝试。

1.3 深度思考

官方文档:https://www.volcengine/docs/82379/1449737
您可以使用具备深度思考能力的模型,如 deepseek r1、doubao thinking 系列模型,来提升最终答案的准确性。模型在回答问题前,会对问题进行分析和拆解,并基于对问题的拆解回答问题,回答会更加全面和深入。当您向模型提问时,方舟返回模型回答问题前的问题思考逻辑(思维链内容),基于此可观察模型推导过程并使用这部分信息。

2.1 环境配置

  1. Arduino IDE:下载并安装 Arduino IDE;
  2. ESP32 开发板库:在 Arduino IDE 中添加 ESP32 支持;
    参考博客:【esp32c3配置arduino IDE教程】
    为安装过程留出一些时间,具体时间可能因您的互联网连接而异。

2.2 所需零件

要学习本教程,您需要1个 ESP32 开发板或者ESP32C3,建议使用后者,笔者发现同样的代码后者可以轻松调用,ESP32不行(可能板子坏了)

目前这是我使用的ESP32S3官方硬件👍👍👍(小小的身材有大大的力量)只需要35元加摄像头麦克风79元,后期我会整理相关专栏进行Arduino系统学习😘😘😘。有需要可以购买xiao开发板💕💕💕

  1. SeeedXIAO ESP32S3 Sense硬件购买地址:https://s.click.taobao/lekazrt

  2. ESP32-S3-CAM 核心开发板 N16R8 wifi蓝牙模块 OV2640摄像头硬件购买地址:https://s.click.taobao/1PTagos

  1. ESP32-S3 NANO开发板 虾哥小智AI 蓝牙WiFi核心板N16R8兼容立创S3

上面硬件三选一,我是第三款硬件

3. 核心代码

3.1 源码分享

#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>

const char *ssid = "IQOO";
const char *password = "12345678";
const char* apiKey = "211f9e11-cd39-4625-b7964a605822";

enum ChatMode {
  SINGLE_TURN = 1,
  MULTI_TURN,
  STREAM_OUTPUT,
  WEB_ENABLED
};

ChatMode currentMode = SINGLE_TURN;
const int maxHistory = 5; // 最多保存5轮对话历史
DynamicJsonDocument historyDoc(2048); // 使用JsonDocument存储历史
int historyIndex = 0;

String processStreamResponse(HTTPClient& http) {
  String output = "";
  WiFiClient* stream = http.getStreamPtr();
  
  while (http.connected()) {
    String line = stream->readStringUntil('\n');
    if (line.startsWith("data: ")) {
      line.remove(0, 6);
      if (line == "[DONE]") break;
      
      JsonDocument doc;
      deserializeJson(doc, line);
      if (doc["choices"][0]["delta"].containsKey("content")) {
        String content = doc["choices"][0]["delta"]["content"].as<String>();
        output += content;
        Serial.print(content);
      }
    }
    delay(1);
  }
  return output;
}

void addToHistory(String role, String content) {
  if (historyIndex >= maxHistory) {
    // 移除最早的历史记录
    for (int i = 0; i < maxHistory - 1; i++) {
      historyDoc["messages"][i] = historyDoc["messages"][i + 1];
    }
    historyIndex = maxHistory - 1;
  }
  
  JsonObject message = historyDoc["messages"][historyIndex].to<JsonObject>();
  message["role"] = role;
  message["content"] = content;
  historyIndex++;
}

String getDeepseekResponse(String input, bool stream = false) {
  HTTPClient http;
  http.setTimeout(30000);
  
  String url = (currentMode == WEB_ENABLED) ? 
    "https://ark-beijing.volces/api/v3/bots/chat/completions" :
    "https://ark-beijing.volces/api/v3/chat/completions";
    
  http.begin(url);
  http.addHeader("Content-Type", "application/json");
  http.addHeader("Authorization", String("Bearer ") + apiKey);
  
  JsonDocument requestDoc;
  requestDoc["model"] = (currentMode == WEB_ENABLED) ? "bot-20250706221156-2m7jb" : "doubao-seed-1-6-flash-250615";
  
  JsonArray messages = requestDoc["messages"].to<JsonArray>();
  
  // 添加历史消息
  if (currentMode == MULTI_TURN && historyIndex > 0) {
    for (int i = 0; i < historyIndex; i++) {
      JsonObject msg = messages.add<JsonObject>();
      msg["role"] = historyDoc["messages"][i]["role"].as<String>();
      msg["content"] = historyDoc["messages"][i]["content"].as<String>();
    }
  }
  
  // 添加当前消息
  JsonObject userMessage = messages.add<JsonObject>();
  userMessage["role"] = "user";
  userMessage["content"] = input;
  
  if (stream) requestDoc["stream"] = true;
  
  String payload;
  serializeJson(requestDoc, payload);
  
  int httpCode = http.POST(payload);
  
  if (httpCode == HTTP_CODE_OK) {
    if (stream) {
      return processStreamResponse(http);
    } else {
      String response = http.getString();
      JsonDocument respDoc;
      deserializeJson(respDoc, response);
      
      String content = respDoc["choices"][0]["message"]["content"].as<String>();
      if (currentMode == MULTI_TURN) {
        addToHistory("user", input);
        addToHistory("assistant", content);
      }
      return content;
    }
  }
  return "Error: " + String(httpCode) + " - " + http.getString();
}

void showMenu() {
  Serial.println("\n当前模式: " + String(currentMode));
  Serial.println("1. 单轮对话");
  Serial.println("2. 多轮对话");
  Serial.println("3. 流式输出");
  Serial.println("4. 联网能力");
  Serial.println("请输入1-4切换模式,或输入问题开始对话:");
}

void setup() {
  Serial.begin(115200);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  
  // 初始化历史文档
  historyDoc["messages"] = JsonArray();
  
  Serial.println("\nWiFi已连接");
  showMenu();
}

void loop() {
  if (Serial.available()) {
    String input = Serial.readStringUntil('\n');
    input.trim();
    
    if (input.length() == 1 && input.toInt() >= 1 && input.toInt() <= 4) {
      currentMode = (ChatMode)input.toInt();
      if (currentMode != MULTI_TURN) {
        historyIndex = 0; // 清除对话历史
        historyDoc["messages"] = JsonArray(); // 重置历史数组
      }
      showMenu();
    } 
    else if (input.length() > 0) {
      Serial.println("\n[提问]: " + input);
      Serial.print("[回答]: ");
      
      String response;
      if (currentMode == STREAM_OUTPUT) {
        response = getDeepseekResponse(input, true);
      } else {
        response = getDeepseekResponse(input);
      }
      
      if (currentMode != STREAM_OUTPUT) {
        Serial.println(response);
      }
      
      // 显示当前对话历史(仅多轮模式)
      if (currentMode == MULTI_TURN && historyIndex > 0) {
        Serial.println("\n当前对话历史:");
        for (int i = 0; i < historyIndex; i++) {
          Serial.print(historyDoc["messages"][i]["role"].as<String>());
          Serial.print(": ");
          Serial.println(historyDoc["messages"][i]["content"].as<String>());
        }
      }
      
      Serial.println("\n----------------------");
      showMenu();
    }
  }
  delay(10);
}

3.2 源码解析

  1. 导入库文件:

    #include <WiFi.h>
    #include <HTTPClient.h>
    #include <ArduinoJson.h>
    
  2. 定义Wi-Fi网络凭证:

    const char *ssid = "IQOO";
    const char *password = "12345678";
    
  3. 定义API Key:

const char* apiKey = "211f9e11-cd39-4625-b7964a605822";


选择自己的api,建议开启所有模型

开启联网能力
您可以使用方舟应用的联网插件,为deepseek-r1-250528模型附加上联网能力,让模型能够回答天气、时间等即时的知识问题。方法如下:

获取应用ID:访问DeepSeek-R1 联网搜索版应用,快速创建联网应用。
内容源、返回结果数量等配置项您可根据需要灵活调整。参考文档:https://www.volcengine/docs/82379/1449737#%E5%BC%80%E5%90%AF%E8%81%94%E7%BD%91%E8%83%BD%E5%8A%9B
替换这里的"bot-20250706221156-2m7jb"

  requestDoc["model"] = (currentMode == WEB_ENABLED) ? "bot-20250706221156-2m7jb" : "doubao-seed-1-6-flash-250615";
  1. 定义输入文本和函数getGPTAnswer(String inputText)

    • 输入文本是固定的问候语"你好,deepseek",实际应用中可以修改。
    • 函数getGPTAnswer()负责发送POST请求并解析返回的JSON数据。
  2. setup()函数:

    • 初始化串口通信,连接到指定的Wi-Fi网络。
    • 获取初始回答并打印,提示用户输入新问题。
  3. loop()函数:

    • 检查串口是否有输入数据。
    • 根据输入选择不同的模型并获取回答。

4. 上传验证

下面给出下载配置,请严格配置

4.1 platformio.ini

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio/page/projectconf.html

[env:freenove_esp32_s3_wroom]
platform = espressif32
board = freenove_esp32_s3_wroom
framework = arduino
lib_deps = bblanchon/ArduinoJson@^7.4.2

; 添加以下两行
build_flags = -DARDUINO_USB_CDC_ON_BOOT=1   ; Enable USB CDC
            ;   -DCORE_DEBUG_LEVEL=1  ; Set debug level

4.2 对话测试

打开串口监视器,注意右下角选择回车符,选择115200波特率,输入你想问的问题,它就可以回答你。

---- 已打开串行端口 COM13 ----
---- 已发送 utf8 编码消息: "2\n" ----

当前模式: 2
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:
---- 已发送 utf8 编码消息: "睡不着\n" ----

[提问]: 睡不着
[回答]: 睡不着的话,可以试试这些方法来帮助放松入睡:

### 1. 呼吸放松法
慢慢吸气,让腹部鼓起,然后慢慢呼气,感受腹部回落,重复几次,专注呼吸能平静身心。

### 2. 冥想引导
可以在心里默想一些宁静的场景,比如漫步在宁静的森林、海边等,让自己沉浸在舒缓的氛围中。

### 3. 调整环境
调暗灯光,拉上窗帘减少光线干扰,保持卧室温度适宜,营造舒适的睡眠环境。

### 4. 轻度活动
如果躺久了还是睡不着,可以起来做一些轻柔的伸展运动,比如拉伸腿部、手臂,让身体微微发热但不过度兴奋。

### 5. 听觉助眠
听一些白噪音,像雨声、溪流声的音频,或者轻柔的纯音乐,帮助屏蔽外界干扰,进入放松状态。

你可以先从这些方法里选一个试试,看看能不能帮助入睡哦。

当前对话历史:
user: 睡不着
assistant: 睡不着的话,可以试试这些方法来帮助放松入睡:

### 1. 呼吸放松法
慢慢吸气,让腹部鼓起,然后慢慢呼气,感受腹部回落,重复几次,专注呼吸能平静身心。

### 2. 冥想引导
可以在心里默想一些宁静的场景,比如漫步在宁静的森林、海边等,让自己沉浸在舒缓的氛围中。

### 3. 调整环境
调暗灯光,拉上窗帘减少光线干扰,保持卧室温度适宜,营造舒适的睡眠环境。

### 4. 轻度活动
如果躺久了还是睡不着,可以起来做一些轻柔的伸展运动,比如拉伸腿部、手臂,让身体微微发热但不过度兴奋。

### 5. 听觉助眠
听一些白噪音,像雨声、溪流声的音频,或者轻柔的纯音乐,帮助屏蔽外界干扰,进入放松状态。

你可以先从这些方法里选一个试试,看看能不能帮助入睡哦。

----------------------

当前模式: 2
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:
---- 已发送 utf8 编码消息: "想听轻音乐\n" ----

[提问]: 想听轻音乐
[回答]: 以下是一些非常适合助眠的轻音乐推荐:


### **1. 久石让《天空之城》**  
空灵悠扬的旋律,仿佛能带你远离喧嚣,沉浸在纯净的音乐世界中,舒缓身心。  

### **2. 班得瑞《安妮的仙境》**  
清新自然的曲风,如漫步在梦幻般的仙境,轻柔的音符能安抚情绪,帮助放松。  

### **3. 神秘园《Song From A Secret Garden》**  
旋律静谧优美,带着淡淡的忧伤与温暖,营造出私密而宁静的氛围,适合放松入眠。  

### **4. 林海《琵琶语》**  
融合了琵琶的婉转与现代音乐的轻柔,曲调温婉雅致,充满东方韵味,能让人平静下来。  

### **5. 卡洛儿《假如爱有天意》**  
钢琴与弦乐交织,旋律浪漫又带着一丝淡淡的哀愁,温柔舒缓,助你进入梦乡。  

你可以在音乐平台搜索这些曲目,找个舒适的姿势,伴着旋律放松身心呀~

当前对话历史:
user: 睡不着
assistant: 睡不着的话,可以试试这些方法来帮助放松入睡:

### 1. 呼吸放松法
慢慢吸气,让腹部鼓起,然后慢慢呼气,感受腹部回落,重复几次,专注呼吸能平静身心。

### 2. 冥想引导
可以在心里默想一些宁静的场景,比如漫步在宁静的森林、海边等,让自己沉浸在舒缓的氛围中。

### 3. 调整环境
调暗灯光,拉上窗帘减少光线干扰,保持卧室温度适宜,营造舒适的睡眠环境。

### 4. 轻度活动
如果躺久了还是睡不着,可以起来做一些轻柔的伸展运动,比如拉伸腿部、手臂,让身体微微发热但不过度兴奋。

### 5. 听觉助眠
听一些白噪音,像雨声、溪流声的音频,或者轻柔的纯音乐,帮助屏蔽外界干扰,进入放松状态。

你可以先从这些方法里选一个试试,看看能不能帮助入睡哦。
user: 想听轻音乐
assistant: 以下是一些非常适合助眠的轻音乐推荐:


### **1. 久石让《天空之城》**  
空灵悠扬的旋律,仿佛能带你远离喧嚣,沉浸在纯净的音乐世界中,舒缓身心。  

### **2. 班得瑞《安妮的仙境》**  
清新自然的曲风,如漫步在梦幻般的仙境,轻柔的音符能安抚情绪,帮助放松。  

### **3. 神秘园《Song From A Secret Garden》**  
旋律静谧优美,带着淡淡的忧伤与温暖,营造出私密而宁静的氛围,适合放松入眠。  

### **4. 林海《琵琶语》**  
融合了琵琶的婉转与现代音乐的轻柔,曲调温婉雅致,充满东方韵味,能让人平静下来。  

### **5. 卡洛儿《假如爱有天意》**  
钢琴与弦乐交织,旋律浪漫又带着一丝淡淡的哀愁,温柔舒缓,助你进入梦乡。  

你可以在音乐平台搜索这些曲目,找个舒适的姿势,伴着旋律放松身心呀~

----------------------

当前模式: 2
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:
---- 已发送 utf8 编码消息: "3\n" ----

当前模式: 3
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:
---- 已发送 utf8 编码消息: "张杰的逆战\n" ----

[提问]: 张杰的逆战
[回答]: ### 1. 基本信息
- **演唱**:张杰
- **发行时间**:2010年
- **所属专辑**:《这,就是爱》
- **歌曲类型**:摇滚风,是网游《逆战》的主题曲

### 2. 歌词特点与歌曲风格
- 歌词充满热血与战斗气息,如“Come on!逆战 逆战来也 王牌要狂野 闯荡宇宙摆平世界;Oh 逆战 逆战来也 王牌要发泄 战斗是我们倔强起点”,展现出一种勇往直前、热血奋战的精神。
- 曲风激昂振奋,张杰以高亢嘹亮的嗓音,将歌曲中那种激烈的战斗氛围和不甘示弱、奋勇向前的情感诠释得淋漓尽致,节奏紧凑,极具爆发力。

### 3. 歌曲影响
- 作为网游《逆战》的主题曲,极大地提升了游戏的知名度和热度,同时也让这首歌本身广为流传,成为张杰的经典代表作之一,在各大音乐平台上播放量颇高,深受歌迷喜爱,还经常在演唱会等场合被张杰热情演绎。
----------------------

当前模式: 3
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:
---- 已发送 utf8 编码消息: "4\n" ----

当前模式: 4
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:
---- 已发送 utf8 编码消息: "大连明天会下雨吗\n" ----

[提问]: 大连明天会下雨吗
[回答]: 
我无法提供实时的天气预报,但您可以通过以下方式获取大连明天(以及未来几天)的准确天气信息:

1. **天气类应用/网站**  
   推荐使用:
   * **中国天气网**:进入官网搜索“大连天气”或下载官方App  
   * **墨迹天气/彩云天气**等主流天气App,定位至大连查看

2. **官方渠道**  
   * 大连市气象局官网/公众号发布权威预报

3. **手机自带功能**  
   在手机搜索栏输入 **“大连 天气”**,系统会直接显示当地天气预报(iOS/安卓均支持)

4. **生活类平台**  
   支付宝/微信小程序中的天气服务模块也可查询  

**温馨提示**:近期大连正处于夏季多雨期,建议出行前随时刷新预报,并携带雨具备用。🌂

如您需要其他帮助(如获取当前天气截图、出行建议等),请随时告诉我!

----------------------

当前模式: 4
1. 单轮对话
2. 多轮对话
3. 流式输出
4. 联网能力
请输入1-4切换模式,或输入问题开始对话:

个人感觉联网功能有点慢其他还行,终于可以流式啦非常爽!


4.3 错误码

如果执行报错,请参见错误信息进行解决。

5. 总结

现在,我们在本教程中学习了如何通过 ESP32 接入豆包大模型 API,实现单轮 / 多轮对话、流式输出、联网搜索四大核心功能。从而实现对外部世界的感知,充分认识这个有机与无机的环境,后期会持续分享ESP32跑FreeRTOS实用案例,为人类社会发展贡献一点微薄之力。🙌🙌🙌

如果你有任何问题,可以通过Q Group(945348278)加入鹏鹏小分队,期待与你思维的碰撞! 😘😘😘