【ESP32接入国产大模型之Deepseek】

embedded/2025/2/19 15:47:20/

【ESP32接入国产大模型之Deepseek

  • 1. Deepseek大模型
    • 1.1 了解Deepseek api
    • 1.2 Http接口鉴权
    • 1.3. 接口参数说明
    • 1.3.1 请求体(request)参数
    • 1.3.2 模型推理
  • 2. 先决条件
    • 2.1 环境配置
    • 2.2 所需零件
  • 3. 核心代码
    • 3.1 源码分享
    • 3.2 源码解析
    • 3.3 连续对话
      • 修改后的代码
      • 代码说明
      • 示例输出
      • 注意事项
  • 4. 上传验证
    • 4.1 对话测试
    • 4.2 报错
  • 5. 总结

Deepseek_4">1. Deepseek大模型

ESP32接入国产大模型之Deepseek

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

在这里插入图片描述

DeepSeek 是一个先进的人工智能平台,旨在提供强大的对话和探索功能。它已经发布了性能更强的版本,并且已经开源,用户可以在网页端、APP 和 API 上注册使用。DeepSeek V3 是其最新的超级模型,用户可以免费与之对话,体验其强大的功能。

DeepSeek 的目标是探索未知的领域,提供创新的解决方案和工具。用户可以通过官方推出的手机 App 快速访问更多工具和资源。这个平台适合那些希望利用先进 AI 技术来增强其工作和生活体验的用户。。本文将重点介绍如何通过ESP32S3接入国产大模型之Deepseek api。
【ESP32接入国产大模型之腾讯混元】
上一篇博客已经分享了
【ESP32接入国产大模型之豆包】
【ESP32接入国产大模型之星火】
【ESP32接入国产大模型之MiniMax】
【ESP32接入语言大模型之智谱清言】
【ESP32接入国产大模型之文心一言】
【ESP32接入语言大模型之通义千问】
【ESP32接入国产大模型之kimi】
【ESP32接入国产大模型之Deepseek
在这里插入图片描述

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

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

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

Deepseek_api_53">1.1 了解Deepseek api

为方便用户使用,我们提供了 原生 HTTP 来实现模型 API 的调用。
Deepseek api

在这里插入图片描述

1.2 Http接口鉴权

Deepseek API 兼容了 OpenAI 的接口规范,这意味着您可以直接使用 OpenAI 官方提供的 SDK 来调用混元大模型。您仅需要将 base_url 和 api_key 替换成混元的相关配置,不需要对应用做额外修改,即可无缝将您的应用切换到混元大模型。详见鉴权认证方式。

  1. apikey
    进入 [API Key 管理]https://console.cloud.tencent.com/hunyuan/start)页面,在您有权限的项目下点击新建 API Key,即可生成长效 API Key。进入兼容OpenAI API KEY的创建页面,点击新建即可生成API KEY。
    点击创建api key
    在这里插入图片描述

API Key 签名鉴权方式要求在 HTTP 请求 header 中按如下方式添加 Authorization header:

Authorization: Bearer $ARK_API_KEY

1.3. 接口参数说明

1.3.1 请求体(request)参数

curl https://api.deepseek.com/chat/completions \-H "Content-Type: application/json" \-H "Authorization: Bearer <DeepSeek API Key>" \-d '{"model": "deepseek-chat","messages": [{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Hello!"}],"stream": false}'

注意

model选默认就好
在这里插入图片描述

1.3.2 模型推理

在这里插入图片描述

上下文拼接
在每一轮对话过程中,模型会输出思维链内容(reasoning_content)和最终回答(content)。在下一轮对话中,之前轮输出的思维链内容不会被拼接到上下文中,如下图所示:

在这里插入图片描述

2. 先决条件

在继续此项目之前,请确保检查以下先决条件。

我们将使用 Arduino IDE 对 ESP32/ESP8266 开发板进行编程,因此在继续本教程之前,请确保已在 Arduino IDE 中安装这些开发板。

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.com/lekazrt
    在这里插入图片描述

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

