(原) 小智AI研究及扩展

原创文章,请后转载,并注明出处。

购买了一个小智AI,它相当于一个“天猫智障精灵”或“小爱音箱”。当然没有它们那么完善,暂时还没有接入其它智能设备。不过接入了AI后,显得比较智能,且当它是一个“聊天助手”吧。

如果能自行接入,即自己建立服务器,或者本地建立部份服务(即本地能够定义并响应部份关键词)就更强大了。

看它开源的情况,应该可以自己做如上的一些改动。

改进/进阶

  1. 外壳改为可配带(戴在手表)
  2. 外壳改为可磁吸(放在胸前)
  3. 增加摄像头(让它可以感知世界)
  4. 建立个人服务器,增加个人资料
  5. 电池插件(现在的电池支持估计6小时?毕竟只有300毫安)
  6. 通过TypeC扩展一个底座,让它可以自由行走
  7. 让它能响应本地服务,控制本地硬件

在本地搭建服务端,准备添加一些本地服务,例如播放本地音乐,操作设备等。


2025.3.5
在xiaozhi-esp32-server的基础上添加一个第三方请求,将语音转向到本地电脑上,基本实现语音控制电脑相关东西。

试用了两个python版本的PC小智12
Godot加上小智服务,加上本地控制,一个实用型的桌面宠物呼之欲出。


最新消息是安卓版的也有了,尚在测试中


2025.3.8

小智固件编译

这里也讲到了如何通过源码编译

  1. 安装ESP IDF
  2. 启动ESP IDF,进入xiaozhi-esp32
  3. idf.py set-target esp32c3
  4. idf.py menuconfig 配置
  5. Xiaozhi Assistan -> Board Type -> 虾哥MiniC3
  6. idf.py build进行编译
  7. idf.py build flash monitor进行下载和显示日志

关于唤醒词的修改,这个mini版本因为是使用C3还用不到(需要S3支持)。


2025.3.8

小智固件更新到1.4.5, 本地服务似乎也更新了。
将修改的部份记录在这里备用,以备"被更(新覆盖)"

在core\handle\receiveAudioHandle.py中修改

from core.handle.sendAudioHandle import sendAudioMessage
import aiohttp
import asyncio
import os
import json
...


            text, file_path = await conn.asr.speech_to_text(conn.asr_audio, conn.session_id)
            logger.bind(tag=TAG).info(f"识别文本: {text}")

            text_len, text_without_punctuation = remove_punctuation_and_length(text)
            # Ease 调用自己的服务功能 ---------------------------
            if await my_service(conn, text, file_path):
                prompt = "服务已响应"
                #await send_stt_message(conn, prompt) # 增加服务已响应的语音提示
                loop = asyncio.get_event_loop()
                # 生成 TTS 语音
                future = conn.executor.submit(conn.speak_and_play, prompt)
                conn.tts_queue.put(future)

                # 立即恢复监听状态
                conn.client_abort = False
                conn.asr_server_receive = True
                conn.client_voice_stop = False  # 新增关键重置项
                conn.asr_audio.clear()
                return  # 提前返回避免执行后续逻辑
            # Ease --------------------------------------------   
            else:     
                if await conn.music_handler.handle_music_command(conn, text_without_punctuation):
                    conn.asr_server_receive = True
                    conn.asr_audio.clear()
                    return
                if text_len <= conn.max_cmd_length and await handleCMDMessage(conn, text_without_punctuation):
                    return
                if text_len > 0:   
                        await startToChat(conn, text)
                else:
                    conn.asr_server_receive = True
        conn.asr_audio.clear()
        conn.reset_vad_states()

...

# -------------------------

async def my_service(conn, text, file_path):
    # 你的服务功能实现
    # logger.bind(tag=TAG).info(f"调用自定义服务处理文本: {text} 和文件路径: {file_path}")
    try:
        response = await some_api_call(text, file_path)
        logger.bind(tag=TAG).info(f"自定义服务响应: {response}")
        if response.get('ret') == 1:
            return True
        else:
            return False
    except Exception as e:
        logger.bind(tag=TAG).error(f"自定义服务调用失败: {e}")
        return False

async def some_api_call(text, file_path):
    url = "https://abc.scwy.net/api"  # 替换为实际的 API URL
    payload = {
        "text": text,
        "file_path": file_path
    }
    async with aiohttp.ClientSession() as session:
        async with session.post(url, json=payload) as response:
            if response.status == 200:
                return await response.json()
            else:
                raise Exception(f"API请求失败,状态码: {response.status}")

相关文章