乐于分享
好东西不私藏

AI助手开口说话:让孩子更方便开口交流

AI助手开口说话:让孩子更方便开口交流

上篇文章解决了”AI能说话”的问题,但孩子反馈:每次语音对话都要跳转页面才能听,操作起来太麻烦了。
这篇文章,就是来解决这个问题的——怎么说更方便,让孩子不用跳转页面,点击就能听。
🤔 到底怎么不方便?
原来的对话模式是这样的:
  • 助手回复文字
  • 音频是独立的MP3文件
  • 用户需要点击跳转才能听
三个明显的痛点:
  1. 孩子使用极不方便手机操作不熟练,跳转后容易迷路,不知道怎么回到对话
  2. 阅读和听觉被迫二选一看文字的时候听不了语音,听语音的时候看不了文字
  3. 操作链路过长看完文字 → 找音频 → 点击播放 → 跳转页面 → 听完回来已忘记上下文
🔧 配置过程实录
第一步:分析现有架构
检查飞书机器人配置,发现每个AI助手都有独立的:
  • FEISHU_APP_ID
  • FEISHU_APP_SECRET
  • open_id体系
这意味着每个助手需要独立的.env配置文件,不能混用凭证。
第二步:创建专属配置文件
在助手工作目录下新建 feishu.env
# 公众号小助手飞书配置export FEISHU_APP_ID="XXXX"export FEISHU_APP_SECRET="XXXX"export FEISHU_RECEIVER="XXXX"export DEFAULT_VOICE="zh-CN-XiaoxiaoNeural"export DEFAULT_BITRATE="24k"export REPLY_WITH_AUDIO="always
"
第三步:调试语音发送
使用edge-tts生成音频,通过飞书API直接发送:
# 进入工作目录cd /XXXX/公众号小助手_workspace# 加载配置source feishu.env# 发送语音bash /XXXX/workspace/skills/feishu-audio-tts/scripts/send_audio.sh "要发送的内容" zh-CN-XiaoxiaoNeural 24k
第四步:解决跨应用问题
一开始用错了飞书凭证,导致报错:open_id cross app
解决方案: 确认每个助手只用自己对应的APP凭证,不能跨应用使用。
第五步:选定语音角色
选定温柔女声”晓晓”(zh-CN-XiaoxiaoNeural),比男声更适合公众号内容场景。
📊 最终配置参数
语音引擎: edge-tts
语音角色: zh-CN-XiaoxiaoNeural(晓晓·女声)
音频格式: Opus
比特率: 24k
脚本位置:/workspace/skills/feishu-audio-tts/scripts/send_audio.sh
✅ 达到的效果
Before(旧模式)
  • 文字回复在对话框
  • 音频需要跳转/下载才能听
  • 平均耗时:15-30秒
  • 孩子友好度:⭐⭐
After(新模式)
  • 语音直接嵌入对话页面
  • 文字紧随语音发送
  • 平均耗时:1秒
  • 孩子友好度:⭐⭐⭐⭐⭐
⚠️ 避坑提示
  1. 每个助手需要独立的飞书.env配置,凭证不能混用
  2. 接收者open_id必须与当前飞书应用匹配,否则报99992361错误
  3. 语音和文字内容要保持一致,避免信息不对称
  4. 语音角色选择:女声晓晓适合温柔场景,男声云希适合正式场景
💬 一句话总结
好的配置,就是让用户在同一页面内完成所有动作——语音和文字同步到达,效率自然提升。
🔊 音频格式对比:MP3 vs Opus
两种方案的对比
对比项
MP3方案(旧)
Opus方案(新)
生成方式
edge-tts生成MP3 → 手动下载 → 发送
edge-tts生成MP3 → ffmpeg转Opus → 直接发送
文件体积
较大(同等音质下)
较小(约节省30-40%)
音质
固定码率
可调节(24k/32k/48k)
播放方式
需下载或外部播放器
飞书内嵌播放器,秒点秒播
用户体验
需要跳转/下载
直接嵌入对话
适用场景
通用场景
飞书/即时通讯
为什么最终选择Opus?
  1. 飞书原生支持:Opus是飞书语音消息的原生格式,发送后直接内嵌播放
  2. 体积小:实测同样内容,Opus比MP3小约30-40%
  3. 延迟低:无需等待下载,接收即可播放
  4. 兼容性好:ffmpeg转换稳定,跨平台无问题
