AI 八股
Agent 面试篇
1️⃣ 什么是 Agent?与传统大模型的区别?
传统大模型 :
本质上是个 「问答机器」,你给它一个输入,它给你一个输出,然后就结束了。就算是多轮对话,它也只是在当前上下文里被动响应你,它不会主动去做任何事,也不知道自己上一步做了什么、下一步该做什么。
缺点:
- 知识冻结: 模型的训练数据有截止日期,它没有任何途径去获取实时信息;
- 不能行动: 传统大模型本质上是文本输出其,所有输出都是一段文字,无法帮用户去调用工具;
- 对话失忆: 传统大模型没有持续性状态,每次调用之间它是完全失忆的
Agent :
本质上是个 「运作闭环」:感知 -> 规划 -> 行动 -> 再感知。
- 感知: 获取当前环境、用户输入、工具返回结果、系统状态等信息。
- 规划: 基于目标和当前状态,判断下一步该做什么。
- 行动: 执行操作,比如调用工具、写代码、发请求、修改文件、回复用户。
- 再感知: 观察行动后的结果,再决定是否继续、修正或结束。
关键特性:
- 工具调用
- 记忆机制
- 自我纠错
2️⃣ Agent 基本架构
Agent 的基本架构有四个核心组件:LLM、工具、记忆、规划模块
LLM: 不管是 用户指令、工具返回结果 还是 记忆保存的内容,最终都要经过LLM来理解和决策。- 工具系统:
LLM本身是个纯粹的「语言处理器」,它不能上网、不能读文件、不能执行代码,但这些限制都可以通过工具来突破;LLM会读取 用户问题 和 工具描述 ,LLM决定要调哪个工具、参数填什么,把决策以JSON格式返回,本地代码去真正执行调用工具,结果再反馈给模型。
- 记忆系统:
- 短期记忆: 当前这轮对话的上下文,保存在
context window; - 长期记忆: 通常用 向量数据库 来保存,把重要信息
embedding之后存起来,下次用的时候做 语义检索 拿回来;
- 短期记忆: 当前这轮对话的上下文,保存在
- 规划模块: 依赖的是
LLM的推理能力- 思维链
CoT: 让模型「把思考过程写出来」,而不是直接输出最终答案; - 思维树
TOT: 在每个推理节点上展开多个可能的分支,然后评估每个分支的质量,选出最优的路径继续往下走
- 思维链
3️⃣ Tools、Agent 和 WorkFlow 的区别?
Tools:本质上是一个 「按特定格式暴露给LLM的函数」,必须给LLM一份看得懂的schema(名字、描述、参数类型);Agent:本质上是一个 决策系统,内部用LLM做大脑,Agent自己判断什么时候调哪个Tool、要不要继续、什么时候结束;WorkFlow:- 程序员把整个执行流程的「骨架」写在代码里;
LLM、Agent、Tools都只是这个流程里的 「节点」,每个节点负责完成自己那一步;- 整体走哪条路、下一步去哪里,全由开发者的代码决定,不是任何节点自己说了算;
4️⃣ WorkFlow 编排模式
Anthropic 在他们的 Agent 工程实践中总结了几种常见的 Workflow 编排模式
- 提示链(
Prompt Chaining): 把一个大任务拆成多个小步骤,前一步的输出作为后一步的输入,像流水线一样串起来; - 路由(
Routing): 先用LLM做分类判断,然后根据分类结果把请求分发到不同的处理分支; - 并行化(
Parallelization): 将任务拆分进行并行处理,最后汇总结果; - 编排者-工人(
Orchestrator-Workers) 中央编排者负责分配任务,多个Worker各自完成子任务; - 评估者-优化者(
Evaluator-Optimizer): 一个LLM负责生成输出,另一个LLM负责评估这个输出的质量,如果评估不通过就把反馈给回生成者,让它改进后重新输出,如此循环直到评估通过或者达到最大重试次数
5️⃣ Agent 的设计范式
目前主流的 Agent 设计范式有:ReAct、Plan-and-Execute、Reflection
ReAct: 主要有由三个步骤形成一个完整的循环(Thought -> Action -> Observation)- 循环过程:
Thought阶段:LLM先把当前的情况分析一遍,把推理过程写出来;Action阶段:LLM根据思考的结论决定调用哪个工具、传什么参数;Observation阶段:工具返回的结果被反馈给LLM,它读取这个结果,然后进入下一轮Thought,重新分析当前局面、决定接下来怎么做。
- 缺点: 每一步都是 局部最优 决策,处理特别复杂的、需要全局规划的任务时,容易在中间迷失方向。
- 循环过程:
Plan-and-Execute: 分开 规划阶段 和 执行阶段,先让一个LLM专门做规划,输出一个完整的步骤列表,然后由另一个LLM逐步执行- 关键机制:动态重规划
- 执行器每执行完一步都会把结果反馈给规划器,规划器会判断:当前的执行结果和预期一致吗?后续的计划还适用吗?需不需要调整?如果发现某一步的结果和预期严重偏离,规划器会修改后续的步骤,甚至插入新的步骤来应对。
Reflection: 在前两种范式的基础上加了一层「质量保障」- 做法:
Agent完成一步或者完成整个任务之后,再让一个LLM来判断做得好不好、结果是否符合预期;- 如果评估不通过,就重试或者换一种策略。
- 做法:
范式选择 其实核心看两个维度:任务复杂度 和 质量要求
- 如果任务步骤不多、每步都比较独立,
ReAct就够了,简单直接; - 如果任务很复杂、步骤之间有依赖关系需要全局统筹,
Plan-and-Execute更合适; - 如果对输出质量要求特别高、允许多花一些时间和成本,就在前面的基础上叠加
Reflection;
6️⃣ 复杂任务拆分
任务拆分: LLM 一次性处理太复杂的任务很容易出错,把大任务拆成小步骤,每步聚焦一件事,准确率会明显提升
分类:
静态拆分: 提前把任务流程设计好,固定成一个确定的
Workflow,每一步是什么、按什么顺序执行,全部事先写死。- 优点:行为可预测,出了问题知道是哪一步的问题,好排查;
- 缺点:灵活性低,遇到你没设计进流程的情况就容易卡住。
动态拆分: 把「任务拆解」交给
LLM来做。给它一个目标,让它先输出一个执行计划,再按计划一步步执行。- 重点:
分析步骤之间的依赖关系,识别出可以 并行 的步骤,是降低总耗时的关键
要让并行真正落地,前提是先把依赖关系画成一张 有向无环图(DAG)
- 节点:步骤
- 边:「依赖」。
- 没有依赖的节点就能同时跑,依赖它们的节点要等父节点完成。