在这里插入图片描述

3. 核心代码

3.1 源码分享

esp32S3 Arduino代码如下

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>// 替换为您的 WiFi 凭据
const char *ssid = "IQOO";
const char *password = "12345678";// 替换为您的 DeepSeek API 密钥
const char* apiKey = "sk-ea62673968ca4a34a1a1f6a82e4";// DeepSeek API 端点
const char* host = "api.deepseek.com";
const int httpsPort = 443;// 创建 WiFiClientSecure 对象
WiFiClientSecure client;// 设置超时时间 (单位:毫秒)
const unsigned long timeout = 10000;// 函数声明
void connectToWiFi();
String askDeepSeek(String question);
void printResponse(String response);void setup() {Serial.begin(115200);// 连接到 WiFiconnectToWiFi();// 关闭证书鉴权client.setInsecure();Serial.println("初始化完成,请输入您的问题:");
}void loop() {// 检查串口是否有输入if (Serial.available()) {String question = Serial.readStringUntil('\n');question.trim(); // 去除换行符和空格if (question.length() > 0) {Serial.println("正在向 DeepSeek 提问...");String response = askDeepSeek(question);printResponse(response);Serial.println("\n请输入下一个问题:");}}
}// 连接到 WiFi
void connectToWiFi() {WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.println("正在连接到 WiFi...");}Serial.println("已连接到 WiFi");
}// 向 DeepSeek 提问
String askDeepSeek(String question) {String response = "";// 连接到 DeepSeek APIif (!client.connect(host, httpsPort)) {Serial.println("连接失败");return "连接失败";}// 构建请求String request = "POST /v1/chat/completions HTTP/1.1\r\n";request += "Host: " + String(host) + "\r\n";request += "Authorization: Bearer " + String(apiKey) + "\r\n";request += "Content-Type: application/json\r\n";request += "Connection: close\r\n";// 构建请求体DynamicJsonDocument doc(1024);doc["model"] = "deepseek-chat";doc["messages"][0]["role"] = "user";doc["messages"][0]["content"] = question;doc["stream"] = true;String requestBody;serializeJson(doc, requestBody);request += "Content-Length: " + String(requestBody.length()) + "\r\n\r\n";request += requestBody;// 发送请求client.print(request);// 记录开始时间unsigned long startTime = millis();// 流式接收响应while (client.connected()) {// 检查超时if (millis() - startTime > timeout) {Serial.println("响应超时");break;}// 读取数据while (client.available()) {String line = client.readStringUntil('\n');if (line.startsWith("data: ")) {String jsonData = line.substring(6);DynamicJsonDocument doc(1024);deserializeJson(doc, jsonData);// 提取回复内容if (doc.containsKey("choices")) {String content = doc["choices"][0]["delta"]["content"];response += content;}}}}// 断开连接client.stop();return response;
}// 打印回复内容
void printResponse(String response) {Serial.println("DeepSeek 回复:");Serial.println(response);
}

这段代码是一个基于Arduino平台(可能是ESP32或ESP8266)的示例,它通过WiFi连接到指定的无线网络,并利用HTTPClient库向智谱清言API发送POST请求以获取AI生成的回答。

3.2 源码解析

以下是详细的解释:

  1. 导入必要的库:
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
  1. 第一处修改定义Wi-Fi网络凭证:
// 1. Replace with your network credentials
const char *ssid = "IQOO";
const char *password = "12345678";
  1. 第二处修改定义要调用的APIkey:
// 2. Replace with your OpenAI API key
const char* apiKey = "sk-ea62673968ca4a34a1a1f6a82e4";

