ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Friend 后端 Replay Harness STT Wire-Fidelity Oracle:Parakeet 实时语音 WebSocket 协议的确定性结构化测试指南

2026/9/15 17:14:26 拓冰建站 浏览量
Friend 后端 Replay Harness STT Wire-Fidelity Oracle:Parakeet 实时语音 WebSocket 协议的确定性结构化测试指南 Friend 后端 Replay Harness STT Wire-Fidelity OracleParakeet 实时语音 WebSocket 协议的确定性结构化测试指南【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend导读本文围绕 Friendomi后端测试体系中一个生命周期标记为 permanent 的专项测试模块——backend/testing/replay_harness_stt_wire_fidelitySTT Wire-Fidelity Oracle展开。它通过一个仅监听 loopback 的受控伪上游fake upstream驱动生产环境真实的 Parakeet 实时 STT WebSocket 客户端process_audio_parakeet/ParakeetWebSocketSocket以及 listen receiver 的回退fallback与终态terminal-session路径验证 wire 层与终态契约的确定性。读完本文你将掌握该 oracle 的定位边界、运行方式、五大契约断言、与生产实现的对应关系以及其只输出受限协议证据、绝不触碰真实数据的安全设计。一、为什么需要一个 Wire-Fidelity OracleFriend 后端的实时语音转录live STT链路中Parakeet 是自托管在 GPU 边界上的流式识别服务。生产代码中这条链路的核心由两个模块承担process_audio_parakeet与ParakeetWebSocketSocketbackend/utils/stt/streaming.py负责与 Parakeet 的/v3/streamWebSocket 建立连接、等待服务端就绪帧、中继 PCM、接收带说话人标签的文本片段ListenReceiverbackend/routers/listen/receiver.py负责整条 listen 会话的音频接收、STT 建连、中会话 failover 与终态上报。要验证客户端确实在收到{type: ready}之后才转发 PCMfinalize 尾部冲刷有序到达特定 close code 触发特定回退/终态这类协议级行为直接连真实提供商会引入不确定性与安全风险。Replay Harness STT Wire-Fidelity Oracle 的答案很明确在 loopback 上架设一个受控的假上游把生产代码原样驱动起来然后只对协议证据做断言。它是确定性deterministic、顾问性advisory、结构化structural的协议测试——它不是提供商一致性测试provider conformance不接触真实提供商、不做服务探测、不抓流量、不使用录音音频。其 LIFECYCLE 标记为 permanent意味着它是长期守护 wire 契约的固定成员而非一次性脚本。二、运行方式与前置条件README 给出的唯一入口是npm run test:replay-stt-wire-fidelity该 npm script 在仓库根目录 package.json 中注册指向 backend/testing/replay_harness_stt_wire_fidelity/run.sh。脚本的完整逻辑如下#!/usr/bin/env bash # Run the advisory STT wire-fidelity oracle against its loopback fake upstream. set -euo pipefail repo_root$(cd $(dirname $0)/../../.. pwd) cd $repo_root if [[ ! -x backend/.venv/bin/python ]]; then echo Missing backend/.venv. Run make setup first. 2 exit 1 fi PYTHONPATHbackend backend/.venv/bin/python -m testing.replay_harness_stt_wire_fidelity.oracle要点脚本先确认backend/.venv/bin/python存在不存在则提示先执行make setup通过PYTHONPATHbackend把仓库根目录加入导入路径从而以-m testing.replay_harness_stt_wire_fidelity.oracle方式执行 oracle 模块模块入口main()运行全部场景成功后以json.dumps(evidence, sort_keysTrue)输出结构化证据任一断言失败则打印Replay STT wire-fidelity oracle failed: 异常类型并以非零码退出。Oracle 进程生命周期内只发生本机 WebSocket 连接127.0.0.1随机端口因此不需要任何云端凭证、真实端点或录音文件可以在 CI 与本地反复执行。三、Oracle 守护的五大 Wire 与终态契约README 明确列出了伪上游需要证明的五项契约每一条都对应着生产路径中一个真实的风险点ready 门控客户端在收到{type: ready}之前不会转发任何 PCM 帧顺序保持合成 PCM 帧的顺序、片段segment投递顺序以及finalize尾部冲刷tail flush都能穿过真实客户端/接收端路径而保持有序capacity 拒绝回退受控的 close1013配合文档化的capacity_full类别在启动阶段恰好选择一次 Modulate 作为回退初始化失败终态初始化期间的受控 close1011在唯一启动回退不可用时走有界的service_status(stt_failed)后接客户端 WebSocket1011的失败路径干净关闭闩锁latch提供商在没有完成终态的情况下干净关闭连接时将 socket 闩锁为 dead并走同一条终态路径不做会话内重试。同时 README 明确划清了边界该 oracle不建立提供商一致性、不验证生产端点行为、不校验转录文本正确性、不承诺客户端兼容性、不构成发布门禁release gate、不覆盖 Phase 0B、也不做端到端捕获保真度验证。四、伪上游与场景编排的源码级拆解Oracle 的核心是一个自包含的可执行模块 backend/testing/replay_harness_stt_wire_fidelity/oracle.py。它直接导入生产代码from routers.listen import receiver as listen_receiver_module from routers.listen.receiver import ListenReceiver from utils.stt.streaming import STTService, ParakeetWebSocketSocket, process_audio_parakeet4.1_LoopbackParakeet受控的假上游_LoopbackParakeet是一个异步上下文管理器通过websockets.serve(self._handle, 127.0.0.1, 0, max_size1024 * 1024)在随机端口上启动只绑定本机的 WebSocket 服务api_url动态取实际端口形如http://127.0.0.1:port。它只保留安全的协议证据endpoint_path默认为/v3/stream、events事件序列、connections连接次数。其处理器_handle按scenario分派四种行为capacity收到连接后立即close(code1013, reasoncapacity_full)记录closed_1013initialization立即close(code1011, reasonstream_initialization_failed)记录closed_1011normal先发{type: ready}随后进入消息循环收到二进制 PCM 就递增frame_index并回发一个带text/start/end/speaker的合成片段收到字符串finalize就回发最后一个尾部片段并结束clean_close发完ready后立即close(code1000, reasoncomplete)。此外它校验两点连接路径必须精确等于/v3/stream否则OracleFailure(client did not use the Parakeet stream endpoint)客户端发来的帧类别必须被支持否则OracleFailure(client sent an unsupported frame class)。处理器中的异常会被捕获并记录到_handler_failure在退出上下文时重新抛出确保伪上游自身的故障不会静默吞掉。4.2 端点注入与证据收敛_configured_parakeet_endpoint(url)临时把HOSTED_PARAKEET_API_URL环境变量指向伪上游地址退出上下文后恢复原值。这与生产代码process_audio_parakeet读取os.getenv(HOSTED_PARAKEET_API_URL)并据此拼出ws://…/v3/stream的方式完全一致backend/utils/stt/streaming.py。_bounded_evidence_logging()把utils.stt.streaming与utils.observability.fallback两个 logger 临时压到CRITICAL保证可执行 oracle 的输出严格落在证据白名单内不被生产日志污染。4.3 本地替身与断言辅助_FallbackSocket受控的本地回退端点send恒真、finish/finalize为空操作、is_connection_dead恒 False——它只用于验证回退被选中一次绝不发起任何真实提供商连接。_ClientSocketlisten 客户端替身只保留公开的安全信封envelopestatusessend_json收到的对象与closesclose code/reason 列表并对非对象信封直接判定OracleFailure。_receiver_host(client)用SimpleNamespace构造一个最小可用的 receiver hoststt_serviceSTTService.parakeet、16 kHz、合成 session id 等配合ListenReceiver(host, [], {})驱动真实接收端代码。_assert_terminal_failure(client)断言终态严格形如——恰好一条statustypeservice_status、statusstt_failed、reason为initialization_failed或connection_lost且恰好一次close(1011, transcription_service_unavailable)并返回排序后的状态 schema 键集合。_wait_for_dead(socket)以 20×50ms 轮询等待socket.is_connection_dead翻转超时即判定干净关闭未闩锁终态。五、四个场景的断言逻辑与输出run_oracle()依次运行四个场景并把证据汇总为{oracle: replay-stt-wire-fidelity, scenarios: {...}}5.1 ready → frame → finalizenormal_normal_wire_scenario通过process_audio_parakeet(receive, languageen, sample_rate16000, channels1)构造生产 socket连续发送bytes(32)、bytes(64)两段 PCM调用socket.finalize()后await socket.drain_and_close()7 秒超时。断言伪上游事件序列严格等于[connected, ready, pcm_1, segment_1, pcm_2, segment_2, finalize, finalize_tail]——证明ready 门控与finalize 尾部冲刷顺序未被破坏回调收到的片段 schema 键恰好为(end, speaker, start, text)且按start递增为[1, 2, 3]——证明片段投递顺序保持连接次数恒为 1无多余建连。5.2 1013 capacity 拒绝 → Modulate 回退恰好一次_capacity_fallback_scenario用patch.object(listen_receiver_module, process_audio_modulate, fallback)替换回退实现为AsyncMock(return_value_FallbackSocket())然后调用 receiver 的_create_stt_socket。断言返回类型是_FallbackSocket、host.stt_service被更新为STTService.modulate、fallback.assert_awaited_once()恰好一次、伪上游只经历[connected, closed_1013]。这对应生产代码中connect_stt_socket_with_fallback的建连链backend/utils/stt/streaming.py主提供商被拒后按固定顺序Modulate → Deepgram → Parakeet且排除主提供商自身推进Parakeet 主路径被1013/capacity_full拒绝后第一条可用腿就是 Modulate。5.3 1011 初始化失败 → 有界终态回退不可用时_initialization_failure_scenario把 Modulate 回退替换为AsyncMock(side_effectRuntimeError(...))模拟回退不可用并 patchshould_initialize_vad_gate返回 False然后调用receiver.initialize_stt()。断言初始化返回 False未错误地成功、回退被调用恰好一次、_assert_terminal_failure通过且reason initialization_failed、伪上游只经历[connected, closed_1011]。这验证了 README 契约第 4 条——有界bounded的失败路径一条service_status(stt_failed) 一次客户端1011关闭不无限重试。5.4 干净关闭 → 闩锁终态且不重试_clean_close_scenario构造 socket 后等待is_connection_dead翻转_wait_for_dead把该 socket 挂到 receiver 上并显式调用receiver._monitor_stt_death(parakeet)随后断言终态信封与关闭行为且伪上游只经历[connected, ready, closed_clean]无第二次建连即无会话内重试。这条契约对应生产实现中的一个关键修复点ParakeetWebSocketSocket._receive_loop在async for msg in ws因上游干净关闭而自然退出时若self._closed未置位即不是本地 drain/finalization 触发会调用self._mark_dead(parakeet ws closed cleanly by provider)把 socket 闩锁为 deadbackend/utils/stt/streaming.py。否则接收循环只在冲刷客户端音频缓冲时_flush_stt_buffer→live_stt_socket_is_dead才能观察到死亡一个没有任何后续音频的干净上游关闭会让移动端 socket 一直停在 Listening 状态直到 300 秒的ws_receive_timeout。_monitor_stt_deathbackend/routers/listen/receiver.py正是用来在死亡闩锁翻转后立即驱动同一条幂等终态路径stt_failed WebSocket 1011。相关单元测试见 backend/tests/unit/test_stt_clean_close_latch.py 与 backend/tests/unit/test_listen_ready_provider.py。六、数据安全设计只有证据没有数据README 对数据安全给出了三条硬性约束oracle 的实现也逐条落实音频只有两段生成的零填充字节数组bytes(32)、bytes(64)不是录音、不是真实语音伪上游回发的片段体是合成文本text: synthetic、speaker: synthetic长度仅足以驱动生产接收端且不被记录、不被返回、不被持久化打印的证据严格受限只有端点路径形状endpoint_path、close-code 类别如1013/1011/1000、事件顺序、回调 schema 键callback_schema_keys、回退次数fallback_attempts与终态结果。PCM、转录文本、提供商请求体、ID、请求头与凭证一律不进入输出。这意味着该 oracle 可以在任何环境包括带敏感数据策略的 CI安全运行同时仍能对 wire 层结构性回归给出高信噪比的判定。七、运行结果解读与作为顾问性测试的定位成功运行时main()输出类似如下的 JSON键已排序{ oracle: replay-stt-wire-fidelity, scenarios: { ready_frame_finalize: { endpoint_path: /v3/stream, event_order: [connected, ready, pcm_1, segment_1, pcm_2, segment_2, finalize, finalize_tail], callback_schema_keys: [[end, speaker, start, text]], callback_order: [1, 2, 3], connection_attempts: 1 }, capacity_fallback: { close_code_class: 1013, fallback_attempts: 1, connection_attempts: 1 }, initialization_failure: { close_code_class: 1011, fallback_attempts: 1, status_schema_keys: [reason, status, type], terminal_close_code: 1011, connection_attempts: 1 }, clean_close_terminal: { close_code_class: 1000, terminal_latched: true, status_schema_keys: [reason, status, type], terminal_close_code: 1011, connection_attempts: 1 } } }若任一断言失败进程以非零码退出并打印失败场景异常类型便于在 CI 中直接定位是ready 门控被破坏片段顺序被打乱回退次数变化还是终态信封漂移。需要再次强调其顾问性定位它守护的是生产代码自身不会在 wire 层悄悄退化的结构性底线而不是Parakeet 部署是否符合提供商规范或转录文本质量如何。后者由其他测试如 backend/tests/unit/test_modulate_stt.py、backend/tests/unit/test_modulate_connection_fallback.py、backend/tests/unit/test_deepgram_connection_fallback.py以及生产监控体系覆盖。把协议结构与提供商一致性分开治理正是这个 oracle 最重要的架构决策。八、扩展阅读伪上游与全部场景实现backend/testing/replay_harness_stt_wire_fidelity/oracle.py运行入口与 npm 注册backend/testing/replay_harness_stt_wire_fidelity/run.sh、package.jsonParakeet 实时流客户端与 ready/finalize/dead-latch 实现backend/utils/stt/streaming.py建连回退链含EXPECTED_REJECTIONS与capacity_full语义backend/utils/stt/streaming.pylisten receiver 的 STT 建连、中会话 failover 与终态监控backend/routers/listen/receiver.py相关单元测试backend/tests/unit/test_stt_clean_close_latch.py、backend/tests/unit/test_listen_ready_provider.py【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考