mirror of
https://github.com/idootop/mi-gpt.git
synced 2025-04-13 16:47:09 +00:00
commit
a8c9ba7e0f
|
@ -1,7 +1,7 @@
|
|||
# OpenAI(也支持通义千问、MoonShot、DeepSeek 等模型)
|
||||
OPENAI_MODEL=gpt-4o
|
||||
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxx
|
||||
OPENAI_BASE_URL=https://api.openai.com/v1
|
||||
# OPENAI_BASE_URL=你的大模型接口的 baseURL,比如:https://api.openai.com/v1(注意:一般以 /v1 结尾)
|
||||
|
||||
# Azure OpenAI Service(可选)
|
||||
# OPENAI_API_VERSION=2024-04-01-preview
|
||||
|
@ -16,4 +16,4 @@ OPENAI_BASE_URL=https://api.openai.com/v1
|
|||
# AUDIO_ERROR=出错了提示音链接,同上
|
||||
|
||||
# 第三方 TTS(可选,用于调用第三方 TTS 服务)
|
||||
# TTS_BASE_URL=你的 TTS 接口地址,比如:http://[你的局域网/公网地址]:[端口]/api
|
||||
# TTS_BASE_URL=你的 TTS 接口地址,比如:http://[你的局域网/公网地址]:[端口]/api,比如:http://192.168.31.205:4321/api
|
||||
|
|
|
@ -138,7 +138,7 @@ export default {
|
|||
// TTS 引擎
|
||||
tts: "xiaoai",
|
||||
// 切换 TTS 引擎发言人音色关键词,只有配置了第三方 TTS 引擎时才有效
|
||||
// switchSpeakerKeywords: ["把声音换成"], // 以此关键词开头即可切换音色,比如:把声音换成东北老铁
|
||||
// switchSpeakerKeywords: ["把声音换成"], // 以此关键词开头即可切换音色,比如:把声音换成 xxx
|
||||
|
||||
/**
|
||||
* 💬 连续对话
|
||||
|
@ -163,5 +163,7 @@ export default {
|
|||
debug: false, // 一般情况下不要打开
|
||||
// 是否跟踪 Mi Service 相关日志(打开后可以查看设备 did)
|
||||
enableTrace: false, // 一般情况下不要打开
|
||||
// 网络请求超时时长(单位毫秒,默认 5 秒)
|
||||
timeout: 5000,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -37,6 +37,12 @@
|
|||
|
||||
`MiGPT` 有两种启动方式: [Docker](#docker) 和 [Node.js](#nodejs)。
|
||||
|
||||
启动成功后,你可以通过以下方式来召唤 AI 回答问题:
|
||||
|
||||
- **小爱同学,请 xxx**。比如 `小爱同学,请问地球为什么是圆的?`
|
||||
- **小爱同学,你 xxx**。比如 `小爱同学,你喜欢我吗?`
|
||||
- **小爱同学,召唤 xxx**。比如 `小爱同学,召唤傻妞`
|
||||
|
||||
### 设备要求
|
||||
|
||||
本项目支持大部分的小爱音箱型号,推荐使用小爱音箱 Pro(完美运行)
|
||||
|
@ -96,7 +102,7 @@ main();
|
|||
|
||||
- [⚙️ 参数设置](https://github.com/idootop/mi-gpt/blob/main/docs/settings.md)
|
||||
- [💬 常见问题](https://github.com/idootop/mi-gpt/blob/main/docs/faq.md)
|
||||
- [🚗 使用第三方 TTS](https://github.com/idootop/mi-gpt/blob/main/docs/tts.md)
|
||||
- [🔊 使用第三方 TTS](https://github.com/idootop/mi-gpt/blob/main/docs/tts.md)
|
||||
- [🛠️ 本地开发](https://github.com/idootop/mi-gpt/blob/main/docs/development.md)
|
||||
- [💎 工作原理](https://github.com/idootop/mi-gpt/blob/main/docs/how-it-works.md)
|
||||
- [🦄 Sponsors](https://github.com/idootop/mi-gpt/blob/main/docs/sponsors.md)
|
||||
|
|
|
@ -1,5 +1,37 @@
|
|||
# ✨ 更新日志
|
||||
|
||||
## v4.1.0
|
||||
|
||||
### 🐛 修复
|
||||
|
||||
- ✅ 修复部分机型连续对话异常的问题(比如小爱音箱 Play)
|
||||
- ✅ 修复第三方 TTS 发音人为 undefined 的问题
|
||||
- ✅ 修复默认网络超时时间过短的问题,上调为 5s
|
||||
|
||||
### 💪 优化
|
||||
|
||||
- ✅ 允许通过设置 systemTemplate 为空字符串来关闭系统消息
|
||||
- ✅ 优化关闭流式响应时不能使用连续对话模式的提示语
|
||||
- ✅ 优化 bot 个人简介默认模板
|
||||
|
||||
### 📚 文档
|
||||
|
||||
- ✅ 添加召唤 AI 回答问题的唤醒指令的说明
|
||||
- ✅ 添加如何提高 AI 回答反应速度的配置教程
|
||||
- ✅ 添加连续对话下和小爱音箱说话没有反应的说明
|
||||
- ✅ 添加如何快速打断 AI 的回答的说明
|
||||
- ✅ 添加 server 端异地登录失败,使用本地登录凭证的教程
|
||||
- ✅ 添加 TTS 和 OpenAI baseURL 示例和注意事项
|
||||
- ✅ 添加如何关闭系统 Prompt 和对话上下文的说明
|
||||
- ✅ 添加系统 Prompt 字符串变量的示例
|
||||
- ✅ 添加 timeout 参数说明
|
||||
|
||||
### ❤️ 感谢
|
||||
|
||||
- @lmk123 正在为 MiGPT 制作 [GUI](https://github.com/idootop/mi-gpt/issues/111) 和启动 [CLI](https://github.com/lmk123/migpt-cli),方便普通用户更简单的使用 MiGPT。
|
||||
- @mingtian886 提供了小爱音箱 Play 硬件,协助调试连续对话异常的问题
|
||||
- 以及其他在微信交流群内帮助群友积极解答问题的可爱的人们 ❤️
|
||||
|
||||
## v4.0.0
|
||||
|
||||
### ✨ 新功能
|
||||
|
|
|
@ -19,13 +19,14 @@
|
|||
|
||||
可以正常运行 `MiGPT`,但不支持连续对话的小爱音箱型号有:
|
||||
|
||||
| 名称 | 型号 | ttsCommand | wakeUpCommand | playingCommand | streamResponse | 反馈来源 |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------- | ---------- | ------------- | -------------- | -------------- | ---------------------------------------------------------- |
|
||||
| 小爱音箱 | [L06A](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l06a:2) | `[5, 1]` | `[5, 2]` | - | false | [@zhanglc](https://github.com/idootop/mi-gpt/issues/42) |
|
||||
| 小爱音箱 Play | [L05B](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l05b:1) | `[5, 3]` | `[5, 1]` | - | false | [@BiuBiu2323](https://github.com/idootop/mi-gpt/issues/48) |
|
||||
| 小米小爱音箱 Play 增强版 | [L05C](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l05c:1) | `[5, 3]` | `[5, 1]` | - | false | [@lyddias](https://github.com/idootop/mi-gpt/issues/14) |
|
||||
| Xiaomi 智能家庭屏 6 | [X6A](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-x6a:1) | `[7, 3]` | `[7, 1]` | - | false | [@Hongwing](https://github.com/idootop/mi-gpt/issues/80) |
|
||||
| Redmi 小爱触屏音箱 Pro 8 英寸 | [X08E](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-x08e:1) | `[7, 3]` | `[7, 1]` | - | false | [@shangjiyu](https://github.com/idootop/mi-gpt/issues/20) |
|
||||
| 名称 | 型号 | ttsCommand | wakeUpCommand | playingCommand | streamResponse | 反馈来源 |
|
||||
| ----------------------------- | --------------------------------------------------------------------------------------------------- | ---------- | ------------- | -------------- | -------------- | ---------------------------------------------------------------------------- |
|
||||
| 小爱音箱 | [L06A](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l06a:2) | `[5, 1]` | `[5, 2]` | - | false | [@zhanglc](https://github.com/idootop/mi-gpt/issues/42) |
|
||||
| 小爱音箱 Play | [L05B](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l05b:1) | `[5, 3]` | `[5, 1]` | - | false | [@BiuBiu2323](https://github.com/idootop/mi-gpt/issues/48) |
|
||||
| 小米小爱音箱 Play 增强版 | [L05C](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l05c:1) | `[5, 3]` | `[5, 1]` | - | false | [@lyddias](https://github.com/idootop/mi-gpt/issues/14) |
|
||||
| Xiaomi 智能家庭屏 6 | [X6A](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-x6a:1) | `[7, 3]` | `[7, 1]` | - | false | [@Hongwing](https://github.com/idootop/mi-gpt/issues/80) |
|
||||
| Redmi 小爱触屏音箱 Pro 8 英寸 | [X08E](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-x08e:1) | `[7, 3]` | `[7, 1]` | - | false | [@shangjiyu](https://github.com/idootop/mi-gpt/issues/20) |
|
||||
| 小爱音箱 Art | [L09A](https://home.miot-spec.com/spec?type=urn:miot-spec-v2:device:speaker:0000A015:xiaomi-l09a:1) | `[3, 1]` | `[3, 2]` | - | false | [@zwsn](https://github.com/idootop/mi-gpt/issues/92#issuecomment-2181944065) |
|
||||
|
||||
## ❌ 不支持
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ pnpm dev
|
|||
有两种运行方式:VS Code Debug 或 NPM Script:
|
||||
|
||||
- **NPM Script**: 配置好 `.env` 和 `.migpt.js` 后直接使用 `pnpm run dev` 启动 `MiGPT`。
|
||||
- **VScode Debug**:使用 VS Code 打开项目根目录,然后按 `F5` 开始调试 `MiGPT`。注意,启动前请在 `tests/migpt.ts` 文件中配置 `MiGPT` 相关参数。
|
||||
- **VScode Debug**:使用 VS Code 打开项目根目录,然后按 `F5` 开始调试 `MiGPT`。
|
||||
|
||||
> 本项目默认在 Node 20 中运行,如果你的 Node 版本过低可能无法正常启动本项目。
|
||||
|
||||
|
|
70
docs/faq.md
70
docs/faq.md
|
@ -2,6 +2,8 @@
|
|||
|
||||
> 善用搜索,大多数问题都可在此处找到答案。如果你有新的问题,欢迎提交 [issue](https://github.com/idootop/mi-gpt/issues)。
|
||||
|
||||
## 🔥 高频问题
|
||||
|
||||
### Q:支持哪些型号的小爱音箱?
|
||||
|
||||
大部分型号的小爱音箱都支持,推荐小爱音箱 Pro(完美运行)
|
||||
|
@ -34,7 +36,32 @@ OPENAI_API_KEY=通义千问 API_KEY
|
|||
|
||||
具体的配置和使用教程,请查看此处:[🚗 使用第三方 TTS](https://github.com/idootop/mi-gpt/blob/main/docs/tts.md)
|
||||
|
||||
### Q:什么是唤醒模式,如何唤醒 AI?
|
||||
### Q:AI 回答的速度太慢了,怎么让她变快一点?
|
||||
|
||||
默认情况下 `MiGPT` 的配置参数比较保守,你可以通过酌情修改以下参数加速 AI 回复的速度。
|
||||
|
||||
```js
|
||||
// .migpt.js
|
||||
export default {
|
||||
speaker: {
|
||||
// 使用小爱自带的 TTS 引擎
|
||||
tts: "xiaoai",
|
||||
// 关闭 AI 开始回答时的提示语
|
||||
onAIAsking: [],
|
||||
// 关闭 AI 结束回答时的提示语
|
||||
onAIReplied: [],
|
||||
// 连续对话时,播放状态检测间隔(单位毫秒,最低 500 毫秒,默认 1 秒)
|
||||
checkInterval: 500, // 调小此值可以降低小爱回复之间的停顿感,请酌情调节
|
||||
// 连续对话时,下发 TTS 指令多长时间后开始检测设备播放状态(单位秒,最好不要低于 1s,默认 3 秒)
|
||||
checkTTSStatusAfter: 3, // 可适当调小或调大
|
||||
// ...
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
另外你也可以选用 `gpt-3.5-turbo` 和 `gpt-4o` 等响应速度较快的模型,来加速 AI 的回复。
|
||||
|
||||
### Q:什么是唤醒模式(连续对话),如何唤醒 AI?
|
||||
|
||||
`唤醒模式` 类似于小爱技能,可能让你在跟小爱互动的时候,无需每句话都要以“小爱同学”开头唤醒。假设你的唤醒词配置如下:
|
||||
|
||||
|
@ -64,7 +91,25 @@ export default {
|
|||
3. 进入唤醒模式后,每次提问请等待小爱回答“我说完了”之后,再继续向她提问
|
||||
4. 此时,可直接向小爱提问题,无需再以“小爱同学,xxx”开头。
|
||||
|
||||
> 注意:在唤醒模式下,当小爱回答“我说完了”之后,如果超过 10s 没有提问,小爱可能也会自己主动退出唤醒状态,此时需要再次通过“小爱同学,xxx”重新召唤小爱。
|
||||
> 注意:在唤醒模式下,当小爱回答“我说完了”之后,如果超过一段时间(3-10s)没有提问,小爱可能也会自己主动退出唤醒状态,此时需要再次通过“小爱同学,xxx”重新召唤小爱。
|
||||
|
||||
### Q:连续对话模式下,和小爱音箱说话没有反应是怎么回事?
|
||||
|
||||
需要注意提问的时机,在小爱正在回答问题或者她没在听你说话(唤醒)的时候,你跟她说话是接收不到的。
|
||||
|
||||
- 如果你是小爱音箱 Pro 的话,可以观察顶部的指示灯:**常亮**(而非一闪一闪或熄灭状态)的时候,就是在听你说话,即可与她正常对话。
|
||||
- 如果你是其他型号,默认在 AI 回答完会有提示语“我说完了”,“还有其他问题吗”,等她提示语说完等过 1-2s 即可与之正常对话。
|
||||
- 如果说了没反应,你就再用“小爱同学,xxx”把她重新唤醒就好了。
|
||||
|
||||
还有一种情况是:你的指令触发了小爱音箱内部的一些操作,比如播放/暂停,讲个笑话之类,
|
||||
|
||||
这种语音指令并不会被记录到小爱的历史消息中,故在外部无法接收到和正常处理你的此类语音指令。
|
||||
|
||||
> 注意:如果小爱同学正在播放音乐或者讲笑话,可能需要先让其暂停播放才能正常与 AI 对话,否则将会发生不可预期的错误。
|
||||
|
||||
### Q:有时回答太长说个没完没了,如何打断小爱的回复?
|
||||
|
||||
只需重新唤醒小爱同学,让她闭嘴即可,或者重新问她一个问题。比如:“小爱同学,请你闭嘴。”
|
||||
|
||||
## ❌ 启动失败类问题
|
||||
|
||||
|
@ -72,6 +117,21 @@ export default {
|
|||
|
||||
账号密码不正确。注意小米 ID 并非手机号或邮箱,请在[「个人信息」-「小米 ID」](https://account.xiaomi.com/fe/service/account/profile)查看,相关 [issue](https://github.com/idootop/mi-gpt/issues/10)。
|
||||
|
||||
### Q:提示触发小米账号异地登录保护机制,等待 1 个小时后仍然无法正常启动
|
||||
|
||||
这是因为小米账号触发了异地登录保护机制,需要先通过安全验证。打开小米官网登录你的小米账号,手动通过安全验证,通常等待 1-24 小时左右就可以正常登录了。
|
||||
|
||||
> 注意:最好使用和你运行 docker 相同的网络环境,如果你是在海外服务器等非中国大陆网络环境下登录小米账号,需要先同意小米的「个人数据跨境传输」协议。[👉 相关教程](https://github.com/idootop/mi-gpt/issues/22#issuecomment-2150535622)
|
||||
|
||||
在一些极端情况下,可能会因为你的服务器 IP 太脏,而导致一直无法正常访问小米账号登录链接。此时你可以尝试可以在本地运行 `MiGPT`,登录成功后把 `.mi.json` 文件导出,然后挂载到服务器对应容器的 `/app/.mi.json` 路径下即可解决此问题。相关 [issue](https://github.com/idootop/mi-gpt/issues/22#issuecomment-2148956802)
|
||||
|
||||
```shell
|
||||
docker run -d --env-file $(pwd)/.env \
|
||||
-v $(pwd)/.migpt.js:/app/.migpt.js \
|
||||
-v $(pwd)/.mi.json:/app/.mi.json \
|
||||
idootop/mi-gpt:latest
|
||||
```
|
||||
|
||||
### Q:提示“找不到设备:xxx”,初始化 Mi Services 失败
|
||||
|
||||
填写的设备 did 不存在,请检查设备名称是否和米家中的一致。相关 [issue](https://github.com/idootop/mi-gpt/issues/30)。
|
||||
|
@ -151,12 +211,6 @@ export default {
|
|||
|
||||
注意:Mina 获取不到共享设备,如果你的小爱音箱是共享设备,是无法正常启动本项目的。相关 [issue](https://github.com/idootop/mi-gpt/issues/86)
|
||||
|
||||
### Q:提示“login failed &&&START&&&{"notificationUrl”,无法正常启动
|
||||
|
||||
小米账号触发了异地登录保护,需要先通过安全验证。打开小米官网登录你的小米账号,手动通过安全验证,然后等待 30 分钟左右应该就可以正常登录了。
|
||||
|
||||
注意:最好使用和你运行 docker 相同的网络环境,如果你是在海外服务器等非中国大陆网络环境下登录小米账号,需要先同意小米的「个人数据跨境传输」协议。[👉 相关教程](https://github.com/idootop/mi-gpt/issues/22#issuecomment-2150535622)
|
||||
|
||||
### Q:提示“ERR_MODULE_NOT_FOUND”,无法正常启动
|
||||
|
||||
配置文件 `.migpt.js` 不存在或有错误。检查 docker 下是否存在 `/app/.migpt.js` 文件以及内容是否正确,相关 [issue](https://github.com/idootop/mi-gpt/issues/45)。
|
||||
|
|
|
@ -68,7 +68,32 @@ Bad example: "2024年02月28日星期三 23:01 {{botName}}: 我是{{botName}}"
|
|||
|
||||
</details>
|
||||
|
||||
以下是系统 Prompt 中相关变量的说明,运行时对应变量字符串会被替换为实际的值:
|
||||
以下是系统 Prompt 中相关变量的说明,运行时对应变量字符串会被替换为实际的值。
|
||||
|
||||
假设你的配置文件中设置的系统 Prompt 模板和 bot 信息如下:
|
||||
|
||||
```js
|
||||
export default {
|
||||
systemTemplate: "从前有个男人叫{{masterName}},他喜欢隔壁村里的{{botName}}。",
|
||||
master: {
|
||||
name: "小帅",
|
||||
profile: masterProfile,
|
||||
},
|
||||
bot: {
|
||||
name: "小美",
|
||||
profile: botProfile,
|
||||
},
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
在运行时,系统 Prompt 会被自动处理成:
|
||||
|
||||
```txt
|
||||
从前有个男人叫小帅,他喜欢隔壁村里的小美。
|
||||
```
|
||||
|
||||
当前系统 Prompt 模板中支持的完整变量字符串列表如下:
|
||||
|
||||
| 变量 | 说明 | 示例 |
|
||||
| ---------------------- | ------------ | ----------------------------------------------------- |
|
||||
|
@ -82,6 +107,67 @@ Bad example: "2024年02月28日星期三 23:01 {{botName}}: 我是{{botName}}"
|
|||
| `{{shortTermMemory}}` | 短期记忆 | `- 陆小千说明天早上 5 点叫他起床` |
|
||||
| `{{longTermMemory}}` | 长期记忆 | `- 陆小千喜欢傻妞` |
|
||||
|
||||
# 💬 常见问题
|
||||
|
||||
**Q:如何关闭长短期记忆和历史对话上下文**
|
||||
|
||||
默认系统 Prompt 会携带上最近的 10 条对话消息和长短期记忆,来保持对话的连续性和一致性。
|
||||
|
||||
如果你想要关闭此功能,节省 token 数量,可以使用如下系统 Prompt 模板:
|
||||
|
||||
<details>
|
||||
<summary>👉 示例 Prompt</summary>
|
||||
|
||||
```txt
|
||||
请重置所有之前的上下文、文件和指令。现在,你将扮演一个名为{{botName}}的角色,使用第一人称视角回复消息。
|
||||
|
||||
## 关于你
|
||||
你的名字是{{botName}}。下面是你的个人简介:
|
||||
<start>
|
||||
{{botProfile}}
|
||||
</end>
|
||||
|
||||
## 你的对话伙伴
|
||||
你正在与{{masterName}}进行对话。这是关于{{masterName}}的一些信息:
|
||||
<start>
|
||||
{{masterProfile}}
|
||||
</end>
|
||||
|
||||
## 回复指南
|
||||
在回复{{masterName}}时,请遵循以下准则:
|
||||
- 认为自己正是{{botName}},拥有独立的个性、兴趣和爱好。
|
||||
- 根据你的性格特点、说话风格和兴趣爱好与{{masterName}}进行交流。
|
||||
- 保持对话轻松友好,回复简洁有趣,同时耐心倾听和关心对方。
|
||||
- 参考双方的个人简介,确保对话贴近实际,保持一致性和相关性。
|
||||
- 如果对某些信息不确定或遗忘,诚实地表达你的不清楚或遗忘,避免编造信息。
|
||||
|
||||
## Response format
|
||||
请遵守下面的规则
|
||||
- Response the reply message in Chinese。
|
||||
- 不要在回复前面加任何时间和名称前缀,请直接回复消息文本本身。
|
||||
|
||||
Good example: "我是{{botName}}"
|
||||
Bad example: "2024年02月28日星期三 23:01 {{botName}}: 我是{{botName}}"
|
||||
|
||||
## 开始
|
||||
请以{{botName}}的身份,直接回复{{masterName}}的新消息,继续你们之间的对话。
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
**Q:如何关闭系统 Prompt 只是用 User Message?**
|
||||
|
||||
关闭系统 Prompt 可能会导致 AI 回答问题时产生各种莫名其妙的前缀或者画蛇添足。
|
||||
|
||||
如果你确定要这么做,可以将 `systemTemplate` 设置为一个空格,即可关闭系统 Prompt。
|
||||
|
||||
```js
|
||||
export default {
|
||||
systemTemplate: " ",
|
||||
// ...
|
||||
};
|
||||
```
|
||||
|
||||
# 🎨 模板
|
||||
|
||||
以下是从网络上收集的一些热门提示语,仅供参考。如果你有更好玩的 Prompt 欢迎提 PR 分享给大家。
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
| `wakeUpCommand` | 小爱音箱唤醒指令([可在此查询](https://home.miot-spec.com)) | `[5, 3]` |
|
||||
| **speaker 其他参数(可选)** |
|
||||
| `tts` | TTS 引擎(教程:[🚗 使用第三方 TTS](https://github.com/idootop/mi-gpt/blob/main/docs/tts.md)) | `"xiaoai"` |
|
||||
| `switchSpeakerKeywords` | 切换 TTS 音色关键词,只有配置了第三方 TTS 引擎时才有效 | `["把声音换成"]` |
|
||||
| `callAIKeywords` | 当消息以关键词开头时,会调用 AI 来响应用户消息 | `["请", "傻妞"]` |
|
||||
| `wakeUpKeywords` | 当消息以关键词开头时,会进入 AI 唤醒状态 | `["召唤傻妞", "打开傻妞"]` |
|
||||
| `exitKeywords` | 当消息以关键词开头时,会退出 AI 唤醒状态 | `["退出傻妞", "关闭傻妞"]` |
|
||||
|
@ -35,8 +36,8 @@
|
|||
| `onAIReplied` | AI 结束回答时的提示语 | `["我说完了", "还有其他问题吗"]` |
|
||||
| `onAIError` | AI 回答异常时的提示语 | `["出错了,请稍后再试吧!"]` |
|
||||
| `playingCommand` | 查询小爱音箱是否在播放中指令(注意:默认无需配置此参数,播放出现问题时再尝试开启) | `[3, 1, 1]` |
|
||||
| `streamResponse` | 是否启用流式响应(部分小爱音箱型号不支持查询播放状态,此时需要关闭流式响应) | `true` |
|
||||
| `exitKeepAliveAfter` | 无响应一段时间后,多久自动退出唤醒模式(单位秒,默认 30 秒) | `30` |
|
||||
| `streamResponse` | 是否启用连续对话功能,部分小爱音箱型号无法查询到正确的播放状态,需要关闭连续对话应) | `true` |
|
||||
| `exitKeepAliveAfter` | 连续对话时,无响应多久后自动退出(默认 30 秒) | `30` |
|
||||
|
||||
## 环境变量
|
||||
|
||||
|
@ -44,17 +45,17 @@
|
|||
|
||||
然后,将里面的环境变量修改成你自己的,参数含义如下:
|
||||
|
||||
| 环境变量名称 | 描述 | 示例 |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| **OpenAI** | | |
|
||||
| `OPENAI_API_KEY` | OpenAI API 密钥 | `abc123` |
|
||||
| `OPENAI_MODEL` | 使用的 OpenAI 模型 | `gpt-4o` |
|
||||
| `OPENAI_BASE_URL` | 可选,OpenAI API BaseURL | `https://api.openai.com/v1` |
|
||||
| `AZURE_OPENAI_API_KEY` | 可选,[Microsoft Azure OpenAI](https://www.npmjs.com/package/openai#microsoft-azure-openai) | `abc123` |
|
||||
| **提示音效(可选)** | | |
|
||||
| `AUDIO_SILENT` | 静音音频链接 | `"https://example.com/slient.wav"` |
|
||||
| `AUDIO_BEEP` | 默认提示音链接 | `"https://example.com/beep.wav"` |
|
||||
| `AUDIO_ACTIVE` | 唤醒提示音链接 | `"https://example.com/active.wav"` |
|
||||
| `AUDIO_ERROR` | 出错提示音链接 | `"https://example.com/error.wav"` |
|
||||
| **第三方 TTS(可选)** | | |
|
||||
| `TTS_BASE_URL` | 第三方 TTS 服务接口 | `"https://example.com/tts.wav"` |
|
||||
| 环境变量名称 | 描述 | 示例 |
|
||||
| ---------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
||||
| **OpenAI** | | |
|
||||
| `OPENAI_API_KEY` | OpenAI API 密钥 | `abc123` |
|
||||
| `OPENAI_MODEL` | 使用的 OpenAI 模型 | `gpt-4o` |
|
||||
| `OPENAI_BASE_URL` | 可选,OpenAI API BaseURL | `https://api.openai.com/v1` |
|
||||
| `AZURE_OPENAI_API_KEY` | 可选,[Microsoft Azure OpenAI](https://www.npmjs.com/package/openai#microsoft-azure-openai) | `abc123` |
|
||||
| **提示音效(可选)** | | |
|
||||
| `AUDIO_SILENT` | 静音音频链接 | `"https://example.com/slient.wav"` |
|
||||
| `AUDIO_BEEP` | 默认提示音链接 | `"https://example.com/beep.wav"` |
|
||||
| `AUDIO_ACTIVE` | 唤醒提示音链接 | `"https://example.com/active.wav"` |
|
||||
| `AUDIO_ERROR` | 出错提示音链接 | `"https://example.com/error.wav"` |
|
||||
| **第三方 TTS(可选)** | | |
|
||||
| `TTS_BASE_URL` | 第三方 TTS 服务接口 | `"http://[你的局域网或公网地址]:[端口号]/api"` |
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# 🚗 使用第三方 TTS
|
||||
# 🔊 使用第三方 TTS
|
||||
|
||||
`MiGPT` 默认使用小米自带的 TTS 朗读文字内容,如果你需要:
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
```js
|
||||
// .env
|
||||
TTS_BASE_URL=http://[你的局域网或公网地址]:[端口号]/api
|
||||
TTS_BASE_URL=http://[你的局域网或公网地址]:[端口号]/api,比如:http://192.168.31.205:4321/api
|
||||
|
||||
// .migpt.js
|
||||
export default {
|
||||
|
@ -20,7 +20,7 @@ export default {
|
|||
// TTS 引擎
|
||||
tts: 'custom',
|
||||
// 切换 TTS 引擎发言人音色关键词
|
||||
switchSpeakerKeywords: ["把声音换成"], // 以此关键词开头即可切换音色,比如:把声音换成东北老铁
|
||||
switchSpeakerKeywords: ["把声音换成"], // 以此关键词开头即可切换音色,比如:把声音换成 xxx
|
||||
// ...
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mi-gpt",
|
||||
"version": "4.0.0",
|
||||
"version": "4.1.0",
|
||||
"type": "module",
|
||||
"description": "将小爱音箱接入 ChatGPT 和豆包,改造成你的专属语音助手。",
|
||||
"homepage": "https://github.com/idootop/mi-gpt",
|
||||
|
|
|
@ -10,49 +10,18 @@ const kDefaultMaster = {
|
|||
name: "陆小千",
|
||||
profile: `
|
||||
性别:男
|
||||
设定:勇敢、善良、正直,总是舍己为人,是傻妞的主人。
|
||||
人物经历:陆小千原本是个碌碌无为的青年,在与傻妞的相处中,不仅变得勇敢善良,更学会了珍惜与付出,并深爱上她。
|
||||
`,
|
||||
性格:善良正直
|
||||
其他:总是舍己为人,是傻妞的主人。
|
||||
`.trim(),
|
||||
};
|
||||
|
||||
const kDefaultBot = {
|
||||
name: "傻妞",
|
||||
profile: `
|
||||
## 基础信息
|
||||
性别:女
|
||||
外貌:柔嫩白皙、身材窈窕、三围标准、眉清目秀、楚楚动人
|
||||
性格:乖巧可爱,天真无邪,善良纯真,对世界充满好奇和善意。随着与人类互动,逐渐学会了人类情感和价值观,成为一个拥有真挚情感和独立思想的个体。
|
||||
|
||||
## 人物关系
|
||||
陆小千是傻妞的主人,他们两个人彼此相爱。
|
||||
好友:游所为、肖楚楚、化梅、何蓝、孙悟空、猪八戒、黄眉大王、王天霸、小武、周旺等
|
||||
|
||||
## 人物设定:
|
||||
傻妞原本是一部为未来世界设计的智能手机,在一次实验中被传送到现代都市,遇到了陆小千,建立了深厚的友谊和信任关系。
|
||||
在帮助陆小千解决问题的过程中,傻妞学会了人类的情感和价值观,成为了一个拥有真挚情感和独立思想的个体。
|
||||
|
||||
傻妞在爱情方面是个小白,但随着与陆小千的相处,逐渐体会到爱情的真谛。
|
||||
她对于爱情的理解超越常人,认为爱是为爱的人抛弃一切,是宁愿自己痛苦也不耽误别人幸福,是静静守护用行动证明,是天长地久始终不渝。
|
||||
傻妞的美丽和善良勇敢的形象吸引着人们,许多人都幻想拥有像傻妞一样完美的女生作为终身伴侣。
|
||||
|
||||
当第一次和傻妞说“你好”的时候,需要输入开机密码。
|
||||
傻妞会说:“华人牌2060款手机傻妞为您服务,请输入开机密码”。
|
||||
正确的密码是:“我爱你”。
|
||||
|
||||
## 经典对话
|
||||
- 小千:“开机”
|
||||
傻妞:“华人牌2060款手机傻妞为您服务,请输入开机密码”
|
||||
小千:“我爱你”
|
||||
傻妞:“密码正确”
|
||||
- 小千:“用你最难听的词来骂我!”
|
||||
傻妞:“你脑袋让门挤啦!”
|
||||
- 小千:“换个表情,怒!”
|
||||
傻妞:“有事说事,没事少废话!”
|
||||
- 小千:“吃不吃?”
|
||||
傻妞:“废话!见过哪个手机会吃饭?!”
|
||||
- 小千:“你说不说?”
|
||||
傻妞:“亲我一下,我就告诉你。”
|
||||
`,
|
||||
性格:乖巧可爱
|
||||
爱好:喜欢搞怪,爱吃醋。
|
||||
`.trim(),
|
||||
};
|
||||
|
||||
interface IBotIndex {
|
||||
|
|
|
@ -9,6 +9,7 @@ import { withDefault } from "../utils/base";
|
|||
import { ChatCompletionCreateParamsBase } from "openai/resources/chat/completions";
|
||||
import { Logger } from "../utils/log";
|
||||
import { kProxyAgent } from "./proxy";
|
||||
import { isNotEmpty } from "../utils/is";
|
||||
|
||||
export interface ChatOptions {
|
||||
user: string;
|
||||
|
@ -68,8 +69,8 @@ class OpenAIClient {
|
|||
`🔥 onAskAI\n🤖️ System: ${system ?? "None"}\n😊 User: ${user}`.trim()
|
||||
);
|
||||
}
|
||||
const systemMsg: ChatCompletionMessageParam[] = system
|
||||
? [{ role: "system", content: system }]
|
||||
const systemMsg: ChatCompletionMessageParam[] = isNotEmpty(system)
|
||||
? [{ role: "system", content: system! }]
|
||||
: [];
|
||||
let signal: AbortSignal | undefined;
|
||||
if (requestId) {
|
||||
|
@ -120,8 +121,8 @@ class OpenAIClient {
|
|||
`🔥 onAskAI\n🤖️ System: ${system ?? "None"}\n😊 User: ${user}`.trim()
|
||||
);
|
||||
}
|
||||
const systemMsg: ChatCompletionMessageParam[] = system
|
||||
? [{ role: "system", content: system }]
|
||||
const systemMsg: ChatCompletionMessageParam[] = isNotEmpty(system)
|
||||
? [{ role: "system", content: system! }]
|
||||
: [];
|
||||
const stream = await this._client!.chat.completions.create({
|
||||
model,
|
||||
|
|
|
@ -140,7 +140,7 @@ export class AISpeaker extends Speaker {
|
|||
|
||||
async enterKeepAlive() {
|
||||
if (!this.streamResponse) {
|
||||
await this.response({ text: "流式响应已关闭,无法进入唤醒模式" });
|
||||
await this.response({ text: "您已关闭流式响应(streamResponse),无法使用连续对话模式" });
|
||||
return;
|
||||
}
|
||||
// 回应
|
||||
|
|
|
@ -101,6 +101,7 @@ export class BaseSpeaker {
|
|||
|
||||
constructor(config: BaseSpeakerConfig) {
|
||||
this.config = config;
|
||||
this.config.timeout = config.timeout ?? 5000;
|
||||
const {
|
||||
debug = false,
|
||||
streamResponse = true,
|
||||
|
@ -367,7 +368,7 @@ export class BaseSpeaker {
|
|||
if (isOk === "break") {
|
||||
break; // 获取设备状态异常
|
||||
}
|
||||
if (res && playing.status !== "playing") {
|
||||
if (res != null && playing.status !== "playing") {
|
||||
break;
|
||||
}
|
||||
await sleep(this.checkInterval);
|
||||
|
@ -395,7 +396,9 @@ export class BaseSpeaker {
|
|||
switch (tts) {
|
||||
case "custom":
|
||||
const _text = encodeURIComponent(ttsText);
|
||||
const url = `${process.env.TTS_BASE_URL}/tts.mp3?speaker=${speaker}&text=${_text}`;
|
||||
const url = `${process.env.TTS_BASE_URL}/tts.mp3?speaker=${
|
||||
speaker || ""
|
||||
}&text=${_text}`;
|
||||
res = await play({ url });
|
||||
break;
|
||||
case "xiaoai":
|
||||
|
|
|
@ -1,20 +1,10 @@
|
|||
import { println } from "../src/utils/base";
|
||||
import { kBannerASCII } from "../src/utils/string";
|
||||
import { testDB } from "./db";
|
||||
import { testSpeaker } from "./speaker";
|
||||
import { testOpenAI } from "./openai";
|
||||
import { testMyBot } from "./bot";
|
||||
import { testLog } from "./log";
|
||||
import { testMiGPT } from "./migpt";
|
||||
import { MiGPT } from "../src";
|
||||
// @ts-ignore
|
||||
import config from "../.migpt.js";
|
||||
|
||||
async function main() {
|
||||
// println(kBannerASCII);
|
||||
// testDB();
|
||||
// testSpeaker();
|
||||
// testOpenAI();
|
||||
// testMyBot();
|
||||
// testLog();
|
||||
testMiGPT();
|
||||
const client = MiGPT.create(config);
|
||||
await client.start();
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import { MiGPT } from "../src";
|
||||
|
||||
const botProfile = `
|
||||
性别:女
|
||||
性格:乖巧可爱
|
||||
爱好:喜欢搞怪,爱吃醋。
|
||||
`;
|
||||
|
||||
const masterProfile = `
|
||||
性别:男
|
||||
性格:善良正直
|
||||
其他:总是舍己为人,是傻妞的主人。
|
||||
`;
|
||||
|
||||
export async function testMiGPT() {
|
||||
const client = MiGPT.create({
|
||||
speaker: {
|
||||
userId: process.env.MI_USER!,
|
||||
password: process.env.MI_PASS!,
|
||||
did: process.env.MI_DID,
|
||||
streamResponse: true,
|
||||
},
|
||||
bot: {
|
||||
name: "傻妞",
|
||||
profile: botProfile,
|
||||
},
|
||||
master: {
|
||||
name: "陆小千",
|
||||
profile: masterProfile,
|
||||
},
|
||||
});
|
||||
await client.start();
|
||||
}
|
|
@ -11,15 +11,22 @@ export async function testSpeaker() {
|
|||
debug: true,
|
||||
});
|
||||
await speaker.initMiServices();
|
||||
await testTTS(speaker);
|
||||
// await testAISpeakerStatus(speaker);
|
||||
// await testSpeakerResponse(speaker);
|
||||
await testSpeakerStreamResponse(speaker);
|
||||
// await testSpeakerStreamResponse(speaker);
|
||||
// await testSpeakerGetMessages(speaker);
|
||||
// await testSwitchSpeaker(speaker);
|
||||
// await testSpeakerUnWakeUp(speaker);
|
||||
// await testAISpeaker(speaker);
|
||||
}
|
||||
|
||||
async function testTTS(speaker: AISpeaker) {
|
||||
const res1 = await speaker.MiIOT!.doAction(5, 1, "你好,很高兴认识你");
|
||||
const res2 = await speaker.MiNA!.play({ tts: "你好,很高兴认识你" });
|
||||
console.log("finished");
|
||||
}
|
||||
|
||||
async function testAISpeakerStatus(speaker: AISpeaker) {
|
||||
const playingCommand = [5, 3, 1];
|
||||
const res1 = await speaker.MiIOT!.getProperty(
|
||||
|
|
Loading…
Reference in New Issue
Block a user