为什么人工测试发现的缺陷不多:Codex、ChatGPT、MASE 与人的协同开发复盘
引言
“磨耳朵”项目从 macOS 本地工具发展到 Android、iOS 和 Windows 共享架构,涉及文件解析、系统 TTS、计时、进度、持久化、后台音频、跨平台界面、应用签名和离线神经语音 POC。项目在很短时间内形成了 17 个可追踪的 OpenSpec 变更和 36 个纵向提交。
在这样一个变化密集的项目里,人工测试确实没有发现大量零散的传统缺陷。人工发现的问题主要集中在少数几类:声学体验、真机参数、真实进程生命周期,以及播放中拖动进度时的异步竞争。
这不能简单归功于“AI 写代码很准”,也不能理解为“有了自动化就不需要人”。更准确的解释是:
ChatGPT 帮助需求逐渐说清楚,Codex 把规格落实为代码和可执行证据,MASE 约束每次变化的过程,而人负责判断真实世界里是否真的好用。四者各自覆盖不同的不确定性。
注1:磨耳朵项目的介绍参见:https://blog.csdn.net/dylanren/article/details/163132389?spm=1001.2014.3001.5501
注2:MASE是麦哲思科技自定义的AI协同开发的过程框架。详细介绍参见:https://blog.csdn.net/dylanren/article/details/110038792?spm=1001.2014.3001.5501
一、先区分:用户反馈不等于软件缺陷
复盘人工反馈时,最容易犯的错误是把所有修改都算成“测试发现了 bug”。本项目的大量反馈其实属于需求浮现:增加退出按钮、暂停时可改定时、显示同步文本、保存历史位置、选择男女声、增加“缓慢”档等。
这些功能在提出之前没有对应的验收规则,实现不可能“违反”一个尚不存在的规则,所以它们是新需求或需求变更,不是逃逸缺陷。
另一些反馈属于体验校准:Android 语速比 macOS 慢、男声不够清晰、句间停顿太短、Mate 30 首屏太松散。功能已经存在,但参数和表现需要真实使用来校准。
真正意义上的功能缺陷,是已经有明确规格而候选没有满足。按项目记录归并,最突出的是两大家族:
- macOS 点击“退出应用”后,进程实际没有退出。
- 播放中拖动进度后,出现“无法继续”、回到开头、重复尝试后显示正在朗读但没有声音。
此外还有候选交付中的遗漏或平台差异,例如 macOS 一度没有显示男声选择入口。这类问题数量不多,但同样需要人工检查最终制品,而不能只看源代码。
二、人工测试究竟发现了什么
下面按“问题家族”归并,而不是按每次对话重复计数。
|
人工发现 |
类型 |
自动化为什么不容易先发现 |
后续如何固化 |
|
Android 比 macOS 慢很多 |
平台校准 |
不同 TTS API 的 rate 单位不同,模拟器和桌面参数不可直接类比 |
建立 Android/Apple 独立参数契约,并保留真机固定样本接收 |
|
Android 声音生硬、像有回音、不清晰 |
设备与声学体验 |
音频非空、调用成功不能代表扬声器上的听感 |
记录 Mate 30、具体 TTS 引擎和 voice,最终选择华为语音引擎 |
|
macOS 退出按钮没有真正退出 |
功能缺陷 |
单元测试能证明清理函数执行,却不能证明签名 App 进程已经终止 |
用真实 release App 做 3 秒进程退出 E2E,并修复 MainActor/delegate 终止握手死锁 |
|
Android 首屏需要滚动、文本界面与 macOS 不一致 |
可用性差距 |
普通 Widget 测试未必代表 Mate 30 的 360×720 视口 |
增加固定视口无滚动门禁、触控尺寸和文本跟随测试 |
|
Kokoro 中文 WAV 非空但完全听不懂 |
候选质量缺陷 |
波形非空、无崩溃、RTF 合格都不能证明语言可理解 |
把盲听复述设为硬门禁,定位到模型与中文前端版本不匹配 |
|
女声更响更易懂,部分男声不合适 |
主观质量与偏好 |
音量、音色和可懂度不能由一个布尔断言替代 |
固定句子、归一化响度、顺序与倒序比较,形成 voice 选择与安全回退 |
|
两个句子之间停顿太短 |
韵律校准 |
文本正确、进度正确仍可能听起来拥挤 |
统一识别标点/换行边界,固定 postUtteranceDelay 并补队列测试 |
|
拖动进度后报错、重头播放或无声 |
并发功能缺陷 |
同步 fake 没有模拟系统 TTS 的迟到 cancel;普通 UI 调用也没模拟一次松手产生重复事件 |
增加 cancel 屏障、100% 最后词边界、真实 CGEvent Slider E2E、single-flight 与 latest-target 合并 |
这个表说明,人工最有价值的发现集中在自动化的盲区,而不是随机地发现大量低级逻辑错误。
三、为什么传统功能缺陷相对较少
1. 需求先变成可验收行为
MASE 的第一道约束不是写代码,而是确认用户可见行为。比如“停止”不是模糊的“结束一下”,而是立即终止、进度归零、文件保留、再次播放从头开始;“定时”明确为 1—240 整数分钟,只累计实际朗读时间。
需求越可验收,AI 越不容易用一个看似合理但语义不同的实现蒙混过去。
2. 测试先于实现
项目对新增能力和缺陷都使用分级 TDD。领域规则先有 unit/contract,跨模块行为有 integration,用户主流程有 P0 E2E。
例如移动端进度拖动修复先得到 20 通过、3 失败的 RED 证据:并发定位发起了第二个 stop、100% 映射到空后缀、SystemSpeech 没有 cancel handler。只有失败可稳定复现后,才实现 single-flight 和取消确认边界。
这减少了“凭感觉改一处、再让用户试试看”的次数。
3. 公共语义由契约保护
播放、暂停、继续、停止、定时、进度等行为跨越 UI、controller、reducer 和 TTS。契约测试把这些语义固定下来,使 Android、iOS、macOS 在调整平台参数时不容易破坏共同规则。
Android 速度校准就是典型例子:修改 Android rate 的同时,契约明确要求 Apple 参数保持不变。
4. 候选版本本身也接受测试
仅测试源码不够。项目对发布 App、APK、签名、权限、版本、ABI、哈希和真实 UI 入口做候选绑定验证。
macOS 退出问题之所以能被系统化修复,是因为最终门禁升级为“点击真实 release App 后,3 秒内进程必须消失”。进度拖动问题最终也不再只调用 controller,而是向签名 App 发送真实鼠标拖动事件,并确认 TTS progress 继续推进。
5. 缺陷要求解释根因,而不是遮住提示
MASE 要求先提出可证伪根因,再修复原因并扫描同类风险。
进度拖动的修复经历了很有代表性的过程:
- 第一层发现 100% 产生空 speech,于是把末尾归一化到最后一个可朗读词。
- 第二层发现系统 stop 返回不等于旧 utterance 已 cancel,于是增加取消屏障。
- 用户复测 8:32 候选仍失败,排除了“装错版本”。
- 最终真实 Slider E2E 发现同一次松手提交两个 seek,第二个事件取消第一个批次,使旧语音仍 active,新语音启动时报 alreadyActive。
- controller 最终采用 single-flight,并把重入请求合并到最后目标。
如果只隐藏错误提示,问题会以无声、重头播放或假 playing 的形式继续出现;根因分析把多个表象收敛为同一个并发所有权问题。
6. 每个工作包可回滚,用户文件受保护
纵向 Conventional Commit、候选哈希、旧 App 备份和用户 Xcode Team 配置排除,使自动开发不必以“工作树必须干净”为理由覆盖用户修改。安全的回滚边界也让修复可以大胆而不鲁莽。
四、ChatGPT、Codex、MASE 和人的角色并不相同
这个项目的低缺陷率来自分工,而不是某一个角色包办一切。
|
角色 |
最擅长处理的不确定性 |
在项目中的典型贡献 |
|
ChatGPT 式对话 |
用户到底想要什么、怎样表达更准确 |
通过追问明确停止、定时、文件格式、速度目标、平台优先级和体验偏好 |
|
Codex 工程执行 |
代码现在是什么、如何修改并验证 |
检查仓库、建立 RED、实现、构建、运行门禁、生成制品和提交 |
|
MASE 规范 |
对话和实现怎样不失控、不丢证据 |
Profile、Spec、TDD、契约、P0 E2E、根因、候选绑定、回滚与状态记录 |
|
人工使用者 |
软件在真实世界里是否有意义 |
判断语速、清晰度、音色、句间隔、真机布局,并发现真实交互时序 |
可以把它理解为一个闭环:
人的真实使用
↓
对话澄清意图与验收标准
↓
MASE / OpenSpec 固化变更边界
↓
Codex 用 TDD 实现并生成候选
↓
自动门禁筛掉可机械判断的问题
↓
人只需要重点判断真实设备与真实体验
└──────────────────────────→ 下一轮需求或缺陷
自动化把人工从大量重复检查中解放出来;人工则把自动化无法理解的“好不好听、顺不顺手、是不是真的退出”带回系统。
五、人工测试最重要的三次贡献
1. 否决“机器指标合格等于语音可用”
Kokoro POC 能生成 WAV,性能数据也可测,但中文听不懂。人工盲听把“可理解性”提升为硬门禁,阻止了一个技术上运行、产品上不可用的候选进入 Android。
这次反馈还促成了更好的听测协议:不提前显示原文,一次只播放一句,用户反馈后再播放下一句;英语样本还要适配 ESL 听者速度。人工测试不仅给出结论,也改进了测试方法。
2. 发现真实 App 生命周期与测试替身的差距
退出逻辑的内部清理测试可以全部通过,但 AppKit 进程仍可能因为终止握手死锁而留在后台。只有点击真实签名 App 并观察进程,才能验证“退出”这个用户语义。
3. 坚持复测,迫使并发模型继续深入
进度拖动经历了多个自动门禁全部通过的候选,用户仍明确反馈“错误依旧”。这条反馈非常关键:它阻止团队把“测试绿”误当成“问题解决”。
进一步调查最终发现真实 Slider 的重复事件和 AVSpeech 的异步取消边界。随后,之前只在人工环境出现的问题被转化成确定性 integration 和真实 E2E,用同样的错误形态先红后绿。
这正是高质量人工测试的价值:不是替自动化反复点按钮,而是在自动化结论与真实体验冲突时,坚持以真实体验为事实。
六、MASE 并没有消除所有缺陷,它改变了缺陷的形态
规范化过程可以显著减少状态机、边界值、输入校验和回归问题,但以下风险仍然很难完全自动化:
- 系统 TTS 和厂商 voice 的声学差异;
- 扬声器、耳机、环境噪声和听者语言能力;
- OS 真正的进程、音频和锁屏生命周期;
- UI 框架产生的真实事件序列;
- provisioning、设备授权和外部工具链状态;
- “自然”“清晰”“舒服”等主观质量。
因此,人工缺陷少不代表可以取消人工验收。更合理的目标是:让自动化覆盖所有可以稳定机械判断的部分,把有限的人工注意力集中到真实世界边界。
七、怎样更客观地评价这种开发方式
本项目可以说“人工发现的传统功能缺陷较少”,但还不能仅凭缺陷数量证明某种方法具有普遍优势。严谨评价还需要更长周期和对照数据。
后续可以持续记录:
- 每个候选被人工否决的原因;
- 反馈属于新需求、需求变更、校准还是缺陷;
- 缺陷从报告到确定性 RED 的时间;
- 同类缺陷是否再次出现;
- 最终候选通过后是否仍有逃逸;
- 每项门禁拦截了多少实际问题;
- 人工测试时间是否更多用于体验,而不是重复功能回归。
这些指标比单纯统计“发现了几个 bug”更能说明 Codex + ChatGPT + MASE 是否真正提高了工程质量。
结语
“磨耳朵”项目中,人工发现的传统缺陷相对少,不是因为人不重要,也不是因为 AI 天生不会犯错。真正的原因是:需求经过对话澄清,代码受到规格和测试约束,候选经过自动门禁,而人把注意力放在机器最不擅长的真实体验上。
最有说服力的时刻,不是自动测试全部通过,而是用户说“错误依旧”以后,系统没有用绿色报告反驳用户,而是继续追踪,直到真实问题能够稳定变红、被系统化修复,再在真实发布路径上变绿。
这是一种比“AI 自动写软件”更准确的描述:人和 AI 共同建立了一套能承认未知、吸收反馈、保留证据并逐步提高可信度的工程闭环。
规范的价值是降低遗漏,不是制造文档负担。让 MASE 保持按风险加载,小改动使用 lite,跨平台、并发、持久化使用 standard;只读取当前 Spec、相关接口、测试和 diff。这样既保持质量,也控制 token 与过程成本。
更多推荐

所有评论(0)