From 81d0adf73c027e70c77ff71116406dd65cb84300 Mon Sep 17 00:00:00 2001
From: hrz <1710360675@qq.com>
Date: Fri, 11 Jul 2025 14:13:39 +0800
Subject: [PATCH] =?UTF-8?q?add:=E5=A3=B0=E7=BA=B9=E8=AF=86=E5=88=AB?=
=?UTF-8?q?=E5=BC=80=E5=90=AF=E6=95=99=E7=A8=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 21 ++--
docs/FAQ.md | 12 ++-
docs/mcp-endpoint-enable.md | 6 +-
docs/voiceprint-integration.md | 96 +++++++++++++++++++
.../controller/AgentVoicePrintController.java | 29 ++++--
.../modules/agent/dao/AgentVoicePrintDao.java | 4 +-
.../agent/entity/AgentVoicePrintEntity.java | 13 ++-
.../agent/service/AgentVoicePrintService.java | 11 +--
.../service/impl/ConfigServiceImpl.java | 2 -
main/manager-web/src/App.vue | 24 ++---
main/manager-web/src/views/VoicePrint.vue | 7 +-
11 files changed, 176 insertions(+), 49 deletions(-)
create mode 100644 docs/voiceprint-integration.md
diff --git a/README.md b/README.md
index b018d5b6..e2c31855 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
本项目为开源智能硬件项目
xiaozhi-esp32提供后端服务
根据小智通信协议使用Python、Java、Vue实现
-帮助您快速搭建小智服务器
+支持MCP接入点和声纹识别
@@ -225,11 +225,12 @@ Websocket接口地址: wss://2662r3426b.vicp.fun/xiaozhi/v1/
| 功能模块 | 描述 |
|:---:|:---|
-| 核心服务架构 | 基于WebSocket和HTTP服务器,提供完整的控制台管理和认证系统 |
-| 语音交互系统 | 支持流式ASR(语音识别)、流式TTS(语音合成)、VAD(语音活动检测),支持多语言识别和语音处理 |
-| 智能对话系统 | 支持多种LLM(大语言模型),实现智能对话 |
-| 视觉感知系统 | 支持多种VLLM(视觉大模型),实现多模态交互 |
-| 意图识别系统 | 支持LLM意图识别、Function Call函数调用,提供插件化意图处理机制 |
+| 核心架构 | 基于WebSocket和HTTP服务器,提供完整的控制台管理和认证系统 |
+| 语音交互 | 支持流式ASR(语音识别)、流式TTS(语音合成)、VAD(语音活动检测),支持多语言识别和语音处理 |
+| 声纹识别 | 支持多用户声纹注册、管理和识别,与ASR并行处理,实时识别说话人身份并传递给LLM进行个性化回应 |
+| 智能对话 | 支持多种LLM(大语言模型),实现智能对话 |
+| 视觉感知 | 支持多种VLLM(视觉大模型),实现多模态交互 |
+| 意图识别 | 支持LLM意图识别、Function Call函数调用,提供插件化意图处理机制 |
| 记忆系统 | 支持本地短期记忆、mem0ai接口记忆,具备记忆总结功能 |
| 工具调用 | 支持客户端IOT协议、客户MCP协议、服务端MCP协议、MCP接入点协议、自定义工具函数 |
| 管理后台 | 提供Web管理界面,支持用户管理、系统配置和设备管理 |
@@ -308,6 +309,14 @@ Websocket接口地址: wss://2662r3426b.vicp.fun/xiaozhi/v1/
---
+### Voiceprint 声纹识别
+
+| 使用方式 | 支持平台 | 免费平台 |
+|:---:|:---:|:---:|
+| 本地使用 | 3D-Speaker | 3D-Speaker |
+
+---
+
### Memory 记忆存储
| 类型 | 平台名称 | 使用方式 | 收费模式 | 备注 |
diff --git a/docs/FAQ.md b/docs/FAQ.md
index e2d428e3..8a884d7d 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -112,7 +112,17 @@ VAD:
参考教程[视觉模型使用指南](./mcp-vision-integration.md)
-### 10、更多问题,可联系我们反馈 💬
+### 10、如何开启MCP接入点 🔧
+
+1、先参考教程[MCP 接入点部署使用指南](./mcp-endpoint-enable.md)
+
+2、再参考教程[MCP 接入点使用指南](./mcp-endpoint-integration.md)
+
+### 12、如何开启声纹识别 🔊
+
+参考教程[声纹识别启用指南](./voiceprint-integration.md)
+
+### 13、更多问题,可联系我们反馈 💬
可以在[issues](https://github.com/xinnan-tech/xiaozhi-esp32-server/issues)提交您的问题。
diff --git a/docs/mcp-endpoint-enable.md b/docs/mcp-endpoint-enable.md
index 7bc72484..6b64ccac 100644
--- a/docs/mcp-endpoint-enable.md
+++ b/docs/mcp-endpoint-enable.md
@@ -1,9 +1,9 @@
# MCP 接入点部署使用指南
-本教程包含2个部分
+本教程包含3个部分
- 1、如何部署MCP接入点这个服务
-- 1、全模块部署时,怎么配置MCP接入点
-- 2、单模块部署时,怎么配置MCP接入点
+- 2、全模块部署时,怎么配置MCP接入点
+- 3、单模块部署时,怎么配置MCP接入点
# 1、如何部署MCP接入点这个服务
diff --git a/docs/voiceprint-integration.md b/docs/voiceprint-integration.md
new file mode 100644
index 00000000..c961dbb7
--- /dev/null
+++ b/docs/voiceprint-integration.md
@@ -0,0 +1,96 @@
+# 声纹识别启用指南
+
+本教程包含2个部分
+- 1、如何部署声纹识别这个服务
+- 2、全模块部署时,怎么配置声纹识别接口
+
+# 1、如何部署声纹识别这个服务
+
+## 第一步,下载声纹识别项目源码
+
+浏览器打开[声纹识别项目地址](https://github.com/xinnan-tech/voiceprint-api)
+
+打开完,找到页面中一个绿色的按钮,写着`Code`的按钮,点开它,然后你就看到`Download ZIP`的按钮。
+
+点击它,下载本项目源码压缩包。下载到你电脑后,解压它,此时它的名字可能叫`voiceprint-api-main`
+你需要把它重命名成`voiceprint-api`。
+
+## 第二步,启动程序
+这个项目是一个很简单的项目,建议使用docker运行。不过如果你不想使用docker运行,你可以参考[这个页面](https://github.com/xinnan-tech/voiceprint-api/blob/main/README.md)使用源码运行。以下是docker运行的方法
+
+```
+# 进入本项目源码根目录
+cd voiceprint-api
+
+# 清除缓存
+docker compose -f docker-compose.yml down
+docker stop voiceprint-api
+docker rm voiceprint-api
+docker rmi ghcr.nju.edu.cn/xinnan-tech/voiceprint-api:latest
+
+# 启动docker容器
+docker compose -f docker-compose.yml up -d
+# 查看日志
+docker logs -f voiceprint-api
+```
+
+此时,日志里会输出类似以下的日志
+```
+250711 INFO-🚀 开始: 生产环境服务启动(Uvicorn),监听地址: 0.0.0.0:8005
+250711 INFO-============================================================
+250711 INFO-声纹接口地址: http://127.0.0.1:8005/voiceprint/health?key=abcd
+250711 INFO-============================================================
+```
+
+请你把声纹接口地址复制出来:
+
+由于你是docker部署,切不可直接使用上面的地址!
+
+由于你是docker部署,切不可直接使用上面的地址!
+
+由于你是docker部署,切不可直接使用上面的地址!
+
+你先把地址复制出来,放在一个草稿里,你要知道你的电脑的局域网ip是什么,例如我的电脑局域网ip是`192.168.1.25`,那么
+原来我的接口地址
+```
+http://127.0.0.1:8005/voiceprint/health?key=abcd
+
+```
+就要改成
+```
+http://192.168.1.25:8005/voiceprint/health?key=abcd
+```
+
+改好后,请使用浏览器直接访问`声纹接口地址`。当浏览器出现类似这样的代码,说明是成功了。
+```
+{"total_voiceprints":0,"status":"healthy"}
+```
+
+请你保留好修改后的`声纹接口地址`,下一步要用到。
+
+# 2、全模块部署时,怎么配置声纹识别
+
+## 第一步 配置接口
+如果你是全模块部署,使用管理员账号,登录智控台,点击顶部`参数字典`,选择`参数管理`功能。
+
+然后搜索参数`server.voice_print`,此时,它的值应该是`null`值。
+点击修改按钮,把上一步得来的`声纹接口地址`粘贴到`参数值`里。然后保存。
+
+如果能保存成功,说明一切顺利,你可以去智能体查看效果了。如果不成功,说明智控台无法访问声纹识别,很大概率是网络防火墙,或者没有填写正确的局域网ip。
+
+## 第二步 设置智能体记忆模式
+
+进入你的智能体的角色配置里,将记忆设置成`本地短期记忆`,一定要开启`上报文字+语音`。
+
+## 第三步 和你的智能体聊天
+
+将你的设备通电,然后和他用正常的语速和音调聊天。
+
+## 第四步 设置声纹
+
+在智控台,`智能体管理`页面,在智能体的面板里,有一个`声纹识别`按钮,点击它。在底部有一个`新增按钮`。就可以对某个人说的话进行声纹注册。
+在弹出的框里,`描述`这个属性建议填写上,可以是这个人的职业、性格、爱好。方便智能体对说话人进行分析和了解。
+
+## 第三步 和你的智能体聊天
+
+将你的设备通电,问它,你知道我是谁吗?如果他能回答得出,说明声纹识别功能正常。
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentVoicePrintController.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentVoicePrintController.java
index cce97a09..1615cee5 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentVoicePrintController.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentVoicePrintController.java
@@ -1,19 +1,30 @@
package xiaozhi.modules.agent.controller;
+import java.util.List;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
-import org.apache.shiro.authz.annotation.RequiresPermissions;
-import org.springframework.web.bind.annotation.*;
+import xiaozhi.common.exception.RenException;
import xiaozhi.common.utils.Result;
import xiaozhi.modules.agent.dto.AgentVoicePrintSaveDTO;
import xiaozhi.modules.agent.dto.AgentVoicePrintUpdateDTO;
import xiaozhi.modules.agent.service.AgentVoicePrintService;
import xiaozhi.modules.agent.vo.AgentVoicePrintVO;
import xiaozhi.modules.security.user.SecurityUser;
-
-import java.util.List;
+import xiaozhi.modules.sys.service.SysParamsService;
@Tag(name = "智能体声纹管理")
@AllArgsConstructor
@@ -21,6 +32,7 @@ import java.util.List;
@RequestMapping("/agent/voice-print")
public class AgentVoicePrintController {
private final AgentVoicePrintService agentVoicePrintService;
+ private final SysParamsService sysParamsService;
@PostMapping
@Operation(summary = "创建智能体的声纹")
@@ -62,14 +74,13 @@ public class AgentVoicePrintController {
@Operation(summary = "获取用户指定智能体声纹列表")
@RequiresPermissions("sys:role:normal")
public Result> list(@PathVariable String id) {
+ String voiceprintUrl = sysParamsService.getValue("server.voice_print", true);
+ if (StringUtils.isBlank(voiceprintUrl) || "null".equals(voiceprintUrl)) {
+ throw new RenException("声纹接口未配置,请先在参数配置中配置声纹接口地址(server.voice_print)");
+ }
Long userId = SecurityUser.getUserId();
List
>().ok(list);
}
-
-
}
-
-
-
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentVoicePrintDao.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentVoicePrintDao.java
index 2d8e1eda..1a5ee364 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentVoicePrintDao.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentVoicePrintDao.java
@@ -1,7 +1,9 @@
package xiaozhi.modules.agent.dao;
-import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
import xiaozhi.modules.agent.entity.AgentChatHistoryEntity;
import xiaozhi.modules.agent.entity.AgentVoicePrintEntity;
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentVoicePrintEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentVoicePrintEntity.java
index 99f2f122..4998b288 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentVoicePrintEntity.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentVoicePrintEntity.java
@@ -1,12 +1,15 @@
package xiaozhi.modules.agent.entity;
-import com.baomidou.mybatisplus.annotation.*;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import xiaozhi.common.entity.BaseEntity;
-
import java.util.Date;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import lombok.Data;
+
/**
* 智能体声纹表
*
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentVoicePrintService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentVoicePrintService.java
index d6264e71..c9d38abd 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentVoicePrintService.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentVoicePrintService.java
@@ -1,12 +1,11 @@
package xiaozhi.modules.agent.service;
+import java.util.List;
import xiaozhi.modules.agent.dto.AgentVoicePrintSaveDTO;
import xiaozhi.modules.agent.dto.AgentVoicePrintUpdateDTO;
import xiaozhi.modules.agent.vo.AgentVoicePrintVO;
-import java.util.List;
-
/**
* 智能体声纹处理service
*
@@ -24,7 +23,7 @@ public interface AgentVoicePrintService {
/**
* 删除智能体的指的声纹
*
- * @param userId 当前登录的用户id
+ * @param userId 当前登录的用户id
* @param voicePrintId 声纹id
* @return 是否成功 T:成功 F:失败
*/
@@ -33,7 +32,7 @@ public interface AgentVoicePrintService {
/**
* 获取指定智能体的所有声纹数据
*
- * @param userId 当前登录的用户id
+ * @param userId 当前登录的用户id
* @param agentId 智能体id
* @return 声纹数据集合
*/
@@ -43,11 +42,9 @@ public interface AgentVoicePrintService {
* 更新智能体的指的声纹数据
*
* @param userId 当前登录的用户id
- * @param dto 修改的声纹的数据
+ * @param dto 修改的声纹的数据
* @return 是否成功 T:成功 F:失败
*/
boolean update(Long userId, AgentVoicePrintUpdateDTO dto);
-
-
}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/config/service/impl/ConfigServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/config/service/impl/ConfigServiceImpl.java
index 0e237b8f..476f09cd 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/config/service/impl/ConfigServiceImpl.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/config/service/impl/ConfigServiceImpl.java
@@ -28,7 +28,6 @@ import xiaozhi.modules.agent.service.AgentMcpAccessPointService;
import xiaozhi.modules.agent.service.AgentPluginMappingService;
import xiaozhi.modules.agent.service.AgentService;
import xiaozhi.modules.agent.service.AgentTemplateService;
-import xiaozhi.modules.agent.service.AgentVoicePrintService;
import xiaozhi.modules.agent.vo.AgentVoicePrintVO;
import xiaozhi.modules.config.service.ConfigService;
import xiaozhi.modules.device.entity.DeviceEntity;
@@ -52,7 +51,6 @@ public class ConfigServiceImpl implements ConfigService {
private final TimbreService timbreService;
private final AgentPluginMappingService agentPluginMappingService;
private final AgentMcpAccessPointService agentMcpAccessPointService;
- private final AgentVoicePrintService agentVoicePrintService;
private final AgentVoicePrintDao agentVoicePrintDao;
@Override
diff --git a/main/manager-web/src/App.vue b/main/manager-web/src/App.vue
index 0eefc0bc..29970c96 100644
--- a/main/manager-web/src/App.vue
+++ b/main/manager-web/src/App.vue
@@ -42,7 +42,7 @@ nav {
}
.el-message {
- top: 45px !important;
+ top: 70px !important;
}