- 重点:
拆分粒度:
- 拆分太细:
- 步骤越多,
LLM调用次数越多,总token消耗上升; - 步骤太碎,每步只做一件极小的事,
LLM看不到全局,产出的各部分也容易衔接生硬;
- 步骤越多,
- 拆分太粗:
- 每步负责的事太多,出错概率上升,出了问题也无法定位是哪一步的责任
- 拆分太细:
7️⃣ Agent 的记忆机制
Agent 需要 记忆模块 才能在多步任务中保持状态、跨任务积累知识;
分类:
- 感知记忆: 表示「当前调用的原始输入」,包括 用户发来的这条消息、上传的截图、传入的文档;
- 短期记忆: 表示「当前任务执行过程中的完整状态」,包括 用户说了什么、模型输出了什么、工具调用返回了什么;
- 长期记忆: 表示「多轮任务保留的信息」,通常存放在 外部数据库,等在下次需要时去检索拿回来用;
- 实体记忆: 提取「对话中出现的关键实体和事实」,存成结构化字段,包括 「用户偏好 Python」「客户预算是 5 万」「项目截止日是 3 月底」。
记忆压缩:
- 定义:
context window是有token上限的。一个复杂的多步任务,对话历史越来越长,工具返回的结果越来越多,很快就会把context window塞满。 - 种类:
- 滑动窗口: 只保留最近 N 轮对话,更早的历史直接丢弃。
- 摘要压缩:
token接近上限时,用LLM把早期的对话历史压缩成一段摘要,替换掉原始的冗长历史。 - 外部存储: 执行过程中产生的中间结果,如果当前步骤不需要但后面可能用到,就先存到向量数据库里,从 context window 中移除,等后面某步需要时再检索回来。
- 定义:
LLM 面试篇
1️⃣ 什么是 Function Calling?
定义:
- 开发者用
schema把 工具描述 传给模型; - 模型判断是否需要 调用工具,返回结构化的
JSON来表达tool_calls,告诉开发者「需要调哪个函数、参数是什么」; - 本地代码拿到这段
JSON去真正执行调用具体的工具,把 工具调用结果 塞回对话,模型再生成最终答案;
- 开发者用
schema 案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询指定城市的实时天气,包含气温、天气状况、风向风速,仅支持中国大陆城市",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如「北京」「上海」,不要带省份前缀"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认用摄氏度"
}
},
"required": ["city"]
}
}
}
]
2️⃣ LLM 是如何学会调用外部工具的?
模型主要靠以下这两个阶段被训练出调用工具的能力
- 监督微调:
Supervised Fine-Tuning - 基于人类反馈的强化学习:
Reinforcement Learning from Human Feedback
- 监督微调:
监督微调
- 背景:
LLM在预训练阶段,主要学习的是给定前面的文字预测下一个token,整个训练过程完全是在 文本空间 里进行的,模型从未见过「工具调用」这件事。
- 定义:
- 给
LLM喂大量「工具调用示范对话」,让它通过模仿学会「看到工具描述 -> 判断要不要调 -> 输出结构化JSON请求」这整套流程。
- 给
- 缺点:
SFT让模型学会了「调工具」这个动作,但模型不知道什么时候该调、什么时候不该调。
- 背景:
基于人类反馈的强化学习:
- 特点:
- 生成多样回答: 针对同一个问题让
LLM生成几种不同的处理方式,有的调了工具,有的直接回答,覆盖各种情况; - 人类打分: 标注员评判哪种回答更合理;
- 训练奖励模型: 利用打分数据,单独训练一个小模型,专门负责打分,它不回答问题,只判断「这个回答人类会喜欢吗」
- 强化学习优化主模型: 拿奖励模型的打分不断调整主模型的参数,让主模型越来越倾向于产出「高分回答」,也就是边界感更准确的工具调用行为
- 生成多样回答: 针对同一个问题让
- 特点:
3️⃣ 什么是 MCP
- 定义:
MCP是Anthropic在 2024 年底推出的开放协议,主要解决的是 「模型接工具太碎片化」 的问题。 - 思路: 工具提供方按协议实现一个
MCP Server,任何支持MCP的 AI 客户端就能直接接进来,一次实现到处复用; - 三种主要能力:
- Tools: 「有副作用的操作」,执行之后会改变外部世界的状态,正因为如此,
Tools通常需要用户授权确认才能执行,不能让模型想调就调; - Resources: 「数据提供给模型看」,比如:读取日志文件、查询数据库记录、获取文档内容;
- Prompts: 「预定义的提示词模板」,带参数占位符,解决的是「每次都要手写重复
prompt」的问题
- Tools: 「有副作用的操作」,执行之后会改变外部世界的状态,正因为如此,
- 底层通讯:
JSON-RPCstdio(标准输入输出):Server作为本地子进程运行,Client通过管道和它通信,Server从stdin读消息,把结果写到stdout。Streamable HTTP:Server作为HTTP服务部署在远程,Client通过HTTP连接和它通信。
4️⃣ 什么是 SKILL
定义:
Agent Skill是把「指令、脚本、模板」一体化打包成可复用能力包的机制。- 关键在于三件事:**
Agent能自动发现它、按需加载它、在需要时调用里面的脚本和资源**。 - 每个
Skill是一个文件夹,里面有一份SKILL.md指令文件,还可以带上脚本、模板、参考文档这些资源。
案例:
1
2
3
4
5
6
7
8code-review/ # Skill 文件夹,名字就是这个 Skill 的标识
├── SKILL.md # 核心指令文件(必须有)
├── scripts/ # 可选:可执行的脚本
│ └── check_security.py # 比如一个安全检查脚本
├── references/ # 可选:参考文档
│ └── review_standards.md # 比如团队的审查标准文档
└── assets/ # 可选:模板、资源文件
└── report_template.md # 比如审查报告的输出模板
设计思想: 渐进式加载
- 第一层:
Agent启动的时候,只加载每个Skill中的Skill.md中的name和description这两个字段; - 第二层:
Agent判断「当前任务和某一个Skill相关」,这时候才会把这个Skill的SKILL.md正文完整加载进来; - 第三层:
Agent在执行过程中,如果指令里提到了「使用assets/report_template.md的模板」,Agent才会在那个时刻去读取这个模板文件。
- 第一层:
参考资料
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 GYu的妙妙屋!
