一、自建 Relay:先解决连接链路
Paseo 的手机端需要通过 Relay 与桌面上的 Paseo daemon 建立连接。原作者的出发点是:默认 Relay 在海外,国内网络环境下可能不稳定,因此自行部署 zenghongtu/paseo-relay,再把桌面端和手机端都指向自己的域名。
1. 部署 Relay
官方仓库给出的最小 Docker 启动方式是:
docker run -p 8411:8411 ghcr.io/zenghongtu/paseo-relay:latest
Relay 默认监听 8411。部署后先在服务器本机或受控网络中检查:
curl http://127.0.0.1:8411/health
/health 应返回服务状态和版本信息。生产环境不要直接向公网暴露明文 HTTP;应使用 Caddy、nginx、Traefik 或 Cloudflare 在上游终止 TLS,并确认域名证书可自动续期。
2. 配置 Paseo
编辑桌面端的 ~/.paseo/config.json。以下使用占位域名,不能原样照抄到生产环境:
{
"daemon": {
"relay": {
"enabled": true,
"endpoint": "relay.example.com:443",
"publicEndpoint": "relay.example.com:443",
"useTls": true
}
},
"app": {
"baseUrl": "https://relay.example.com"
}
}
保存后重启 Paseo daemon:
paseo daemon stop
paseo daemon start
重新生成或扫描连接二维码,再从手机网络实际测试会话连接,不能只以 /health 成功作为最终结论。
3. Relay 的安全边界
据官方 Relay 说明,转发内容使用端到端加密,Relay 只转发加密字节,不应看到会话正文;但它仍可能观察到 IP、连接时间、流量大小和会话标识等元数据。Relay 本身没有单独的账户认证层,安全性依赖客户端的 ECDH/NaCl box 加密与 TLS 传输。因此需要同时做到:
- 公网入口只开放 HTTPS/WSS,禁止明文回源暴露;
- 保持 Relay 镜像、反向代理和系统补丁更新;
- 日志不记录查询参数、令牌或会话内容;
- 对异常连接数、带宽和
/health状态做监控。
官方参考:paseo-relay
二、语音输入:本地模型与兼容接口
Paseo 的语音能力可以本地运行,也可以调用 OpenAI 兼容服务。官方文档说明,本地 ONNX 模式默认使用 CPU;模型缺失时才会下载到 $PASEO_HOME/models/local-speech。
目前官方列出的本地 STT 模型包括英语版 parakeet-tdt-0.6b-v2-int8 和支持 25 种欧洲语言的 v3,均不包含中文。因此,中文语音输入需要换用外部 STT,或直接使用操作系统、输入法自带的语音听写。
1. 接入 OpenAI 兼容 STT
原作者先以本地 FunASR 服务为例,把听写和语音模式的 STT provider 指向 openai,同时为 STT 单独设置地址和密钥:
{
"features": {
"dictation": {
"stt": { "provider": "openai" }
},
"voiceMode": {
"stt": { "provider": "openai", "model": "paraformer" }
}
},
"providers": {
"openai": {
"stt": {
"apiKey": "YOUR_STT_API_KEY",
"baseUrl": "http://127.0.0.1:8000/v1"
}
}
}
}
这里的密钥必须使用专用、最小权限凭据,不能把真实值写进公开帖子、仓库或客户端日志。若服务只在本机使用,应绑定回环地址;若跨机访问,则需要 TLS、访问控制和防火墙限制。
2. Qwen3-ASR-Flash 为什么需要适配层
Paseo 的 STT 客户端按 OpenAI Audio API 发送 multipart/form-data 到 /v1/audio/transcriptions。阿里云百炼的 Qwen3-ASR-Flash 虽提供 OpenAI 兼容访问,但使用的是 Chat Completions 形态:请求进入 /v1/chat/completions,音频作为 input_audio(Base64 Data URI 或公开 URL)提交,结果从聊天响应中读取。
两个接口的路径、请求体和响应结构并不相同,不能只改 baseUrl。原作者使用 Cloudflare Worker 做薄适配层,核心流程是:
- 接收 Paseo 发往
/v1/audio/transcriptions的 multipart 音频文件; - 把音频转换为 Base64 Data URI;
- 构造
qwen3-asr-flash的input_audio消息并请求百炼 Chat Completions 接口; - 从
choices[0].message.content提取转写文本; - 向 Paseo 返回
{ "text": "转写结果" }。
这类适配器至少应补充请求大小限制、超时、上游错误映射和严格的 CORS 来源白名单。不要记录 Authorization、原始音频或完整上游响应;生产环境也不应把长期密钥硬编码在脚本中。官方接口参考:Qwen-ASR API。
三、验证清单
完成配置后,建议逐项验证:
GET /health返回预期状态和版本,TLS 证书链与自动续期正常;- Paseo 重启后能通过自建 Relay 生成连接信息,手机在 Wi-Fi 与移动网络下均可连接;
- 用几秒钟的短音频测试听写,确认中文结果进入 Paseo,而不是只看到上游 HTTP 200;
- 分别测试缺少文件、错误密钥、上游超时和超大音频,确保适配层返回可理解的错误;
- 检查 Relay、反向代理和适配层日志,确认没有令牌、音频正文或转写内容;
- 若不需要 Paseo 内置语音,直接关闭相关功能,避免误触和不必要的模型下载。
原帖没有给出统一的性能基准、并发容量、费用测算或长期稳定性数据。自建 Relay 能改善链路可控性,但不能保证所有网络环境下都稳定;云端 STT 也会引入新的隐私、费用、延迟和供应商依赖边界。
官方语音文档:Paseo Voice
原作者:wbc
原帖:https://linux.do/t/topic/2829068