为你的开发板提供全套的AI对话方案,包括但不限于
ESP32
系列开发板的IAT+LLM+TTS
集成方案。依赖式注入到项目,不影响现有项目。
对于开发机器人的对话功能,您仅需准备好 IAT
、LLM
、TTS
服务,其他的事情交给 ESP-AI
。
本项目服务端代码基于 Nodejs,硬件代码基于 Arduino IDE。
开源不易,右上角点个 Star
支持一下下吧 ~
- 离线语音唤醒
- IAT ➡️ LLM/RAG ➡️ TTS
- 配置化
- 插件化
- 开箱即用
- 离线语音唤醒优化
- 文档网站
- 提供无代码接入方案
- 提供免费服务与收费服务
- 提供开发板(PCB)
下面分别展示在只需要对话的情况下,你需要写的Node.js
和Arduino
代码。
努力建设中...
QQ 交流群: 854445223
简单三步,即可将一个智能助手运行起来。
- 安装服务端插件
- 将插件引入你的项目中,配置好相关的
key
并运行 - 将提供的客户端代码烧录到
ESP32s3
开发板中(需将/client/libraries 中的插件导入到IDE)
后续升级仅需在发布页面下载相关文件即可:https://github.com/wangzongming/esp-ai/releases
- nodejs >= v14.0.0 (node <= v18.x, npm <= v9.x 不然安装 esp-ai 可能会报错)
- Arduino IDE >= v2.x( v1.x 未测试过 )
- Arduino IDE 中安装 esp v2.x 开发板(不能大于 2.x )
- 需将
/client/libraries
中的插件导入到IDE插件中,默认位置在C:\Users\用户名\Documents\Arduino\libraries
。
文件名 | 备注 |
---|---|
arduino-audio-tool | 新版IDE可以直接搜索安装 |
arduinoWebSockets | 新版IDE可以直接搜索安装 |
esp-ai | esp-ai 暂时不可搜索安装 |
xiao_ming_tong_xue_inferencing | 离线语音识别模型 暂时不可搜索安装 |
- 注册讯飞开放平台账号(其他平台见下文支持度,也支持豆包、百度等)
- 获取讯飞开放平台账号的 appid 和 apikey
- 将 example/index.js、example/example.ino 这两个文件复制到本本地电脑中。
- 进入你电脑中的 example/ 目录中。
- 执行命令安装ESP-AI
# 或者使用:yarn add esp-ai
npm i esp-ai
- 运行服务
# 生产环境中请使用 pm2 来运行服务以保证服务的可靠和性能: pm2 start ./index.js -i max
node ./index.js
- 在
Arduino IDE
中打开example.ino
并且上传到开发板中。 - 接好线就搞定啦~
ESP32-s3 | INMP441 |
---|---|
3v3 | VDD |
GND | GND |
GND | L/R |
5 | WS |
4 | SCK |
6 | SD |
ESP32-s3 | Max98357A |
---|---|
3v3 | VDD |
GND | GND |
17 | LRC |
16 | BCLK |
15 | DIN |
ESP32-s3 | 电位器 |
---|---|
3v3 | VDD |
GND | GND |
OUT | 34 |
ESP32-s3 | LED |
---|---|
GND | GND |
18 | 正极 |
✔️ 已支持 ❗开发中 ❌ 不支持
开发板 | IAT | LLM | TTS | 离线唤醒 |
---|---|---|---|---|
ESP32-s3 | ✔️ | ✔️ | ✔️ | ✔️ |
nodemcu-32 | ✔️ | ✔️ | ✔️ | ❌ |
ESP32-xiao-s3 | ❗ | ❗ | ❗ | ✔️ |
增加中... |
✔️ 已支持 ❗开发中 ❌ 不支持
不同功能可以使用不同的服务商,比如服务中使用讯飞的TTS和阿里的LLM, 而不是只用讯飞的产品,只需要更改配置文件即可。
服务方 | IAT | LLM | TTS |
---|---|---|---|
本地服务(插件方式) | ✔️ | ✔️ | ✔️ |
讯飞 | ✔️ | ✔️ | ✔️ |
火山引擎(豆包等) | ❗ | ❗ | ✔️ |
阿里积灵(千问等) | ❗ | ✔️ | ❗ |
服务方 | 插件类型 | 插件地址 |
---|---|---|
海豚配音 | TTS | https://github.com/wangzongming/esp-ai-plugin-tts-ttson |
插件演示 | IAT | https://github.com/wangzongming/esp-ai-plugin-iat-example |
插件演示 | LLM | https://github.com/wangzongming/esp-ai-plugin-llm-example |
✔️ 已支持 ❗开发中 ❌ 不支持
方案 | 是否支持 | 模型开源仓库 |
---|---|---|
Edge Impulse | ✔️ | https://studio.edgeimpulse.com/studio/422422 |
ESP-SR | ❗ | ❗ |
增加中... |
INMP441(MIC) -> audio -> ESP32 -> wake-on-voice -> audio -> esp-ai -> IAT Server -> text -> esp-ai -> LLM -> reply -> esp-ai -> TTS -> esp-ai -> ESP32 -> max98357(loudspeaker)
待补充结构图
#include <esp-ai.h>
ESP_AI esp_ai;
// [必 填] 是否调试模式, 会输出更多信息
bool debug = true;
// [必 填] wifi 配置: { wifi 账号, wifi 密码 } 注意:要用双引号!
ESP_AI_wifi_config wifi_config = { "oldwang", "oldwang520" };
// [必 填] 服务配置: { 服务IP, 服务端口 }
ESP_AI_server_config server_config = { "192.168.1.5", 8080 };
// [必 填] 离线唤醒方案:{ 方案, 识别阈值 }, "edge_impulse" | "diy",为 "diy" 时可调用 esp_ai.wakeUp() 方法进行唤醒
ESP_AI_wake_up_config wake_up_config = { "edge_impulse", 0.7 };
// [可留空] 麦克风引脚配置:{ bck_io_num, ws_io_num, data_in_num }
ESP_AI_i2s_config_mic i2s_config_mic = {};
// [可留空] 扬声器引脚配置:{ bck_io_num, ws_io_num, data_in_num, 采样率(默认 1600) }
ESP_AI_i2s_config_speaker i2s_config_speaker = {};
// [可留空] 音量调节配置:{ 输入引脚,输入最大值(1024|4096),默认音量(0-1) }
ESP_AI_volume_config volume_config = { 34, 4096, 0.5 };
// 收到指令后的回调,比如开灯、关灯,由服务端配置。
void on_command(char command_id, char data) {
Serial.print("收到指令");
Serial.println(command_id);
Serial.println(data);
}
void setup() {
Serial.begin(115200);
// 开始运行 ESP-AI
esp_ai.begin({ i2s_config_mic, i2s_config_speaker, wifi_config, server_config, wake_up_config, volume_config, debug });
// wifi 测试代码
// Serial.println(esp_ai.wifiIsConnected() ? "已连接" : "未连接");
// Serial.println(esp_ai.localIP().c_str());
// 用户指令监听
esp_ai.onEvent(on_command);
}
void loop() {
// 连接wifi后会返回 True
if (!esp_ai.wifiIsConnected()) {
return;
}
esp_ai.loop();
}
提供 Typescript
定义文件,TS
项目也可正常引用。
const espAi = require("esp-ai");
espAi({
/**
* 服务端口, 默认 8080
*/
port: 8080,
/**
* 日志输出模式:0 不输出(线上模式), 1 普通输出, 2 详细输出
*/
devLog: 1,
/**
* 语音识别服务、TTS服务、LLM 服务的提供方, 默认为 xun_fei
* @value xun_fei 讯飞的服务
* @value dashscope 阿里-积灵
* @value bai_du 百度的服务(预计 1.0 版本支持)
* @value privatization 自己的服务(预计 1.0 版本支持)
*/
iat_server: "xun_fei",
tts_server: "xun_fei",
llm_server: "xun_fei",
// llm_server: "dashscope",
/**
* 不同的服务商需要配置对应的 key
* 每个服务商配置不是完全一样的,具体请参考文档
*/
api_key: {
// 讯飞:https://console.xfyun.cn/services/iat 。打开网址后,右上角三个字段复制进来即可。
xun_fei: {
appid: "xxx",
apiSecret: "ZjQwYxxxxxx",
apiKey: "9cd65073xxxxx",
// LLM 版本
llm: "v3.5",
},
// 阿里云-积灵: https://dashscope.console.aliyun.com/apiKey
// 积灵主要是提供llm(推荐使用这个llm服务)
dashscope: {
apiKey: "sk-xxxx",
// LLM 版本
llm: "qwen-turbo",
},
// 火山引擎(豆包等):https://console.volcengine.com/speech/service/8?AppID=6359932705
volcengine:{
// 火山引擎的TTS与LLM使用不同的key,所以需要分别配置
tts:{
// 服务接口认证信息
appid: "xxx",
accessToken: "xxx",
},
// 暂不支持 llm
llm:{
// 获取地址:https://console.volcengine.com/ark/region:ark+cn-beijing/endpoint?current=1&pageSize=10
model: "ep-xxx",// 每个模型都有一个id
// 获取地址:https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey
apiKey: "32dacfe4xxx",
}
},
// 海豚ai,适配中...
ttson:{
token: "ht-"
},
},
/**
* 意图表:当用户唤醒 小明同学 后,小明同学可以做下面的任务
*/
intention: [
{
// 关键词
key: ["帮我开灯", "开灯", "打开灯"],
// 向客户端发送的指令
instruct: "device_open_001",
message: "开啦!还有什么需要帮助的吗?"
},
{
// 关键词
key: ["帮我关灯", "关灯", "关闭灯"],
// 向客户端发送的指令
instruct: "device_close_001",
message: "关啦!还有什么需要帮助的吗?"
},
{
// 关键词
key: ["退下吧", "退下"],
// 内置的睡眠指令
instruct: "__sleep__",
message: "我先退下了,有需要再叫我。"
}
],
/**
* 初始化LLM时的提示
*/
llm_init_messages: [
{
"role": "system",
"content": "你是一个非常厉害的智能助手!你的名字叫小明同学。"
},
{
"role": "system",
"content": "你擅长用精简的句子来回答用户的问题。每次回答用户的问题最多都不会超过50字。除非用户指定多少字。"
},
],
/**
* 被唤醒后的回复
*/
f_reply: "小明在的",
/**
* 休息时的回复
*/
sleep_reply: "我先退下了,有需要再叫我。",
/**
* llm 参数控制, 可以设置温度等
*/
llm_params_set: (params) => {
// 千问top_p、top_k ...
// params.top_p = 0.5;
// 讯飞 temperature ...
// params.parameter.chat.temperature = 0.4;
// params.parameter.chat.max_tokens = 100;
// 改完后一定要返回出去
return params;
},
/**
* tts 参数控制, 可以设置说话人、音量、语速等
* 不同服务要求的参数格式和属性名字不同,根据下面属性进行配置
*/
tts_params_set: (params) => {
/** 阿里积灵 **/
// 说话人列表见:https://console.xfyun.cn/services/tts
// params.model = : "sambert-zhimiao-emo-v1"
/** 讯飞 **/
// 说话人列表见:https://help.aliyun.com/zh/dashscope/developer-reference/model-list-old-version?spm=a2c4g.11186623.0.0.5fbe490eBdtzX0
// params.vcn = "aisbabyxu";
/** 火山引擎 **/
// 说话人列表见:https://www.volcengine.com/docs/6561/97465
// params.voice_type = "BV051_streaming"
// params.voice_type = "BV021_streaming"
// params.voice_type = "BV506_streaming"
/** 海豚配音 **/
// token注册:https://www.ttson.cn/
// 说话人列表见:https://github.com/wangzongming/esp-ai/tree/master/src/functions/tts/ttson/角色列表.yaml
// params.voice_id = 2115;
// 改完后一定要返回出去
return params;
},
/**
* 新设备连接服务的回调
* @param {string} device_id 设备id
* @param {WebSocket} ws 连接句柄,可使用 ws.send() 发送数据
*/
onDeviceConnect({ device_id, ws }) { },
/**
* iat 回调
* @param {string} device_id 设备id
* @param {string} text 语音转的文字
*/
onIATcb({ device_id, text }) { },
/**
* tts 回调
* @param {string} device_id 设备id
* @param {Buffer} is_over 是否完毕
* @param {Buffer} audio 音频流
*/
onTTScb({ device_id, is_over, audio }) { },
/**
* llm 回调
* @param {string} device_id 设备id
* @param {string} text 大语言模型推理出来的文本片段
* @param {boolean} is_over 是否回答完毕
* @param {object[]} llm_historys 对话历史
*
*/
onLLMcb({ device_id, text, is_over, llm_historys }) { },
});
假如你按照插件仓库中的说明安装好插件后,只需要在配置中增加如下代码即可。
espAi({
plugins: [
// 引入插件
require("esp-ai-plugin-llm-xxx")
]
});
目前语音唤醒由于训练样本不多,准确度并不高,会持续优化。
欢迎 pr 一起共建~。