OfferPilot:把AI Agent面试准备变成一次真实诊断

AI Agent 方向的面试,有一个很尴尬的问题:很多人学了一堆概念,真正开口讲项目、讲架构、讲 trade-off 时,还是会暴露出“不像做过”的感觉。
不是因为不会背 ReAct、RAG、Tool Calling,也不是因为不知道 LangChain / LangGraph,而是因为面试官真正想听的是:你能不能把一个 Agent 系统从模型调用、工具执行、上下文管理、状态维护、检索、权限、Web 交互一路讲成一个完整工程。
所以我做了一个小项目:OfferPilot。
它不是一个刷题网站,也不是一个普通 ChatBot,而是一个面向 AI Agent / LLM 工程面试的智能诊断 Agent。你输入面试题和回答,或者直接录音回答,它会从结构、技术深度、表达完整度、工程可信度几个角度给出诊断,并生成一份可复制、可保存的 Markdown 报告。
项目地址:
https://github.com/ranxi2001/OfferPilot
一句话介绍
OfferPilot 想解决的问题很简单:
把“我感觉自己会了”变成“我能被系统性诊断哪里没讲清楚”。
它适合三类人:
- 正在准备 AI Agent / LLM 应用开发岗位面试的人;
- 想把 Agent 工程知识从教程迁移到真实项目的人;
- 想练习“如何讲清楚自己做过一个 Agent 系统”的开发者。
我比较在意的一点是,OfferPilot 没有把自己包装成万能面试神器。它更像一个“冷静的陪练”:你讲完,它指出你哪里太空、哪里缺例子、哪里缺工程细节、哪里需要补充权衡。
为什么要做这个项目
现在 AI Agent 学习资料很多,但从学习到面试中间有一段断层。
你可能知道:
- Agent Loop 是 Thought / Action / Observation 的迭代;
- Tool Calling 可以让模型调用外部函数;
- RAG 可以让模型查知识库;
- 多 Agent 可以拆角色协作;
- 流式输出可以改善前端体验。
但面试时问题通常不是“请背一下 Agent Loop 定义”,而是:
- 你怎么控制工具调用预算?
- 工具执行失败以后怎么重试?
- 上下文太长时怎么压缩?
- 子 Agent 之间怎么并发、怎么汇总?
- 语音输入接入后,ASR、诊断、TTS 怎么串起来?
- 如何避免子 Agent 递归调用工具导致系统卡死?
这些问题只看教程不够,必须落到代码里。
OfferPilot 就是把这些工程问题揉成一个能跑的产品原型。
核心能力
目前 OfferPilot 已经完成了几个关键模块。
1. 面试诊断
你可以输入一个面试问题和自己的回答,系统会输出:
- 回答评分;
- 核心差距;
- 缺失的技术点;
- 可以补充的工程细节;
- 更像面试表达的改写建议。
这不是简单地“润色回答”。润色只能让句子更顺,诊断才会告诉你:这段回答到底为什么不够像一个做过项目的人。
2. 录音回答诊断
面试不是写作文,真正难的是开口。
OfferPilot 支持在前端直接录音,浏览器会把音频转成 WAV,后端调用 Mimo ASR 做转写,然后把转写文本送入诊断 Agent。
完整链路是:
flowchart TD
A[录音或上传音频] --> B[浏览器转为 WAV]
B --> C[上传到 /api/transcribe]
C --> D[Mimo ASR 转写]
D --> E[面试诊断 Agent]
E --> F[Markdown 诊断报告]
F --> G[复制或保存为 .md]
这一步很关键。因为很多回答写出来还行,但说出来会出现:逻辑跳跃、术语堆砌、缺少结论、重复绕圈。录音诊断能更接近真实面试状态。
3. 实时模拟面试
项目也支持实时模拟面试:AI 逐题提问,TTS 播报问题,用户用文字或录音回答,系统即时分析缺陷,最后生成总结报告。
这让 OfferPilot 不只是“单题诊断器”,而更接近一个完整的面试训练工作台。
4. 简历分析与 JD 匹配
除了回答诊断,OfferPilot 还做了两个很实用的模块:
- 简历分析:检查 STAR 结构、量化程度、技术决策、个人贡献;
- JD 匹配:分析关键词覆盖率、缺失能力、岗位职级和包装建议。
AI Agent 面试准备不应该只练题。简历、JD、项目表达和口头回答其实是一套系统,任何一个环节断掉,面试表现都会不稳定。
5. 能力雷达与学习路径
OfferPilot 会从多个维度给出能力评分,并生成学习路径建议。
这类功能的价值不在于分数本身,而在于帮助你定位:你现在是“概念不熟”,还是“项目讲不清”,还是“工程细节太虚”。
工程架构:不是套壳,而是手写 Agent Loop
OfferPilot 的一个设计取舍是:手写 Agent Loop,不依赖 LangChain / LangGraph。
这不是说框架不好。我的判断是,如果目标是学习和面试准备,手写一遍更能理解 Agent 系统里的真实边界:预算、状态、工具、上下文、失败恢复、权限控制、流式输出。
整体结构大致如下:
flowchart LR
User[用户输入 / 录音] --> Web[Next.js Web UI]
Web --> API[HTTP API Server + SSE]
API --> Agent[Agent Loop]
Agent --> QE[Query Engine]
Agent --> Tools[工具注册表]
Agent --> Sub[子 Agent 并发池]
Agent --> Ctx[分层上下文]
Agent --> Mem[会话记忆]
Agent --> Perm[权限与审计]
QE --> Models[Claude / OpenAI兼容 / DeepSeek / Mock]
Agent --> KB[SQLite FTS5 + Embedding 知识库]
API --> Audio[ASR / TTS]
Agent --> Report[诊断报告]
从代码结构看,核心模块包括:
agent/:Agent Loop,负责工具执行和预算控制;query-engine/:Provider 路由、流式输出、重试、结果收集;tools/:工具注册表和内置面试工具;sub-agent/:专家子 Agent 运行时和并发池;realtime/:ASR / TTS 集成与实时面试辅助;knowledge/:Markdown 知识解析、FTS 检索和 embedding;context/:分层上下文与压缩;memory/:会话级记忆;permission/:工具风险控制和审计;db/:SQLite 持久化;web/:Next.js 前端界面。
这套结构本身也可以作为一个 Agent 工程面试项目来讲:不是“我调了某个框架”,而是“我理解一个 Agent 产品需要哪些层”。
语音链路:让训练更接近真实面试
我个人觉得 OfferPilot 里最有意思的是语音诊断链路。
文本输入很容易给人一种错觉:你以为自己能讲清楚,其实只是能慢慢写清楚。面试现场是另一回事,尤其是 AI Agent 这种概念密度很高的方向,开口时经常会出现三类问题:
- 先讲技术名词,忘了先给结论;
- 讲了功能,没有讲为什么这样设计;
- 讲了架构,没有讲失败场景和权衡。
OfferPilot 接入了 Mimo ASR / TTS:
- ASR:
mimo-v2.5-asr; - TTS:
mimo-v2.5-tts; - Base URL:
https://api.xiaomimimo.com/v1。
前端录音后会展示一个独立的“思维链 / 处理流程”卡片,包括转写状态、诊断状态、录音播放器、录音下载和转写文本。这样用户能看到整条链路发生了什么,而不是突然冒出一段诊断结果。
sequenceDiagram
participant U as 用户
participant W as Web UI
participant S as API Server
participant M as Mimo ASR
participant A as Diagnostician Agent
U->>W: 录音回答
W->>W: 编码为 WAV
W->>S: POST /api/transcribe
S->>M: input_audio 转写
M-->>S: 转写文本
S-->>W: 返回 transcript
W->>S: 请求诊断
S->>A: 调用面试诊断 Agent
A-->>W: 流式返回 Markdown 报告
这条链路也暴露了很多真实工程问题,比如音频格式适配、API 代理、状态展示、失败重试、用户体验反馈等。它们都比“调用一次大模型”更接近真实产品。
模型配置:兼容 OpenAI 风格接口
OfferPilot 支持 OpenAI 兼容模型配置,默认聊天模型是 gpt-5.5。
核心环境变量如下:
OPENAI_API_KEY=sk-...
OPENAI_BASE_URL=https://api.ai.tosky.top/v1
OPENAI_MODEL=gpt-5.5
MIMO_API_KEY=sk-...
MIMO_BASE_URL=https://api.xiaomimimo.com/v1
MIMO_ASR_MODEL=mimo-v2.5-asr
MIMO_TTS_MODEL=mimo-v2.5-tts
ANTHROPIC_API_KEY=sk-ant-...
DEEPSEEK_API_KEY=sk-...
这里的重点不是“只能用某个模型”,而是把 Provider 抽象出来。面试诊断这种场景,模型质量确实重要,但工程上更重要的是:你能不能稳定切换 Provider、处理失败、保持输出结构一致。
如何运行
项目使用 Node.js,建议 Node.js 20 或 22。
安装依赖:
npm install
cp .env.example .env
启动 API Server:
npm run serve
启动 Web UI:
cd web
npm install
npm run dev
打开页面:
http://localhost:3000
健康检查:
http://localhost:3001/health
也可以用 Docker Compose:
docker compose up -d
可以怎么用它准备面试
如果你只是把 OfferPilot 当成一个工具,可以这样用:
- 先选一个 Agent / LLM 工程面试题;
- 不看资料,直接录音回答一遍;
- 看诊断报告里指出的缺口;
- 补一版更完整的工程化回答;
- 再录音复测,观察表达是否更稳定。
如果你把 OfferPilot 当成一个项目案例,可以重点研究这几块:
- Agent Loop 如何组织工具调用;
- Query Engine 如何管理模型 Provider;
- 子 Agent 并发如何避免递归卡死;
- 上下文压缩与会话记忆如何配合;
- ASR / TTS 如何接入 Web 产品;
- Markdown 报告如何兼顾可读性和可导出性。
这比单纯刷题更有效,因为它会逼你把概念讲成系统。
我对这个项目的定位
OfferPilot 不是终点,更像一个切口。
它一边是面试训练工具,另一边是 Agent 工程样板。对用户来说,它帮助你发现表达漏洞;对开发者来说,它展示了一个不靠大框架也能串起来的 Agent 产品原型。
我比较喜欢这种项目:足够具体,不是空泛概念;足够完整,不只是一个 demo;又足够小,可以让人读代码、改代码、理解每一层为什么存在。
未来可以继续往几个方向扩展:
- 更细的岗位画像和题库体系;
- 更稳定的长期训练记录;
- 更完整的 PDF 报告导出;
- 更强的项目经历包装与追问模拟;
- 更接近真实面试官风格的多轮压力面。
但当前版本已经能完成一件事:让 AI Agent 面试准备从“自我感觉良好”,变成“可诊断、可复盘、可迭代”。
结语
如果你正在准备 AI Agent / LLM 工程方向的面试,可以试试 OfferPilot。
项目地址:
https://github.com/ranxi2001/OfferPilot
如果你正在学习 Agent 工程,也可以把它当成一个参考项目:看它怎么处理模型调用、工具执行、上下文、状态、子 Agent、语音链路和 Web 交互。
真正有用的学习,不是多收藏一个教程,而是把知识压到一个能跑的系统里。OfferPilot 就是这个方向上的一次实践。
OfferPilot:把AI Agent面试准备变成一次真实诊断
Kubernetes和云原生:从Docker到K8s的知识三明治