本文介绍「面试吧」(Interview Agent)的 Multi-Agent 架构设计思路。面试吧是一个已上线的企业级 AI 模拟面试平台,基于字节跳动开源的 Eino 框架构建,完整技术栈:Go + Eino + Milvus + Hertz + Thrift。在线体验:interviewbar.xyz/
为什么选 Eino,而不是 LangChain?
做 AI Agent 项目,第一个问题是框架选型。
市面上最主流的是 LangChain,但它是 Python 生态的。对于 Go 后端工程师来说,用 Python 写 Agent 意味着:
- 引入一套完全不同的工程体系
- 高并发场景下性能天花板明显
- 和现有 Go 服务的集成成本高
字节跳动开源的 Eino 是专门为 Go 设计的 Agent 框架,核心是 Graph 编排模型:把 Agent 的执行流程抽象成有向图,节点是 Component(LLM、Tool、Retriever 等),边是数据流。
这个设计的好处是:复杂的多智能体协作流程,可以用图来清晰表达,而不是一堆嵌套的函数调用。
面试吧的 Multi-Agent 设计
面试吧的核心场景是:用户上传简历,AI 面试官根据简历和岗位要求进行多轮专业提问,最后生成评估报告。
这个场景天然适合 Multi-Agent:不同技术领域的面试,需要不同的「专家」来主导。
我们设计了两类 Agent:
专项面试官(Specialized Agent)
每个技术领域一个独立 Agent,目前覆盖:Go、Java、MySQL、Redis、算法等 5+ 个方向。
agent/interview/specialized/
├── go_interviewer.go
├── java_interviewer.go
├── mysql_interviewer.go
├── redis_interviewer.go
└── algorithm_interviewer.go
每个专项 Agent 有自己的 System Prompt,定义了该领域的考察重点、提问风格、难度梯度。
专项 Agent 的提问不是随机生成的,而是通过 RAG 从 Milvus 知识库里检索对应领域的高质量题目,再结合用户简历内容进行个性化提问。
综合面试官(General Agent)
基于 ReAct 范式实现,负责:
- 综合评估候选人的整体能力
- 跨领域的系统设计题
- 根据简历内容追问项目经验
ReAct 的核心是「思考 → 行动 → 观察」的循环,让 Agent 能够根据用户的回答动态调整下一个问题,而不是按固定脚本走。
RAG 的接入方式:Tool Use
面试吧的 RAG 不是独立模块,而是以 Tool 的形式接入 Agent。
Agent 在需要检索知识时,主动调用检索 Tool,Tool 返回结果后,Agent 基于检索内容生成回答。
// tool/get_resume_info_tool.go
type RetrieveInput struct {
Query string `json:"query"`
Domain string `json:"domain"` // go / java / mysql / redis
Category string `json:"category"` // algorithm / system / project
TopK int `json:"top_k"`
}
检索层用的是 Milvus 的混合检索:向量相似度 + 标量字段过滤。
纯向量检索的问题是:语义相近但领域不同的内容会混在一起。加上 domain 和 category 的标量过滤后,Go 并发题只会从 Go 知识库里检索,不会和 MySQL 锁的内容混淆。
异步架构:为什么要用消息队列
AI 推理是耗时操作,一次面试评估报告的生成可能需要 10-30 秒。
如果同步等待,用户体验很差,服务的并发能力也会被拖垮。
我们的方案是:手写基于 Redis 的消息队列,将评估报告生成任务异步化。
用户提交面试结束
→ 写入 Redis Queue
→ 立即返回「生成中」
→ Consumer 异步消费,调用 LLM 生成报告
→ 报告生成后推送给前端(SSE)
SSE(Server-Sent Events)负责流式推送,让报告内容像打字机一样逐字出现,而不是等全部生成完再一次性返回。
工程化:IDL 驱动开发
面试吧的前后端协作用的是 Thrift IDL 驱动开发。
先定义 .thrift 文件,用 hz 工具自动生成路由、Handler 骨架、请求/响应结构体,前后端都基于同一份 IDL 对齐接口契约。
好处是:接口变更时,改 IDL 重新生成,不会出现前后端字段对不上的问题。
// idl/interview.thrift
service InterviewService {
StartInterviewResp StartInterview(1: StartInterviewReq req)
SubmitAnswerResp SubmitAnswer(1: SubmitAnswerReq req)
GetReportResp GetReport(1: GetReportReq req)
}
整体架构总结
用户请求
→ Hertz 网关(JWT 鉴权 / CORS / Recovery)
→ Handler(Thrift IDL 生成)
→ Service 层
├── 简历解析 Agent(Eino + PDF 解析)
├── 专项面试 Agent × N(Eino Graph + RAG Tool)
└── 综合面试 Agent(Eino ReAct)
→ Milvus(向量检索)
→ Redis Queue(异步任务)
→ SSE 流式响应
这套架构的核心设计原则:
- Agent 无状态:每个 Agent 只负责自己领域,通过 Tool 获取外部知识
- 降级优先:Milvus 故障时自动回退纯 LLM,不中断主流程
- 异步解耦:耗时任务全部走消息队列,保证接口响应时间
最后
面试吧目前已上线,可以直接体验:interviewbar.xyz/
这个项目也是我们出版的 Go + AI 实战课程的核心项目,完整源码 + 视频教程 + 文档教程,已完成。
并且我们已签约人民邮电出版社,书稿已完成,坐等出版社印刷出版。
感兴趣的同学可以加我微信了解:wangzhongyang1993
标签:#Go #Eino #RAG #MultiAgent #Milvus #AI应用开发 #字节跳动