我是波哥,专注于大模型/推荐系统,持续分享AI算法岗面试岗知识干货、实战项目、面试经验。
【大模型LLM训练营】、【大模型算法冲刺营】持续进行中,详细内容:大模型1v1第5期已经开始直播了!
详情了解可+v:Burger_AI
最近在训练营陪跑同学面试的过程中,遇到一场比较有代表性的 AI Agent 岗位面试,整理出来分享给大家。面试官两位接力问,总时长 30+ 分钟,覆盖 Python 基础、算法、Agent 工程等多个维度。题目本身不算偏,但对 Agent 工程化落地的考察比较深,值得所有准备大模型应用开发岗的同学重点复盘。
本文面向所有对 AI Agent 岗位感兴趣的同学,包括转行同学、应届生、以及刚接触大模型应用开发的工程师。每个知识点都会从「是什么 → 为什么 → 怎么答」三个层次展开,确保零基础也能看懂。
一、先搞清楚:AI Agent 岗位到底在做什么?
在进入面试题之前,先给新同学补一个背景。
什么是 AI Agent?
简单来说,Agent 就是能自主使用工具、完成复杂任务的 AI 系统。和普通聊天机器人的区别在于:
聊天机器人:你问一句,它答一句,只会说话 Agent:你给它一个目标(比如「帮我订明天去北京的机票」),它会自己规划步骤、调用工具、处理错误、最终完成任务
Agent 工程师日常在做什么?
设计 Agent 的推理流程 —— 什么时候该调工具、什么时候该问用户、什么时候该总结 训练或调优模型 —— 让模型能稳定地输出工具调用指令 搭建工具生态 —— 把公司的各种 API、数据库、外部服务接入给模型使用 优化上下文 —— 在有限的 token 预算内让模型看到最关键的信息 工程化落地 —— 处理并发、错误重试、可观测性、成本控制
理解了这些,下面的面试题你就知道为什么这么问了。
二、面试概况
目标岗位: AI Agent / 大模型应用开发工程师 面试公司: 某头部新能源车企(智能座舱/智能助理方向) 面试时长: 30+ 分钟 面试形式: 两位面试官接力提问
车企做 Agent 主要场景是车载智能助理 —— 用户说「我有点冷」,Agent 要能理解意图、调用空调 API、反馈结果;用户说「找家附近的川菜馆导航过去」,Agent 要能串联搜索、地图、导航多个工具。所以车企对 Function Calling 的稳定性和小模型的落地能力特别看重(车端算力有限,不能都靠云端大模型)。
三、完整题目梳理
🧩 第一位面试官:基础 + 项目
谈谈深拷贝和浅拷贝的区别 Python 装饰器的实现原理 列举几个常见的 Python 魔术方法 算法题:给定一个无序整数列表和目标值,找出和为目标值的两个数 Agent 上下文工程有哪些核心手段,项目里用过哪些 Function Calling 的底层原理是什么?你项目里是怎么落地的? 有没有接触过 MCP?怎么用的? 对 Anthropic 的 Skills 机制有了解吗?
🧩 第二位面试官:框架专项
聚焦主流 Agent 框架的状态管理、底层执行模型、生态对比等细节,对框架的使用深度和原理理解都有较高要求(此处略去,后续单独成篇)。
四、题目分类与难度分布
典型失分点: MCP 的实际使用细节、Skills 的概念认知。这类题目光看过资料记不住,必须动手跑一遍才能答得出来。
五、重点题目精讲
🔥 重点 1:Function Calling 原理与项目落地
📖 先补背景:什么是 Function Calling?
想象一下,你问模型「今天上海天气怎么样?」,模型自己是没法知道实时天气的(训练数据有截止时间)。但如果你告诉模型「你可以调用 get_weather(city) 这个工具」,模型就能生成一个调用指令,你的程序拿到指令后真的去调 API,把结果再喂给模型,模型就能回答了。
这个「让模型生成工具调用指令」的能力,就是 Function Calling。
它的典型工作流程:
ounter(lineounter(line用户问题 → 模型判断是否要调工具 → 输出 JSON 格式的调用指令→ 程序执行工具 → 结果回传模型 → 模型生成最终回答
为什么这道题这么重要?
因为 Function Calling 是 Agent 的基础能力。Agent 之所以能做复杂任务,就是因为它能调用工具;而调用工具的前提,就是模型能稳定地输出格式正确的调用指令。如果模型输出的 JSON 格式错了、参数填错了,整个 Agent 就崩了。
💡 标准答法:模型层 + 工程层双视角
模型层(让模型「会」调用):
通过 SFT(Supervised Fine-Tuning,监督微调) 让模型学会在合适时机输出结构化 JSON
💬 什么是 SFT? 简单说就是给模型喂「问题-标准答案」对,让它学会什么场景该输出什么格式。比如喂一万条「天气问题 → get_weather 调用指令」,模型就学会了遇到天气问题要调这个工具。
主流做法会引入特殊 token(如
<tool_call>/<tool_response>)标记工具调用的边界💬 为什么需要特殊 token? 让模型清楚知道「我现在是在说话,还是在写工具调用指令」,避免混在一起。
工程层(保证模型输出「对」):
Constrained Decoding(约束解码) 把 JSON Schema 编译成状态机,逐 token 约束生成
💬 人话解释: 模型生成每个字的时候,程序都在旁边盯着 —— 这一步只能输出
{、那一步只能输出字段名、再下一步只能输出字符串。这样从数学上保证输出的 JSON 100% 合法,不会出现括号没闭合、字段名拼错这种低级错误。Tool Schema 注入方式 有两种:直接写在 system prompt 里 vs 用 OpenAI 规范的
tools字段。后者通常更稳定,因为模型在训练时就是按这个格式学的。多轮工具调用的上下文管理 —— 每次调工具要正确配对
tool_call_id、回填role=tool的消息,否则模型会搞不清楚哪个结果对应哪次调用。参数校验失败的重试反馈机制 —— 模型有时会填错参数(比如日期格式错),这时要把错误信息反馈给模型让它重试,而不是直接报错。
🌟 项目化落地经验(同学的实战分享)
同学分享的实践路径非常典型,值得新同学参考:
起点: 一开始用 Prompt 驱动(就是把工具描述写在 system prompt 里,靠大模型自己理解),发现小模型(参数量小的模型)工具选择不稳定 —— 明明该调 A 工具却调了 B。
升级方案: 用 Qwen3 0.6B + LoRA 做 SFT 微调。
💬 什么是 LoRA? 一种「轻量级微调」技术。微调整个模型参数量太大、太贵,LoRA 只训练一小部分新加的参数,效果接近全量微调,但成本低得多。是目前小团队做模型微调的主流方案。
核心工作三件事:
数据构造 —— 搭了三千多条训练数据的 Pipeline,覆盖五类业务场景,处理了正负样本不平衡问题
💬 什么是正负样本? 正样本 = 应该调工具的情况;负样本 = 不该调工具的情况(比如用户只是闲聊)。如果负样本太少,模型会变得「见什么都想调工具」;反之则「该调不调」。
Loss 设计 —— 采用 argument-level 的 CE Loss,只对参数 token 算损失
💬 人话解释: 一段工具调用输出里,有很多「固定格式」的字符(比如
{"name":"...", "arguments":{),这些模型很容易学会;真正难的是参数值填什么。只对参数部分算 loss,能让模型把学习重点放在最关键的地方,避免被格式文本「稀释」注意力。效果 —— 工具调用准确率从 60% 多提升到近 90%
加分细节(面试时主动说): 「bad case 主要集中在多参数嵌套场景(比如参数本身是一个对象),后续计划通过 CoT(Chain-of-Thought 思维链)数据增强进一步优化」—— 这句话能显示出持续迭代的工程思维,不是做完项目就不管了。
一句话总结: Function Calling 是「模型能输出(SFT)+ 工程能约束(Constrained Decoding)+ 数据能迭代(Bad case 分析)」三者结合的产物,任何一环缺失都会影响最终准确率。
🔥 重点 2:Agent 上下文工程的系统化框架
📖 先补背景:为什么要做「上下文工程」?
大模型有个硬限制:上下文窗口(Context Window)。就像人的工作记忆一样,一次只能记住有限的信息 —— 超过了,要么塞不下直接报错,要么模型「注意力涣散」,重要信息被淹没。
Agent 场景下这个问题特别严重,因为一个 Agent 往往要:
记住多轮对话历史 看到几十个可用工具的说明 处理工具返回的大段结果 跟进用户的长期偏好
全塞进 context 里?一方面 token 费用爆炸,另一方面模型会「看晕」,效果反而下降。
所以「上下文工程」的本质就是:在有限的 context 预算里,让模型看到最关键的信息。
💡 标准答法:Write / Select / Compress / Isolate 四字诀
同学答了「动态检索 + 摘要剪枝 + 多 agent 隔离」三点,方向对了,但缺乏系统性。业界(LangChain 官方博客提出)把 Agent 上下文工程归纳为四类手段,记住这四个词就能答得很漂亮:
Write(写入) —— 把信息写到 context 外部,需要的时候再读
💬 典型例子: scratchpad(草稿本)、memory store(长期记忆库)。比如用户说「我叫小明,是程序员」,把这个信息存到数据库,下次需要时再取,不用每次都塞进 prompt。
Select(筛选) —— 按需检索最相关的上下文
💬 典型例子: RAG(检索增强生成)、工具按需加载。比如工具库有 100 个,但根据当前问题,只把最可能用到的 5 个工具 schema 放进 prompt。
Compress(压缩) —— 对已有内容做摘要、剪枝、截断
💬 典型例子: 多轮对话超过 20 轮后,把前 15 轮用小模型摘要成一段话;工具返回的 10000 字结果,只提取关键字段再给模型。
Isolate(隔离) —— 不让所有子任务共用同一个 context
💬 典型例子: multi-agent 架构,每个 sub-agent 有自己独立的 context;或者在 sandbox 里跑子任务,避免中间结果污染主 context。
Write / Select / Compress / Isolate —— 这四个词答出来,面试官一听就知道你是系统学过的,而不是东拼西凑。
🌟 项目结合答法示范
空答理论框架不够,要结合项目说。推荐这种三段式结构:
「我项目里主要用了 Select 和 Compress 两类。
Select 上做了工具的按需动态加载 —— 系统有 30 多个工具,如果全塞进 prompt 会消耗近 2000 token,而且模型容易选错。我先用一个小模型做意图分类,根据意图只加载相关的 5-8 个工具,准确率提升了 15%。
Compress 上对多轮对话做了分段摘要,超过 8000 token 触发压缩,保留最近 3 轮原文 + 更早内容的摘要。
后续准备引入 Isolate 的思路,用 sub-agent 隔离不同子任务的上下文,避免工具调用的长结果污染主对话。」
这样回答: 既有理论框架,又有项目支撑,还有后续规划,是面试中最理想的三段式结构。
🔥 重点 3:MCP 协议的认知
📖 先补背景:没有 MCP 之前,工具接入有多痛苦?
假设你要给 Agent 接入 10 个服务:Notion、Slack、GitHub、Google Drive、Jira……
传统做法: 每个服务都要自己写适配代码 —— 调用 Notion 的 API 格式、调用 Slack 的 API 格式、调用 GitHub 的 API 格式,每家都不一样。更糟的是,如果你用的是 Cursor 编辑器,它的工具接入方式又和你的 Agent 不一样,重复造轮子。
这就是 MCP 要解决的问题:定义一套标准,让所有工具提供方按统一接口暴露能力,所有 AI 应用按统一方式接入。
类比一下:MCP 之于 AI 工具生态,就像 USB-C 之于充电接口 —— 以前每个品牌自己的充电口,现在统一了。
💡 标准答法:三大核心原语 + Client-Server 架构
MCP(Model Context Protocol) 是 Anthropic 2024 年底推出的模型上下文协议,本质是定义了 AI 应用和外部数据/工具交互的标准化接口。
三大核心原语(Primitives):
Resources(资源) —— 可被模型读取的数据
例子:文件内容、数据库记录、API 返回的数据。Resources 是「只读」的信息源。
Tools(工具) —— 可被模型调用的函数
例子:执行代码、发邮件、创建 Notion 页面。Tools 会产生副作用,改变外部状态。
Prompts(提示词模板) —— 预定义的可复用 prompt 模板
例子:「代码 review 模板」「周报生成模板」。Prompts 让常用任务标准化。
架构模式(Client-Server):
Host —— 终端应用,比如 Claude Desktop、Cursor、你自己的 Agent 系统 MCP Server —— 每个 Server 是一个独立进程,暴露一组 Resources / Tools / Prompts 交互方式 —— Host 启动后连接多个 Server,动态发现有哪些能力可用
举个具体例子:你在 Claude Desktop 里配置了 notion-mcp-server 和 github-mcp-server,Claude 启动时就自动知道「我能读 Notion 页面、能创建 GitHub issue」,这些能力不需要 Anthropic 自己实现,是由各 Server 独立提供的。
🎯 高频追问:MCP 和 Function Calling 是什么关系?
这是面试官特别爱追的问题,答错会显得没理解本质。
Function Calling 是模型能力 —— 解决「模型怎么生成工具调用指令」 MCP 是协议标准 —— 解决「工具怎么被统一暴露和发现」
二者是互补关系,不是替代关系。
完整链路是:MCP Server 声明有哪些工具 → Host 把这些工具以 Function Calling 格式喂给模型 → 模型通过 Function Calling 生成调用指令 → Host 把指令转发给对应的 MCP Server 执行。
一句话总结: MCP 让 Agent 的工具生态从「每家自己实现」变成「标准协议插拔」,是 AI 领域的 USB-C。
🔥 重点 4:对 Anthropic Skills 的认知
📖 先补背景:Skills 解决的是什么问题?
假设你做了一个 Agent,发现一个痛点:模型不知道怎么处理 PDF。你写了一大段 prompt 教它「遇到 PDF 先用 pypdf 读文本、如果是扫描件用 OCR、表格用 camelot……」
但问题来了:
这段 prompt 每次都要塞进 context,浪费 token 如果有 20 种不同文件类型要处理,prompt 会爆炸 新人同事也要写类似的流程文档,散落各处难复用
Skills 就是把这些「怎么做某类任务的最佳实践」打包成可复用、按需加载的能力包。
💡 标准答法
Skills 是 Anthropic 2025 年推出的机制,本质是**「按需加载的能力包」**。
核心特点:
每个 Skill 是一个文件夹,包含: SKILL.md—— 说明文档(这个 Skill 干什么、什么时候用、怎么用)配套资源 —— 脚本、模板、示例文件 Skill 的 description字段写明了触发场景,模型会根据任务按需加载比如有 pdfskill、docxskill、excelskill,模型遇到对应任务时自动打开读取 SKILL.md,获得详细操作指引
工作流程示例:
ounter(lineounter(lineounter(lineounter(line用户:「把这个 PDF 转成 Word」→ 模型看到任务涉及 PDF,主动加载 pdf skill 的 SKILL.md→ 读到「PDF 转 Word 应该用 xxx 库,步骤是 1/2/3」→ 按指引执行
🎯 高频追问:Skills 和 MCP 有什么区别?
这也是必考追问题。两者都和「扩展 AI 能力」有关,但定位完全不同:
| 本质 | ||
| 加载方式 | ||
| 解决问题 | ||
| 适用场景 | ||
| 典型形态 | ||
| 类比 |
一句话总结: Skills 解决「模型怎么用好工具」,MCP 解决「工具怎么被标准化暴露」,二者搭配才是完整的 Agent 能力栈。
🔥 重点 5:Python 基础三连问
这三道题属于基本盘,答不好会让面试官直接对基础水平打折扣。新同学要特别注意,这类题目不是要你背答案,而是要讲清楚原理。
📌 深拷贝 vs 浅拷贝
核心区别:
浅拷贝 只复制外层容器,内部嵌套对象共享引用
常用方法:
copy.copy()、切片lst[:]、dict.copy()深拷贝 递归复制每一层,完全独立
常用方法:
copy.deepcopy()
举个例子就懂了:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineimport copya = [[1, 2], [3, 4]]b = copy.copy(a) # 浅拷贝c = copy.deepcopy(a) # 深拷贝a[0].append(999)print(b) # [[1, 2, 999], [3, 4]] —— 被影响了!print(c) # [[1, 2], [3, 4]] —— 没被影响
加分点(主动说出来):
可以控制拷贝行为 —— 自定义类可以实现 __copy__和__deepcopy__魔术方法循环引用处理 —— deepcopy有内部 memo 字典记录已拷贝对象,防止无限递归性能考虑 —— deepcopy比浅拷贝慢很多,不要滥用
📌 装饰器原理
本质: 装饰器是一个「接收函数、返回函数」的高阶函数,依赖 Python 两个核心特性:
函数是一等对象 —— 函数可以像变量一样传递、赋值、作为参数 闭包 —— 内部函数可以访问外部函数的变量
语法糖解释:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line@decoratordef func():pass# 等价于def func():passfunc = decorator(func)
典型实现模板:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linefrom functools import wrapsdef my_decorator(func):@wraps(func) # 保留原函数的 __name__、__doc__ 等元信息def wrapper(*args, **kwargs):# 前置逻辑(如打日志、计时)result = func(*args, **kwargs)# 后置逻辑return resultreturn wrapper
加分点:
functools.wraps为什么重要 —— 不用的话,被装饰函数的__name__会变成wrapper,影响调试和框架识别带参数的装饰器需要三层嵌套(最外层接收参数、中间层接收函数、内层是 wrapper) 类装饰器 —— 实现 __call__方法也能当装饰器用装饰器的常见用途 —— 日志、计时、缓存、权限校验、重试
📌 常见魔术方法分类记忆
零散列举不如按类别组织,更能体现系统性思维:
初始化类: __init__(实例初始化)/__new__(实例创建)/__del__(析构)字符串表示: __str__(给人看)/__repr__(给开发者看)运算符重载: __add__/__eq__/__lt__/__hash__容器行为: __len__/__getitem__/__setitem__/__iter__/__contains__上下文管理: __enter__/__exit__(用于with语句)可调用对象: __call__(让实例能像函数一样被调用)属性访问: __getattr__/__setattr__/__getattribute__
面试答题建议: 先说分类框架,再每类举 1-2 个例子,最后结合一个实际场景(比如 context manager 实现文件自动关闭)。
🔥 重点 6:算法题 —— 两数之和
经典哈希表题,也是很多同学的算法入门第一题。
题目: 给定一个无序整数列表和一个目标值,找出列表中和为目标值的两个数的下标。
核心思路: 边遍历边查表。对每个数 x,先查哈希表里有没有它的「补数」target - x,有就直接返回下标,没有就把 x 存进表。
标准一遍解法:
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(linedef two_sum(nums, target):seen = {} # key: 数值, value: 下标for i, x in enumerate(nums):complement = target - xif complement in seen:return [seen[complement], i]seen[x] = ireturn []
复杂度分析(面试时主动说):
时间复杂度 O(n):只遍历一次 空间复杂度 O(n):哈希表最多存 n 个元素
可能的追问方向(提前准备):
如果数组已排序? → 用双指针法(一头一尾),空间降到 O(1) 如果要找所有不重复的两数组合? → 需要去重逻辑(结果排序 + set 去重) 扩展到三数之和 / 四数之和? → 排序 + 双指针 + 剪枝,是 LeetCode 高频题
六、复盘总结与备考建议
✅ 答得好的部分
Python 基础扎实 —— 深浅拷贝、装饰器、魔术方法这类经典题能快速准确回答,这是所有开发岗的基本盘 算法题应答稳 —— 两数之和的哈希表一遍解法属于必会,面试时能脱口而出 项目数据有说服力 —— Function Calling 从 60% 到 90% 这种带数据的项目经验,是简历上最亮的点,强烈推荐所有同学在项目描述里都带上量化指标
⚠️ 需要重点补强的部分
第一优先级(下场面试前必掌握):
MCP 三大原语 + Client-Server 架构 —— 动手跑通一个 MCP Server demo,哪怕只实现一个简单的天气工具 Anthropic Skills 的加载机制 —— 读官方文档,理解它与 MCP 的分工 Agent 上下文工程的 Write/Select/Compress/Isolate 四类框架 —— 项目中落地验证至少两种 Function Calling 的 bad case 分析与优化路径 —— 自己项目里哪些场景准确率低、为什么、怎么改
第二优先级(加分项):
主流开源 Function Calling 数据集的构造方法(ToolBench、Gorilla 等) Constrained Decoding 的主流实现对比(outlines、xgrammar、lm-format-enforcer) 小模型工具调用的优化技巧(Chain-of-Thought 增强、多轮 reflection)
七、给新同学的学习路径建议
如果你是刚入门 AI Agent 方向的同学,看到这篇复盘可能会有点懵 —— 概念太多了。给大家一个循序渐进的学习路径:
🎯 阶段一(2-3 周):跑通第一个 Agent
用 Python + OpenAI API,从零实现一个能调用天气工具的 Agent(不用任何框架) 目标:彻底搞懂 Function Calling 的完整流程,这是所有 Agent 的基石 输出:写一篇博客讲清楚「从用户问题到模型调工具再到最终回答」每一步发生了什么
🎯 阶段二(2-3 周):理解框架的价值
学一个主流 Agent 框架(LangChain / LangGraph / LlamaIndex 任选其一) 把阶段一的天气 Agent 用框架重写一遍,对比代码量和复杂度 目标:知道框架帮你解决了什么痛点,而不是背 API
🎯 阶段三(3-4 周):深入工程化
学习上下文工程(Write/Select/Compress/Isolate)、MCP 协议、Skills 机制 做一个有一定业务场景的 Agent 项目(比如个人财务助理、简历优化助手) 目标:把简历项目做到能讲 10 分钟不卡壳,每个技术选型都能说出为什么
🎯 阶段四(持续):跟进前沿
关注 Anthropic、OpenAI 的官方博客和技术报告 关注 LangChain 官方博客的 Concept 文章(不只是 Tutorial) 在 X(Twitter)上关注几位 Agent 领域的核心开发者
八、训练营同学的共性问题
从这场面试暴露的问题来看,绝大多数同学的学习路径都是「跟着教程跑 demo → 项目里用起来 → 面试时答不上原理」。要突破这个瓶颈,我建议:
读官方文档的 Concept 章节 —— MCP、Skills 这些新概念,官方文档讲得最清楚,但大多数同学只看 Tutorial 不看 Concept 动手跑 demo 比看资料有效 10 倍 —— MCP Server 半小时就能搭起来,跑一遍胜过看十篇博客 横向对比学习 —— 不要只盯着一个技术栈,MCP / Skills / Function Calling / Agent 框架都过一遍,建立生态地图 面试前系统梳理 —— 像这篇复盘一样,把自己用过的每个技术点都问一遍「为什么这么设计」,答不上就是漏洞 准备「三段式」项目讲解 —— 背景痛点 + 技术方案 + 效果数据,每个项目点都能按这个结构展开
写在最后: 面试其实是考你懂多少。工具的调用方式一周能学会,但底层设计思想的理解往往要花几个月。训练营的意义就在于帮大家少走弯路,把真正值得深挖的知识点系统化地学透。
如果你是新入门的同学,不要被文章里一堆概念吓到 —— 所有资深工程师都是从「什么是 Function Calling」开始问的。按照第七章的学习路径走,2-3 个月就能建立起扎实的知识体系。
希望这份复盘对正在准备 Agent 岗的同学有帮助,有问题欢迎在评论区交流👇
夜雨聆风