aichat_sdk 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aichat_sdk-0.1.2/.gitignore +27 -0
- aichat_sdk-0.1.2/PKG-INFO +144 -0
- aichat_sdk-0.1.2/README.md +109 -0
- aichat_sdk-0.1.2/aichat_sdk/__init__.py +418 -0
- aichat_sdk-0.1.2/aichat_sdk/asr/asr_client.py +206 -0
- aichat_sdk-0.1.2/aichat_sdk/config.py +17 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/__init__.py +160 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/mcp/__init__.py +322 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/mcp/external.py +156 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/mcp/mcp_end_session.py +10 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/mcp/mcp_exec.py +32 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/mcp/mcp_read_skill.py +44 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/mcp/server.py +8 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/openai_client.py +253 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/skills.py +63 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/system_prompt/__init__.py +49 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/system_prompt/system.jinja2 +67 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/type_enum.py +21 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/utils/__init__.py +0 -0
- aichat_sdk-0.1.2/aichat_sdk/llm/utils/calendar.py +182 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/__init__.py +17 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/__main__.py +17 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/mcp_joke.py +50 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/mcp_play_music.py +67 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/mcp_weather.py +51 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/mcp_web_search.py +162 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/music//344/270/200/350/267/257/345/220/221/345/214/227.jsonl +72 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/music//346/231/264/345/244/251.jsonl +126 -0
- aichat_sdk-0.1.2/aichat_sdk/mcp_tool/server.py +8 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/__init__.py +54 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/bytedancev1/bidirection.py +338 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/bytedancev1/protocols.py +508 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/bytedancev2/bidirection.py +373 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/bytedancev2/protocols/__init__.py +41 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/bytedancev2/protocols/protocols.py +527 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/edge/__init__.py +0 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/edge/bidirection.py +184 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/edge/main.py +94 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/mimo/__init__.py +1 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/mimo/bidirection.py +127 -0
- aichat_sdk-0.1.2/aichat_sdk/tts/mimo/main.py +88 -0
- aichat_sdk-0.1.2/aichat_sdk/utils/event_emitter.py +81 -0
- aichat_sdk-0.1.2/aichat_sdk/utils/opus_codec.py +136 -0
- aichat_sdk-0.1.2/pyproject.toml +55 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
build
|
|
2
|
+
dist
|
|
3
|
+
*.egg
|
|
4
|
+
*.egg-info
|
|
5
|
+
.DS_Store
|
|
6
|
+
__pycache__/
|
|
7
|
+
.idea/
|
|
8
|
+
|
|
9
|
+
# uv
|
|
10
|
+
.venv/
|
|
11
|
+
|
|
12
|
+
# pytest and coverage
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.coverage
|
|
15
|
+
htmlcov/
|
|
16
|
+
|
|
17
|
+
# mypy
|
|
18
|
+
.mypy_cache/
|
|
19
|
+
|
|
20
|
+
.env
|
|
21
|
+
*.log
|
|
22
|
+
*.pt
|
|
23
|
+
|
|
24
|
+
aichat_sdk/asr/audio_*
|
|
25
|
+
|
|
26
|
+
examples/web/config.json
|
|
27
|
+
examples/web/sessions/
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: aichat_sdk
|
|
3
|
+
Version: 0.1.2
|
|
4
|
+
Summary: Voice chat SDK with streaming LLMs, MCP tools, and ByteDance, Edge, and MiMo TTS.
|
|
5
|
+
Project-URL: Homepage, https://gitee.com/fa0/aichat_sdk
|
|
6
|
+
Project-URL: Repository, https://gitee.com/fa0/aichat_sdk
|
|
7
|
+
Author: dairoot
|
|
8
|
+
Keywords: chat,openai,sdk,tts
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: av>=12.0
|
|
20
|
+
Requires-Dist: edge-tts>=7.0
|
|
21
|
+
Requires-Dist: fastmcp>=3.4.7
|
|
22
|
+
Requires-Dist: jinja2>=3.1.0
|
|
23
|
+
Requires-Dist: lunardate==0.2.2
|
|
24
|
+
Requires-Dist: numpy>=1.24
|
|
25
|
+
Requires-Dist: openai>=1.40.0
|
|
26
|
+
Requires-Dist: pydantic>=2.0
|
|
27
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
28
|
+
Requires-Dist: python-socks>=3.0.0
|
|
29
|
+
Requires-Dist: pyyaml>=6.0
|
|
30
|
+
Requires-Dist: sounddevice>=0.5.6
|
|
31
|
+
Requires-Dist: websockets>=12.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: types-pyyaml>=6.0.12; extra == 'dev'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# aichat_sdk
|
|
37
|
+
|
|
38
|
+
一个语音对话 SDK。用户对着麦克风说话,SDK 负责听懂(语音识别)、想清楚(大模型 + 工具)、说出来(语音合成),宿主程序只需要把声音收进来、把声音放出去。
|
|
39
|
+
|
|
40
|
+
## 它能做什么
|
|
41
|
+
|
|
42
|
+
- **像人一样聊天**:回复是口语、短句,不念标题、不念符号,适合直接朗读;用户随时插话就能打断
|
|
43
|
+
- **会查东西**:天气、笑话、联网搜索(微博、搜狗,不用配 key),还能按需接入外部 MCP 工具
|
|
44
|
+
- **会用技能**:读取本机 `~/.agents/skills` 下的技能说明,按里面的指引一步步执行命令,比如查飞书群聊、发消息、看日程
|
|
45
|
+
- **会放音乐**:本地曲库点歌,边放边推歌词
|
|
46
|
+
- **知道时间和地点**:公历、农历、临近节日、用户所在城市,都会告诉模型
|
|
47
|
+
- **自己结束对话**:聊完了或者空闲太久,会说句再见然后关会话
|
|
48
|
+
|
|
49
|
+
## 它是怎么工作的
|
|
50
|
+
|
|
51
|
+
整条链路是一根事件驱动的流水线:
|
|
52
|
+
|
|
53
|
+
1. **听**:麦克风的声音通过 WebSocket 送到独立的 ASR 服务(单独的 `asr_server` 仓库,识别、断句、声纹都在那边),识别结果回到 SDK
|
|
54
|
+
2. **想**:识别出的文字交给大模型。模型可以直接回答,也可以先调工具、读技能、执行命令,拿到结果再回答;整个过程流式进行,第一个字出来就开始往下传
|
|
55
|
+
3. **说**:模型每吐出一点文字就喂给语音合成,合成出的音频编成 Opus 包排进队列
|
|
56
|
+
4. **播**:宿主从队列里按顺序取消息——识别结果、工具调用、每句话的开始和结束、音频包、歌词、结束信号——自己解码播放
|
|
57
|
+
|
|
58
|
+
有一条必须遵守的约定:**收到音频就把麦克风静音,收到「音频播完」再恢复拾音**,否则机器会听见自己说话。
|
|
59
|
+
|
|
60
|
+
## 大模型这一层
|
|
61
|
+
|
|
62
|
+
- 支持任何 OpenAI 兼容的接口,实际用过 DeepSeek 和通义千问
|
|
63
|
+
- 系统提示词是模板生成的,把角色人设、当前日期、用户位置、可用技能清单一起注入;提示词专门为语音场景写,要求模型说人话、说短话
|
|
64
|
+
- **思考模式按需开关**:用户刚说完话的第一次调用不开思考,保证回得快;一旦调过工具,后面的调用就打开思考,让推理过程走单独的通道、不会被念出来(`AgentInfo.tool_thinking` 可关掉,网页控制台上也有对应勾选框)。这么做是因为某些模型关掉思考后会把「让我先看看」这类内心独白直接写进回复,提示词管不住
|
|
65
|
+
- 推理内容会保存在对话记录里,web 页面上折叠显示,方便排查模型为什么这么答
|
|
66
|
+
|
|
67
|
+
## 0.1.2 更新
|
|
68
|
+
|
|
69
|
+
ASR、`ChatBot.send_text()` 和 LLM 用户消息统一使用 `speaker` 字段,原 `username`
|
|
70
|
+
字段及 `get_username()` 钩子已移除,接入方需同步更新消息解析和调用参数。
|
|
71
|
+
ASR 返回的说话人直接传入 LLM,SDK 不进行二次声纹匹配。
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
uv pip install --upgrade aichat-sdk==0.1.2
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 说话人
|
|
78
|
+
|
|
79
|
+
ASR 的 STT 消息中的 `speaker` 会经 `ChatBot.send_text()` 传入 LLM,写入该条 user
|
|
80
|
+
消息 JSON 的 `speaker` 字段。说话人以 ASR 返回值为准,SDK 不进行二次匹配或改写。
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
await chat_bot.send_text("打开客厅灯", speaker="speaker_1", audio_url=audio_url)
|
|
84
|
+
# ASR 已返回真实姓名时:
|
|
85
|
+
await chat_bot.send_text("打开客厅灯", speaker="小明", audio_url=audio_url)
|
|
86
|
+
# 直接使用 LlmAgent 时:
|
|
87
|
+
await chat_bot.llm.chat("打开客厅灯", "user", speaker="小明")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
省略、传 `None` 或空字符串时不写入 `speaker`;每条消息独立,不沿用上一位说话人。
|
|
91
|
+
`unknown` 表示无法识别,不能视为固定的同一个人。提示词约定匿名编号只用于区分说话人,
|
|
92
|
+
不作为姓名称呼;真实姓名可用于称呼。SDK 不执行声纹匹配或保存声纹库。
|
|
93
|
+
|
|
94
|
+
## 语音合成
|
|
95
|
+
|
|
96
|
+
- **字节跳动**(默认):服务端双向流式,逐字喂进去就出声,延迟最低;`tts_engine="bytedancev1"`(默认,简写 `v1`)或 `"bytedancev2"`(简写 `v2`)
|
|
97
|
+
- **微软 Edge**:免 key,按标点切成小段并发请求,段短所以首包也快
|
|
98
|
+
- **小米 MiMo**:`tts_engine="mimo"`,使用 `mimo-v2.5-tts` 预置音色,按标点分段请求、逐段流式输出 24kHz PCM,支持插话打断
|
|
99
|
+
|
|
100
|
+
各引擎输出格式一致,切换只需要改一个参数。
|
|
101
|
+
|
|
102
|
+
从 `0.1.0` 升级到 `0.1.1` 时,原 `bytedance`、`v2`、`bytedancev2` 配置改用 `bytedancev1`(简写 `v1`);原 `v3`、`bytedancev3` 改用 `bytedancev2`(简写 `v2`)。直接导入 TTS 模块时也需同步调整路径,旧 `tts/bytedance/` 实现已删除。默认引擎仍使用原来的实现。
|
|
103
|
+
|
|
104
|
+
可通过 `from aichat_sdk import get_tts_engines` 查询 SDK 支持的引擎,返回每个引擎的 `name`、`label`、`aliases` 和 `default`。查询目录无需配置密钥,也不会加载各引擎依赖或发起连接;web 配置台的下拉选项和配置校验均使用该目录。
|
|
105
|
+
|
|
106
|
+
### 使用 MiMo TTS
|
|
107
|
+
|
|
108
|
+
按 [MiMo 官方文档](https://mimo.mi.com/docs/zh-CN/quick-start/usage-guide/audio/speech-synthesis-v2.5) 获取 API Key,在环境变量或 `.env` 中配置:
|
|
109
|
+
|
|
110
|
+
```dotenv
|
|
111
|
+
MIMO_API_KEY=你的小米MiMo密钥
|
|
112
|
+
MIMO_TTS_VOICE=mimo_default
|
|
113
|
+
# 可选:语气、语速等自然语言指令,不会被朗读
|
|
114
|
+
MIMO_TTS_INSTRUCTIONS=用自然、温柔的语气说话
|
|
115
|
+
# 可选,默认地址如下
|
|
116
|
+
# MIMO_BASE_URL=https://api.xiaomimimo.com/v1
|
|
117
|
+
MIMO_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
使用 `.env` 时,在导入 SDK 前加载配置(web 配置台已自动加载):
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from dotenv import load_dotenv
|
|
124
|
+
|
|
125
|
+
load_dotenv()
|
|
126
|
+
from aichat_sdk import ChatBot
|
|
127
|
+
|
|
128
|
+
chat_bot = ChatBot(tts_engine="mimo")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
其余初始化、拾音和队列播放流程与现有示例相同;web 配置台也可直接选择 `mimo`。`MIMO_API_KEY` 独立于聊天模型的 `OPENAI_API_KEY`。音色默认 `mimo_default`,可改为 `冰糖`、`茉莉`、`苏打`、`白桦` 等预置音色。
|
|
132
|
+
|
|
133
|
+
MiMo 每次请求接收一段完整文本;SDK 在逗号、句号等停顿处发起请求,段内边收音频边推送,结束时补发未带标点的尾句。当前接入预置音色合成,音色设计和音色克隆模型尚未接入。
|
|
134
|
+
|
|
135
|
+
## 怎么试
|
|
136
|
+
|
|
137
|
+
- 配好 `.env`:大模型的地址、模型名和 key;用字节 TTS 的话再加它的 App ID 和 Key;ASR 服务地址不改就用默认的本机端口
|
|
138
|
+
- 先把 `asr_server` 跑起来
|
|
139
|
+
- 有麦克风和扬声器就运行 `tests/test_run_v2.py` 直接对话;没有麦克风就运行 `tests/test_run.py`,它在代码里塞了两句话进去
|
|
140
|
+
- 想边聊边改配置,运行 `examples/web/main.py`,浏览器打开本机 8080 端口:可以换模型、换音色、改人设、开关工具、配外部 MCP,保存后立即生效;聊天信息通过「实时聊天」和「详细信息」两个标签切换,默认显示实时聊天。「详细信息」查看 `llm.messages` 模型上下文(含工具调用、思考),「实时聊天」查看 `chat_bot.receive_item()` 实际消费的识别文本、助手语句、工具、歌词和会话结束事件(不显示音频包、语句结束和播放结束)。重新开始会清空两份记录,每轮聊完仍自动保存完整的 `llm.messages`
|
|
141
|
+
|
|
142
|
+
## 给开发者
|
|
143
|
+
|
|
144
|
+
要改代码,先看 `AGENTS.md`:队列和事件的实现细节、MCP 工具怎么注册注销、TTS 会话的生命周期限制、各种踩过的坑都记在那里。
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# aichat_sdk
|
|
2
|
+
|
|
3
|
+
一个语音对话 SDK。用户对着麦克风说话,SDK 负责听懂(语音识别)、想清楚(大模型 + 工具)、说出来(语音合成),宿主程序只需要把声音收进来、把声音放出去。
|
|
4
|
+
|
|
5
|
+
## 它能做什么
|
|
6
|
+
|
|
7
|
+
- **像人一样聊天**:回复是口语、短句,不念标题、不念符号,适合直接朗读;用户随时插话就能打断
|
|
8
|
+
- **会查东西**:天气、笑话、联网搜索(微博、搜狗,不用配 key),还能按需接入外部 MCP 工具
|
|
9
|
+
- **会用技能**:读取本机 `~/.agents/skills` 下的技能说明,按里面的指引一步步执行命令,比如查飞书群聊、发消息、看日程
|
|
10
|
+
- **会放音乐**:本地曲库点歌,边放边推歌词
|
|
11
|
+
- **知道时间和地点**:公历、农历、临近节日、用户所在城市,都会告诉模型
|
|
12
|
+
- **自己结束对话**:聊完了或者空闲太久,会说句再见然后关会话
|
|
13
|
+
|
|
14
|
+
## 它是怎么工作的
|
|
15
|
+
|
|
16
|
+
整条链路是一根事件驱动的流水线:
|
|
17
|
+
|
|
18
|
+
1. **听**:麦克风的声音通过 WebSocket 送到独立的 ASR 服务(单独的 `asr_server` 仓库,识别、断句、声纹都在那边),识别结果回到 SDK
|
|
19
|
+
2. **想**:识别出的文字交给大模型。模型可以直接回答,也可以先调工具、读技能、执行命令,拿到结果再回答;整个过程流式进行,第一个字出来就开始往下传
|
|
20
|
+
3. **说**:模型每吐出一点文字就喂给语音合成,合成出的音频编成 Opus 包排进队列
|
|
21
|
+
4. **播**:宿主从队列里按顺序取消息——识别结果、工具调用、每句话的开始和结束、音频包、歌词、结束信号——自己解码播放
|
|
22
|
+
|
|
23
|
+
有一条必须遵守的约定:**收到音频就把麦克风静音,收到「音频播完」再恢复拾音**,否则机器会听见自己说话。
|
|
24
|
+
|
|
25
|
+
## 大模型这一层
|
|
26
|
+
|
|
27
|
+
- 支持任何 OpenAI 兼容的接口,实际用过 DeepSeek 和通义千问
|
|
28
|
+
- 系统提示词是模板生成的,把角色人设、当前日期、用户位置、可用技能清单一起注入;提示词专门为语音场景写,要求模型说人话、说短话
|
|
29
|
+
- **思考模式按需开关**:用户刚说完话的第一次调用不开思考,保证回得快;一旦调过工具,后面的调用就打开思考,让推理过程走单独的通道、不会被念出来(`AgentInfo.tool_thinking` 可关掉,网页控制台上也有对应勾选框)。这么做是因为某些模型关掉思考后会把「让我先看看」这类内心独白直接写进回复,提示词管不住
|
|
30
|
+
- 推理内容会保存在对话记录里,web 页面上折叠显示,方便排查模型为什么这么答
|
|
31
|
+
|
|
32
|
+
## 0.1.2 更新
|
|
33
|
+
|
|
34
|
+
ASR、`ChatBot.send_text()` 和 LLM 用户消息统一使用 `speaker` 字段,原 `username`
|
|
35
|
+
字段及 `get_username()` 钩子已移除,接入方需同步更新消息解析和调用参数。
|
|
36
|
+
ASR 返回的说话人直接传入 LLM,SDK 不进行二次声纹匹配。
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv pip install --upgrade aichat-sdk==0.1.2
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 说话人
|
|
43
|
+
|
|
44
|
+
ASR 的 STT 消息中的 `speaker` 会经 `ChatBot.send_text()` 传入 LLM,写入该条 user
|
|
45
|
+
消息 JSON 的 `speaker` 字段。说话人以 ASR 返回值为准,SDK 不进行二次匹配或改写。
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
await chat_bot.send_text("打开客厅灯", speaker="speaker_1", audio_url=audio_url)
|
|
49
|
+
# ASR 已返回真实姓名时:
|
|
50
|
+
await chat_bot.send_text("打开客厅灯", speaker="小明", audio_url=audio_url)
|
|
51
|
+
# 直接使用 LlmAgent 时:
|
|
52
|
+
await chat_bot.llm.chat("打开客厅灯", "user", speaker="小明")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
省略、传 `None` 或空字符串时不写入 `speaker`;每条消息独立,不沿用上一位说话人。
|
|
56
|
+
`unknown` 表示无法识别,不能视为固定的同一个人。提示词约定匿名编号只用于区分说话人,
|
|
57
|
+
不作为姓名称呼;真实姓名可用于称呼。SDK 不执行声纹匹配或保存声纹库。
|
|
58
|
+
|
|
59
|
+
## 语音合成
|
|
60
|
+
|
|
61
|
+
- **字节跳动**(默认):服务端双向流式,逐字喂进去就出声,延迟最低;`tts_engine="bytedancev1"`(默认,简写 `v1`)或 `"bytedancev2"`(简写 `v2`)
|
|
62
|
+
- **微软 Edge**:免 key,按标点切成小段并发请求,段短所以首包也快
|
|
63
|
+
- **小米 MiMo**:`tts_engine="mimo"`,使用 `mimo-v2.5-tts` 预置音色,按标点分段请求、逐段流式输出 24kHz PCM,支持插话打断
|
|
64
|
+
|
|
65
|
+
各引擎输出格式一致,切换只需要改一个参数。
|
|
66
|
+
|
|
67
|
+
从 `0.1.0` 升级到 `0.1.1` 时,原 `bytedance`、`v2`、`bytedancev2` 配置改用 `bytedancev1`(简写 `v1`);原 `v3`、`bytedancev3` 改用 `bytedancev2`(简写 `v2`)。直接导入 TTS 模块时也需同步调整路径,旧 `tts/bytedance/` 实现已删除。默认引擎仍使用原来的实现。
|
|
68
|
+
|
|
69
|
+
可通过 `from aichat_sdk import get_tts_engines` 查询 SDK 支持的引擎,返回每个引擎的 `name`、`label`、`aliases` 和 `default`。查询目录无需配置密钥,也不会加载各引擎依赖或发起连接;web 配置台的下拉选项和配置校验均使用该目录。
|
|
70
|
+
|
|
71
|
+
### 使用 MiMo TTS
|
|
72
|
+
|
|
73
|
+
按 [MiMo 官方文档](https://mimo.mi.com/docs/zh-CN/quick-start/usage-guide/audio/speech-synthesis-v2.5) 获取 API Key,在环境变量或 `.env` 中配置:
|
|
74
|
+
|
|
75
|
+
```dotenv
|
|
76
|
+
MIMO_API_KEY=你的小米MiMo密钥
|
|
77
|
+
MIMO_TTS_VOICE=mimo_default
|
|
78
|
+
# 可选:语气、语速等自然语言指令,不会被朗读
|
|
79
|
+
MIMO_TTS_INSTRUCTIONS=用自然、温柔的语气说话
|
|
80
|
+
# 可选,默认地址如下
|
|
81
|
+
# MIMO_BASE_URL=https://api.xiaomimimo.com/v1
|
|
82
|
+
MIMO_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
使用 `.env` 时,在导入 SDK 前加载配置(web 配置台已自动加载):
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from dotenv import load_dotenv
|
|
89
|
+
|
|
90
|
+
load_dotenv()
|
|
91
|
+
from aichat_sdk import ChatBot
|
|
92
|
+
|
|
93
|
+
chat_bot = ChatBot(tts_engine="mimo")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
其余初始化、拾音和队列播放流程与现有示例相同;web 配置台也可直接选择 `mimo`。`MIMO_API_KEY` 独立于聊天模型的 `OPENAI_API_KEY`。音色默认 `mimo_default`,可改为 `冰糖`、`茉莉`、`苏打`、`白桦` 等预置音色。
|
|
97
|
+
|
|
98
|
+
MiMo 每次请求接收一段完整文本;SDK 在逗号、句号等停顿处发起请求,段内边收音频边推送,结束时补发未带标点的尾句。当前接入预置音色合成,音色设计和音色克隆模型尚未接入。
|
|
99
|
+
|
|
100
|
+
## 怎么试
|
|
101
|
+
|
|
102
|
+
- 配好 `.env`:大模型的地址、模型名和 key;用字节 TTS 的话再加它的 App ID 和 Key;ASR 服务地址不改就用默认的本机端口
|
|
103
|
+
- 先把 `asr_server` 跑起来
|
|
104
|
+
- 有麦克风和扬声器就运行 `tests/test_run_v2.py` 直接对话;没有麦克风就运行 `tests/test_run.py`,它在代码里塞了两句话进去
|
|
105
|
+
- 想边聊边改配置,运行 `examples/web/main.py`,浏览器打开本机 8080 端口:可以换模型、换音色、改人设、开关工具、配外部 MCP,保存后立即生效;聊天信息通过「实时聊天」和「详细信息」两个标签切换,默认显示实时聊天。「详细信息」查看 `llm.messages` 模型上下文(含工具调用、思考),「实时聊天」查看 `chat_bot.receive_item()` 实际消费的识别文本、助手语句、工具、歌词和会话结束事件(不显示音频包、语句结束和播放结束)。重新开始会清空两份记录,每轮聊完仍自动保存完整的 `llm.messages`
|
|
106
|
+
|
|
107
|
+
## 给开发者
|
|
108
|
+
|
|
109
|
+
要改代码,先看 `AGENTS.md`:队列和事件的实现细节、MCP 工具怎么注册注销、TTS 会话的生命周期限制、各种踩过的坑都记在那里。
|