后端转 Agent 岗最常见的错位是这一种:简历里 Agent 内容只有两三行,面试里被问的全是后端题。
不是面试官不懂 Agent,是他手上只有你的简历。问题分布基本等于简历的项目权重分布。
这句话反过来用就是方法:你想被问什么,就在那上面堆出足够的问题密度。下面按技术密度讲四件事:项目要补哪些可追问的结构,记忆为什么要外置,工具链路怎么拆,MCP 的边界怎么划。后面另外补三处简历硬伤和一段 AI 协作方法。
一、先承认这个映射关系
一个典型的简历长这样:四个项目里三个是后端项目,唯一的 Agent 项目正文两三行。我见过好几份长这样的简历,结果都差不多,几乎没问到 Agent。
原因很直接。两三行最多够问一轮,剩下的时间面试官要么放你走,要么回头问后端,因为那里的素材足够撑满整场。
反过来看面试官视角的提问成本:
| 简历上该方向的篇幅 | 面试官可提的问题量 | 实际提问倾向 |
|---|---|---|
| 两三行(只有技术名词) | 一两轮就到底 | 转向别的项目 |
| 一段(有链路和取舍) | 能撑住追问链 | 深挖一轮再转 |
| 一节(有边界、失败案例、数据口径) | 能扛住深挖并给数据口径 | 主线追问,其余项目变陪衬 |
这张表不是精确统计,是个判断模型。它的用处是让你在投简历之前先自查一件事:你想被问的那个方向,在简历上的篇幅占比是多少。
二、Agent 项目要补的四个抓手
功能数量不影响面试官判断,能不能插进去提问才影响。四个抓手,按这个顺序补最省力。
意图识别。用户说一句话,你怎么知道他要干什么。直接把这句话丢给模型不叫意图识别,那叫转发。真做过的版本能回答三件事:怎么分类,分类不准怎么澄清,完全认不出来怎么兜底。
Agent 生命周期。一次会话从进入到结束,中间有哪些状态,谁负责推进,超时怎么办,用户中途改主意怎么办。状态讲得清,面试官会认为你写过生产代码。
记忆分层。这一处最容易被问穿,下一节单独说。
工具调用链路。这一处有固定模板,再下一节单独说。
三、记忆分层:为什么长期信息必须外置
最容易被问穿的错误答法是「我们有记忆机制,能把用户历史信息记住」。往下问一句存在哪,就卡住了。
从工程角度看,把长期信息塞进 context 有两个成本绕不开。
第一个是 token 成本。上下文随轮次线性增长,历史越长每次请求越贵,而且这部分钱花在重复传输上,不产生新信息。
第二个是注意力稀释。上下文里塞进大量与当前问题无关的历史,模型对关键指令的注意力会被摊薄,表现不是报错,是回答变得含糊。
还有一致性这块,吃过亏的才知道:偏好类信息散落在多轮对话里,没有单一事实来源,同一个用户下次换个会话再问,行为就不一致。
所以正确口径只有一条边界:短期记忆是当前这次对话的上下文,存在会话里,跟着这次请求走;偏长期的信息,比如用户偏好、历史行为,不该塞进 context,而是去调外部服务,比如公司内部的用户画像服务。
伪代码大致是这样:
# 伪代码,示意分层职责,不是可运行实现
def build_context(session, user_id, query):
# 短期:只取最近若干轮,超出就滚动丢弃
recent = session.tail_turns(n=RECENT_LIMIT)
# 长期:不拼进 prompt,按需查询,只取当前意图相关的字段
profile = profile_service.get(user_id, fields=relevant_fields(query))
return compose(
system=SYSTEM_PROMPT_SLIM,
long_term_hint=profile.as_hint(), # 只放结论,不放原始流水
recent_turns=recent,
query=query,
)
这段伪代码里真正值得讲给面试官听的是两处:tail_turns(n=RECENT_LIMIT) 说明短期有上限,profile_service.get(...) 说明长期信息走外部服务而不是拼字符串。剩下的是实现细节。
四、工具调用链路:四段拆法
任何自研工具都能套同一个模板:输入从哪来,中间怎么处理,输出给谁,异常怎么兜。
以一个批量入库工具为例,四段拆开是这样:
| 段位 | 本例的说法 | 面试官会追问什么 |
|---|---|---|
| 输入 | 前端传一个批量文件上来 | 文件格式不合法怎么挡,编码不统一怎么办 |
| 处理 | 后端按行解析、分批入库 | 单批多大,一行报错会不会拖垮整批 |
| 输出 | 返回成功条数和失败行 | 失败行怎么标,调用方怎么拿到 |
| 异常 | 失败行带上行号和原因,支持单独重试 | 重试怎么避免重复入库 |
工具的 schema 也要能说清,因为模型是靠这个描述决定调不调:
{
"name": "import_batch_rows",
"description": "按批导入行数据,返回成功条数与失败行",
"parameters": {
"type": "object",
"properties": {
"file_url": { "type": "string", "description": "待导入文件的地址" },
"batch_size": { "type": "integer", "description": "单批行数,不传则用默认值" },
"retry_failed_only": { "type": "boolean", "description": "是否只重试上次失败的行" }
},
"required": ["file_url"]
}
}
这里的做法是只把兜底参数设为必填:批大小和重试开关都能被默认值兜住,文件地址拿不到就没什么可执行的。这种设计细节比功能列表有用得多,因为它说明你考虑过参数缺失的分支。
很多人讲工具习惯从技术栈讲起,用了什么框架,接了什么模型。技术栈是结果不是链路。面试官想听的是数据怎么流动,以及出问题的时候你在哪一层兜住。
五、MCP:模型决策,运行时执行
这一处最容易自己给自己挖坑。
如果 MCP 工具是模型自己决定调用、由运行时去执行,正确的说法只有八个字:模型决策,运行时执行。不要说成「我实现了协议调用」。
两者的追问深度差一个数量级:
| 你说的话 | 面试官接着问 | 你要准备到哪一层 |
|---|---|---|
| 我实现了 MCP 协议 | 握手流程、server 怎么注册、工具 schema 怎么校验、错误怎么回传 | 协议规范级 |
| 模型决策,运行时执行 | 模型怎么选工具、参数错了怎么重试、多工具怎么编排 | 编排逻辑级 |
你把边界说在哪一层,就要准备好那一层的追问。说成自己实现的协议,等于邀请对方考协议细节,问到规范层就当场崩。
面试里最贵的不是不够高级,是高级了但接不住追问。一句撑不住的高话,比一句实话伤害大得多。
同样的判断标准可以套到所有表述上:这句话出去,对方追问三层,你能不能接住。接不住就降一层说。降一层不掉分,接不住才掉分。
六、简历层面还有三处硬伤
第一处是两个项目都写「至今」。面试官会算你的并行度和在职时长,两个至今放在一起逻辑上不成立,等于主动邀请他怀疑真实性。改法是说清哪个是主线、哪个是并行的副线,时间区间各自落到月份。空档可以解释,逻辑矛盾解释不了。
第二处是项目顺序。把想被问的项目放在最前面,因为面试官的注意力也是有限资源,第一屏决定他先问什么。这一条是我自己加的判断,不在这次复盘里。
第三处是项目取舍。四个项目要不要删,判断是不用全删,重点扩核心;真要删,删相关性最低的那个。判断哪个该删需要两个条件同时成立:与目标岗位相关度最低,而且你自己讲不出三个细节。保留一个讲不动的后端项目,比删掉它更伤,因为讲不动的地方就是减分的地方。
七、顺带说 AI 协作开发:分工与校验
这套跟面试技巧无关,但它决定你手上有没有真项目可讲。
定位是:用 AI 的时候,把 AI 当员工,你自己是老板。
按能力边界分活,别让一个模型干所有事:
| 环节 | 用什么样的模型 | 原因 |
|---|---|---|
| 需求拆解、架构设计 | 长上下文模型 | 要同时容纳多份文档和约束 |
| 日常代码开发 | 快模型 | 迭代频次高,等不起 |
| 高阶架构决策 | 能力最强的模型 | 出错成本最高,值得花 |
| 测试、审查 | 换厂商 | 避免同一能力边界重复犯同一个错 |
最后一行值得展开。开发和测试用同一个厂商的模型,两边会对同一类错误同时失明,测试就变成了自我确认。跨厂商选型的价值不在谁更强,在于错误模式不重合。
三条文档原则:先用技术文档约束 AI 的输出,而不是让它先写代码;文档和代码一起进代码库,文档不是写完就丢;测试驱动,先让 AI 生成测试用例再让它写实现。
重复动作要 Skill 化,比如自动生成提交信息、线上问题排查、代码检索。Skill 会不会被正确调用,靠三件事校验:约定场景的触发关键词、看模型的执行过程、任务结束后让模型自己复核这次工具调用是否合理。
还有三件踩过坑才知道的:AI 跑长任务卡住或超时,主动打断问进度、补信息,别干等;上下文要主动压缩,把历史对话总结成文档,新开窗口再读回来;多窗口要分工,架构师一个窗口、并行开发几个窗口、代码审查一个窗口,按垂直解耦的需求拆才能真并行。
结语
回到开头那个映射关系。面试官的问题分布等于简历的项目权重分布,这不是玄学,是信息不对称下的必然结果。
所以转岗的动作不是「在简历里加一行 Agent」,而是把那个项目扩到能撑住三轮追问:第一轮问你怎么做的,第二轮问为什么这么做,第三轮问出问题怎么办。
三轮撑得住,方向对了;撑不住,功能再多也还是那两三行。