fix(interview): stabilize VAD orchestration and structured LLM output - #95
Merged
Conversation
将PaddleOCR改为后端启动时同步加载的常驻Worker,通过JSON Lines协议复用已加载模型,避免每次请求重复启动Python进程。\n\n同步更新Web端OCR可用性探测、Docker与本地启动配置、接口文档及OCR测试,支持本地实际上传JD截图进行识别。
pionxe
requested review from
HansonL622,
fj-sunny,
suerzzh,
the-Louvre and
yydounai1234
August 14, 2026 10:59
| // open through natural pauses and never let a new user turn cancel an | ||
| // interviewer response while the candidate is still speaking. | ||
| turn_detection: { type: 'semantic_vad', threshold: 0.8, prefix_padding_ms: 1_000, silence_duration_ms: 3_000, create_response: false, interrupt_response: true }, | ||
| turn_detection: { type: 'semantic_vad', threshold: 0.8, prefix_padding_ms: 1_000, silence_duration_ms: 3_000, create_response: true, interrupt_response: true }, |
There was a problem hiding this comment.
[P1] 禁止移动端 VAD 自动创建面试响应
这里把 create_response 打开后,供应商可在 speech_stopped 后立即开始回答,而 responseAwaitingInterviewState 直到转写完成事件才会设为 true,后端 submitTurn 的状态结果则更晚。因此自动响应可能在取消逻辑生效前已经播放,甚至在接口较慢时完整结束,随后 sendInterviewResponse 又基于状态机创建第二个响应,重新引入重复提问或跳题。Web 端同一面试契约明确使用 create_response: false;移动端也应只保留自动 VAD 检测和打断,把响应创建交给状态机结果。
Comment on lines
+113
to
+114
| return baseAvailable() && workerReady && workerProcess != null | ||
| && workerProcess.isAlive(); |
There was a problem hiding this comment.
[P1] 让 OCR 可用性探测能够重启 Worker
启动时的 Worker 初始化失败会把 workerReady 留为 false,此处之后只返回不可用而不调用 ensureWorkerStarted()。这使注释所述的“首次 OCR 请求重试”实际无法发生:Web 端先用可用性接口禁用图片入口,服务端 MaterialTextExtraction 也会在调用 recognizeText 前检查 available() 并直接抛错。一次瞬时启动超时或资源问题因此会让 OCR 在整个进程生命周期内保持关闭,必须重启应用才能恢复;可用性探测或调用门控应触发受锁保护的重启尝试。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Root Cause
面试链路此前同时存在自动响应和状态机响应两套触发路径,可能导致响应重复、过早结束或用户语音被截断。同时,结束流程仅依赖模型响应完成事件,未等待客户端音频播放缓冲完全排空。
材料整理请求没有显式声明 JSON_OBJECT 格式,也增加了模型返回非结构化内容、解析失败和修复请求失败的概率。
Changes
LlmResponseFormatLlmProvider和AiProviderRegistry增加格式参数重载response_formatevaluation、advice和summary使用简体中文BACKEND_HOST_PORT配置本地后端映射端口Validation
./mvnw -q -DskipITs -Dtest=InterviewReportCoordinatorTest,InterviewSceneServiceTest,QwenRealtimeProviderTest testnpm run check:realtime-eventsgit diff --checkNotes
移动端 Jest 检查未执行,原因是当前环境缺少
jest可执行文件。