转换命令示例
MP3Opus(使用ffmpegffmpeg-iinput.mp3 \-c:alibopus \-b:a 24k \output.opus
🖼️ 聊天界面效果对比
图1:旧模式(文字+跳转收听)
特征:
  • 助手回复文字内容在对话框中
  • 音频以独立文件形式存在
  • 用户需要:看完文字 → 找到音频入口 → 点击跳转 → 等待加载 → 播放
  • 整个流程需要3-5步操作
  • 音频播放后无法快速回到之前对话位置
图2:新模式(语音+文字同屏)
特征:
  • 语音消息直接出现在对话中
  • 文字内容紧随语音下方展示
  • 用户点击语音即可直接播放
  • 整个流程只需1步:点击播放
  • 始终保持对话上下文连贯
关键差异总结
差异点
旧模式
新模式
音频位置
对话框外独立存在
对话框内直接展示
操作步骤
3-5步(找→点→等→播→回)
1步(直接点击)
上下文
易断片
始终连贯
视觉呈现
文字和音频分离
语音+文字同步到达
学习成本
需教用户怎么跳转
无需任何学习
适用人群
成年人/熟悉手机操作
儿童/老人/所有人群
💡 一张图看懂升级逻辑
旧路径: 文字 → 跳转 → 音频 → 上下文丢失
新路径: 文字 + 音频同时到达 → 点击即听 → 上下文保持
本文档持续更新中,如有问题欢迎留言交流~
📜 附录:send_audio.sh 脚本内容
#!/bin/bash# 飞书音频消息发送脚本# 将文本转换为语音并发送到飞书set -e# 参数检查TEXT="$1"VOICE="${2:-zh-CN-XiaoxiaoNeural}"BITRATE="${3:-24k}"if [ -z "$TEXT" ]; then  echo "❌ 错误:缺少文本参数"  echo ""  echo "用法: $0 \"要发送的文本\" [语音类型] [比特率]"  echo ""  echo "参数:"  echo "  文本      - 要转换为语音的文字(必需)"  echo "  语音类型  - edge-tts语音类型(默认: zh-CN-XiaoxiaoNeural)"  echo "  比特率    - Opus编码比特率(默认: 24k)"  echo ""  echo "示例:"  echo "  $0 \"你好,这是一条语音消息\""  echo "  $0 \"Hello\" en-US-JennyNeural 32k"  exit 1fi# 显示任务信息echo "🎤 飞书音频消息发送"echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"echo "📝 文本: $TEXT"echo "🎙️  语音: $VOICE"echo "⚡ 比特率: $BITRATE"echo ""# 检查工具echo "🔧 检查工具..."if ! python3 -m edge_tts --version &> /dev/null; then  echo "❌ edge-tts 未安装"  echo "   安装: pip3 install edge-tts"  exit 1fiif ! command -v ffmpeg &> /dev/null; then  echo "❌ ffmpeg 未安装"  exit 1fi# 检查飞书凭证echo "🔑 检查飞书凭证..."if [ -z "$FEISHU_APP_ID" ] || [ -z "$FEISHU_APP_SECRET" ]; then  echo "❌ 缺少飞书凭证"  echo "   请设置环境变量:"  echo "   export FEISHU_APP_ID=\"你的App ID\""  echo "   export FEISHU_APP_SECRET=\"你的App Secret\""  exit 1fi# 接收者(默认为当前用户)RECEIVER="${FEISHU_RECEIVER:-}"if [ -z "$RECEIVER" ]; then  echo "❌ 缺少接收者"  echo "   请设置环境变量:"  echo "   export FEISHU_RECEIVER=\"接收者open_id\""  exit 1fiecho "👤 接收者: $RECEIVER"# 1. 获取飞书访问令牌echo ""echo "🔑 获取飞书 token..."TOKEN_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" \  -H "Content-Type: application/json" \  -d "{\"app_id\": \"$FEISHU_APP_ID\", \"app_secret\": \"$FEISHU_APP_SECRET\"}")TOKEN=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys,json;print(json.load(sys.stdin).get('tenant_access_token', ''))" 2>/dev/null || echo "")CODE=$(echo "$TOKEN_RESPONSE" | python3 -c "import sys,json;print(json.load(sys.stdin).get('code', ''))" 2>/dev/null || echo "")if [ "$CODE" != "0" ] || [ -z "$TOKEN" ]; then  echo "❌ 获取 token 失败"  echo "错误信息:$TOKEN_RESPONSE"  exit 1fiecho "✅ Token 获取成功"# 2. 生成 MP3 音频(使用 edge-tts)echo ""echo "🎙️ 使用 edge-tts 生成音频..."MP3_FILE="/tmp/feishu-audio-$$.mp3"# 使用edge-tts生成音频python3 -m edge_tts --text "$TEXT" --voice "$VOICE" --write-media "$MP3_FILE" --rate=+0--pitch=+0Hz > /dev/null 2>&1if [ ! -f "$MP3_FILE" ] || [ ! -s "$MP3_FILE" ]; then  echo "❌ TTS 生成失败"  exit 1fiecho "✅ TTS 音频生成完成: $(stat -f%z "$MP3_FILE") bytes"# 3. 转换为 opus 格式echo ""echo "🔄 转换为 opus 格式..."OPUS_FILE="/tmp/feishu-audio-$$.opus"ffmpeg -y -i "$MP3_FILE" \  -c:a libopus \  -b:a "$BITRATE" \  "$OPUS_FILE" > /dev/null 2>&1if [ ! -f "$OPUS_FILE" ] || [ ! -s "$OPUS_FILE" ]; then  echo "❌ 格式转换失败"  exit 1fiecho "✅ 格式转换完成: $(stat -f%z "$OPUS_FILE") bytes"# 4. 读取音频时长并转换为毫秒echo ""echo "⏱️  读取音频时长..."EXACT_DURATION=$(ffmpeg -i "$OPUS_FILE" 2>&1 | grep Duration | awk '{print $2}' | tr -d , | awk -F'{print ($1*3600)+($2*60)+$3}')if [ -z "$EXACT_DURATION" ]; then  echo "❌ 无法读取时长"  exit 1fi# 转换为毫秒(飞书 API 要求)DURATION_MS=$(awk "BEGIN {printf \"%.0f\", $EXACT_DURATION * 1000}")echo "✅ 时长: ${EXACT_DURATION}秒 (${DURATION_MS}毫秒)"# 5. 上传文件到飞书(duration 用毫秒)echo ""echo "📤 上传到飞书服务器..."UPLOAD_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/files" \  -H "Authorization: Bearer $TOKEN" \  -F "file=@$OPUS_FILE" \  -F "file_type=opus" \  -F "file_name=voice.opus" \  -F "duration=$DURATION_MS")FILE_KEY=$(echo "$UPLOAD_RESPONSE" | python3 -c "import sys,json;data=json.load(sys.stdin);print(data.get('data', {}).get('file_key', ''))" 2>/dev/null || echo "")if [ -z "$FILE_KEY" ]; then  echo "❌ 上传失败"  echo "$UPLOAD_RESPONSE"  exit 1fiecho "✅ 文件上传成功 (file_key: ${FILE_KEY:0:30}...)"# 6. 发送音频消息(duration 用毫秒)echo ""echo "📨 发送音频消息..."SEND_RESPONSE=$(curl -s -X POST "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id" \  -H "Authorization: Bearer $TOKEN" \  -H "Content-Type: application/json" \  -d "{    \"receive_id\": \"$RECEIVER\",    \"msg_type\": \"audio\",    \"content\": \"{\\\"file_key\\\": \\\"$FILE_KEY\\\", \\\"duration\\\"$DURATION_MS}\"  }")MESSAGE_ID=$(echo "$SEND_RESPONSE" | python3 -c "import sys,json;data=json.load(sys.stdin);print(data.get('data', {}).get('message_id', ''))" 2>/dev/null || echo "")if [ -z "$MESSAGE_ID" ]; then  echo "❌ 发送失败"  echo "$SEND_RESPONSE"  exit 1fi# 7. 清理临时文件rm -f "$MP3_FILE" "$OPUS_FILE" 2>/dev/null || true# 8. 完成echo ""echo "━━━━━━━━━━━━━━━━━━━━━━━━━━"echo "🎉 音频消息发送成功!"echo ""echo "📊 统计信息:"echo "   • 文本长度: ${#TEXT} 字符"DUR_SEC=$(awk "BEGIN {printf \"%.1f\", $DURATION_MS / 1000}")echo "   • 音频时长: ${DUR_SEC} 秒"echo "   • 语音: $VOICE"echo "   • 格式: Opus (${BITRATE})"echo "   • 消息ID: ${MESSAGE_ID:0:20}..."echo ""# 返回消息ID供后续使用echo "$MESSAGE_ID"
🔧 依赖环境
工具
说明
安装命令
edge-tts
微软TTS引擎
pip3 install edge-tts
ffmpeg
音频格式转换
brew install ffmpeg (macOS)
curl
HTTP请求
系统自带
📌 注意事项
  1. 环境变量:使用脚本前需先设置 FEISHU_APP_IDFEISHU_APP_SECRETFEISHU_RECEIVER
  2. 凭证安全:生产环境中建议使用 .env 文件管理凭证,不要直接写在命令中
  3. 临时文件:脚本会自动清理 /tmp/ 下的临时MP3和Opus文件
  4. 错误处理:脚本使用 set -e 会在遇到错误时立即退出