多轮对话中“Chatterfly 忘记刚才说过的话”,通常只有两种来源:语音转写没把关键信息送进系统,或者转写没问题但上下文在某一轮被重置。排查顺序建议反过来——先确认每一轮的转写文本,再探测上下文保持能力。否则很容易把转写丢字误判成上下文丢失,去反复调会话参数却没有效果。
适用场景是单设备、单会话的连续语音对话排查。操作动作:设计三轮脚本、逐轮保存转写文本、每轮追问具体字段。验证方式:转写文本与口述原文逐字比对,再对照回答是否准确。风险边界:转写准确不等于上下文一定保留,重新唤醒、静默超时、会话切换都可能清空上下文;具体阈值需结合自己的客户端版本和配置确认。
设计一个三轮对话脚本,每轮包含一个关键信息
脚本的目的不是聊得自然,而是让每轮都带一个可校验的关键信息,且第三轮同时考旧信息和新信息。下面这组可以直接照读,每轮之间停顿一两秒,不要中途插话。
| 轮次 | 口述内容 | 关键信息 | 第三轮要检验的点 |
|---|---|---|---|
| 第一轮 | 我叫林舟,帮我订周三下午的会议室 | 名字:林舟;时间:周三下午 | 名字是否还在 |
| 第二轮 | 时间改成周四上午 | 时间变为周四上午 | 时间是否被更新 |
| 第三轮 | 我叫什么名字,时间是什么时候,再加一个投影仪 | 名字+时间+新增项 | 旧信息是否被顶掉 |
每轮结束后把转写文本抄进一份记录文件,推荐用最简单的 CSV,转写文本列先留空手填,避免混入主观判断:
轮次,口述原文,转写文本,是否含关键信息,备注
1,我叫林舟 帮我订周三下午的会议室,,,
2,时间改成周四上午,,,
3,我叫什么名字 时间是什么时候 再加一个投影仪,,,关键信息尽量选人名、时间、数字、否定词这几类,它们最容易在语音转写里丢,也最容易在上下文里被覆盖。
逐轮核对转写文本,确认信息是否完整进入系统
拿到转写文本后做逐字对比,而不是“读起来差不多”。把口述原文和转写文本各存一行,用 diff 看差异位置:
echo '我叫林舟,周三下午订会议室' > original.txt
echo '我叫林舟,下午订会议室' > asr.txt
diff -u original.txt asr.txt上面这种差异丢掉了“周三”,属于关键信息遗漏。核对时按下表分类标记,比笼统写“转写不准”更有用:
- 遗漏类:时间、人名、数量、否定词整块消失,常见于语速偏快或句中停顿被切断。
- 错字类:同音字混淆,例如把“周四”写成“周十”,这类错误进入上下文后比直接丢失更难发现。
- 截断类:后半句没转出来,通常表现为转写文本明显短于口述原文。
如果不方便逐字听写,可以先用日志里的转写字段筛一遍再人工核对,字段名按实际日志替换:
grep -n -i 'transcript\|asr' chatterfly.log | tail -n 50只要这一层对不上,就先解决拾音距离、环境噪声和语速问题,不要继续测上下文——此时任何“忘记”都不可信。
在每轮对话后询问 Chatterfly 是否记得上一轮信息
提问句式建议固定,避免每轮换说法引入额外歧义。可用的句式包括:“我刚才说了什么?”、“上一轮我让你改的时间是几点?”、“我第一轮说的名字是什么?”。
开放式的“我刚才说了什么”回答往往含糊,判定困难;更稳的做法是直接问具体字段,名字、时间、数量各问一次,然后按下表记录:
| 轮次 | 提问句式 | 回答内容 | 判定 |
|---|---|---|---|
| 第二轮后 | 我第一轮说的名字是什么? | (记录原话) | 准确/部分/丢失/编造 |
| 第三轮后 | 现在的时间是几点? | (记录原话) | 准确/部分/丢失/编造 |
“编造”这一档要单独记:回答里出现了脚本里从没说过的名字或时间,说明问题不在保留而在补全,处理方向完全不同。
如果转写无误但上下文丢失,测试重新唤醒是否重置上下文
当转写完整、回答却只保留当前轮信息时,用下面这组步骤判断是不是重新唤醒导致的:
- 正常完成前两轮,确认第二轮的回复里还带着第一轮的名字。
- 按你的客户端支持的方式故意重新唤醒(唤醒词、按键唤醒、锁屏后再解锁等)。
- 唤醒后先说一句与任务无关的话,例如“嗯,在吗”,把当前轮清空。
- 再问“我第一轮说的名字是什么”,对比重新唤醒前的回答。
同时做一组对照:不重新唤醒,只在第二轮到第三轮之间明显拉长停顿,再问同样的问题。两组结果对照后,才能区分“唤醒重置会话”和“静默超时清空上下文”,两者的处理方向不一样。
总结多轮对话的稳定轮次和边界条件
把每次测试写进同一张表,逐次增加轮次(3、5、8……)或拉长轮间隔,直到出现第一次丢信息,记下那一轮或那个间隔。不要凭“大概几轮”的印象判断,以转写文本和回答记录为准。
| 测试次数 | 连续轮次 | 轮间隔 | 是否重新唤醒 | 首次丢失出现在第几轮 | 丢失的字段 |
|---|---|---|---|---|---|
| 1 | 3 | 约 2 秒 | 否 | (填写) | (填写) |
| 2 | 5 | 约 2 秒 | 否 | (填写) | (填写) |
| 3 | 5 | 约 10 秒 | 是 | (填写) | (填写) |
可感知的边界通常是这样几条:连续几轮内、间隔较短且不重新唤醒时,之前说过的名字和时间能被再次引用;一旦重新唤醒或间隔拉长,旧信息可能不再被带出。具体轮次和秒数在不同版本、不同音频输入下会不一样,需要自己实测确认,不宜照搬别人的数值。
最后用这张表把整条链路对号入座,再决定改哪一环:
| 现象 | 转写文本 | 上下文回答 | 更可能的原因 | 下一步验证 |
|---|---|---|---|---|
| 第二轮就答错名字 | 第一轮缺名字 | 回答缺失 | 转写遗漏 | 靠近设备、放慢语速后重测 |
| 转写完整却答不出 | 含名字完整 | 说“没听清” | 上下文未保留 | 不重新唤醒,连续问同一字段 |
| 重新唤醒后丢失 | 完整 | 只答唤醒后的内容 | 唤醒重置会话 | 与静默等待组对照 |
| 回答流畅但与原文不符 | 完整 | 给出不存在的细节 | 模型补全 | 换成具体字段逐一复核 |