Agent面试八股文
大清已经亡了,但是八股文该背还是要背啊,别的不说,可以在别人面前好好装杯不是。
Agent 八股专题第一期:LLM 与 Agent 工程面试 10 连问
面向:大模型应用开发、Agent 工程、RAG 系统、AI 平台岗位
目标:不是背概念,而是能把概念讲到工程实现、系统设计、线上经验这一层。
目录
- Transformer 为什么比 RNN 更适合大模型时代?
- Self-Attention 到底在干什么?
- 为什么聊天模型大多是 Decoder-only?
- Next-token prediction 为什么能学到推理能力?
- Temperature、top-p、top-k 分别控制什么?
- temperature = 0,模型就一定不会错吗?
- Context Window 是什么?为什么不是越大越好?
- KV Cache、Prompt Cache、Context Cache 有什么区别?
- 为什么有了 1M 长上下文还需要 RAG?
- Function Calling 到底解决什么问题?
1. Transformer 为什么比 RNN 更适合大模型时代?
面试官真正想听什么
不是想听一句:
Transformer 用 Attention,RNN 有长距离依赖问题。
这个回答太浅。
更好的回答应该从三个层面讲:
- 训练并行性
- 长距离依赖建模
- 工程扩展性
标准回答
Transformer 相比 RNN/LSTM 更适合大模型时代,核心原因不是单纯“效果更好”,而是它更适合在 GPU/TPU 上做大规模并行训练。
RNN 是按时间步递归计算的:
h1 -> h2 -> h3 -> h4 -> ...第t个 token 的状态依赖第t-1个状态,所以训练时很难完全并行。
Transformer 则是一次性处理整个 token 序列:
[x1, x2, x3, x4] -> Self-Attention -> new representations所有 token 可以同时参与矩阵计算,更适合大规模硬件加速。
工程味回答
更像工程同学的说法是:
Transformer 赢在并行训练和 scaling。它通过 self-attention 让任意两个 token 可以直接交互,长距离信息路径更短;同时矩阵乘法密集,适合 GPU/TPU 扩展。但代价是注意力计算和 KV Cache 会随着上下文长度增长带来显存和延迟压力,所以后面才有长上下文优化、prefix cache、paged attention 等工程方案。
这一点材料里也强调:回答 Transformer 时,要能自然连到上下文窗口、KV Cache、prefix cache 等工程问题,而不是只背论文结构。
面试追问
Q:Transformer 没有缺点吗?
有。
标准 self-attention 的复杂度和序列长度强相关。长上下文时:
输入越长 -> prefill 越慢 -> KV Cache 越大 -> 并发越低所以生产系统里,不能无脑把所有文档都塞进 prompt。
2. Self-Attention 到底在干什么?
一句话解释
Self-Attention 的本质是:
对每个 token,动态决定当前上下文中哪些 token 更重要,然后把相关 token 的信息加权汇总回来。
经典公式:
Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) VQ/K/V 怎么理解?
可以用一句很面试友好的话解释:
Q:我现在想找什么信息 K:每个 token 身上有什么可匹配的特征 V:每个 token 真正携带的内容例如句子:
The animal didn't cross the street because it was too tired.模型在处理it的时候,需要判断it指的是animal还是street。
Self-Attention 会让it这个位置去关注上下文中更相关的 token。
简化版代码理解
importtorchimporttorch.nn.functionalasF B,T,D=2,5,16# batch, sequence length, hidden dimx=torch.randn(B,T,D)Wq=torch.randn(D,D)Wk=torch.randn(D,D)Wv=torch.randn(D,D)Q=x @ Wq K=x @ Wk V=x @ Wv scores=Q @ K.transpose(-2,-1)/(D**0.5)weights=F.softmax(scores,dim=-1)out=weights @ Vprint(out.shape)# [B, T, D]这个代码不是工业实现,但能说明核心流程:
输入 token 向量 -> 生成 Q/K/V -> 计算相关性 -> softmax 得到权重 -> 加权汇总 V面试陷阱
不要说:
Attention 就是模型理解了重点词。
更严谨的说法:
Attention 是一种可学习的信息路由机制,它通过权重分配让不同 token 之间交换信息,但不等同于人类意义上的注意力,也不能简单解释成模型“真正理解了”。
3. 为什么聊天模型大多是 Decoder-only?
先区分三类架构
| 架构 | 代表 | 适合任务 |
|---|---|---|
| Encoder-only | BERT | 分类、匹配、Embedding、Rerank |
| Encoder-Decoder | T5、BART | 翻译、摘要、文本转换 |
| Decoder-only | GPT、Qwen、LLaMA | 聊天、代码生成、Agent、开放式生成 |
标准回答
聊天模型大多采用 Decoder-only,是因为它和自回归生成任务高度一致。
Decoder-only 的训练目标是:
给定前面的 token,预测下一个 token这和聊天、代码生成、工具调用、Agent 推理的接口非常统一:
输入上下文 -> 继续生成所以它天然适合开放式生成。
工程化解释
Decoder-only 的优势不只是模型结构,而是生态成熟:
流式输出 KV Cache Prefix Cache Function Calling Structured Output 多轮对话 Agent Loop这些能力基本都是围绕 Decoder-only LLM 建起来的。
材料中也指出,生产系统通常不是一个 Decoder-only 模型包打天下;Embedding、Rerank、分类等模块仍然可能使用 Encoder-only 或其他小模型。
项目表达模板
面试时可以这样讲:
我们在主生成链路中选择 Decoder-only 指令模型,因为业务目标是开放式问答和工具调用,而不是单纯分类。对于检索召回和重排,则使用 Embedding/Rerank 模型。也就是说,生成主流程用 Decoder-only,但系统整体是多模型协同。
这比“我们用了 Qwen/ChatGPT 做问答”强太多。
4. Next-token prediction 为什么能学到推理能力?
面试官想考什么
很多人会被这个问题卡住:
只是预测下一个 token,为什么能做数学、代码、推理、工具调用?
关键在于:训练语料里不仅有普通文本,还包含大量隐式结构。
例如:
问题 -> 解法 代码需求 -> 代码实现 Bug -> 修复过程 论文 -> 摘要 用户意图 -> 工具调用模型在海量语料上学习的不是某个单点任务,而是大量任务背后的统计结构和模式。
更准确的回答
Next-token prediction 学到的是:
语言模式 知识分布 任务格式 代码模板 推理轨迹 对话策略 工具调用模式但它不是严格逻辑引擎,也不是数据库。
所以模型会:
能推理,但不保证每次正确 懂很多,但可能过时 会编程,但可能写出隐藏 bug 能调用工具,但可能填错参数这和 Agent 有什么关系?
Agent 的很多能力,本质上是在利用模型的 in-context learning:
system prompt few-shot examples tool schema retrieved documents memory state这些东西都被塞进上下文,让模型在运行时“临时适配任务”。
这也是为什么 Prompt Engineering、Context Engineering、RAG、Function Calling 都是大模型应用的核心模块。材料中也提到,提示词、示例、工具 schema、检索结果,本质上都在利用 in-context learning。
5. Temperature、top-p、top-k 分别控制什么?
先说结论
这些参数控制的不是模型“懂不懂”,而是:
从模型已经算出的概率分布里,怎么选择下一个 token。
模型前向计算后会得到 logits:
token A: 0.50 token B: 0.25 token C: 0.15 token D: 0.10采样参数决定从这个分布里怎么选。
Temperature
Temperature 控制分布的“尖锐程度”。
temperature 低 -> 更保守,更稳定 temperature 高 -> 更多样,更发散适合低温度的任务:
JSON 抽取 分类 意图识别 工具参数生成 合同字段提取适合高温度的任务:
文案生成 标题 brainstorm 创意方案 多候选改写Top-p
Top-p,也叫 nucleus sampling。
它保留累计概率达到p的最小 token 集合。
例如:
A: 0.50 B: 0.25 C: 0.15 D: 0.10如果top_p = 0.8,可能保留:
A + B + C = 0.90然后只在 A/B/C 里面采样。
Top-k
Top-k 更简单:
只保留概率最高的 k 个 token例如top_k = 3:
A、B、C 保留 D 直接排除简单采样代码
importtorchimporttorch.nn.functionalasF logits=torch.tensor([5.0,3.0,2.0,1.0])defsample_with_temperature(logits,temperature=1.0):scaled_logits=logits/temperature probs=F.softmax(scaled_logits,dim=-1)returnprobsprint("T=0.5:",sample_with_temperature(logits,0.5))print("T=1.0:",sample_with_temperature(logits,1.0))print("T=2.0:",sample_with_temperature(logits,2.0))温度越高,分布越平;温度越低,高概率 token 越占优势。
6. temperature = 0,模型就一定不会错吗?
标准答案
不会。
temperature = 0 只是让模型更倾向选择最高概率 token,不代表答案一定正确。
材料里也明确强调,低温度不能修复错误知识、缺失上下文、错误工具结果、差的 prompt 或模型能力上限。
为什么?
因为错误可能来自很多地方:
模型本身不知道 上下文没有证据 RAG 检索错了 工具返回错了 prompt 任务定义模糊 schema 设计不清楚 输出格式没有约束这时调 temperature 没有本质帮助。
错误优化顺序
很多新手一看到输出不稳定,就开始乱调参数,这是典型低水平操作。
更靠谱的排查顺序:
1. 任务是否定义清楚? 2. 模型选型是否匹配? 3. 上下文证据是否足够? 4. Prompt 是否有冲突? 5. Tool schema 是否清晰? 6. 输出格式是否可验证? 7. 最后再调 temperature / top_p / max_tokens项目经验表达
可以这样说:
我们线上没有把 temperature 当成主要优化手段。对于抽取、分类、路由、工具参数生成,优先做 schema 约束和字段校验;对于创意生成,才适当提高 temperature。模型错误时,优先排查上下文、检索结果、工具返回和任务定义,而不是直接调采样参数。
这就是“工程意识”。
7. Context Window 是什么?为什么不是越大越好?
定义
Context Window 指模型一次请求中能处理的 token 总预算。
注意:它通常包括:
system prompt developer prompt 用户输入 历史对话 检索片段 工具 schema 工具返回结果 模型输出预留 token所以它不是“能塞多少文档”这么简单。
为什么不是越大越好?
因为长上下文会带来四类成本:
1. Token 计费更高 2. Prefill 更慢,首 token 延迟更高 3. KV Cache 占用更多显存 4. 并发能力下降材料中也强调,长上下文解决的是“放得下”,而检索、重排、压缩、缓存解决的是“用得好、用得省、用得快”。
Prefill 和 Decode
LLM 推理通常分两阶段:
Prefill:读取完整输入上下文,生成 KV Cache Decode:逐 token 生成输出,复用历史 KV Cache长 prompt 首 token 慢,主要是因为 prefill 阶段重。
工程经验
不要这样做:
把整篇 PDF + 全部历史对话 + 所有工具说明 + 所有业务规则全部塞进去更好的做法:
稳定系统提示词 动态检索相关片段 历史对话做 summary 工具结果结构化压缩 关键信息前置 输出 token 预留预算8. KV Cache、Prompt Cache、Context Cache 有什么区别?
这是面试高频题。
对照表
| 概念 | 解决什么问题 | 作用层级 |
|---|---|---|
| KV Cache | 单次生成时避免重复计算历史 token | 模型推理内部 |
| Prompt/Prefix Cache | 多个请求共享相同前缀时,避免重复 prefill | 推理服务层 |
| Context Cache | 把大块上下文作为缓存对象复用 | API/应用层 |
KV Cache
KV Cache 缓存的是每一层 Attention 里的 Key/Value 状态。
它不是缓存自然语言答案。
错误说法:
KV Cache 就是把之前回答存起来正确说法:
KV Cache 是把历史 token 在注意力计算中需要的 K/V 状态缓存起来,下一步生成时不用重新计算整段历史。Prompt Cache
Prompt Cache 适合这种场景:
固定 system prompt 固定 tool schema 固定产品规则 固定长文档前缀如果这些内容每次请求都一样,就可以复用前缀计算结果。
提高缓存命中率的写法
差的上下文拼接方式:
prompt=f""" 当前时间:{time.time()}请求ID:{uuid.uuid4()}系统规则:{rules}工具定义:{tools}用户问题:{query}"""每次都插入随机字段,缓存基本废掉。
更好的方式:
stable_prefix=f""" 系统规则:{rules}工具定义:{tools}"""dynamic_suffix=f""" 用户问题:{query}"""把稳定前缀和动态输入拆开。
9. 为什么有了 1M 长上下文还需要 RAG?
标准答案
因为长上下文解决的是容量问题,不解决信息质量问题。
即使模型支持 1M token,也会遇到:
关键信息被埋在中间 上下文噪声太多 旧版本规则污染新规则 成本太高 首 token 太慢 模型不一定能稳定利用全部上下文RAG 的价值
RAG 不是因为模型窗口小才存在。
RAG 的核心价值是:
提高证据密度 降低无关噪声 控制成本和延迟 支持知识更新 提供可追溯引用 减少幻觉简单 RAG 流程
defrag_pipeline(query):# 1. query rewriterewritten_query=rewrite_query(query)# 2. retrievedocs=vector_search(rewritten_query,top_k=20)# 3. rerankreranked_docs=rerank(query,docs)# 4. compresscontext=compress_docs(reranked_docs[:5])# 5. generateanswer=llm_generate(query=query,context=context)returnanswer面试表达
可以这样讲:
长上下文让模型“放得下更多东西”,但 RAG 让模型“看到更相关的东西”。生产系统里通常不会因为模型支持 1M context 就取消 RAG,因为成本、延迟、噪声、引用追溯和知识更新仍然是现实问题。
这句话非常稳。
10. Function Calling 到底解决什么问题?
一句话定义
Function Calling 解决的是:
让模型用机器可解析、可校验、可执行的结构化方式表达动作意图。
材料中也明确指出,Function Calling 的本质不是模型真的执行函数,而是模型输出工具名和参数,应用侧代码负责校验、权限控制和真正执行。
没有 Function Calling 会怎样?
如果没有 Function Calling,模型可能输出:
我建议你调用 search_order(order_id=123)然后开发者只能靠字符串解析。
问题很多:
工具名可能写错 参数字段可能缺失 日期格式可能混乱 枚举值可能漂移 自然语言难以稳定解析Function Calling 的标准流程
用户请求 -> 模型读取 tool schema -> 模型输出 tool call -> Runtime 校验参数 -> Tool Executor 执行工具 -> 外部系统返回结果 -> 工具结果回填给模型 -> 模型生成最终回答Tool Schema 示例
tools=[{"type":"function","function":{"name":"search_order","description":"根据订单号查询订单状态、物流信息和支付状态。","parameters":{"type":"object","properties":{"order_id":{"type":"string","description":"订单号,例如 OD202605200001"}},"required":["order_id"]}}}]Runtime 校验示例
frompydanticimportBaseModel,Field,ValidationErrorclassSearchOrderArgs(BaseModel):order_id:str=Field(...,description="订单号")defexecute_tool(tool_name:str,arguments:dict):iftool_name=="search_order":try:args=SearchOrderArgs(**arguments)exceptValidationErrorase:return{"error":"invalid_arguments","details":e.errors()}returnsearch_order_api(args.order_id)return{"error":"unknown_tool"}重点是:不要相信模型输出的 arguments,一定要校验。
面试追问:Function Calling 和结构化输出有什么区别?
| 项目 | 结构化输出 | Function Calling |
|---|---|---|
| 关注点 | 最终答案长什么样 | 模型要调用什么动作 |
| 输出对象 | JSON、枚举、对象 | tool name + arguments |
| 是否执行外部动作 | 通常不执行 | 通常需要应用侧执行 |
| 适合场景 | 抽取、分类、审核 | 查数据库、调用 API、发起任务 |
材料中也提到,结构化输出关注最终输出结构,Function Calling 关注模型如何以结构化方式提出动作请求。
总结:这 10 题要形成一条主线
这 10 个问题不是孤立知识点,而是一条完整链路:
Transformer -> Decoder-only LLM -> Next-token prediction -> 采样参数 -> Context Window -> KV Cache -> RAG -> Function Calling -> Agent Runtime真正面试时,不要把每题答成孤立八股。更高级的答法是:
LLM 本质是基于 Transformer 的自回归 token 生成模型。它通过上下文进行 in-context learning,但上下文有成本、有窗口、有噪声,所以需要 RAG、Context Engineering 和缓存机制。模型本身只生成概率分布,采样参数控制输出风格,但不能替代任务建模。要让模型进入真实业务系统,就需要结构化输出和 Function Calling,把自然语言能力接到数据库、API 和工具执行链路里。再往上,Agent 就是在目标、状态、工具、观察和终止条件之间形成多步闭环。
这段话背下来不是目的,真正要理解的是:大模型应用不是“调 prompt”,而是围绕模型能力边界做系统工程。
面试速记版
1. Transformer 赢在并行训练、长程依赖和 scaling,但长上下文成本高。 2. Self-Attention 是信息路由,不是人类注意力。 3. Decoder-only 适合开放式生成,生态围绕它成熟。 4. Next-token prediction 学到的是分布模式,不是严格逻辑和事实数据库。 5. Temperature/top-p/top-k 控制采样,不控制知识正确性。 6. 低温不等于正确,只是更保守。 7. Context Window 是 token 总预算,不是免费文档仓库。 8. KV Cache 是推理内部状态缓存,不是答案缓存。 9. 1M context 不能替代 RAG,RAG 提供证据密度、低成本和可追溯。 10. Function Calling 让模型以结构化方式表达动作意图,真正执行在应用侧。下一篇建议选题
第二批 10 题直接进入Agent 核心范式(求求各位大哥大姐点个赞,点个转发,点个关注,祝你们顺风顺水顺财神!):
1. 什么是 Agent?和普通 LLM 应用有什么区别? 2. Workflow 和 Agent 的边界是什么? 3. ReAct 是什么?为什么适合工具调用? 4. Plan-and-Execute 和 ReAct 怎么选? 5. CodeAct 为什么在软件工程 Agent 里很强? 6. Agent 如何做任务拆解? 7. Tool Use 的完整执行链路是什么? 8. Memory 在 Agent 里到底解决什么问题? 9. Multi-Agent 什么时候有意义? 10. Agent 为什么必须设计终止条件?