3天速成 使用AI《从零开发一款 AI 面试作弊助手》一

一、别焦虑了,先把"外挂"做出来

最近技术圈充满了"前端已死"、"AI 取代程序员"的论调。焦虑是真实的,但大部分焦虑来自"看别人做",而不是"自己做"。

当你真正动手用 AI 开发一个复杂的实时交互产品时,你会发现:AI 很强,但某些细节需要调试和把控。

用AI,三天从 0 开始打造一款AI 面试作弊助手。不是 Demo,是能实时听懂面试官提问、能看懂笔试题屏幕、并即时推送答案的"硬核外挂"。

这篇文章,就是这次前端架构的完整复盘。

项目地址:OfferCar AI - AI 面试笔试助手 | 智能面试模拟平台

二、架构美学:不做通用,做场景

市面上的 AI 聊天 Demo 满天飞,大多是 useChat 一把梭。但在"面试作弊"这个高压场景下,通用型架构根本扛不住。

我们需要的是极致的解耦

1. UI 与逻辑的物理隔离

UI 组件不持有业务状态

为此抽象了 SessionMainContent ------ 它是整个系统的"显示器"。它只负责一件事:渲染

  • 它不关心是"面试"还是"笔试"。
  • 它不关心消息是 Socket 推送的还是 HTTP 拉取的。
  • 它只接收 messages 数组和回调函数。
typescript 复制代码
// 纯粹的 UI 定义,没有杂乱的 useEffect
interface SessionMainContentProps {
  messages: ChatMessage[];        // 数据源
  streamingContent: string;       // 流式缓冲区
  isStreaming: boolean;           // 状态位
  sendPendingMessagesToAI: () => void; // 动作指令
  // ...
}

2. 业务容器:Controller 的诞生

ExamSessionInterviewSession。这两个组件是真正的业务容器

  • InterviewSession :初始化 useInterviewSession,建立语音识别通道,挂载 DeviceStatusPanel(音量监控)。
  • ExamSession :初始化 useExamSession,监听全局截图指令,挂载简化版状态栏。

这种设计让 MVP 阶段的代码极易维护:改 UI 不动逻辑,改逻辑不崩 UI。

三、核心大脑:useChatSession 的炼成

这是整个前端最"重"的 Hook,也是与 LLM 搏斗的修罗场。在 MVP 阶段,我砍掉了所有花哨功能,只保留付费闭环所需的逻辑。

1. 思考链(CoT)的 60fps 渲染

现在的 DeepSeek 等推理模型会输出 <think> 标签。如果直接渲染,用户会看到一堆乱码;如果等思考完再显示,用户会以为网断了。

我的解法:流式解析 + 渲染节流

我们实现了一个 thinkTagProcessor,实时将 <think> 转换为 Markdown 的引用块 > 。同时,为了防止高频 setState 导致 React 掉帧(尤其在低端笔记本上),我加入了 requestAnimationFrame 节流。

typescript 复制代码
// 节流阀:让 AI 的思考过程如丝般顺滑,而不是卡顿的打印机
const tickThinkThrottle = useCallback(() => {
  if (!isThinkRafRunningRef.current) return;
  setStreamingContent(remainTextRef.current); // 只有这里才会触发重绘
  thinkRafIdRef.current = requestAnimationFrame(tickThinkThrottle);
}, []);

2. 消息围栏:只听面试官的话

面试场景有一个痛点:面试者的废话太多。如果全发给 AI,上下文瞬间爆炸。

我在 sendPendingMessagesToAI 中加入了一层过滤器

typescript 复制代码
const sendPendingMessagesToAI = useCallback(async () => {
  const pendingMessages = messages.filter((msg) => {
    // 开启 scopeCharacter 后,AI 自动屏蔽面试者发言,只聚焦面试官的问题
    if (scopeCharacter) {
      return msg.speaker === 'interviewer';
    }
    return true;
  });
  // ...
}, [/*...*/]);

这不仅仅是省 Token,更是为了提高回答的信噪比

四、降维打击:WebRTC 的另类用法

提到 WebRTC,大家第一反应是视频通话。但在我的架构里,WebRTC 是跨端通信的高速公路

这是典型的"技术降维打击"。我们不需要视频流,我们需要的是低延迟的指令通道

1. DataChannel:不传视频传指令

我利用 WebRTC 的 DataChannel 建立了两个核心管道:

  • exam-commands:传输控制指令。Electron 截图后,通过此通道直接将 Base64 推送到 Web 端,速度毫秒级。
  • recognition-text:传输实时语音转写文本。

这种设计避开了传统 HTTP 轮询的延迟,也比 WebSocket 更轻量(P2P 直连)。

typescript:hooks.ts 复制代码
// 监听来自 Electron 的"量子纠缠"信号
channel.onmessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.type === 'screenshot') {
    // 瞬间上屏,无感知传输
    addImageToPendingMessages(message.data);
  }
};

五、体验微操:Redux 配置中心

UI/UX 的作用是什么?是**"显得值钱"**。

为了让用户觉得"这个外挂很专业",我用 Redux Toolkit (settingsSlice) 管理了全局偏好:

  • 字号微调:AI 回答字号、面试官字号独立控制。
  • 双语开关:一键切换中英对照,瞬间提升逼格。

这些配置在 SessionMainContent 中被实时订阅。用户拖动滑块,界面即时响应。这种掌控感,是付费意愿的来源之一。

六、结语:AI 时代,拿回你的生产资料

写到这里,我想说:代码只是工具,是连接现实与数字世界的铲子。AI 让这把铲子变成了挖掘机,但挖掘机本身不会决定去哪里挖掘宝藏。

在这个项目里,AI 帮我生成了100% 的 业务逻辑。 别焦虑,去创造。打开编辑器,去想一个你真正想解决的问题。 项目地址:OfferCar AI - AI 面试笔试助手 | 智能面试模拟平台

下一篇,我们将深入 Electron 客户端,看看如何进入系统音频流,实现无感采集。

相关推荐
xiaoxue..3 小时前
React Hooks :useRef、useState 与受控/非受控组件全解析
前端·react.js·前端框架
C_心欲无痕4 小时前
react - createPortal魔法传送门
javascript·vue.js·react.js
沛沛rh455 小时前
React 学习笔记:State、hook —— 组件的记忆
前端·javascript·react.js
C_心欲无痕13 小时前
react - useImperativeHandle让子组件“暴露方法”给父组件调用
前端·javascript·react.js
web小白成长日记18 小时前
深入理解 React 中的 Props:组件通信的桥梁
前端·javascript·react.js
烟袅21 小时前
React 表单的控制欲:什么时候我们真得控制它了,什么时候该放养了?
前端·react.js
鱼鱼块1 天前
彻底搞懂 React useRef:从自动聚焦到非受控表单的完整指南
前端·react.js·面试
韭菜炒大葱1 天前
React Hooks :useRef、useState 与受控/非受控组件全解析
前端·react.js·前端框架
MoonPointer-Byte1 天前
MoonReader:基于 SpringBoot 3.4 & React 的沉浸式协作阅读平台
spring boot·后端·react.js