这段代码是一个用于ESP32微控制器的程序,旨在通过WiFi连接到DeepSeek API,并与之进行交互。以下是代码的主要功能概述:

  1. WiFi连接:代码首先连接到指定的WiFi网络(ssidpassword)。如果连接丢失,它会尝试重新连接。

  2. 用户输入处理:通过串口监视器,用户可以输入问题或消息。这些输入被发送到DeepSeek API进行处理。

  3. API请求:代码构建一个HTTP POST请求,包含用户输入的内容,并将其发送到DeepSeek API。请求使用JSON格式,并包含API密钥进行身份验证。

  4. 分块响应处理:由于API响应可能是分块的,代码实现了分块解析状态机来处理这些响应。它读取每个块的大小和数据,直到所有数据接收完毕。

  5. 响应解析:接收到的响应被解析为JSON格式,并提取出DeepSeek的回复内容。代码还提取并显示了使用的Token数量(输入、输出和总计)。

  6. 错误处理:代码包含了对连接失败、JSON解析错误和API错误的处理,确保在出现问题时能够提供有用的调试信息。

总体而言,这段代码展示了如何在ESP32上实现与远程API的交互,处理分块响应,并解析JSON数据。这对于需要与云服务进行通信的物联网(IoT)应用非常有用。

3.3 连续对话

为了实现上下文拼接功能,并让模型在每一轮对话中输出思维链内容,我们需要对代码进行以下改进:

  1. 维护对话历史:

    • 使用一个数组或列表来存储用户和模型的对话内容。
    • 每次对话时,将用户的问题和模型的回复添加到对话历史中。
  2. 拼接上下文:

    • 在每次请求时,将对话历史作为上下文传递给 DeepSeek API。
  3. 提取思维链内容:

    • 根据 DeepSeek API 的响应,提取模型输出的思维链内容(通常是一个字段,如 reasoningchain_of_thought)。

以下是修改后的代码:


修改后的代码

#include <Arduino.h>
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>// 替换为您的 WiFi 凭据
const char *ssid = "IQOO";
const char *password = "12345678";// 替换为您的 DeepSeek API 密钥
const char* apiKey = "sk-ea62673968ca4a34a1a1f6a82e4";// DeepSeek API 端点
const char* host = "api.deepseek.com";
const int httpsPort = 443;// 创建 WiFiClientSecure 对象
WiFiClientSecure client;// 设置超时时间 (单位:毫秒)
const unsigned long timeout = 10000;// 对话历史
const int maxHistory = 10; // 最大对话轮次
String conversationHistory[maxHistory]; // 存储对话历史
int historyIndex = 0; // 当前对话历史索引// 函数声明
void connectToWiFi();
String askDeepSeek(String question);
void printResponse(String response);
void addToHistory(String role, String content);
void printHistory();void setup() {Serial.begin(115200);// 连接到 WiFiconnectToWiFi();// 关闭证书鉴权client.setInsecure();Serial.println("初始化完成,请输入您的问题:");
}void loop() {// 检查串口是否有输入if (Serial.available()) {String question = Serial.readStringUntil('\n');question.trim(); // 去除换行符和空格if (question.length() > 0) {// 将用户问题添加到对话历史addToHistory("user", question);Serial.println("正在向 DeepSeek 提问...");String response = askDeepSeek(question);printResponse(response);// 将模型回复添加到对话历史addToHistory("assistant", response);// 打印当前对话历史printHistory();Serial.println("\n请输入下一个问题:");}}
}// 连接到 WiFi
void connectToWiFi() {WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(1000);Serial.println("正在连接到 WiFi...");}Serial.println("已连接到 WiFi");
}// 向 DeepSeek 提问
String askDeepSeek(String question) {String response = "";// 连接到 DeepSeek APIif (!client.connect(host, httpsPort)) {Serial.println("连接失败");return "连接失败";}// 构建请求String request = "POST /v1/chat/completions HTTP/1.1\r\n";request += "Host: " + String(host) + "\r\n";request += "Authorization: Bearer " + String(apiKey) + "\r\n";request += "Content-Type: application/json\r\n";request += "Connection: close\r\n";// 构建请求体DynamicJsonDocument doc(1024);doc["model"] = "deepseek-chat";doc["stream"] = true;// 添加对话历史JsonArray messages = doc.createNestedArray("messages");for (int i = 0; i < historyIndex; i++) {JsonObject message = messages.createNestedObject();message["role"] = i % 2 == 0 ? "user" : "assistant"; // 交替用户和助手角色message["content"] = conversationHistory[i];}// 添加当前问题JsonObject newMessage = messages.createNestedObject();newMessage["role"] = "user";newMessage["content"] = question;String requestBody;serializeJson(doc, requestBody);request += "Content-Length: " + String(requestBody.length()) + "\r\n\r\n";request += requestBody;// 发送请求client.print(request);// 记录开始时间unsigned long startTime = millis();// 流式接收响应while (client.connected()) {// 检查超时if (millis() - startTime > timeout) {Serial.println("响应超时");break;}// 读取数据while (client.available()) {String line = client.readStringUntil('\n');if (line.startsWith("data: ")) {String jsonData = line.substring(6);DynamicJsonDocument doc(1024);deserializeJson(doc, jsonData);// 提取回复内容if (doc.containsKey("choices")) {String content = doc["choices"][0]["delta"]["content"];response += content;}// 提取思维链内容(假设字段为 "reasoning")if (doc.containsKey("choices") && doc["choices"][0].containsKey("delta") && doc["choices"][0]["delta"].containsKey("reasoning")) {String reasoning = doc["choices"][0]["delta"]["reasoning"];Serial.println("思维链: " + reasoning);}}}}// 断开连接client.stop();return response;
}// 打印回复内容
void printResponse(String response) {Serial.println("DeepSeek 回复:");Serial.println(response);
}// 添加对话历史
void addToHistory(String role, String content) {if (historyIndex < maxHistory) {conversationHistory[historyIndex] = content;historyIndex++;} else {// 如果历史记录已满,移除最早的记录for (int i = 0; i < maxHistory - 1; i++) {conversationHistory[i] = conversationHistory[i + 1];}conversationHistory[maxHistory - 1] = content;}
}// 打印对话历史
void printHistory() {Serial.println("\n当前对话历史:");for (int i = 0; i < historyIndex; i++) {Serial.println((i % 2 == 0 ? "用户: " : "助手: ") + conversationHistory[i]);}
}

代码说明

  1. 对话历史管理:

    • 使用 conversationHistory 数组存储对话内容。
    • 通过 addToHistory 函数将用户问题和模型回复添加到历史中。
    • 如果历史记录已满,移除最早的记录以保持最大轮次。
  2. 上下文拼接:

    • 在每次请求时,将对话历史作为 messages 数组传递给 DeepSeek API。
  3. 思维链提取:

    • 假设 DeepSeek API 返回的思维链内容字段为 reasoning,在流式接收时提取并打印。
  4. 对话历史打印:

    • 使用 printHistory 函数打印当前对话历史,方便调试和观察上下文。

示例输出

初始化完成,请输入您的问题:
你好,DeepSeek!
正在向 DeepSeek 提问...
思维链: 用户打招呼,我需要回应问候。
DeepSeek 回复:
你好!我是 DeepSeek,很高兴为您服务。请问有什么可以帮您的?当前对话历史:
用户: 你好,DeepSeek!
助手: 你好!我是 DeepSeek,很高兴为您服务。请问有什么可以帮您的?请输入下一个问题:

注意事项

  1. API 字段名称:

    • 确保 reasoning 字段与 DeepSeek API 返回的思维链字段名称一致。如果不一致,请根据 API 文档修改。
  2. 历史记录长度:

    • 根据 ESP32 的内存限制,调整 maxHistory 的大小,避免内存不足。
  3. 流式数据解析:

    • 确保解析逻辑能够正确处理流式数据的分块传输。

希望这段代码能满足您的需求!如果有其他问题,请随时告诉我。

4. 上传验证

下面给出下载配置,请严格配置
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.org/page/projectconf.html[env:esp32s3-cam]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
board_upload.flash_size = 16MB
board_build.partitions = default_16MB.csv
board_build.mcu = esp32s3
monitor_speed = 115200
upload_speed = 921600
lib_deps = bblanchon/ArduinoJson@^7.3.0

4.1 对话测试

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

在这里插入图片描述

个人感觉混元比其他国内大模型响应有点快啦,大约10s返回,太爽啦!😘😘😘

4.2 报错

如果返回error ,大家对照列表查询错误代码,结合提示排查解决

在这里插入图片描述

5. 总结

🥳🥳🥳现在,我们在本教程中,您学习了如何使用ESP32接入语言大模型之Deepseek。🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境,后期会持续分享esp32跑freertos实用案列🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

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

鸣谢B站UP星汇极客
参考文献:ESP32对接DeepSeek API,实现AI大模型交互功能。


http://www.ppmy.cn/embedded/162491.html

相关文章

Azure从0到1

我能用Azure做什么? Azure提供100多种服务,能够从在虚拟机上运行现有应用程序到探索新的软件范式,如智能机器人和混合现实。许多团队开始通过将现有应用程序移动到在Azure中运行的虚拟机(VM)来探索云。将现有应用程序迁移到虚拟机是一个良好的开端,但云不仅仅是运行虚拟…

算法学习笔记之贪心算法

导引&#xff08;硕鼠的交易&#xff09; 硕鼠准备了M磅猫粮与看守仓库的猫交易奶酪。 仓库有N个房间&#xff0c;第i个房间有 J[i] 磅奶酪并需要 F[i] 磅猫粮交换&#xff0c;硕鼠可以按比例来交换&#xff0c;不必交换所有的奶酪 计算硕鼠最多能得到多少磅奶酪。 输入M和…

从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地

导读&#xff1a;日志数据已成为企业洞察系统状态、监控网络安全及分析业务动态的宝贵资源。网易云音乐引入 Apache Doris 作为日志库新方案&#xff0c;替换了 ClickHouse。解决了 ClickHouse 运维复杂、不支持倒排索引的问题。目前已经稳定运行 3 个季度&#xff0c;规模达到…

机器学习入门-读书摘要

先看了《深度学习入门&#xff1a;基于python的理论和实践》这本电子书&#xff0c;早上因为入迷还坐过站了。。 因为里面的反向传播和链式法则特别难懂&#xff0c;又网上搜了相关内容进行进一步理解&#xff0c;参考的以下文章&#xff08;个人认为都讲的都非常好&#xff0…

机器学习 - 线性模型

一、线性模型的定义&#xff1a; 线性模型(Linear Model)是机器学习中应用最广泛的模型&#xff0c;指通过样本特 征的线性组合来进行预测的模型.给定一个&#x1d437;维样本&#x1d499; [&#x1d465;1,⋯,&#x1d465;&#x1d437;]T&#xff0c;其线性 组合函数为 即…

Flutter 实现 iOS 小组件与主 App 的通信

前言 在 Flutter 项目中实现 iOS 小组件与主 App 的通信&#xff0c;主要依赖于 App Groups 技术&#xff0c;以下是具体实现步骤和注意事项。 配置 App Groups 在 Xcode中为 Flutter 主应用&#xff08;Runner&#xff09;和 Widget Extension 配置相同的App Group 标识符…

水务+AI应用探索(一)| FastGPT+DeepSeek 本地部署

在当下的科技浪潮中&#xff0c;AI 无疑是最炙手可热的焦点之一&#xff0c;其强大的能力催生出了丰富多样的应用场景&#xff0c;广泛渗透到各个行业领域。对于水务行业而言&#xff0c;AI 的潜力同样不可估量。为了深入探究 AI 在水务领域的实际应用成效&#xff0c;切实掌握…

CentOS 7上安装Python 3的步骤如下

CentOS 7上安装Python 3的步骤如下 上传或下载 Python 3 安装包 #下载 wget https://www.python.org/ftp/python/3.13.2/Python-3.13.2.tgz#安装 tar zxvf Python-3.13.2.tgz安装依赖 #安装依赖包 yum install -y zlib-devel bzip2-devel ncurses-devel sqlite-devel readli…