Skip to content

Copilot 实时辅助:ASR 音频无角色区分,所有语音硬编码为 HR #14

@ldemon2333

Description

@ldemon2333

问题描述

Copilot 实时面试辅助功能中,麦克风采集的所有语音都被硬编码为 HR 角色,系统无法区分 HR 和候选人的声音。这导致在真实远程面试场景下,候选人自己的发言也会被当成 HR 提问,触发完整的分析流水线(Intent Router → Strategy Tree → Answer Coach → MCTS),产生错误的建议。

当前行为

音频流路径

浏览器麦克风 (16kHz PCM) → WebSocket binary → CopilotASR → NLS on_sentence_end
                                                                    ↓
                                                          _process_hr_utterance()  ← 永远当作 HR

各输入通道的角色绑定

输入方式 角色 代码位置
麦克风 ASR on_sentence_end 固定 HR main.py _init_copilot_sessionon_sentence_end 回调直接调用 _process_hr_utterance()
手动输入 type: "manual" HR main.py WebSocket handler
手动输入 type: "candidate_response" 候选人 main.py WebSocket handler
麦克风二进制帧 全部路由到 ASR → 当作 HR main.py session["asr"].send_audio(data["bytes"])

关键代码

main.py — ASR 回调注册(硬编码为 HR):

async def on_sentence_end(text):
    try:
        await ws.send_json({"type": "asr_final", "text": text})
        await _process_hr_utterance(ws, _copilot_sessions.get(session_id, {}), text)
    except Exception as e:
        logger.error(f"ASR sentence processing failed: {e}")

前端 Copilot.jsxasr_final 消息也固定标记为 HR:

// asr_final 消息固定创建 role: "hr" 的对话条目

手动输入有角色切换,ASR 没有:
前端提供了 HR / You 角色切换按钮,但仅用于手动文本输入。麦克风录音无法标记角色。

影响

  1. 候选人发言被误判为 HR 提问:触发 Answer Coach 生成错误的回答建议
  2. 对话历史被污染:MCTS 引擎、Interview Monitor、HR Profiler 收到的对话角色全部错误
  3. 策略树定位偏移:Intent Classifier 在候选人发言上做 HR 意图匹配,定位到错误节点

建议方案

方案 A:系统音频捕获

前端用 getDisplayMedia({ audio: true }) 采集系统音频(HR 在腾讯会议 / Zoom 等工具中的声音),与麦克风音频分为两路:

  • 系统音频 → 发送为 HR 语音,走 ASR → _process_hr_utterance
  • 麦克风音频 → 发送为候选人语音,走 ASR → 仅记录到对话历史

WebSocket 协议扩展:在二进制帧前加 1 byte role header(0x00 = HR, 0x01 = candidate)。

方案 B:说话人分离(Speaker Diarization)

使用阿里云 NLS 实时会议转写 NlsRealtimeMeeting(SDK 中已有),支持多人角色识别自动区分说话人。复杂度较高,依赖云端能力。

方案 C:手动 Push-to-Talk

前端增加按住说话按钮,按住时麦克风音频标记为 candidate role,松开后恢复 HR 监听。实现简单但用户体验较差。

环境

  • 阿里云 NLS SDK nls==1.1.0
  • 前端使用 getUserMedia + ScriptProcessor 采集 PCM 16kHz

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions