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 list = agentVoicePrintService.list(userId, id); return new Result>().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; }