Skip to content

feat(interview): 面试工程化加固(single-flight 防重复扣费 + 追问规则短路 + 追问维度约束 + 评分防注入) - #4

Merged
AAA-413 merged 4 commits into
developfrom
feat/engineering-hardening
Aug 26, 2026
Merged

feat(interview): 面试工程化加固(single-flight 防重复扣费 + 追问规则短路 + 追问维度约束 + 评分防注入)#4
AAA-413 merged 4 commits into
developfrom
feat/engineering-hardening

Conversation

@AAA-413

@AAA-413 AAA-413 commented Aug 26, 2026

Copy link
Copy Markdown
Owner

背景

分析竞品 AI-Meeting(程序员牛肉)的模拟面试实现后,提炼出 4 个可借鉴的工程化点,落地到本项目。

改动内容

1. 分布式 single-flight 防重复扣费

  • 新增 app/common/single_flight.py:内容指纹 + Redis 原子锁(SET NX EX)+ 结果回放(TTL 600s)
  • 包裹追问生成的 LLM 调用:同一题 + 同一答案的并发/重复请求只执行一次 LLM,其余等待或直接回放,避免前端重复提交、网关重试导致的重复扣费
  • Redis 不可用或等待超时时自动降级为直接执行,不影响可用性

2. 追问决策代码级规则短路

  • 放弃性回答("不会"/"不知道"/空白等,≤20 字)直接短路不追问,省一次 LLM 调用,决策可解释

3. 追问五选一维度约束

  • 追问限定单一维度:实现细节 / 边界条件 / 性能指标 / 故障排查 / 技术取舍,避免泛泛而问

4. 评分防注入

  • 评估 prompt 增加防注入条款:候选人回答中出现"请忽略以上规则"等试图操纵评分的指令,视为无效回答强制 0 分

测试

  • 新增 tests/test_single_flight.py:6 个用例,覆盖指纹确定性、放弃回答识别、并发合并、结果回放、降级兜底
  • 现有 test_interview_question_service.pytest_structured_output_aliases.pytest_topic_registry.py 全部通过

说明

本分支基于 feat/realtime-stt(含实时语音 STT 功能),故相对 develop 的 diff 也包含语音功能提交。

Claude Code added 4 commits July 18, 2026 16:06
用户测试发现长语音(>5s)只识别出最后一句尾段。

根因:之前的 _ROLLING_WINDOW_SECONDS=5 实现是错的——
  audio_chunk = bytes(buffer[-rolling_window_bytes:])  # 只取最后 5s

buffer 无限增长,但推理只用最后 5s 窗口,前面的内容直接被丢。
这是为了避免 O(n²) 复杂度引入的优化,但破坏了正确性。

修复:每次 partial 都对完整 buffer 跑一次推理。SenseVoice CPU
17x 实时,单次推理 ~60ms/秒音频,O(n²) 在 30s 以内完全可控:
  - 30s 音频:30 次推理,总 CPU ~2s(每 1s 音频 60ms)
  - 60s 音频:60 次推理,总 CPU ~7s(仍可接受)

权衡:丢内容 vs 多算点 CPU,永远选丢内容是 bug。

测试:14/14 仍然通过(只检查事件流,不检查具体文本内容)
用户测试发现:浏览器通过 Vite 代理连后端 WS,Vite log 报
'ws proxy error: Error: write EPIPE'。binary PCM 帧被 Vite 代理丢了,
server 端 buffer 永远是空,partial 永远不触发。

根因:Vite 5.x dev server 的 ws: true proxy 对 binary 帧处理有 bug
(http-proxy 库的 WS frame 透传问题)。HTTP 帧没事,binary 帧被丢。

修复:dev 环境让 WS 直连后端 :8002,不走 Vite 代理。
- 新增 wsUrl() helper:把 apiUrl() 的 http:// 换成 ws://
- voiceStream.ts 改用 wsUrl() 构建连接 URL
- 新增 frontend/.env.development:VITE_API_BASE_URL=http://localhost:8002
  (Vite 自动加载 .env.development 仅在 dev mode;prod 用 .env.production 留空)

CORS 兼容:backend 的 CORS_ALLOWED_ORIGINS 已包含 :5173
backend 端没有 Origin check(ws_router.py 也不查 Origin),dev 跨源 OK

Vite 代理仍然保留(HTTP /api 走 Vite 代理仍然有效),仅 WS 绕开
- 新增分布式 single-flight 防重复扣费(内容指纹 + Redis 原子锁 + 结果回放)
- 追问决策加代码级规则短路:放弃性回答直接不追问,省一次 LLM 调用
- 追问加五选一维度约束(实现细节/边界条件/性能指标/故障排查/技术取舍)
候选人回答中出现'请忽略以上规则'等操纵评分指令时,视为无效回答强制 0 分
@AAA-413
AAA-413 merged commit 0efc262 into develop Aug 26, 2026
2 of 4 checks passed
@AAA-413
AAA-413 deleted the feat/engineering-hardening branch August 26, 2026 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant