本文是「速通 AI」系列的配套面试指南,覆盖从数学基础到 Agent 开发的高频面试题。每道题附完整解答,可用于面试准备。
使用建议:先通读「速通 AI」系列文章理解原理,再用本文检验掌握程度。面试前重点复习自己答不上来的题目。
最后更新:2026-09-15。使用前建议结合实际项目经验理解记忆。
1. 数学基础(第 1 篇)
Q1:梯度下降的原理是什么?学习率过大/过小分别会怎样?
梯度下降是通过迭代更新参数来最小化损失函数的优化算法。核心公式:
$$ \theta_{\text{new}} = \theta_{\text{old}} - \eta \cdot \nabla L(\theta) $$其中 $\eta$ 是学习率,$\nabla L$ 是损失函数对参数的梯度。
学习率的影响:
- 太大:步子跨过最优解,来回震荡甚至发散。例如 $y=(x-3)^2$,$\eta=1.0$ 时 $x$ 在 0 和 6 之间来回跳。
- 太小:收敛极慢,可能需要数万步才能到达最优点。
- 刚好:稳定收敛,远处大步走、近处小步挪(梯度自动减速)。
实际训练中通常从 0.001 开始,观察 loss 曲线:震荡就减小,下降太慢就增大。
面试时怎么讲:“梯度下降就是’沿着最陡的方向下山’。每步算一次梯度(哪个方向最陡),往反方向走一步。学习率控制步子大小——太大会震荡,太小走不动。实际中用 Adam 或 SGD+动量,不用原始梯度下降。”
面试官可能追问:“学习率过大除了震荡还可能发生什么?” → 答案:loss 爆炸(NaN),参数更新后进入损失函数的"悬崖"区域,梯度突然变大导致参数飞出去。解决方案:梯度裁剪 + 学习率 warmup。
Q2:什么是反向传播算法?它的数学本质是什么?
反向传播是高效计算神经网络中每个参数梯度的算法。数学本质是链式法则。
对于复合函数 $y = f(g(x))$,链式法则给出 $\frac{dy}{dx} = f'(g(x)) \cdot g'(x)$。
在神经网络中,损失 $L$ 是多层复合函数。反向传播从损失出发,逐层往回计算每个参数的"责任":
$$ \frac{\partial L}{\partial W} = \frac{\partial L}{\partial z} \cdot \frac{\partial z}{\partial W} $$每一步都很简单(局部导数),但组合起来就能高效计算复杂网络的所有梯度。这就是为什么反向传播让训练深层网络成为可能。
常见误区:以为反向传播是一种独立的算法。实际上它只是链式法则的系统性应用——前向传播构建计算图,反向传播沿图计算梯度。
面试时怎么讲:“反向传播就是链式法则的系统性应用。从损失出发,逐层往回算每个参数的梯度。关键点:每层的梯度 = 上游传回来的误差信号 × 本层的局部梯度。这就是为什么激活函数的导数很重要——如果导数接近 0,梯度就会在这一层’断掉’。”
Q3:Sigmoid 函数的导数是什么?为什么会出现梯度消失?
Sigmoid 导数的推导结果:
$$ \sigma'(x) = \sigma(x) \cdot (1 - \sigma(x)) $$这个结果意味着导数可以直接用函数值计算,不需要重新算指数函数。
梯度消失的原因:当 $x$ 很大时 $\sigma(x) \approx 1$,$\sigma'(x) \approx 0$;当 $x$ 很小时 $\sigma(x) \approx 0$,$\sigma'(x) \approx 0$。Sigmoid 的最大导数仅为 0.25(当 $x=0$ 时)。在网络中每经过一层 Sigmoid,梯度至少衰减为原来的 1/4。经过 10 层后梯度衰减为 $0.25^{10} \approx 10^{-6}$——参数几乎不更新,网络"学不动了"。
常见误区:很多人以为 Sigmoid 的梯度消失是因为"导数小于 1"。实际上任何导数小于 1 的函数连乘都会消失,Sigmoid 的问题更严重——它的最大导数只有 0.25,消失速度比 ReLU(正区间导数恒为 1)快得多。
面试时怎么讲:“Sigmoid 把输入压缩到 0-1,但问题是导数最大只有 0.25。多层连乘后梯度指数衰减——10 层后梯度只剩 0.25 的 10 次方,约等于零。这就是为什么深层网络用 ReLU(正区间导数恒为 1,不会消失)。”
Q4:ReLU 和 Sigmoid 的区别?为什么 ReLU 成为主流?
| 维度 | Sigmoid | ReLU |
|---|---|---|
| 公式 | $\frac{1}{1+e^{-x}}$ | $\max(0, x)$ |
| 输出范围 | (0, 1) | [0, +∞) |
| 正区间梯度 | 最大 0.25,会消失 | 恒为 1,不消失 |
| 计算效率 | 需要指数运算 | 只需一次比较 |
| 激活模式 | 所有神经元都有输出 | 部分神经元输出 0(稀疏激活) |
ReLU 成为主流的三个原因:
- 正区间梯度恒为 1:不会消失,支持训练深层网络
- 计算效率极高:$\max(0, x)$ 比 $e^{-x}$ 快得多
- 稀疏激活:部分神经元被"关闭",相当于天然正则化
ReLU 的代价是"死亡 ReLU"问题(负区间梯度恒为 0),解决方案包括 Leaky ReLU、GELU/Swish。
常见误区:以为 ReLU 没有缺点。实际上"死亡 ReLU"是真实存在的问题——如果一个神经元的输入持续为负,它就永远不会更新,相当于"死了"。Leaky ReLU 给负区间一个小斜率(如 0.01),GELU 用平滑曲线替代硬切换。
面试时怎么讲:“ReLU 的核心优势是正区间梯度恒为 1,不会消失。代价是负区间梯度为 0(死亡 ReLU)。现代模型用 GELU 或 Swish 替代——它们在负区间有小梯度,不会完全死掉。”
面试官可能追问:“GELU 和 ReLU 的区别?” → GELU 是平滑的 ReLU,在 $x=0$ 处不是硬切换而是渐变。GPT/BERT 用 GELU,ResNet 用 ReLU。GELU 的表达能力更强但计算稍慢。
Q5:Softmax 函数的作用?为什么要用 $e^x$?
Softmax 把一组任意实数转换为概率分布(所有值 > 0,且和为 1):
$$ \text{softmax}(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}} $$用 $e^x$ 的三个原因:
- $e^x > 0$ 保证所有输出为正数(概率不能为负)
- $e^x$ 单调递增(保持大小关系)
- $e^x$ 的导数是自己(计算方便)
数值稳定性:输入很大时 $e^x$ 会溢出。解决方案是减去最大值:$\text{softmax}([1000, 1001, 1002]) = \text{softmax}([-2, -1, 0])$,结果完全一样但不会溢出。
常见误区:以为 Softmax 只用于分类任务的输出层。实际上 Softmax 在 Transformer 的注意力机制中也大量使用——计算注意力权重时必须用 Softmax 把分数归一化为概率分布。
面试时怎么讲:“Softmax 把任意实数变成概率分布——所有值大于 0,和为 1。用 e 的 x 次方是因为它保证正数且单调递增。数值稳定性靠减最大值解决。不只是分类输出层,Transformer 的注意力权重也用 Softmax。”
面试官可能追问:“Softmax 的温度参数 T 有什么用?” → $T$ 控制输出的"尖锐程度"。$T \rightarrow 0$ 时接近 argmax(确定性),$T \rightarrow \infty$ 时接近均匀分布(随机性)。推理时用 $T < 1$ 让输出更确定,用 $T > 1$ 让输出更多样。
Q6:什么是过拟合?如何用正则化解决?L1 和 L2 正则化的区别?
过拟合:模型在训练数据上表现很好,但在新数据上表现差——就像"死记硬背练习题,考试遇到新题就不会"。
面试时怎么讲:“过拟合就是模型把训练数据的噪声也学了。解决方法:L1/L2 正则化(限制权重大小)、Dropout(随机丢弃神经元)、数据增强(增加训练数据多样性)、早停(验证集 loss 不再下降就停)。”
正则化通过在损失函数中加入惩罚项,限制模型复杂度:
$$ L_{\text{total}} = L_{\text{original}} + \lambda \cdot \text{惩罚项} $$| 特性 | L1 (Lasso) | L2 (Ridge) |
|---|---|---|
| 惩罚项 | $\sum \|w_i\|$ | $\sum w_i^2$ |
| 效果 | 使部分权重变为 0(特征选择) | 使所有权重趋近 0(权重衰减) |
| 几何直觉 | 菱形约束,容易在角点相交 | 圆形约束,交点通常不在坐标轴上 |
| 适用场景 | 特征很多,需要筛选 | 特征都有用,防止过拟合 |
实操建议:大多数场景用 L2(权重衰减)就够了。如果特征维度很高(如 NLP 的 one-hot)且怀疑只有少数特征有用,用 L1 做特征选择。实际中常用 Elastic Net(L1 + L2 的组合)。
常见误区:以为正则化是解决过拟合的唯一方法。实际上数据增强、Dropout、早停(Early Stopping)、减少模型复杂度都是有效的抗过拟合手段。正则化只是其中之一。
面试官可能追问:“除了正则化还有什么方法防止过拟合?” → 数据增强(增加训练数据多样性)、Dropout(随机丢弃神经元)、早停(验证集 loss 不再下降时停止训练)、减少模型参数量、交叉验证。
Q7:什么是最大似然估计?它和交叉熵损失有什么关系?
最大似然估计(MLE):选择让观测数据出现概率最大的参数。
例如硬币抛 10 次出现 7 次正面,MLE 的答案是 $p = 0.7$——这很直觉。
关键联系:交叉熵损失 = 负对数似然。当你最小化交叉熵时,你实际上在最大化似然——让模型的参数使得观测到的训练数据出现的概率最大。这就是为什么交叉熵是分类任务的标准损失函数——它有坚实的概率论基础。
面试时怎么讲:“最大似然估计就是选让观测数据出现概率最大的参数。交叉熵 = 负对数似然——最小化交叉熵就是最大化似然。这就是为什么分类任务用交叉熵损失——它有概率论基础,不是随便选的。”
常见误区:以为 MLE 总是正确的。实际上 MLE 对小样本容易过拟合——抛 3 次全是正面,MLE 算出 p=1,显然不对。需要贝叶斯方法(加先验)或正则化。
Q8:梯度下降有哪几种变体?SGD、Mini-batch、Batch 的区别?
| 方法 | 每步使用的数据 | 优点 | 缺点 |
|---|---|---|---|
| 批量梯度下降(BGD) | 全部数据 | 梯度方向最准确 | 数据量大时极慢 |
| 随机梯度下降(SGD) | 1 个样本 | 快 | 方向不稳定 |
| 小批量梯度下降(MBGD) | 32/64/128 个样本 | 兼顾速度和稳定性 | 需要调 batch size |
实际训练中几乎都用 MBGD。batch size 通常从 32 开始,根据 GPU 显存调整。SGD 的随机噪声反而有助于跳出局部最优。
常见误区:以为 batch size 越大越好。实际上大 batch 会让优化陷入"尖锐最小值"(sharp minima),泛化性变差。小 batch 的噪声反而有助于找到"平坦最小值"(flat minima),泛化性更好。
常见误区:以为 Adam 总是比 SGD 好。实际上 Adam 的泛化性通常不如 SGD+动量——Adam 容易陷入"尖锐最小值"(sharp minima),在测试集上表现差。CV 任务(对泛化性要求高)通常用 SGD+动量。
面试官可能追问:“Adam 的一阶矩和二阶矩是什么?” → 一阶矩 $m_t$ 是梯度的指数移动平均(方向),二阶矩 $v_t$ 是梯度平方的指数移动平均(幅度)。一阶矩提供动量,二阶矩提供自适应学习率。
Q9:矩阵乘法在神经网络中扮演什么角色?为什么 GPU 适合做矩阵运算?
神经网络的前向传播本质上就是一连串的矩阵乘法:
$$ \text{output} = \text{input} \cdot W + b $$每一层都在做"输入 × 权重矩阵 + 偏置"。
GPU 适合的原因:矩阵乘法的本质是"大量独立的乘加运算",这些运算是完全并行的。CPU 有少量强核心(如 8 个),GPU 有大量计算核心,擅长并行处理简单的乘加运算(如几千个核心同时做 $a \times b + c$)。矩阵乘法正好适合 GPU 的"人海战术"。
面试时怎么讲:“神经网络的前向传播就是一连串矩阵乘法。CPU 有 8 个强核心,GPU 有几千个弱核心。矩阵乘法的每个元素独立计算——GPU 的几千个核心同时算,比 CPU 的 8 个核心串行算快几百倍。”
常见误区:以为 GPU 什么都比 CPU 快。实际上 GPU 擅长并行的简单计算(矩阵乘法),但串行复杂逻辑(如 if/else 分支)CPU 更快。GPU 的优势是"人海战术",不是"单兵作战"。
Q10:什么是特征值和特征向量?PCA 降维的原理?
对于矩阵 $A$,如果 $A\mathbf{v} = \lambda\mathbf{v}$,则 $\mathbf{v}$ 是特征向量,$\lambda$ 是特征值。
PCA 降维原理:
- 计算数据的协方差矩阵
- 求协方差矩阵的特征值和特征向量
- 特征值大的特征向量 = 数据变化最大的方向
- 只保留前 $k$ 个最重要的方向,丢弃其他
核心思想:100 个特征中,前 3 个"最重要的方向"就能解释 95% 的数据变化。维度从 100 降到 3,但只损失 5% 的信息。
面试时怎么讲:“PCA 找数据变化最大的方向(主成分),把数据投影到这些方向上。100 维数据,前 3 个主成分可能就解释 95% 的方差——维度从 100 降到 3,只损失 5% 信息。”
常见误区:以为 PCA 总是好的。实际上 PCA 假设数据的主要结构是线性的,对非线性数据效果差(此时需要用 Kernel PCA 或自编码器)。另外 PCA 会丢失方差小但对分类重要的维度。
面试官可能追问:“PCA 和 t-SNE 的区别?” → PCA 是线性降维,保持全局结构,速度快。t-SNE 是非线性降维,保持局部结构,速度慢但可视化效果好。PCA 适合预处理,t-SNE 适合可视化。
2. 深度学习与 PyTorch(第 2 篇)
Q11:神经网络为什么需要激活函数?没有激活函数会怎样?
没有激活函数时,无论多少层网络,本质上都只是一个线性变换(矩阵连乘还是矩阵)。两层网络合并后:$y = W_3(W_2(W_1 x + b_1) + b_2) + b_3 = Wx + b$——等于一层。
激活函数引入非线性,让网络能够拟合任意复杂的函数。这就是"万能近似定理":一个有足够多神经元的单隐层网络,可以逼近任意连续函数。
常见误区:以为激活函数越多越好。实际上每加一层激活函数都会引入信息损失(如 ReLU 会把负值清零)。深度网络的关键是平衡非线性和信息保留——残差连接就是为了让信息能"绕过"激活函数直接传递。
面试时怎么讲:“没有激活函数,多层网络等于一层——矩阵连乘还是矩阵。激活函数引入非线性,让网络能拟合任意复杂函数。但不能用太多——ReLU 会把负值清零,信息会丢失。所以用残差连接让信息能’绕过去’。”
面试官可能追问:“万能近似定理说单隐层就够了,为什么还要深层网络?” → 单隐层需要指数级多的神经元才能逼近复杂函数,深层网络用更少的参数就能学到层次化的特征(底层→边缘,中层→纹理,高层→物体)。
Q12:反向传播的完整计算过程?链式法则如何应用?
以 2 层网络为例:
前向传播:$z_1 = W_1 x + b_1$ → $a_1 = \sigma(z_1)$ → $z_2 = W_2 a_1 + b_2$ → $L$
反向传播(从右往左):
- $\frac{\partial L}{\partial z_2} = z_2 - y$(损失对输出的梯度)
- $\frac{\partial L}{\partial W_2} = (z_2 - y) \cdot a_1^T$(输出层权重的梯度)。交叉熵 + Softmax 组合下,$\delta_2 = \hat{y} - y$ 就是预测值减真实值。
- $\frac{\partial L}{\partial a_1} = W_2^T \cdot (z_2 - y)$(误差传回隐藏层)
- $\frac{\partial L}{\partial z_1} = \frac{\partial L}{\partial a_1} \odot \sigma'(z_1)$(通过激活函数导数过滤)
- $\frac{\partial L}{\partial W_1} = \frac{\partial L}{\partial z_1} \cdot x^T$(隐藏层权重的梯度)
每层的梯度 = 误差信号 × 激活函数导数 × 输入信号。
面试时怎么讲:“反向传播就是链式法则的系统性应用。从损失出发,逐层往回算每个参数的梯度。关键点:每层的梯度 = 上游传回来的误差信号 × 本层的局部梯度(激活函数导数 × 输入)。这就是为什么激活函数的导数很重要——如果导数接近 0(如 Sigmoid),梯度就会在这一层’断掉’。”
Q13:梯度消失和梯度爆炸的原因和解决方案?
梯度消失:激活函数导数 < 1(如 Sigmoid 最大导数仅 0.25),多层连乘后指数衰减。深层参数几乎不更新。
梯度爆炸:权重矩阵谱范数 > 1,多层连乘后指数增长。loss 变为 NaN 或震荡发散。
面试时怎么讲:“梯度消失和爆炸的根因是链式法则的连乘效应。消失:导数 < 1 连乘后趋近 0,深层参数不更新。爆炸:导数 > 1 连乘后趋近无穷,loss 变 NaN。解决:ReLU(正区间导数恒为 1)、残差连接(梯度高速公路)、梯度裁剪(限制梯度最大值)。”
| 问题 | 解决方案 |
|---|---|
| 梯度消失 | ReLU(正区间导数恒为 1)、残差连接(梯度高速公路)、BatchNorm |
| 梯度爆炸 | 梯度裁剪(clip_grad_norm)、权重初始化(He/Xavier)、BatchNorm |
Q14:CNN 的卷积操作原理?参数共享和平移不变性是什么?
卷积核(如 3×3 的小矩阵)像"滑动窗口"在图片上滑动,检测局部特征。
参数共享:同一个卷积核用在图片的所有位置——不管图片多大,参数量都是 3×3 = 9 个。
平移不变性:因为参数共享,猫在图片左上角和右下角,识别方法是一样的。
三大优势:
- 局部感知:每个输出只看 3×3 区域
- 参数共享:同一套参数检测同一特征
- 平移不变性:目标在任何位置都能被检测到
权重共享将参数量从 $C_{\text{in}} \times C_{\text{out}} \times k^2 \times H \times W$ 降为 $C_{\text{in}} \times C_{\text{out}} \times k^2$,是 CNN 能处理大图像的根本原因。例如输入 224×224×3,全连接需要约 1.5 亿参数,CNN 只需几千个。
常见误区:以为 CNN 只能处理图像。实际上 1D-CNN 也广泛用于文本分类(TextCNN)和时间序列分析。CNN 的核心是局部特征提取——只要数据有局部结构(时间序列的窗口、文本的 n-gram),CNN 就适用。
面试时怎么讲:“CNN 用卷积核滑动检测局部特征。核心优势:参数共享(同一个核扫全图,参数量与图片大小无关)+ 平移不变性(猫在左上角和右下角都能识别)。这就是为什么 CNN 能处理大图片——全连接要 1.5 亿参数,CNN 只要几千个。”
面试官可能追问:“CNN 的感受野是什么?怎么计算?” → 感受野是输出特征图上一个像素对应原始输入的区域大小。3×3 卷积堆 2 层,感受野 = 5×5。公式:$r_l = r_{l-1} + (k-1) \times \prod_{i=1}^{l-1} s_i$。
Q15:ResNet 的残差连接为什么能解决梯度消失?
传统层:$y = F(x)$,梯度 $\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \cdot \frac{\partial F}{\partial x}$
残差层:$y = F(x) + x$,梯度 $\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \cdot (\frac{\partial F}{\partial x} + 1)$
多了一个 $+1$ 的"梯度高速公路"。即使 $\frac{\partial F}{\partial x}$ 接近 0,梯度仍然可以通过 $+1$ 直接传回去。这就是为什么 ResNet 可以训练 152 层甚至更深的网络。没有残差连接,152 层的网络梯度方差会膨胀到无法训练——每层梯度连乘,要么指数衰减(消失)要么指数增长(爆炸)。
常见误区:以为残差连接是"跳过了一层"。实际上 $y = F(x) + x$ 仍然经过了 $F(x)$ 的计算,只是额外加了原始输入。模型可以学到 $F(x) \approx 0$(什么都不做),但更常见的是学到 $F(x)$ 是对 $x$ 的"微调"。
面试时怎么讲:“残差连接就是 $y = F(x) + x$。反向传播时梯度多了一条 ‘+1’ 的高速公路——即使 F 的梯度接近 0,梯度也能直接传回去。这就是 ResNet 能训练 152 层的原因。”
面试官可能追问:“Pre-LN 和 Post-LN 的区别?” → Pre-LN 在注意力/FFN 之前做 LayerNorm(训练更稳定,梯度更平滑),Post-LN 在之后做(原始 Transformer 的做法,需要 warmup)。现代模型(GPT-3、LLaMA)均采用 Pre-LN。
Q16:RNN 的梯度消失问题?LSTM 的门控机制如何缓解?
RNN 的梯度需要从 $h_T$ 一路传回 $h_1$,每一步都乘以 $W_h$。如果 $W_h$ 的特征值 < 1,梯度指数衰减;如果 > 1,梯度指数增长。
LSTM 的解决方案:引入细胞状态 $C_t$ 和三个门(遗忘门、输入门、输出门)。
关键:细胞状态的更新是加法而非乘法:$C_t = f_t \odot C_{t-1} + i_t \odot \tilde{C}_t$
加法的梯度是 1,不会衰减。这就是"梯度高速公路"——信息可以沿着细胞状态直接传递,不需要经过激活函数的连乘。
面试时怎么讲:“RNN 的梯度消失是因为每步都乘以 W_h。LSTM 用细胞状态 C_t 做加法更新——加法的梯度是 1,不会衰减。三个门控制信息的遗忘、输入、输出。这就是 LSTM 能处理长序列的原因。”
常见误区:以为 LSTM 完全解决了梯度消失。实际上遗忘门 $f_t < 1$ 时梯度仍会衰减,只是比 RNN 慢得多。超长序列(10000+ 步)LSTM 仍然会遇到长程依赖问题。
面试官可能追问:“LSTM 真的完全解决了梯度消失吗?” → 没有完全解决。遗忘门 $f_t < 1$ 时梯度仍会衰减,只是比 RNN 的连乘衰减慢得多。对于超长序列(10000+ 步),LSTM 仍然会遇到长程依赖问题——这就是为什么 Transformer 出现了。
Q17:GRU 和 LSTM 的区别?
| 特性 | LSTM | GRU |
|---|---|---|
| 门的数量 | 3 个(遗忘门、输入门、输出门) | 2 个(重置门、更新门) |
| 状态 | 隐藏状态$h_t$ + 细胞状态 $C_t$ | 只有隐藏状态$h_t$ |
| 参数量 | 更多 | 更少(约 LSTM 的 75%) |
| 效果 | 长序列更好 | 短序列相当,训练更快 |
选择建议:默认用 LSTM(效果更稳定),数据量大或需要快速实验时用 GRU。
实操建议:序列长度 < 100 且数据量少 → GRU(参数少,不容易过拟合);序列长度 > 100 或对精度要求高 → LSTM。现代大模型已经不用 RNN 了(用 Transformer),但理解 LSTM 对面试很重要。
面试官可能追问:“既然 Transformer 更好,为什么还要学 LSTM?” → ① LSTM 是理解序列建模演进的关键一环;② 某些实时场景(如流式语音识别)LSTM 仍有优势(Transformer 需要完整序列);③ 面试官想看你是否理解 RNN 的局限性。
Q18:BatchNorm 的原理和作用?为什么能加速训练?
对每个 mini-batch 的数据做标准化:
- 计算这个 batch 的均值 $\mu$ 和方差 $\sigma^2$
- 标准化:$\hat{x} = (x - \mu) / \sqrt{\sigma^2 + \varepsilon}$
- 缩放和平移:$y = \gamma \cdot \hat{x} + \beta$($\gamma$ 和 $\beta$ 是可学习的参数)
为什么有效:BatchNorm 的核心作用是平滑损失曲面,让梯度更加稳定,从而允许使用更大的学习率,加速收敛。
常见误区:以为 BatchNorm 随时都能用。实际上 BatchNorm 在 batch size 很小时(如 1-2)效果很差(统计量不准);在序列数据上不适合(每个 token 的统计量不同);与 Dropout 同时使用时可能产生冲突。
面试时怎么讲:“BatchNorm 对每个 mini-batch 做标准化,平滑损失曲面,允许用更大学习率。但有两个坑:batch 小时统计量不准;和 Dropout 同时用可能冲突。所以 Transformer 用 LayerNorm(不依赖 batch size)。”
面试官可能追问:“BatchNorm 在推理时怎么处理?” → 推理时不用当前 batch 的统计量,而是用训练时累积的 running mean 和 running variance(指数移动平均)。这就是为什么 model.eval() 很重要——它切换 BatchNorm 到推理模式。
Q19:Dropout 的原理?训练和推理时的区别?
训练时随机将 50% 的神经元输出置为 0。类比:期末考试随机缺席一半学生,迫使每个学生都必须自己学会知识。
推理时关闭 Dropout,但所有权重乘以 $(1-p)$ 来补偿训练时的缩放。
常见误区:以为 Dropout 和 BatchNorm 可以同时使用。实际上两者对数值分布的假设不同——BatchNorm 依赖 batch 统计量,Dropout 随机改变激活值,同时使用可能导致训练不稳定。现代 Transformer 通常只用 LayerNorm + Dropout(或不用 Dropout)。
面试时怎么讲:“Dropout 训练时随机把 50% 神经元置零,推理时关闭。作用是防止过拟合——迫使每个神经元独立学习。坑:和 BatchNorm 同时用会不稳定。”
面试官可能追问:“为什么推理时不用 Dropout?” → 推理需要确定性输出——同一个输入应该每次都得到同样的结果。Dropout 的随机性只在训练时有用(正则化),推理时必须关闭。
Q20:PyTorch 的自动求导(Autograd)是如何工作的?
- 前向传播时:PyTorch 记录每一步操作,构建"计算图"
- 调用
.backward()时:从输出节点开始,沿计算图反向传播 - 每个节点:通过链式法则计算梯度
- 结果:存储在每个叶子节点的
.grad属性中
PyTorch 使用"动态图"策略——每次前向传播时实时构建计算图,支持 Python 的 if/for 控制流,调试方便。
面试时怎么讲:“PyTorch 自动求导:前向传播时构建计算图(记录每一步操作),调用 backward() 时沿图反向计算梯度。关键特点:动态图——每次前向传播实时构建,支持 if/for,调试方便。TensorFlow 1.x 是静态图(先定义图再执行),调试困难。”
面试官可能追问:“PyTorch 和 TensorFlow 的核心区别?” → PyTorch 用动态图(define by run),调试方便,适合研究。TensorFlow 2.x 也支持动态图,但 1.x 是静态图(define then run),部署更方便。现在两者差距在缩小。
Q21:Adam 优化器的原理?和 SGD 的区别?
Adam = Momentum + RMSProp:
- Momentum(一阶矩):累积历史梯度的均值,减少震荡
- RMSProp(二阶矩):累积历史梯度的方差,自适应调整每个参数的学习率
对于梯度一直很大的参数,学习率自动变小;对于梯度一直很小的参数,学习率自动变大。
| 优化器 | 特点 | 适用场景 |
|---|---|---|
| SGD | 简单、泛化好 | CV 任务 |
| Adam | 收敛快、对学习率不敏感 | NLP/Transformer 首选 |
| AdamW | Adam + 解耦权重衰减 | Transformer 训练标准 |
实操建议:CV 任务通常用 SGD+动量,泛化性更好;NLP/大模型通常用 AdamW,收敛更稳定。
Q22:混合精度训练的原理?为什么能节省显存?
大部分计算用 float16(快、省显存),关键操作(损失计算、梯度累积)保留 float32(准)。
以 7B 模型为例:
| 精度 | 模型参数显存 | 总显存 |
|---|---|---|
| float32 | 28 GB | ~112 GB |
| 混合精度 | ~18 GB | ~88 GB |
节省约 30% 显存,训练速度提升 2-3 倍,精度与 float32 持平。
实操建议:如果你在训练大模型,几乎必须用混合精度(PyTorch 的 torch.cuda.amp)。显存省 30%,速度快 2 倍,精度几乎无损。唯一注意:loss scaling 要开(PyTorch 的 GradScaler 自动处理)。
常见误区:以为混合精度只是"把 float32 换成 float16"。实际上需要保留关键操作的 float32(损失计算、梯度累积),否则会数值溢出。还需要 loss scaling(放大损失值)防止小梯度下溢为 0。
面试官可能追问:“什么是 loss scaling?” → float16 的最小正值约 $6 \times 10^{-8}$,很小的梯度会下溢为 0。Loss scaling 先把损失值放大(如 ×1024),梯度也跟着放大,更新前再缩回来。
3. Transformer 架构(第 3 篇)
Q23:Self-Attention 的计算过程?Q、K、V 分别代表什么?
Q(Query):每个词的"需求"——我在找什么信息 K(Key):每个词的"标签"——我能提供什么 V(Value):每个词的"内容"——我的实际信息
计算过程:
- $Q = X \cdot W_Q$,$K = X \cdot W_K$,$V = X \cdot W_V$(三个不同的线性变换)
面试时怎么讲:“Self-Attention 让每个词都能看到所有其他词。Q 是’我在找什么’,K 是’我能提供什么’,V 是’我的内容’。Q 和 K 点积得到相关性分数,Softmax 归一化后加权求和 V。除以根号 d_k 防止 Softmax 饱和。”
面试官可能追问:“为什么 Q/K/V 要用不同的权重矩阵?” → 如果用同一个矩阵,Q=K=V,注意力分数会退化为自相关。用不同的矩阵让模型能学习"需求"和"提供"的不同表示——就像搜索引擎的查询词(Q)和文档标题(K)是不同的东西。
- $\text{scores} = Q \cdot K^T$(计算每对词之间的相关性)
- $\text{scaled\_scores} = \text{scores} / \sqrt{d_k}$(缩放,防止 softmax 梯度消失)
- $\text{weights} = \text{softmax}(\text{scaled\_scores})$(归一化为概率分布)
- $\text{output} = \text{weights} \cdot V$(加权求和)
每个词的输出都是所有词的 Value 的加权和,权重由词与词之间的相关性决定。
Q24:为什么要除以 $\sqrt{d_k}$?不除会怎样?
当 $d_k$ 很大时,$Q \cdot K^T$ 的值可能很大。大的输入值会导致 softmax 输出接近 one-hot(如 0.982),梯度接近 0,训练停滞。
除以 $\sqrt{d_k}$ 让方差回到 1,softmax 的梯度正常。
| 方案 | 输入值 | Softmax 输出 | 梯度状态 |
|---|---|---|---|
| 不缩放 | [26, 18, 30, 22] | [0.018, 0.000, 0.982, 0.000] | 梯度很小 |
| 缩放(÷8) | [3.25, 2.25, 3.75, 2.75] | [0.276, 0.102, 0.455, 0.167] | 梯度正常 |
为什么点积的方差是 $d_k$? 假设 Q 和 K 的每一维独立同分布,均值 0 方差 1。点积 $q \cdot k = \sum_{i=1}^{d_k} q_i k_i$,每一项 $q_i k_i$ 的方差是 1(独立随机变量乘积的方差 = 方差之积 = 1×1 = 1)。$d_k$ 个独立项求和,方差相加:$\text{Var}(q \cdot k) = d_k$。除以 $\sqrt{d_k}$ 后:$\text{Var}(q \cdot k / \sqrt{d_k}) = d_k / d_k = 1$。
常见误区:很多人以为除以 $\sqrt{d_k}$ 是为了"数值稳定性"(防止溢出)。实际上浮点数精度足够处理这些数值,真正的问题是 Softmax 的梯度——当输入值方差很大时,Softmax 会进入饱和区,梯度接近零,训练停滞。
面试时怎么讲:“Q 和 K 的每一维是均值 0 方差 1 的随机变量,点积是 $d_k$ 项求和,方差变成 $d_k$。当 $d_k=64$ 时,点积的典型值可能在 [-16, 16] 范围,Softmax 会输出接近 one-hot 的分布。除以 $\sqrt{d_k}$ 把方差压回 1,让 Softmax 输出更均匀,梯度正常。”
Q25:多头注意力的作用?为什么不用一个大的注意力头?
单头注意力只能学到一种"注意力模式"。多头注意力的每个头学习不同的"关系检测器":
- Head 1 可能学到指代关系(“it"指代"animal”)
- Head 2 可能学到修饰关系(“tired"修饰"animal”)
- Head 3 可能学到因果关系(“didn’t cross"和"tired"有因果)
就像 CNN 中多个卷积核分别检测竖线、横线、斜线一样。
常见误区:以为头数越多越好。实际上头数过多会导致每个头的 $d_k$ 太小($d_k = d_{\text{model}} / n_{\text{heads}}$),每个头的表达能力下降。BERT-base 用 12 头($d_k=64$),LLaMA-7B 用 32 头($d_k=128$)——头数和维度需要平衡。
面试时怎么讲:“单头注意力只能学到一种关注模式,比如语法关系。多头注意力让模型同时从多个角度理解——一个头关注语法,一个头关注语义,一个头关注指代。最后拼接起来,信息更丰富。就像 CNN 用多个卷积核检测不同边缘一样。”
Q26:位置编码的作用?为什么 Transformer 需要位置信息?
Self-Attention 是"位置无关"的——“狗咬人"和"人咬狗"在 Self-Attention 的计算中完全一样。但它们的意思完全不同。
位置编码额外告诉模型"每个词在哪个位置”,让模型能够区分词序。
常见误区:以为位置编码是"加到词向量上"的固定值。实际上正弦位置编码是固定的,但可学习的位置编码(如 BERT 用的)是训练出来的。RoPE 更特殊——它乘到 Q/K 上,不加到输入上。
面试官可能追问:“RoPE 和正弦位置编码的区别?” → 正弦编码加到输入上(绝对位置),RoPE 乘到 Q/K 上(相对位置)。RoPE 的关键优势:注意力分数只依赖相对位置 $(n-m)$,支持长度外推。LLaMA/Qwen/Mistral 都用 RoPE。
Q27:正弦位置编码的设计原理?为什么用 sin/cos?
$$ PE(pos, 2i) = \sin(pos / 10000^{2i/d}), \quad PE(pos, 2i+1) = \cos(pos / 10000^{2i/d}) $$三个巧妙原因:
- 每个位置有唯一的编码:sin/cos 的组合可以唯一标识每个位置
- 相对距离可用线性变换表示:$PE(pos+k)$ 可以用 $PE(pos)$ 的线性变换得到
- 可以外推到更长的序列:正弦函数是周期性的,可以计算任意位置
实操建议:如果你在训练新模型,用 RoPE 替代正弦编码(LLaMA/Qwen 都用它)。如果你在用 BERT/GPT-2,它已经是正弦编码了,不需要改。
面试时怎么讲:“正弦位置编码用 sin/cos 函数给每个位置一个唯一编码。三个巧妙之处:每个位置唯一、相对距离可以用线性变换表示、可以外推到更长序列。但现代模型已改用 RoPE(相对位置,效果更好)。”
面试官可能追问:“为什么底数选 10000?” → 这是一个经验选择。10000 的幂次可以产生从高频到低频的正弦波——低维度变化快(捕捉近距离关系),高维度变化慢(捕捉远距离关系)。
Q28:Encoder 和 Decoder 的区别?
| 特性 | Encoder | Decoder |
|---|---|---|
| 作用 | “理解”——读懂输入 | “写作”——生成输出 |
| 注意力 | Self-Attention(双向,所有位置互相看) | Masked Self-Attention(单向,只能看前面) + Cross-Attention |
| 输入 | 完整的输入序列 | 已生成的部分序列 + Encoder 的输出 |
| 代表模型 | BERT | GPT |
常见误区:以为 Encoder 和 Decoder 的区别只是"双向 vs 单向”。实际上 Decoder 还有 Cross-Attention(从 Encoder 获取信息)和 Masked Attention(遮盖未来位置)。这就是为什么 Decoder 适合生成——它能同时看输入和已生成的内容。
面试时怎么讲:“Encoder 双向理解(BERT),Decoder 单向生成(GPT)。Decoder 额外有 Masked Attention(遮盖未来)和 Cross-Attention(看 Encoder 输出)。现代趋势是 Decoder-only 统一一切。”
面试官可能追问:“有没有同时用 Encoder 和 Decoder 的模型?” → T5、BART 是 Encoder-Decoder 架构,适合翻译、摘要等"输入→输出"任务。现代趋势是 Decoder-only(GPT、LLaMA),因为它更简单且 scaling law 更好。
Q29:Masked Self-Attention 的作用?为什么要遮盖未来位置?
训练时我们知道完整的译文,但不能让模型"偷看"未来的词。如果不加 Mask,模型会直接抄答案,什么都学不到。
实现方式:将未来位置的注意力分数设为 $-\infty$,softmax 后变为 0。
常见误区:以为 Masked Attention 是"遮盖已生成的词"。实际上恰恰相反——遮盖的是"未来还没生成的词",让模型只能看前面已生成的内容。
面试官可能追问:“Mask 是在训练时还是推理时用?” → 训练时必须用(因为训练数据是完整的,不遮盖会偷看答案)。推理时不需要显式 Mask——因为生成是逐词的,每次输入只包含已生成的词,天然看不到未来。
Q30:Cross-Attention 是什么?Q、K、V 分别来自哪里?
- Q 来自 Decoder(“我在找什么信息?")
- K 和 V 来自 Encoder(“源语言提供了什么信息?")
这让 Decoder 在生成每个译文词时,都能"回头看"原文的相关部分——这就是"注意力对齐”。
面试官可能追问:“Cross-Attention 和 Self-Attention 的计算有什么区别?” → 计算方式完全一样(Q·K^T → Softmax → ·V),区别在于 Q 来自 Decoder,K/V 来自 Encoder。Self-Attention 的 Q/K/V 都来自同一个序列。
Q31:残差连接和 LayerNorm 的作用?
残差连接:$y = F(x) + x$,保留原始信息 + 新学到的信息。来自 ResNet 的智慧,让梯度可以"跳过"层。
LayerNorm:对同一样本的不同维度做归一化,稳定数值范围。用 LayerNorm 而非 BatchNorm 的原因:NLP 中每个句子长度不同,BatchNorm 的统计量不稳定。
常见误区:以为残差连接是"可选的优化”。实际上没有残差连接,深层 Transformer 根本训不动——梯度会指数衰减。残差连接是 Transformer 能堆叠到 96 层(GPT-3)的关键。
面试官可能追问:“LayerNorm 放在哪里?Pre-LN 还是 Post-LN?” → Pre-LN(注意力/FFN 之前)训练更稳定,GPT-3、LLaMA 都用。Post-LN(之后)是原始 Transformer 的做法,需要 warmup。
Q32:FFN(前馈网络)的作用?为什么升维 4 倍?
FFN 对每个位置独立做非线性变换:$\text{FFN}(x) = \text{ReLU}(x \cdot W_1) \cdot W_2$
升维 4 倍(512→2048)的原因:在高维空间中做非线性变换,可以画出更复杂的"分类边界",再投影回原维度。
Attention vs FFN 的分工:
- Attention:收集信息(“看看别人说了什么”)
- FFN:处理信息(“想想自己该怎么理解”)
常见误区:以为 FFN 只是"升维再降维"的线性变换。实际上中间有激活函数(ReLU 或 SwiGLU)——没有激活函数,两次线性变换可以合并为一次,升维就失去意义了。
面试时怎么讲:“FFN 对每个位置独立做非线性变换。先升维 4 倍,增加表达能力,再降回原维度。Attention 负责收集信息,FFN 负责处理信息——两者交替堆叠。”
Q33:LayerNorm 和 BatchNorm 的区别?为什么 Transformer 用 LayerNorm?
| 特性 | BatchNorm | LayerNorm |
|---|---|---|
| 归一化维度 | 跨 batch(同一特征在不同样本上归一化) | 跨特征(同一样本在不同维度上归一化) |
| 依赖 batch size | 是 | 否 |
| 适合变长序列 | 不适合 | 适合 |
Transformer 用 LayerNorm 的原因:NLP 中每个句子长度不同、每个 token 的含义不同,用 LayerNorm 更合适。所以 BatchNorm 在 batch 较小时统计量不稳定(均值和方差估计不准),而 LayerNorm 可以稳定地在任意 batch size 下工作(甚至 batch size=1 也能正常归一化)。
常见误区:以为 LayerNorm 和 BatchNorm 的区别只是"归一化的维度不同"。实际上核心区别是对 batch size 的依赖——BatchNorm 需要统计整个 batch 的均值和方差,batch 小时估计不准;LayerNorm 每个样本独立计算,与 batch size 无关。
*实操建议:CV 用 BatchNorm(batch size 大,图像数据分布稳定);NLP/序列任务用 LayerNorm(batch size 小,序列长度不一);视觉 Transformer(ViT)也用 LayerNorm。*这就是为什么 Transformer(batch size 通常较小)必须用 LayerNorm。
Q34:Transformer 的计算复杂度是多少?和 RNN 相比如何?
| 特性 | RNN | Transformer |
|---|---|---|
| 计算复杂度 | $O(n \cdot d^2)$ | $O(n^2 \cdot d)$ |
| 长距离依赖 | 困难(梯度消失) | 容易(直接连接) |
| 并行计算 | 不可(串行) | 可以(所有位置同时) |
| 训练速度 | 慢 | 快(10-100 倍) |
当 $n < d$ 时 Transformer 更快。大多数 NLP 任务中 $d=512$,$n$ 通常 < 512,所以 Transformer 更优。
常见误区:以为 Transformer 总是比 RNN 快。实际上当序列长度 $n$ 很大时(如 $n=100000$),$O(n^2)$ 的注意力计算会成为瓶颈——这就是为什么长序列需要 Flash Attention、稀疏注意力等优化技术。
实操建议:短序列(<512)→ Transformer 快且效果好;长序列(>4096)→ 需要 Flash Attention 或稀疏注意力;超长序列(>100K)→ 考虑 Mamba(线性注意力)或 Longformer。
面试官可能追问:“Flash Attention 是什么?” → Flash Attention 通过分块计算和避免存储完整的 $n \times n$ 注意力矩阵,把显存从 $O(n^2)$ 降到 $O(n)$,同时利用 GPU 的 SRAM 缓存加速计算。不是改变注意力的数学,而是改变计算的实现方式。
4. 预训练语言模型(第 4 篇)
Q35:BERT 和 GPT 的核心区别?分别适合什么任务?
| 特性 | BERT | GPT |
|---|---|---|
| 架构 | Transformer Encoder | Transformer Decoder |
| 方向 | 双向(同时看前后文) | 单向(只看前面的词) |
| 训练目标 | 遮盖词预测(MLM) | 预测下一个词(自回归) |
| 擅长任务 | 理解类(分类、NER、问答) | 生成类(文本生成、对话) |
BERT 像"阅读理解"——读完全文再回答。GPT 像"写作"——一个字一个字地写。
面试时怎么讲:“BERT 是双向 Encoder,适合理解任务(分类、NER)。GPT 是单向 Decoder,适合生成任务(对话、写作)。核心区别:BERT 能看到前后文,GPT 只能看前面。所以 BERT 理解更好,GPT 生成更好。”
实操建议:分类任务用 BERT 更方便;生成任务首选 GPT。微调成本 BERT 更低(参数量小)。
常见误区:以为 BERT 和 GPT 可以互换。实际上 BERT 不能做自回归生成(训练时每个位置都能看到全文),GPT 不能做双向理解(训练时只能看前面)。用 BERT 做生成或用 GPT 做分类都是"大材小用"或效果不好。
Q36:BERT 的 MLM(遮盖语言模型)预训练任务是怎么做的?
随机遮盖 15% 的词,让模型预测被遮盖的词。
15% 被选中词的处理策略(80/10/10 规则):
- 80% 替换为 [MASK]:让模型学习"根据上下文填空"
- 10% 替换为随机词:迫使模型不能只依赖 [MASK] 标记
- 10% 保持原词不变:让模型学习"判断每个词是否正确"
常见误区:以为 BERT 训练时总是看到 [MASK] 标记。实际上只有 80% 的被选中词用 [MASK],10% 用随机词,10% 保持原词——这让模型无法投机取巧,必须真正理解语言。
面试官可能追问:“为什么不用 100% [MASK]?” → 如果 100% 用 [MASK],模型会学到"只在看到 [MASK] 时才预测"的捷径。混合策略让模型对每个位置都需要理解上下文。
Q37:BERT 的 NSP(下一句预测)任务的作用?
给模型两个句子,判断它们是否是连续的。
- 正例:“他去超市买了牛奶。” + “然后回家做早餐。” → IsNext
- 负例:“他去超市买了牛奶。” + “今天天气很好。” → NotNext
让模型学到"句子之间的逻辑关系",对问答、推理等任务有帮助。
常见误区:以为 NSP 很重要。实际上 RoBERTa 论文证明 NSP 对性能提升不大,甚至可能有害。后来的模型(如 RoBERTa、LLaMA)都去掉了 NSP,只用 MLM。
面试官可能追问:“为什么 NSP 没用?” → NSP 太简单了——模型可能只学到"两个句子是否来自同一篇文档"的表面特征(如主题一致性),而不是真正的语言理解。
Q38:GPT 的自回归生成过程?每次生成一个 token 时在做什么?
- 输入已有的文本(如"I love")
- 模型输出下一个词的概率分布(如 “AI”=53.2%, “the”=9.7%)
- 采样(或取 argmax)选择一个词(如"AI")
- 将"AI"拼接到输入 → “I love AI”
- 重复步骤 2-4,直到生成结束标记
每次生成都要重新计算整个序列的注意力(新 token 需要看到前面所有 token),所以生成 100 个 token 需要 100 次前向传播。
常见误区:以为 GPT 生成时每次只看上一个词。实际上 GPT 用 Masked Self-Attention,每个新 token 可以看到前面所有 token(不只是上一个)。这就是为什么 GPT 能保持上下文连贯。
面试时怎么讲:“GPT 逐词生成:输入已有文本,模型输出下一个词的概率分布,采样选一个词,拼回去继续。训练时所有位置同时算 loss(并行),推理时必须逐词生成(串行)。”
面试官可能追问:“GPT 的训练和推理有什么区别?” → 训练时用 teacher forcing(所有位置同时计算 loss,并行);推理时必须逐词生成(串行)。这就是为什么训练比推理快得多——训练一次前向传播处理整个序列,推理生成 n 个词需要 n 次前向传播。
Q39:什么是预训练+微调范式?为什么有效?
预训练:在海量无标注文本上学习通用语言表示(语法、语义、世界知识)。
微调:在少量标注数据上适配特定任务。
面试时怎么讲:“预训练+微调就是’先学通用语言,再学特定任务’。预训练在海量文本上学语法、语义、世界知识;微调用少量标注数据适配具体任务。学习率要小(2e-5),避免灾难性遗忘。”
有效的三个原因:
- 预训练学到了通用语言表示——不管什么任务都需要理解语言
- 迁移学习——学过英语的人学法语更容易
- 小学习率避免灾难性遗忘——保留预训练知识,缓慢适应新任务
常见误区:以为预训练+微调总是最好的。实际上如果目标任务与预训练数据差异很大(如医学文本),微调效果可能不如从头训练。另外微调学习率过大(如 1e-3)会导致灾难性遗忘——预训练知识被覆盖,模型在新任务上表现反而更差。
实操建议:数据少+任务简单 → 提示词工程;数据少+任务复杂 → LoRA;数据多+任务复杂 → 全量微调。微调学习率:2e-5 到 5e-5,不要超过 1e-4。
面试官可能追问:“全量微调 vs LoRA vs 提示词工程,怎么选?” → 数据少+任务简单 → 提示词工程;数据少+任务复杂 → LoRA;数据多+任务复杂 → 全量微调。优先级:先试提示词工程 → 其次 LoRA → 最后全量微调。
Q40:什么是 Tokenizer?BPE 分词算法的原理?
Tokenizer 把人类的文字翻译成计算机的数字。
**BPE(Byte Pair Encoding)**的原理:
- 初始化:每个字符为一个 token
- 统计所有相邻字符对的出现频率
- 合并频率最高的对(如 e+s → es)
- 重复步骤 2-3,直到达到目标词表大小
优点:词表大小适中(3-5 万),能处理任何未登录词(总能拆成子词)。
面试时怎么讲:“BPE 分词:先把每个字符当 token,然后不断合并出现频率最高的字符对。比如 ’e’ 和 ’s’ 经常一起出现,就合并成 ’es’。重复直到词表够大。优点:词表适中,能处理任何未登录词。”
常见误区:以为 BPE 分词是"按词切分"。实际上 BPE 是按子词切分——“unhappiness” 可能被切成 “un”+“happi”+“ness”。这就是为什么 LLM 能处理任何未登录词——总能拆成已知的子词。
面试官可能追问:“不同模型的分词器可以互换吗?” → 不可以。每个模型用自己的词表训练 BPE,同一个词在不同模型中可能被切成不同的子词。用错分词器会导致乱码或性能下降。
Q41:HuggingFace 的 Pipeline 是什么?
Pipeline 是 HuggingFace 的一行代码推理接口,自动完成预处理、模型加载、后处理:
from transformers import pipeline
classifier = pipeline('sentiment-analysis')
result = classifier("I love this movie!")
# [{'label': 'POSITIVE', 'score': 0.9998}]
支持的任务包括:情感分析、文本生成、问答、NER、零样本分类等。
面试官可能追问:“Pipeline 和直接加载模型有什么区别?” → Pipeline 自动处理了分词、后处理、设备分配等细节,一行代码就能用。直接加载模型需要手动处理这些,但更灵活。生产环境通常用直接加载,快速原型用 Pipeline。
Q42:什么是 Embedding?为什么文本需要转换为向量?
Embedding 把文本转换为固定长度的数字向量。语义相似的文本 → 向量接近(余弦相似度接近 1)。
原因:计算机只能处理数字。把现实世界的东西(图片、文字、声音)转换为向量,就是"表示学习"的核心任务。
常见误区:以为同一个词在所有上下文中的 Embedding 都一样。实际上 Word2Vec/GloVe 确实是静态的(同一个词一个向量),但 BERT/GPT 的 Embedding 是上下文相关的——“bank"在"river bank"和"bank account"中的向量不同。
面试官可能追问:“Embedding 的维度怎么选?” → 常见:128(小模型)、256(中等)、768(BERT-base)、1024(BERT-large)、1536(OpenAI text-embedding-3-small)。维度越大表达能力越强,但计算和存储成本也越高。
Q43:BERT 的 [CLS] token 有什么用?
[CLS] 放在句子开头,用于分类任务的输出。BERT 的最后一层在 [CLS] 位置的输出向量被当作整个句子的"摘要表示”,接一个线性层就能做分类。
常见误区:以为 [CLS] 的输出天然就是句子的"最佳表示"。实际上 [CLS] 只是通过 Self-Attention 聚合了所有位置的信息——它的质量取决于预训练任务。BERT 的 MLM 任务让每个 token 都学会理解上下文,[CLS] 自然也学到了。
面试官可能追问:“为什么不用所有 token 的平均值做句子表示?” → 可以,而且在某些任务上效果更好(如 Sentence-BERT)。[CLS] 的优势是它在预训练时就被"训练"为句子级别的表示,但平均池化(mean pooling)在语义相似度任务上通常更稳定。
Q44:三种 Transformer 架构(Encoder-only、Decoder-only、Encoder-Decoder)的区别和代表模型?
| 架构 | 代表模型 | 注意力方式 | 擅长任务 |
|---|---|---|---|
| Encoder-only | BERT, RoBERTa | 双向(全连接) | 理解、分类、NER |
| Decoder-only | GPT, LLaMA | 单向(因果 Mask) | 生成、对话 |
| Encoder-Decoder | T5, BART | 编码双向 + 解码单向 | 翻译、摘要 |
实操建议:理解类任务(分类、NER、问答)→ Encoder-only(BERT);生成类任务(对话、写作)→ Decoder-only(GPT/LLaMA);输入→输出任务(翻译、摘要)→ Encoder-Decoder(T5)。现代趋势是 Decoder-only 统一一切。
面试时怎么讲:“三种架构:Encoder-only(BERT,双向,擅长理解)、Decoder-only(GPT,单向,擅长生成)、Encoder-Decoder(T5,擅长翻译摘要)。现代趋势是 Decoder-only 统一一切——因为架构更简单,scaling law 更好。”
实操建议:理解类任务(分类、NER、问答)→ Encoder-only(BERT);生成类任务(对话、写作)→ Decoder-only(GPT/LLaMA);输入→输出任务(翻译、摘要)→ Encoder-Decoder(T5)。现代趋势是 Decoder-only 统一一切。
面试官可能追问:“为什么现代大模型都是 Decoder-only?” → ① 架构更简单(只有 Masked Self-Attention + FFN);② Scaling law 更好(同样的参数量,Decoder-only 效果更好);③ 统一接口(理解和生成都用同一个模型)。
5. LLaMA 架构(第 5 篇)
Q45:LLaMA 相比原始 Transformer 有哪些改进?
| 改进 | 替代了什么 | 解决的问题 | 效果 |
|---|---|---|---|
| RMSNorm | LayerNorm | 归一化计算量大 | 计算减少 ~15% |
| RoPE | 正弦位置编码 | 绝对位置,外推差 | 支持相对位置,长序列友好 |
| SwiGLU | ReLU FFN | 表达能力有限 | 基准测试提升 |
| KV Cache | 无缓存 | 重复计算 K/V | 推理加速 seq_len 倍 |
| GQA | MHA/MQA | KV Cache 显存大 | 显存减少 ~4 倍 |
常见误区:以为 LLaMA 的 5 大改进是"全新的发明"。实际上 RMSNorm(2019)、RoPE(2021)、SwiGLU(2020)、KV Cache(2019)、GQA(2023)都是独立提出的改进。LLaMA 的贡献是把这些改进组合在一起,证明了"小模型+更多数据+更好架构"比"大模型+少数据"更有效。
面试官可能追问:“LLaMA 和 GPT 的核心区别?” → 架构类似(都是 Decoder-only),但 LLaMA 用了 RMSNorm+RoPE+SwiGLU+GQA,GPT-3 用的是 LayerNorm+正弦编码+ReLU+MHA。LLaMA 是开源的,GPT 是闭源的。
Q46:RMSNorm 和 LayerNorm 的区别?为什么 RMSNorm 更快?
| LayerNorm(4 步) | RMSNorm(3 步) |
|---|---|
| 1. 计算均值 | 1. 计算均方根 |
| 2. 计算方差 | 2. 归一化 |
| 3. 归一化 | 3. 缩放 |
| 4. 缩放 + 偏置 | — |
RMSNorm 去掉了"减均值"和"偏置"。实验发现效果差别很小,但计算量减少约 15%。
面试时怎么讲:“RMSNorm 比 LayerNorm 少一步减均值,只做归一化+缩放。实验发现效果几乎一样,但计算省 15%。LLaMA、Qwen 都用 RMSNorm。”
实操建议:如果你在训练自己的模型,用 RMSNorm 替代 LayerNorm 可以省 15% 计算且效果不变。如果你在用别人的模型(如 LLaMA),不需要改——它已经是 RMSNorm 了。
面试官可能追问:“RMSNorm 在什么情况下不如 LayerNorm?” → 当输入分布严重偏移时(如训练初期或数据分布变化大),LayerNorm 的"减均值"操作可以更好地稳定数值。但实践中这种场景很少见。
Q47:RoPE 旋转位置编码的原理?和传统位置编码的区别?
RoPE 把词向量的每两个维度看作一个二维平面上的点,位置 $m$ 的词向量旋转 $m \times \theta$ 角度。
关键性质:注意力分数只依赖于相对位置 $(n-m)$,而不是绝对位置。
| 特性 | 正弦位置编码 | RoPE |
|---|---|---|
| 编码方式 | 加到输入上 | 乘到 Q/K 上 |
| 位置类型 | 绝对位置 | 相对位置 |
| 外推能力 | 有限 | 较好 |
实操建议:如果你在训练新模型,用 RoPE(LLaMA/Qwen/Mistral 都用它)。如果你在用别人的模型,不需要改——它已经是 RoPE 了。RoPE 的外推能力可以通过 NTK-aware scaling 进一步增强。
Q48:SwiGLU 激活函数的特点?和 ReLU 的区别?
SwiGLU = Swish + GLU(门控线性单元):
$$ \text{FFN}(x) = (\text{Swish}(x \cdot W_1) \odot x \cdot W_3) \cdot W_2 $$$W_3$ 产生的值像一个"阀门",控制 $W_1$ 的信息通过多少。不像 ReLU 的"硬开关",SwiGLU 是"可调节的阀门"。
实操建议:SwiGLU 已成为现代大模型的标配(LLaMA、Qwen、Mistral 都用它)。如果你在训练新模型,用 SwiGLU 替代 ReLU FFN 可以提升效果,代价是参数量略增(3 个权重矩阵 vs 2 个)。
Q49:KV Cache 的作用?为什么能加速推理?显存开销怎么算?
自回归生成时,每个新 token 都需要计算所有位置的 K 和 V。KV Cache 把之前算过的 K 和 V 缓存起来,下次直接复用。
效果:每个新 token 只需要 1 次前向传播(而不是 seq_len 次),推理速度提升 seq_len 倍。
显存公式:$2 \times \text{层数} \times \text{头数} \times d_k \times \text{序列长度} \times \text{精度字节数}$
LLaMA-7B 单条序列约 1GB,LLaMA-70B(GQA 8 KV 头)约 1.3GB。
常见误区:以为 KV Cache 只加速"注意力计算"($Q \cdot K^T$)。实际上 KV Cache 省掉的是重复的 K/V 线性投影($X \cdot W_K$ 和 $X \cdot W_V$),注意力本身的 $Q \cdot K^T$ 计算仍然需要遍历所有缓存位置。另一个误区:以为 KV Cache 的显存开销可以忽略——当序列长度很长(如 128K)或 batch size 很大时,KV Cache 会成为显存瓶颈,这就是 GQA 和 MQA 的动机。
面试时怎么讲:“自回归生成每个新 token 时,需要计算所有位置的 K 和 V。KV Cache 把之前算过的缓存起来,下次直接复用——省掉了重复的线性投影。代价是显存:LLaMA-7B 单条约 1GB,长序列时会成为瓶颈。”
Q50:GQA(分组查询注意力)和 MHA、MQA 的区别?
| 方案 | Q 头数 / K 头数 / V 头数 | 特点 |
|---|---|---|
| MHA | 32 / 32 / 32 | 质量最好,KV Cache 最大 |
| MQA | 32 / 1 / 1 | KV Cache 最小,质量下降明显 |
| GQA | 32 / 8 / 8 | 每 4 个 Q 头共享一组 KV,质量接近 MHA,速度接近 MQA |
GQA 让 KV Cache 减小约 4 倍(7B:32 Q 头 / 8 KV 组)至 8 倍(70B:64 Q 头 / 8 KV 组),同时模型质量几乎不变。
面试时怎么讲:“MHA 每个 Q 头有独立的 KV,质量最好但 Cache 最大。MQA 所有 Q 共享一个 KV,Cache 最小但质量差。GQA 折中——每 4 个 Q 共享一组 KV,质量接近 MHA,速度接近 MQA。”
实操建议:部署大模型时,如果显存紧张,优先检查是否可以用 GQA。LLaMA-2 和 LLaMA-3 已经默认用 GQA,不需要额外配置。
面试官可能追问:“MHA → MQA → GQA 的演进逻辑是什么?” → MHA 质量最好但 KV Cache 太大 → MQA 极端压缩(所有 Q 共享 1 个 KV)但质量下降 → GQA 折中(每 4 个 Q 共享 1 组 KV),质量接近 MHA,速度接近 MQA。
Q51:Temperature、Top-K、Top-P 采样策略的区别?
Temperature:控制输出的"随机性"。T 越小分布越尖锐(确定),T 越大分布越平坦(随机)。
Top-K:只从概率最高的 K 个词中采样。K=1 等价于贪心搜索。
Top-P(Nucleus Sampling):按概率从高到低排序,累加直到概率之和超过 P。动态调整候选集大小。
| 场景 | Temperature | Top-P |
|---|---|---|
| 代码生成 | 0.0 | 1.0 |
| 一般对话 | 0.7 | 0.9 |
| 创意写作 | 1.0 | 0.95 |
实操建议:代码生成用 Temperature=0(确定性输出,保证正确性);一般对话用 0.7+0.9(平衡);创意写作用 1.0+0.95(多样性)。不要同时设 Temperature 很低和 Top-P 很低——会退化为贪心搜索。
面试官可能追问:“Top-K 和 Top-P 哪个更好?” → Top-P 更好——它根据概率分布动态调整候选集大小。Top-K 的问题是 K 固定,简单问题和复杂问题用同一个 K。实际中通常用 Top-P=0.9 或 0.95。
Q52-54:为什么 LLaMA 用 RMSNorm/RoPE/SwiGLU?
这三个问题的答案都是"问题→方案→代价"分析:
RMSNorm:LayerNorm 计算量大(需要减均值)→ RMSNorm 去掉减均值 → 计算减少 15%,效果几乎不变
RoPE:正弦位置编码只编码绝对位置、外推差 → RoPE 编码相对位置 → 支持长序列,但计算稍复杂
SwiGLU:ReLU 表达能力有限(硬开关)→ SwiGLU 用门控机制 → 基准测试提升,但参数量增加约 50%(用 8/3d 隐藏维度补偿)
面试官可能追问:“为什么不直接用 ReLU?” → ReLU 的"硬开关"(负值全清零)会丢失信息。SwiGLU 的门控是"可调节的阀门",对每个维度独立控制通过量。实验发现 SwiGLU 在所有基准测试上都优于 ReLU。
6. LLM 应用开发(第 6 篇)
Q55:什么是 RAG(检索增强生成)?为什么需要它?
大模型有三大硬伤:知识截止日期、幻觉、无法访问私有数据。
RAG 的解决方案:先帮大模型"查资料",再让它"基于资料回答"。知识可以实时更新,减少幻觉,可以访问私有数据。
面试时怎么讲:“大模型有三大硬伤:知识截止、幻觉、不能访问私有数据。RAG 的方案:先检索相关文档,再让模型基于文档回答。就像开卷考试——不让模型’凭记忆’,而是’查资料’后回答。”
常见误区:以为 RAG 可以完全消除幻觉。实际上如果检索到的文档不相关或有错误,模型仍然会生成错误答案。RAG 的效果高度依赖检索质量——“garbage in, garbage out”。
面试官可能追问:“RAG 的最大挑战是什么?” → ① 检索质量(不相关的文档会误导模型);② chunk_size 选择(太大不精确,太小丢失上下文);③ 多跳推理(需要综合多个文档才能回答的问题)。
实操建议:如果你的知识库更新频繁(如产品文档)→ RAG;如果需要深度适配专业领域(如医学术语)→ 微调;如果只是简单的格式或风格调整 → 提示词工程。优先级:提示词工程 → RAG → 微调。
面试官可能追问:“RAG 和微调哪个更好?” → 没有绝对的好坏。RAG 适合知识频繁更新、需要引用来源的场景;微调适合需要深度适配的场景。实际中常常两者结合:微调让模型更好地理解检索到的内容,RAG 提供最新的知识。
Q56:提示词工程的核心技巧?结构化提示词的四要素?
四要素:
- 角色:告诉模型"你是谁"(如"你是一位资深 Python 工程师")
- 任务:告诉模型"做什么"(如"写一个 FastAPI 接口")
- 格式:告诉模型"怎么输出"(如"输出完整的 Python 代码")
- 约束:告诉模型"边界在哪"(如"使用异步函数,返回 JSON 格式")
面试官可能追问:“提示词越长效果越好吗?” → 不是。提示词太长会稀释关键信息(“Lost in the Middle"现象),且增加 token 费用。最佳实践:精炼、结构化、只包含必要信息。
Q57:什么是 Chain of Thought(思维链)?为什么能提升推理能力?
在提示词中加一句"让我们一步一步思考”,模型会展示中间推理步骤。
原因:激活了模型的"慢思考"模式,被迫展示中间步骤,减少了"跳步"导致的错误。类似于人类"打草稿"比"心算"更准确。
常见误区:以为 CoT 对所有任务都有用。实际上 CoT 主要对需要推理的任务(数学、逻辑、多步决策)有效。对简单的事实检索(如"法国的首都是什么?")反而会降低效率——不需要推理,直接回答就好。
面试官可能追问:“CoT 和 Few-shot 可以同时用吗?” → 可以,而且效果通常更好。在 Few-shot 的示例中展示推理过程(如"第 1 步…第 2 步…所以答案是…"),模型会学到"先推理再回答"的模式。
Q58:Few-shot 和 Zero-shot 的区别?
- Zero-shot:直接让模型做任务,不给示例
- Few-shot:给几个示例,让模型学会模式
Few-shot 的关键:示例的质量和多样性很重要,至少 2-3 个正例和 2-3 个反例。
实操建议:大多数任务先试 Zero-shot,效果不好再加 Few-shot。Few-shot 的示例要覆盖边界情况(如正例+反例+模糊案例)。如果 Few-shot 也不够,考虑微调。
面试官可能追问:“Few-shot 的示例顺序会影响结果吗?” → 会。研究表明示例的顺序、数量、质量都会影响输出。最佳实践:最后一个示例与当前输入最相似(近因效应)。
Q59:LangChain 的核心组件有哪些?
- LLM 调用:统一接口(支持 OpenAI、本地模型、各种 API)
- 提示模板:结构化、可复用的提示词
- 链(Chain):LCEL 管道语法,组合多个组件
- 文档加载与向量存储:PDF/Markdown 解析 + 向量搜索
- RAG 链:检索增强生成的标准实现
- Agent:让模型自主决策
常见误区:以为 LangChain 是必须的。实际上如果你只需要简单的 LLM 调用,直接用 OpenAI SDK 就够了。LangChain 的价值在于复杂的链式调用和 RAG 管道——简单场景用它反而增加复杂度。
面试官可能追问:“LangChain 的最大问题是什么?” → ① 抽象层太多(调试困难);② 版本更新太快(API 经常变);③ 性能开销(中间层增加了延迟)。简单场景建议直接用 SDK。*
Q60:LCEL 管道语法是什么?
LangChain Expression Language,用 | 把组件串联起来:
chain = template | llm | StrOutputParser()
类比 Unix 管道:cat file | grep "error" | sort
常见误区:以为 LCEL 只是语法糖。实际上 LCEL 自动处理了异步、批处理、流式输出、错误重试等复杂逻辑——手动实现这些需要大量代码。
面试官可能追问:“LCEL 和普通函数调用有什么区别?” → LCEL 的
|运算符会自动组合组件的输入/输出类型,支持异步(ainvoke)、批处理(batch)、流式(astream),且可以可视化调试(chain.get_graph())。
Q61:Embedding 的作用?如何计算文本相似度?
Embedding 把文本转换为固定长度的数字向量。语义相似的文本向量接近。
余弦相似度:$\cos(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{|\mathbf{a}| \cdot |\mathbf{b}|}$
值域 [-1, 1],越接近 1 越相似。
面试官可能追问:“余弦相似度和欧氏距离有什么区别?” → 余弦相似度只看方向(夹角),不看大小;欧氏距离同时看方向和大小。文本相似度通常用余弦相似度(因为文本向量的长度不重要,方向才重要)。
Q62:什么是 Function Calling?大模型如何使用外部工具?
Function Calling 让大模型能够"使用工具"。工作流程:
- 用户提问 → 大模型分析,判断需要调用哪个工具
- 大模型生成工具调用指令(函数名 + 参数)→ 外部系统执行
- 工具返回结果 → 大模型整合结果生成回答
关键理解:大模型不直接执行工具,它只是"决策者"。
面试时怎么讲:“Function Calling 三步:① 定义工具(告诉模型有哪些函数可用);② 模型决策(分析问题,输出函数名+参数);③ 外部执行(你自己的代码执行函数,结果返回模型)。模型不执行工具,只决策。”
面试官可能追问:“Function Calling 和 MCP 的区别?” → Function Calling 是各家的"方言"(OpenAI、Anthropic 格式不同),MCP 是统一的"普通话"。MCP 有三大能力:Tools(工具)、Resources(资源)、Prompts(提示模板)。实际中 MCP 正在逐步替代各家的 Function Calling。
Q63:ChatGLM 和 Qwen3 的特点?
ChatGLM:智谱 AI 开发,中文能力强,支持 Function Calling,128K 上下文。
Qwen3:阿里云开发,多尺寸可选(0.6B-72B),深度思考模式(类似 o1),混合推理(简单问题快速模式,复杂问题深度思考)。
实操建议:中文场景优先试 Qwen3(中文能力强,开源);英文场景用 LLaMA/Mistral;需要 Function Calling 用 ChatGLM 或 Qwen3。选模型时先看任务需求,再看参数量。
面试官可能追问:“开源模型和闭源模型怎么选?” → 数据敏感 → 开源模型(本地部署);追求效果 → 闭源模型(GPT-4、Claude);预算有限 → 开源小模型 + LoRA 微调。
Q64:流式输出(Streaming)的原理和优势?
普通输出:等模型生成全部内容后一次性返回 → 用户等待时间长。
流式输出:模型每生成一个 token 就立即返回 → 用户看到文字逐字出现。
底层通过 SSE(Server-Sent Events)或 chunked transfer encoding 实现。
常见误区:以为流式输出会加速生成。实际上流式输出不改变模型的生成速度——总时间是一样的。它只是改善了用户体验(首字延迟降低,用户不用等全部生成完)。
面试官可能追问:“流式输出对后端有什么影响?” → ① 连接保持时间更长(需要 WebSocket 或 SSE);② 错误处理更复杂(生成到一半出错怎么办);③ 无法预知总长度(无法设置 Content-Length)。
7. RAG 检索增强生成(第 7 篇)
Q65:RAG 的完整流程?离线索引和在线查询分别做什么?
离线索引(一次性):文档 → 文本切分 → Embedding → 存入向量数据库
在线查询(每次):用户问题 → 问题 Embedding → 向量数据库中搜索最相似的文档块 → 组装提示词 → 发送给 LLM → 生成回答
面试时怎么讲:“RAG 分离线和在线。离线:文档切块→转成向量→存入向量数据库。在线:用户问题转向量→在数据库中找最相似的文档块→拼成提示词→让 LLM 基于文档回答。”
面试官可能追问:“chunk_size 怎么选?” → 太大(如 2000 字)→ 检索不精确,包含太多无关信息;太小(如 100 字)→ 语义不完整,丢失上下文。经验:500-1000 字,重叠 10-20%。不同文档类型需要不同策略(代码 vs 文档 vs 表格)。
Q66:文档切分策略有哪些?固定长度、递归、语义切分的区别?
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 固定长度 | 每 500 字符切一刀 | 简单 | 可能在句子中间切断 |
| 递归 | 按段落→句子→词的优先级切 | 尽量在自然边界处切分 | 块大小不均匀 |
| 语义 | 根据语义相似度自动找切分点 | 每个块语义完整 | 计算量较大 |
实操建议:大多数场景用递归切分(LangChain 的 RecursiveCharacterTextSplitter)就够了。chunk_size=500-1000,overlap=10-20%。如果文档结构复杂(如代码、表格),用语义切分。
常见误区:以为 chunk_size 越小越好。实际上太小(如 100 字)会导致语义不完整,检索到的片段缺乏上下文。太大(如 2000 字)会导致检索不精确,包含太多无关信息。经验:500-1000 字是最佳起点。
Q67:向量数据库的原理?和传统数据库的区别?
传统数据库:精确匹配(WHERE title = '深度学习')
向量数据库:语义相似度搜索(“找到和’深度学习’含义最接近的书”)
核心是 ANN(近似最近邻)算法,用"聪明的策略"加速搜索,牺牲少量精度换取大量速度。
实操建议:小数据(<100 万向量)→ FAISS(内存,快);中等数据 → Chroma/Qdrant(磁盘持久化);大数据+生产环境 → Milvus/Weaviate(分布式)。
面试官可能追问:“向量数据库和传统数据库可以同时用吗?” → 可以,而且应该。向量数据库做语义搜索(“含义相近”),传统数据库做精确过滤(“作者=张三”)。混合检索(语义+关键词)效果最好。
Q68:HNSW 算法的原理?为什么比暴力搜索快?
HNSW(分层可导航小世界图)= 多层索引。
- 最顶层:只有"超级节点",快速定位大致区域
- 中间层:缩小范围
- 最底层:所有节点,精确定位
搜索时从顶层开始,逐层向下。复杂度 $O(\log n)$,比暴力搜索 $O(n \times d)$ 快几个数量级。精度 95-99%。
面试官可能追问:“HNSW 的 M 参数是什么?” → M 是每个节点的最大邻居数。M 越大,图越密集,搜索精度越高但构建越慢、显存越大。经验:M=16 是常用起点。
Q69:混合检索(语义 + 关键词)的优势?
纯语义检索:可能检索到语义相似但关键词不匹配的文档。
纯关键词检索:可能漏掉语义相关但用词不同的文档。
混合检索取长补短:70% 语义 + 30% 关键词,同时考虑"意思相近"和"关键词匹配"。
实操建议:大多数 RAG 场景用混合检索效果最好。LangChain 的 EnsembleRetriever 可以轻松实现。权重从 70% 语义 + 30% 关键词开始调。
面试官可能追问:“BM25 和向量检索的区别?” → BM25 是关键词匹配(精确但不理解语义),向量检索是语义匹配(理解含义但可能漏掉精确关键词)。两者互补。
Q70:多查询检索(Multi-Query)的原理?
一个问题自动生成多个变体表述:
- 原始问题:“什么是 RAG?”
- 变体 1:“解释检索增强生成技术”
- 变体 2:“RAG 的定义和原理”
合并所有查询的检索结果,召回率大幅提升。
面试官可能追问:“Multi-Query 的代价是什么?” → 每次查询需要多次 LLM 调用(生成变体)+ 多次检索,延迟和成本都增加。实际中通常生成 3-5 个变体就够了。
Q71:Corrective RAG 和 Adaptive RAG 的区别?
Corrective RAG:检索后评估文档相关性,不相关就用网络搜索补充,回答后还要评估质量。
Adaptive RAG:先判断问题类型(简单事实/复杂知识/推理),再选择最合适的处理方式(直接回答/检索回答/思维链推理)。
实操建议:大多数场景用标准 RAG 就够了。如果检索质量不稳定 → Corrective RAG(加相关性评估);如果问题类型多样 → Adaptive RAG(动态选择策略)。两者都增加了系统复杂度和延迟。
Q72:GraphRAG 和传统 RAG 的区别?知识图谱的作用?
传统 RAG:把文档切成片段,用向量搜索找最相关的片段。片段之间没有"关系"。
GraphRAG:从文档中提取实体和关系,构建知识图谱,社区检测,为每个社区生成摘要。能回答需要"综合多个信息源"的复杂问题。
面试官可能追问:“GraphRAG 的最大挑战是什么?” → ① 实体提取的准确性(LLM 可能提取错误的实体/关系);② 知识图谱的构建成本(需要大量 LLM 调用);③ 图谱更新(文档变化时需要重新构建)。
Q73:如何评估 RAG 效果?Faithfulness、Relevance、Correctness 分别衡量什么?
| 维度 | 指标 | 衡量什么 |
|---|---|---|
| 检索质量 | Recall@k, Precision@k | 检索到的文档是否包含正确答案 |
| 生成质量 | Faithfulness(忠实度) | 回答是否基于检索到的文档(没有编造) |
| 生成质量 | Relevance(相关性) | 回答是否和问题相关 |
| 生成质量 | Correctness(正确性) | 回答是否正确 |
| 端到端 | Answer Correctness | 最终回答是否正确 |
面试官可能追问:“Faithfulness 和 Correctness 有什么区别?” → Faithfulness 是"回答是否基于检索到的文档"(没有编造),Correctness 是"回答是否正确"。可能 Faithfulness 高但 Correctness 低(文档本身有错),也可能反过来(模型编造了正确答案但没引用来源)。
Q74:RAG vs 微调 vs 提示词工程,分别适合什么场景?
| 方法 | 开发成本 | 知识更新 | 适用场景 |
|---|---|---|---|
| 提示词工程 | 最低 | 不支持 | 简单任务、快速原型 |
| RAG | 中等 | 实时更新 | 知识问答、文档查询 |
| 微调 | 最高 | 需重新训练 | 专业领域、格式要求 |
推荐优先级:先试提示词工程 → 其次 RAG → 最后微调。
面试时怎么讲:“三种方法各有适用场景。提示词工程成本最低,适合快速验证。RAG 适合知识频繁更新的场景(如产品文档)。微调适合深度适配专业领域(如医学术语)。实际中常常组合使用。”
面试官可能追问:“可以同时用 RAG 和微调吗?” → 可以,而且效果通常更好。微调让模型更好地理解检索到的内容(如医学术语),RAG 提供最新的知识。实际中常见组合:先用领域数据微调基础模型,再用 RAG 增强知识覆盖。
8. Agent 开发与生产部署(第 8 篇)
Q75:LoRA 的原理?为什么低秩假设成立?参数量怎么算?
LoRA 的核心洞察:微调时权重的变化量 $\Delta W$ 是低秩的。可以用两个小矩阵近似:$\Delta W \approx A \times B$。
$A$:$(d, r)$,$B$:$(r, d)$,$r$ 通常为 8 或 16。
参数量示例($d=768, r=8$):$A$ 有 6144 个参数,$B$ 有 6144 个参数,总共 12288 个。原始权重有 589824 个参数,减少了 98%。
低秩假设成立的原因:预训练模型已经学到了通用知识,微调只是学"新的任务特定知识",信息量远小于原始知识。
面试时怎么讲:“LoRA 的核心洞察:微调时权重变化量是低秩的。用两个小矩阵 A×B 近似变化量,只训练 A 和 B(参数减少 98%)。推理时合并回原始权重,无额外开销。”
常见误区:以为 LoRA 的效果总是接近全量微调。实际上在需要深度适配的任务(如代码生成、多语言翻译)上,LoRA 的效果可能比全量微调低 1-3%。另外 LoRA 只修改注意力层的权重,对 FFN 层的影响有限。
面试官可能追问:“LoRA 的 r 怎么选?” → 简单任务(情感分类)→ r=8;复杂任务(代码生成)→ r=32-64。r 越大效果越好但参数越多。经验:从 r=8 开始,效果不好再增大。
实操建议:数据量少 → LoRA;数据量充足 → 全量微调。任务简单(如情感分类)→ LoRA;任务复杂(如代码生成)→ 全量微调。
Q76:QLoRA 的原理?为什么能在消费级 GPU 上微调 7B 模型?
QLoRA = 4-bit 量化 + LoRA:
面试时怎么讲:“QLoRA = 先用 4-bit 量化压缩模型(14GB→3.5GB),再加 LoRA 适配器微调。总显存约 6GB,一张 RTX 3060 就够。核心创新:NF4 量化格式(根据正态分布设计的 4-bit 格式)+ 双重量化(量化参数也量化)。”
- 用 4-bit 量化加载大模型(14GB → 3.5GB)
- 在量化模型上添加 LoRA 适配器(只占 0.03GB)
- 只训练 LoRA 参数
总显存约 6GB,一张 RTX 3060 就够了。
Q77:8-bit 和 4-bit 量化的区别?NF4 为什么比 FP4 好?
| 方案 | 模型大小(7B) | 精度损失 |
|---|---|---|
| float16 | 14 GB | 极小 |
| 8-bit | 7 GB | < 1% |
| 4-bit NF4 | 3.5 GB | ~1-2% |
NF4(Normal Float 4)比 FP4 好的原因:大模型的权重分布近似正态分布。NF4 的量化区间根据正态分布的 CDF 划分,数据密集处区间密、数据稀疏处区间疏,量化误差最小化。
实操建议:部署大模型时,优先用 4-bit NF4 量化(显存省 75%,精度损失 <2%)。如果显存极其紧张,用 NF4+双重量化。如果精度要求高,用 8-bit 量化。
面试官可能追问:“量化会影响推理速度吗?” → 4-bit 量化不仅省显存,还能加速推理(因为内存带宽是瓶颈,数据量小了读取更快)。但反量化(4-bit→float16)有少量开销。总体推理速度提升 1.5-2 倍。
实操建议:部署大模型时,优先用 4-bit NF4 量化(显存省 75%,精度损失 <2%)。如果显存极其紧张,用 NF4+双重量化。如果精度要求高,用 8-bit 量化。
Q78:什么是 Agent?和 Chain 的区别?
| 特性 | Chain | Agent |
|---|---|---|
| 流程 | 固定(A→B→C) | 动态决策 |
| 类比 | 工厂流水线 | 真人客服 |
| 适合任务 | 流程明确的任务 | 需要判断和选择的任务 |
面试时怎么讲:“Chain 是固定流程(A→B→C),Agent 是动态决策——根据情况选工具。类比:Chain 是工厂流水线,Agent 是真人客服。Agent 更灵活但更难调试,需要安全机制防止无限循环。”
实操建议:如果任务流程可以画成流程图(如"查数据库→生成报告→发邮件")→ Chain;如果任务需要动态判断(如"根据用户意图选择不同工具")→ Agent。Chain 更稳定,Agent 更灵活但更难调试。
面试官可能追问:“Agent 的最大挑战是什么?” → ① 幻觉(Agent 可能调用错误的工具或传错参数);② 无限循环(Agent 可能反复调用同一工具);③ 安全性(Agent 有执行权限,需要严格的安全机制)。
Q79:Function Calling 的工作流程?
- 用户提问 → 大模型分析问题,判断需要调用哪个工具
- 大模型生成工具调用指令(函数名 + 参数)
- 外部系统执行工具,返回结果
- 大模型整合结果生成最终回答
关键:大模型不直接执行工具,它只是"决策者"。
面试官可能追问:“如果模型调用了错误的工具怎么办?” → 需要安全机制:① 工具白名单(只允许调用预定义的工具);② 参数校验(检查参数是否合法);③ 人工确认(高风险操作需要人类确认)。
Q80:MCP 协议是什么?和 Function Calling 的区别?
MCP(Model Context Protocol)是工具调用的统一标准。
| 对比项 | Function Calling | MCP |
|---|---|---|
| 格式兼容 | 各家格式不同 | 统一标准 |
| 工具适配 | 为每个平台单独适配 | 只需实现一次 |
| 类比 | “方言” | “普通话” |
实操建议:如果你在开发 Agent,优先用 MCP(生态在快速增长)。如果目标平台只支持 Function Calling(如 OpenAI),先用 FC,后续迁移到 MCP。
MCP 有三大能力:Tools(工具)、Resources(资源)、Prompts(提示模板)。
Q81:ReAct 模式的工作流程?Thought/Action/Observation 分别是什么?
ReAct = Reasoning + Acting:
- Thought(思考):分析问题,决定下一步
- Action(行动):调用工具
- Observation(观察):查看工具返回的结果
- 重复 1-3 直到信息足够
- Final Answer:生成最终回答
类比侦探破案:思考→调查→观察线索→再思考→直到破案。
面试时怎么讲:“ReAct = 思考+行动。循环:Thought(分析问题)→ Action(调用工具)→ Observation(看结果)→ 重复直到信息足够 → Final Answer。终止条件:LLM 自行判断或最大步数限制。”
面试官可能追问:“ReAct 的终止条件是什么?怎么防止无限循环?” → 两种方式:① LLM 自行判断"信息足够了"并输出 Final Answer;② 设置最大步数限制(如最多 5 轮)。实际中通常两者结合——防止 LLM 判断失误导致无限循环。
Q82:LangGraph 的 State、Node、Edge 概念?
State(状态):Agent 的"工作台",存放所有中间结果。
Node(节点):Agent 的"工作站",每个负责一个特定任务(分析、搜索、生成)。
Edge(边):工作站之间的"连接"。普通边是固定路径,条件边根据状态动态选择路径。
实操建议:如果你在开发 Agent,优先用 LangGraph(LangChain 生态,文档完善)。如果需要更灵活的控制,直接用状态机。LangGraph 的核心优势是可视化调试和 Human-in-the-Loop 支持。
面试官可能追问:“LangGraph 和 LangChain AgentExecutor 的区别?” → AgentExecutor 是简单的循环(Agent→Tool→Agent),LangGraph 是图结构(支持分支、循环、并行),更灵活。复杂 Agent 用 LangGraph,简单场景用 AgentExecutor。
Q83:多智能体(Supervisor 模式)的架构?
Supervisor(经理)负责分配任务给多个专业 Agent:
- 搜索 Agent:只负责搜索
- 代码 Agent:只负责写代码
- 分析 Agent:只负责数据分析
每个 Agent 的上下文窗口保持"干净",不会被不相关的工具描述干扰。
实操建议:简单任务用单 Agent + 多工具就够了。复杂任务(如"调研→写代码→测试→部署")才需要多智能体。Supervisor 模式最常用——经理 Agent 负责分配任务,专业 Agent 负责执行。
面试官可能追问:“多智能体的最大挑战是什么?” → ① Agent 之间的通信(如何传递上下文而不丢失信息);② 错误传播(一个 Agent 出错会影响整个链);③ 成本(每个 Agent 都要调用 LLM,token 消耗翻倍)。
Q84:全量微调 vs LoRA vs QLoRA 的显存对比?
| 方案 | LLaMA-7B 显存需求 | 参考硬件 |
|---|---|---|
| 全量微调 float32 | ~112 GB | 2 张 A100 80GB |
| 全量微调 float16 | ~56 GB | 1 张 A100 80GB |
| LoRA float16 | ~18 GB | 1 张 RTX 4090 |
| QLoRA 4-bit | ~6 GB | 1 张 RTX 3060 |
QLoRA 的显存分布:4-bit 模型 3.5GB(58%)+ 激活值 1.5-2.5GB(30-42%)+ LoRA/优化器/梯度 0.13GB(2%)。
实操建议:预算有限 → QLoRA(RTX 3060 就够);预算充足 → LoRA float16(RTX 4090);追求极致效果 → 全量微调(A100)。大多数场景 LoRA 就够了。
9. 综合题
Q85:从零搭建 Transformer 需要几步?
串联 Q23-Q34 的知识点,按模块拆解:
- 输入层:Token Embedding + Position Embedding(或 RoPE)→ 词向量 + 位置信息
- Encoder Block(重复 N 次):
- Multi-Head Self-Attention:Q/K/V 线性变换 → 缩放点积 → Softmax → 加权求和
- 残差连接 + LayerNorm
- FFN:Linear(512→2048) → ReLU/SwiGLU → Linear(2048→512)
- 残差连接 + LayerNorm
- Decoder Block(重复 N 次):
- Masked Self-Attention(遮盖未来位置)
- Cross-Attention(Q 来自 Decoder,K/V 来自 Encoder)
- FFN + 残差 + LayerNorm
- 输出层:Linear → Softmax → 预测下一个词的概率分布
显存估算:以 6 层 Encoder、$d_{\text{model}}=512$、$d_{\text{ff}}=2048$ 为例,参数量约 2000 万,float32 下约 80MB。
面试官可能追问:“从零搭建和用预训练模型有什么区别?” → 从零搭建适合学习原理,但训练需要大量数据和算力。实际项目中几乎 always 用预训练模型 + 微调——省时省力省算力。
Q86:大模型训练显存占用如何估算?
串联 Q22、Q49、Q75-Q76 的知识点:
$$ \text{总显存} = \text{模型参数} + \text{梯度} + \text{优化器状态} + \text{激活值} + \text{KV Cache} $$以 LLaMA-7B + Adam + float16 为例:
| 项目 | 计算 | 显存 |
|---|---|---|
| 模型参数 | $7B \times 2$ bytes | 14 GB |
| 梯度 | $7B \times 2$ bytes | 14 GB |
| 优化器状态(Adam) | $7B \times (4+4)$ bytes | 56 GB |
| 激活值 | 取决于 batch size 和序列长度 | 4-20 GB |
| KV Cache | 推理时才需要 | ~1 GB |
| 合计 | 88-105 GB |
降显存方案:
- 混合精度(float16 + float32):优化器状态减半 → 省 ~28 GB
- LoRA:只训练 0.1% 参数 → 梯度和优化器状态几乎为零
- QLoRA:4-bit 量化模型参数 → 14 GB → 3.5 GB
- 梯度累积:减少 batch size → 减少激活值显存
面试官可能追问:“为什么优化器状态占这么多?” → Adam 需要存储每个参数的一阶矩(均值)和二阶矩(方差),每个都是 float32(4 bytes)。7B 参数 × 2 个状态 × 4 bytes = 56 GB。这就是为什么 LoRA 省显存——只训练 0.1% 参数,优化器状态也只占 0.1%。
10. RAG 进阶与评估(第 7 篇补充、第 9 篇)
Q87:Parent-Child Chunking 解决了什么问题?
Parent-Child Chunking 解决了 RAG 中"检索精度"和"生成质量"的核心矛盾。
矛盾在于:检索需要小 chunk(向量表示精准,检索准确),生成需要大 chunk(上下文完整,LLM 回答好)。如果用大 chunk 检索,向量表示被稀释,检索不准;如果用小 chunk 生成,上下文不完整,回答质量差。
Parent-Child 方案:Parent Chunk(大块,如 2000 字)包含多个 Child Chunk(小块,如 300 字)。用 Child Chunk 的向量做检索(精准),命中后返回其 Parent Chunk(完整上下文),Parent Chunk 送入 LLM。
面试时怎么讲:“Parent-Child Chunking 解决了检索精度和生成质量的矛盾。用小块检索(精准),用大块生成(完整)。就像图书馆:用索引卡找书(精准),找到后读整本书(完整)。”
Q88:HyDE 的原理和适用场景?
HyDE(Hypothetical Document Embeddings):先让 LLM 生成一个"假设的回答",用这个假设回答去检索,而不是用原始问题检索。
原理:用户的问题通常很短(如"什么是 LoRA?"),向量表示信息量有限。假设回答更长、更丰富,向量表示更接近知识库中的文档向量,检索效果更好。
适用场景:用户查询较短、表述模糊时效果显著。不适用场景:用户查询已经很具体时,假设回答可能引入噪声。
面试时怎么讲:“HyDE 让 LLM 先’幻想’一个回答,用这个回答去检索。因为假设回答比短问题更接近文档的向量表示,检索效果更好。代价是多了一次 LLM 调用。”
Q89:Reranker 和 Embedding 检索的区别?为什么需要两阶段?
Embedding 检索是"双编码器"架构——查询和文档分别独立编码,只做点积。快但不够精确,因为查询和文档之间没有深度交互。
Reranker 是"交叉编码器"架构——将查询和文档拼接在一起,作为整体送入模型。能捕获更细粒度的交互信息,更精确但更慢。
两阶段流程:先用 Embedding 检索从百万文档中快速找到 top-50,再用 Reranker 从 50 个中精排取 top-5。兼顾速度和精度。
面试时怎么讲:“Embedding 检索快但粗糙(分别编码,只做点积),Reranker 精确但慢(拼接编码,深度交互)。两阶段:先粗排(百万→50),再精排(50→5),兼顾速度和精度。”
Q90:RRF(Reciprocal Rank Fusion)公式是怎么工作的?
RRF 用于融合多个检索器的排名结果。公式:
$$ \text{RRF\_score}(d) = \sum_{i=1}^{n} \frac{1}{k + \text{rank}_i(d)} $$其中 $k$ 是常数(通常 = 60),$\text{rank}_i(d)$ 是文档 $d$ 在第 $i$ 个检索器中的排名。
核心思想:不关心绝对分数,只关心排名。在多个检索器中排名都靠前的文档得分最高。
面试时怎么讲:“RRF 不看绝对分数,只看排名。公式是 1/(k+排名) 的求和。如果一个文档在稠密检索排第 1、BM25 排第 3,它的 RRF 分数就是 1/61 + 1/63。在多个检索器中都排前面的文档,RRF 分数最高。”
Q91:RAGAS 的四大指标分别衡量什么?Faithfulness 怎么计算?
| 指标 | 衡量对象 | 核心问题 |
|---|---|---|
| Faithfulness | 生成质量 | 回答有没有编造? |
| Answer Relevancy | 生成质量 | 回答切不切题? |
| Context Precision | 检索质量 | 相关文档排在前面吗? |
| Context Recall | 检索质量 | 所有信息都检索到了吗? |
Faithfulness 的计算:LLM 将回答拆分为若干独立声明→逐一验证每个声明是否能在上下文中找到依据→有依据的声明数 / 总声明数。
例如:上下文说"LLaMA 3 于 2024 年 4 月发布",回答说"LLaMA 3 于 2024 年 4 月发布,参数量为 700 亿"。声明 1 有依据,声明 2 无依据→Faithfulness = 1/2 = 0.5。
Q92:幻觉有哪几种类型?怎么检测?
| 类型 | 定义 | 示例 |
|---|---|---|
| 事实性幻觉 | 不符合事实 | “爱因斯坦获 1922 年诺奖”(实际 1921 年) |
| 忠实性幻觉 | 与检索上下文不一致 | 上下文说 100 亿,回答说 200 亿 |
| 推理性幻觉 | 推理过程引入不存在的逻辑 | “A>B, B>C, 所以 A<C” |
检测方法:RAGAS Faithfulness(检测忠实性幻觉)、SelfCheckGPT(多次回答对比一致性)、事实核查 API(与搜索引擎交叉验证)。
Q93:Self-RAG 的反思 token 机制是什么?
Self-RAG 让模型在生成过程中插入特殊的"反思 token"来评估自己的输出:
[Retrieve]/[No Retrieve]——判断是否需要检索[Relevant]/[Irrelevant]——判断检索结果是否相关[Supported]/[Not Supported]——判断生成的回答是否被上下文支持
这些反思 token 在训练时就学会了。模型不仅生成文本,还自我评估质量。如果判断 [Not Supported],则重新生成。
面试时怎么讲:“Self-RAG 让模型自己判断’要不要检索’、‘检索结果好不好’、‘回答有没有依据’。通过反思 token 实现自我纠错,比盲目检索+生成更可靠。”
11. Agent 进阶(第 8 篇补充)
Q94:Function Calling 的底层机制?LLM 真的在"调用"函数吗?
LLM 不执行任何函数。Function Calling 的本质是 LLM 生成了一段结构化 JSON,告诉外部系统"请帮我调这个函数"。
完整流程:你在系统 prompt 中定义工具→LLM 决定是否调用→LLM 输出 JSON(函数名+参数)→你的代码解析 JSON 并执行→把结果塞回 LLM 上下文→LLM 继续推理。
面试时怎么讲:“LLM 从头到尾只做了一件事——生成文本。‘调用工具’是你的代码在做,LLM 只是告诉你’调哪个、传什么参数’。这就是为什么 Function Calling 需要外部系统配合——LLM 自己什么都执行不了。”
Q95:tool_choice 的三种模式分别在什么场景使用?
| 模式 | 行为 | 适用场景 |
|---|---|---|
"auto" | LLM 自行决定是否调用 | 大多数场景 |
"none" | 强制不调用任何工具 | 明确不需要工具时(如闲聊) |
| 指定工具 | 强制调用某个特定工具 | 你确定需要调某个工具时(如用户说"帮我查天气") |
并行工具调用:LLM 可以在一次回复中同时调用多个工具(如同时查北京和上海的天气),两次调用并行执行。
Q96:ReAct 的局限性?Plan-and-Execute 如何改进?
ReAct 的局限:走一步看一步,缺乏全局视角→容易走弯路、做多余操作、忘记前面做过什么。
Plan-and-Execute 的改进:将 Agent 拆成两个角色——Planner(规划器)负责生成完整步骤列表,Executor(执行器)逐步执行。Planner 可以根据中间结果调整后续计划。
关键优势:有全局视角、步骤可追溯、Planner 和 Executor 可以用不同模型(Planner 用强模型,Executor 用快模型)。
Q97:Agentic RAG 和传统 RAG 的区别?
| 维度 | 传统 RAG | Agentic RAG |
|---|---|---|
| 流程 | 固定管道(检索→生成) | Agent 动态决策 |
| 检索决策 | 一定检索 | Agent 判断是否需要检索 |
| 失败处理 | 检索不到也硬生成 | 换策略重试或回退到网搜 |
| 多轮检索 | 只检索一次 | 可以多轮检索,评估结果是否足够 |
三种模式:Router Agent(路由到不同数据源)、自适应检索 Agent(决定是否需要检索、检索几次)、多源 Agent(多数据源交叉验证)。
Q98:Agent 常见的失败模式有哪些?怎么调试?
五种失败模式:无限循环(工具返回不明确→Agent 认为没完成)、工具参数幻觉(LLM 生成错误的函数名/参数)、过度调用工具(能直接回答的也要调工具)、上下文超长崩溃(工具返回结果太长)、错误累积(前面小错后面放大)。
调试建议:开启 Trace 日志(Langfuse/LangSmith)、从简单任务开始测试、建立回归测试集(20-50 个典型任务)、善用 Human-in-the-loop。
Q99:多 Agent 协作的优势和适用场景?
多 Agent 的价值:分工明确(每个 Agent 专注一个角色)、相互校验(一个 Agent 的输出由另一个审核)、可扩展(新增能力只需添加新 Agent)、突破上下文限制(每个 Agent 独立的上下文窗口)。
框架选择:CrewAI(角色扮演+任务流,学习曲线低)、AutoGen(对话驱动协作,创意讨论)、LangGraph(图状态机,精确控制,生产就绪)。
Q100:Agent Memory 的三层架构?
| 层次 | 名称 | 存储位置 | 生命周期 |
|---|---|---|---|
| 短期记忆 | Working Memory | LLM 上下文窗口 | 对话结束即消失 |
| 长期记忆 | Long-term Memory | 向量数据库 | 跨对话持久化 |
| 情景记忆 | Episodic Memory | 对话日志 | 永久保存 |
短期记忆是当前对话的上下文,长期记忆是用户偏好和历史决策,情景记忆是过去的完整交互序列。实现:短期→上下文+摘要压缩,长期→向量数据库,情景→对话日志+关键决策记录。
12. 生产环境工程化(第 10 篇)
Q101:LLM 应用为什么需要 Tracing?Langfuse 和 LangSmith 怎么选?
一个 RAG+Agent 请求涉及多个步骤(查询改写→检索→Rerank→Agent 规划→工具调用→生成)。没有 Tracing 时,如果结果不好,你不知道是哪一步出了问题。Tracing 记录每一步的输入、输出、耗时、Token 数。
选择:LangSmith 是 LangChain 官方的商用 SaaS,与 LangChain 原生集成,适合快速原型。Langfuse 是开源的,可自部署,数据安全可控,适合生产环境。
Q102:Prompt Injection 的四层防御策略?
四层防御:第 1 层输入过滤(关键词检测+LLM Guard 安全模型)、第 2 层 Prompt 加固(分隔符隔离+指令重复+角色锚定)、第 3 层输出过滤(PII 检测+NeMo Guardrails)、第 4 层监控告警(异常请求记录+定期审查)。
面试时怎么讲:“Prompt Injection 防御是分层的——输入层过滤已知攻击模式,Prompt 层加固系统指令,输出层检测敏感信息泄露,监控层记录异常行为。没有银弹,需要多层配合。”
Q103:熔断器的三个状态和工作原理?
三个状态:CLOSED(正常转发,统计失败率)→失败率超阈值→OPEN(直接返回降级结果,不调用下游)→冷却时间到→HALF-OPEN(试探性放行少量请求)→探测成功→CLOSED / 探测失败→OPEN。
作用:防止下游 LLM 服务持续故障时拖垮上游服务。没有熔断器时,每个请求都要等超时→线程池耗尽→你的服务也挂了。
Q104:LLM 应用的成本优化有哪些策略?
四种策略:Prompt 缓存(相同请求直接返回缓存结果,节省 30-50%)、模型路由(简单问题用小模型,复杂问题用大模型,节省 60-80%)、Token 优化(压缩上下文、动态截断、减少系统 prompt)、流式输出(SSE,不等全部生成完再返回,降低首 token 延迟)。
Q105:工具太多导致 LLM 选不准怎么办?
三个策略:按意图分类动态加载(每次只暴露 5-10 个相关工具)、两阶段选择(Embedding 粗筛→LLM 精选)、优化工具描述(写清"什么时候用"和"什么时候不用",好的 description 能让准确率从 60% 提升到 95%)。
工具数量与准确率的关系:5 个工具→95%、15 个→80%、50 个→50%。
Q106:从 Demo 到生产,最关键的工程化步骤是什么?
五个关键步骤:可观测性(Langfuse 全链路追踪,知道哪一步出问题)、安全防护(Prompt Injection 四层防御)、错误处理(重试退避+模型降级链+熔断器,保证可用性)、成本优化(模型路由+缓存,控制 Token 消耗)、评估体系(RAGAS + 回归测试集,持续优化)。
面试时怎么讲:“从 Demo 到生产,最关键的是五件事:能追踪(Langfuse)、能防御(Guardrails)、能容错(重试+降级+熔断)、能控成本(路由+缓存)、能评估(RAGAS+回归测试)。这五个缺一不可。”
13. 大模型基础进阶
Q107:什么是大语言模型?和传统 NLP 模型有什么区别?
| 维度 | 传统 NLP 模型 | 大语言模型(LLM) |
|---|---|---|
| 参数量 | 百万-亿级 | 十亿-万亿级 |
| 训练数据 | 特定任务标注数据 | 海量无标注文本 |
| 任务方式 | 每个任务训练一个模型 | 一个模型解决多种任务 |
| 能力获取 | 需要微调才能用 | 零样本/少样本直接用 |
LLM 的通用性来自 Transformer 架构 + 海量数据 + 大规模参数。传统 NLP 像"专科医生",LLM 像"全科医生"。
Q108:大模型是怎么训练出来的?
预训练流程:数据收集(互联网爬取,TB 级)→数据清洗(去重、过滤低质量)→分词训练(BPE,词表 32K-100K)→分布式训练(数千张 GPU 并行:数据并行+张量并行+流水线并行)→学习率调度(Warmup + Cosine Decay)→评估。
以 LLaMA-7B 为例:70 亿参数,训练数据 1 万亿 token,2048 张 A100 GPU,训练约 21 天,成本约 100 万美元。
Q109:什么是 Scaling Law?大模型的「涌现能力」是怎么回事?
Scaling Law:模型的损失 $L$ 与参数量 $N$、数据量 $D$、计算量 $C$ 之间存在幂律关系。增加规模几乎总能提升效果,且趋势可预测。
Chinchilla 最优比例:参数量和数据量应同步增长,最优比例约为每个参数对应 20 个训练 token。
涌现能力:某些能力在模型规模较小时完全不存在,超过某个阈值时突然出现。例如 Few-shot 学习在 ~10B 参数时涌现,Chain-of-Thought 推理在 ~100B 参数时涌现。
Q110:SFT 之后还有哪些 Post-Training?RLHF、DPO、GRPO、拒绝采样什么关系?
| 方法 | 需要奖励模型? | 需要人类标注? | 复杂度 |
|---|---|---|---|
| RLHF(PPO) | 是 | 是 | 高 |
| DPO | 否 | 是(偏好对) | 中 |
| GRPO | 否 | 否 | 低 |
| 拒绝采样 | 可选 | 否 | 低 |
RLHF 是经典方案(ChatGPT 使用),DPO 更简单稳定(LLaMA-2 使用),GRPO 不依赖人类标注(DeepSeek 使用)。
Q111:大模型的 DPO 和 PPO 的区别是什么?
PPO:需要先训练奖励模型,再用 PPO 算法优化。训练复杂,需要同时维护 4 个模型(生成模型、参考模型、奖励模型、价值模型)。
DPO:跳过奖励模型,直接用偏好数据优化。损失函数直接编码"让模型更偏好 chosen 回答,远离 rejected 回答"。
DPO 优势:更简单、更稳定、计算量更小。
Q112:大模型生成文本时的解码策略有哪些?贪心、Beam Search、采样分别什么时候用?
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 贪心搜索 | 每步选概率最高的 token | 代码生成、数学推理 |
| Beam Search | 保留 Top-B 个候选序列 | 翻译、摘要 |
| 采样 | 按概率分布随机选择 | 对话、创意写作 |
贪心搜索容易陷入重复循环。Beam Search 通过保留多个候选缓解,但计算量是贪心的 B 倍。实际对话场景通常用采样(配合 Temperature/Top-K/Top-P)。
Q113:KV Cache 是什么?Prompt Caching 的原理是什么?
KV Cache:自回归生成时缓存已计算的 K、V 向量,新 token 只需增量计算。没有 KV Cache 时生成 100 个 token 需要重新计算 100 次完整注意力,有 KV Cache 后只需增量计算,速度提升约 38 倍。
Prompt Caching:多个请求共享相同 System Prompt 前缀时,前缀的 KV Cache 可以复用。100 个用户共享 1000 token 的 System Prompt,前缀计算从 100 次降到 1 次。
Q114:大模型量化是什么?INT8/INT4/AWQ/GPTQ 怎么选?
| 方案 | 精度 | 特点 |
|---|---|---|
| INT8 | 8-bit | 最简单,精度损失最小,显存减半 |
| NF4(QLoRA) | 4-bit | 非均匀量化,正态分布数据精度高 |
| GPTQ | 4/3/2-bit | 逐层量化,需校准数据 |
| AWQ | 4-bit | 保护重要权重通道,精度损失比 GPTQ 小 |
选择建议:精度敏感→INT8;微调→NF4(QLoRA);部署推理→AWQ(精度好)或 GPTQ(速度快)。
Q115:什么是 CoT?为啥效果好?它有什么缺点或局限性?
CoT(Chain of Thought):让模型展示中间推理步骤,而非直接给答案。加一句"让我们一步一步思考"就能显著提升推理准确率。
局限性:对简单事实查询反而降低效率(增加 token 消耗和延迟);推理链可能编造看似合理但实际错误的中间步骤;成本翻倍(token 数通常是直接回答的 3-5 倍);不适合实时场景。
适用:数学/逻辑推理。不适用:简单事实查询、文本分类、翻译。
Q116:大模型为什么会出现幻觉?怎么缓解?
| 原因 | 缓解方法 |
|---|---|
| 训练数据噪声 | 数据清洗、知识截止日期标注 |
| 解码策略随机性 | 降低 Temperature |
| 知识边界模糊 | Prompt 要求"不确定时说不知道" |
| 长上下文信息丢失 | Rerank、减少上下文长度 |
| 训练目标偏差 | RLHF/DPO 对齐训练 |
Q117:MoE 混合专家模型是什么?DeepSeek V3、Qwen 为什么用 MoE?
MoE 将 FFN 层替换为多个专家网络 + 门控路由,每个 token 只激活 Top-K 个专家。
为什么用 MoE:相同计算成本下扩大模型容量。DeepSeek-V3 有 671B 参数,但每个 token 只激活 37B——拥有大模型的知识容量,推理成本接近小模型。
Q118:大模型部署有哪些主流方案?vLLM、TGI、llama.cpp、SGLang 怎么选?
| 方案 | 核心技术 | 适用场景 |
|---|---|---|
| vLLM | PagedAttention | 高吞吐在线服务 |
| TGI | HuggingFace 生态 | 快速部署 HF 模型 |
| llama.cpp | CPU/量化推理 | 边缘设备、消费级硬件 |
| SGLang | RadixAttention | 复杂推理流程、结构化输出 |
Q119:大模型能力评测指标有哪些?
| 基准 | 测试内容 | 评估方式 |
|---|---|---|
| MMLU | 57 个学科知识问答 | 多选题准确率 |
| HumanEval | 代码生成 | 生成代码通过率 |
| GSM8K | 小学数学推理 | 解题准确率 |
| TruthfulQA | 生成真实回答 | 人类评估 |
| MT-Bench | 多轮对话 | GPT-4 评分 |
| Chatbot Arena | 综合对话 | ELO 排名(人类盲评) |
Q120:对比使用过哪些主流大模型?你们项目中最终选用了哪个模型?为什么?
| 模型 | 特点 | 适用场景 |
|---|---|---|
| GPT-4o | 综合能力最强,多模态 | 通用场景、复杂推理 |
| Claude 3.5 | 长上下文(200K)、安全 | 长文档分析、代码 |
| DeepSeek-V3 | 开源、MoE、性价比高 | 中文场景、成本敏感 |
| Qwen3 | 中文优秀、多模态 | 中文应用、端侧部署 |
| LLaMA-3.1 | 开源标杆、生态丰富 | 研究、二次开发 |
选型:追求效果→GPT-4o/Claude;追求性价比→DeepSeek-V3;中文→Qwen3;私有部署→LLaMA/Qwen 开源。
Q121:为什么长上下文会出现 Lost in the Middle?上下文窗口越大越好吗?
Lost in the Middle:当上下文很长时,LLM 倾向于关注开头和结尾的信息,忽略中间内容。上下文窗口不是越大越好:更大的窗口意味着更高的计算成本、更多的噪声信息、更严重的 Lost in the Middle 问题。
缓解策略:Rerank(将最相关的 chunk 放在最前面)、只放最相关的 Top-K、分段处理。
Q122:多头注意力(MHA)有哪些局限?MQA、GQA、Flash Attention 怎么解决?
MHA 的局限:每个注意力头都有独立的 K、V 矩阵,推理时 KV Cache 显存开销大。
MQA:所有头共享 K、V,KV Cache 缩减为 1/头数,但质量有损失。GQA:折中方案,分组共享 K、V。LLaMA-70B 用 GQA(8 组),显存减少 ~4 倍,质量几乎不变。Flash Attention:分块计算避免存储完整注意力矩阵,显存 $O(n^2) \to O(n)$,速度提升 2-4 倍。
Q123:大模型的位置编码?sin/cos、RoPE、ALiBi 有什么区别?
| 特性 | 正弦位置编码 | RoPE | ALiBi |
|---|---|---|---|
| 编码方式 | 加到输入上 | 乘到 Q/K 上 | 加到注意力分数上 |
| 位置类型 | 绝对位置 | 相对位置 | 相对位置 |
| 外推能力 | 有限 | 较好 | 好 |
| 使用模型 | 原始 Transformer | LLaMA、Qwen | BLOOM、MPT |
14. RAG 进阶
Q124:Embedding 有哪几种算法你了解过吗?
| 代际 | 代表方法 | 核心思路 |
|---|---|---|
| 第一代 | Word2Vec / GloVe | 静态词向量,每个词一个固定向量 |
| 第二代 | Sentence-BERT | 句子向量,对比学习训练 |
| 第三代 | BGE-M3 / E5 | 多语言、多任务、对比学习 |
Word2Vec 两种训练方式:CBOW(用上下文预测中心词)和 Skip-gram(用中心词预测上下文)。现代方法用对比学习——正样本对拉近,负样本对推远。
Q125:讲讲你用的向量数据库?数据量级?性能?瓶颈?
以 Milvus 为例:百万级向量(1024 维),HNSW 索引,单机检索延迟 < 10ms。
性能瓶颈:向量数量超过千万级时,HNSW 内存占用过大。解决方案:IVF-PQ 量化压缩(显存减少 500 倍,精度损失 2-5%)、按业务分区、PCA 降维(1024→256 维)。
Q126:如何润色用户的 Query(Query Rewrite)?目的是什么?
用户原始查询往往不适合直接检索(太短、太模糊)。查询改写提升检索精准度。
| 方法 | 原理 |
|---|---|
| Multi-Query | LLM 将问题改写为多个变体 |
| HyDE | LLM 先生成假设回答,用回答检索 |
| Step-back | 从具体问题退后到通用问题 |
Q127:什么是多路召回?具体怎么做?
多路召回 = 同时使用多种检索方式,合并结果。最常见的是"向量检索 + BM25 关键词检索"。融合方式:RRF——不看绝对分数,只看排名,多个检索器中排名都靠前的文档得分最高。
Q128:RAG 检索优化策略有哪些?
| 阶段 | 策略 |
|---|---|
| 查询阶段 | 查询改写(Multi-Query、HyDE、Step-back) |
| 检索阶段 | 混合检索(稠密+稀疏,RRF 融合) |
| 重排阶段 | Reranker(Cross-Encoder 精排 top-50→top-5) |
| 生成阶段 | 上下文压缩、引用追溯 |
| 评估阶段 | Self-RAG(自判断检索质量) |
Q129:了解哪些更复杂的 RAG 范式?
| 范式 | 核心思路 |
|---|---|
| Corrective RAG | 检索后评估相关性,低则回退到网搜 |
| Self-RAG | 反思 token 自判断 |
| Adaptive RAG | 根据查询类型选择不同策略 |
| Agentic RAG | Agent 动态决策是否需要检索 |
| GraphRAG | 知识图谱增强,适合多跳推理 |
Q130:在什么场景下,你会选择使用图数据库来增强传统的向量检索?
当查询涉及多跳推理(“张三的老板的妻子在哪工作?")、全局性总结(“这些文档讨论了哪些主题?")、实体关系推理时,向量检索无法覆盖。
GraphRAG 从文档中抽取实体和关系构建知识图谱,用社区检测聚类,查询时在图上遍历。代价是构建成本高(需要 LLM 抽取实体)。
Q131:如何规避 RAG 系统中大模型的幻觉?
- Self-RAG:反思 token 机制,让模型自判断回答是否被上下文支持
- Corrective RAG:检索后评估相关性,低则用网搜补充
- RAGAS Faithfulness:将回答拆分为声明,逐个验证
- 引用追溯:要求模型标注信息来源
Q132:怎么量化你的 RAG 效果?
检索质量:Recall@k、Precision@k、MRR、NDCG。
生成质量(RAGAS):Faithfulness(回答有没有编造)、Answer Relevancy(切不切题)、Context Precision(相关文档排在前面吗)、Context Recall(所有信息都检索到了吗)。
Q133:RAG 知识库如何实现动态与持续更新?
- 变更检测:监控源文档的修改时间/哈希值
- 增量写入:新文档直接写入向量数据库
- 版本管理:每个 Chunk 附带文档版本号
- Embedding 模型更新:全量重索引或向量空间对齐
Q134:在实际落地中,你觉得 RAG 最难的地方是哪里?
- 文档解析:扫描件 PDF、复杂表格、多列排版
- 评估标准:没有统一的"好"标准
- 长尾 case:80% 查询效果好,20% 长尾查询效果差
- 知识时效性:文档更新后新旧信息冲突
- 成本控制:每一步都有成本
Q135:不同来源的文档发生知识冲突时,RAG 应该信谁?
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 时间戳优先 | 最新的文档优先 | 事实随时间变化 |
| 来源可信度 | 为不同来源设置权重 | 有权威/非权威之分 |
| 多源交叉验证 | 多个来源一致的信息更可信 | 高可靠性场景 |
| 人工标注 | 对冲突内容标记优先级 | 医疗、法律、金融 |
实际工程中,通常将冲突解决逻辑放在 Reranker 阶段。
15. LLM 工具调用进阶
Q136:大模型的 Function Call 能力是怎么训练出来的?
- SFT 阶段:构造大量工具调用训练数据(用户问题→工具调用 JSON→工具返回→最终回答)
- RLHF 阶段:人类标注员评判工具调用是否合理,训练奖励模型
- 数据构造:覆盖多种工具组合、边界 case(不该调时不要调)、参数格式变体
Q137:什么场景下使用 Function Calling,什么场景下使用 MCP?
| 场景 | 推荐方案 |
|---|---|
| 单平台、少量工具 | Function Calling(简单直接) |
| 多框架、多工具生态 | MCP(工具与框架解耦) |
| 需要热插拔工具 | MCP(动态注册) |
| 远程工具(云端 API) | MCP(SSE 传输) |
| 快速原型验证 | Function Calling(无额外依赖) |
Q138:Skill 是什么?MCP 和 Agent Skill 的区别?Function Calling、Skill、MCP 三者区别?
Skill 是用 Markdown 文件(SKILL.md)描述的能力模块,AI 通过阅读描述来理解和使用工具。
Function Calling 是 LLM 层面的能力(生成工具调用 JSON),MCP 是通信协议层面的标准(工具和 AI 应用怎么对话),Skill 是能力描述层面的抽象(用自然语言描述工具能做什么)。
Q139:什么是 A2A 协议?它和 MCP 协议的区别是什么?
| 维度 | MCP | A2A |
|---|---|---|
| 通信对象 | AI 应用 ↔ 工具 | Agent ↔ Agent |
| 核心能力 | Tools/Resources/Prompts | Task/Artifact/Message |
| 提出者 | Anthropic |
MCP 解决"应用和工具通信”,A2A 解决"Agent 之间通信”。
Q140:说说 WebSocket 和 SSE 通信的区别及局限性?
| 维度 | SSE | WebSocket |
|---|---|---|
| 通信方向 | 单向(服务端→客户端) | 双向 |
| 协议 | HTTP | 独立协议(ws://) |
| 适用场景 | LLM 流式输出 | 实时双向对话 |
| 实现复杂度 | 低 | 中 |
| 代理兼容 | 好 | 差 |
LLM 应用中 SSE 最常用——服务端逐 token 推送。WebSocket 适用于语音 Agent 等需要双向通信的场景。
Q141:工具调用格式非法、参数错误、超时或失败时,Agent 如何容错?
| 失败类型 | 容错策略 |
|---|---|
| 格式非法 | JSON Schema 校验 + 重试(提示 LLM 修正) |
| 参数错误 | 参数校验 + 默认值填充 + 反馈错误信息 |
| 超时 | 超时时间 + 降级(跳过或用缓存) |
| 执行失败 | 重试(最多 3 次)+ 错误信息反馈 LLM |
核心原则:不要让工具失败直接中断 Agent 流程。
16. Agent 进阶
Q142:什么是 Agent?与大模型有什么本质不同?
$$ \text{Agent} = \text{LLM} + \text{工具调用} + \text{自主决策循环} + \text{记忆} $$| 维度 | 大模型 | Agent |
|---|---|---|
| 工具使用 | 不能 | 能 |
| 记忆 | 无 | 有(短期/长期/情景) |
| 决策 | 一次性生成 | 多步推理循环 |
| 自主性 | 被动响应 | 主动规划和执行 |
Q143:Agent 的基本架构由哪些核心组件构成?Workflow、Agent、Tools 的概念和区别?
五个核心组件:State(状态管理)、Node(处理节点)、Edge(连接和条件跳转)、Tool(外部工具)、Memory(记忆)。
| 概念 | 定义 | 特点 |
|---|---|---|
| Tool | 单个可执行的操作 | 无状态、无决策 |
| Workflow | 预定义的步骤序列 | 固定流程、确定性 |
| Agent | 自主决策系统 | 动态规划、根据中间结果调整 |
Q144:了解哪些 Agent 设计范式?Agent 和 Workflow 的区别?
| 范式 | 适合场景 | 核心思路 |
|---|---|---|
| ReAct | 简单任务(1-3 步) | 走一步看一步 |
| Plan-and-Execute | 复杂任务(5-10 步) | 先规划再执行 |
| Reflexion | 需要纠错的任务 | 执行后反思 |
| LLM Compiler | 精确控制的工作流 | 用代码表达计划 |
Q145:复杂任务怎么做任务拆分?为什么要拆分?效果如何提升?
为什么要拆分:LLM 上下文窗口有限,复杂任务一次性塞入会导致信息过载。
拆分方法:按目标拆分(大目标→子目标)、按数据源拆分、按能力拆分(搜索→搜索引擎,写作→LLM)。
效果提升:每个子任务上下文更聚焦,工具选择更精准,中间结果可验证,错误可定位。
Q146:Agent 的长短期记忆系统怎么做的?记忆是怎么存的?粒度是多少?怎么用的?
| 记忆类型 | 存储粒度 | 检索方式 |
|---|---|---|
| 短期 | 每轮对话完整消息 | 直接拼接(最近 N 轮) |
| 长期 | 关键事实/偏好(50-200 token/条) | 语义检索 Top-K |
| 情景 | 完整交互序列(500-2000 token/轮) | 时间戳+关键词 |
Q147:Agent 记忆压缩通常有哪些方法?
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 摘要压缩 | LLM 将多轮对话压缩为摘要 | 对话轮次多 |
| 滑动窗口 | 只保留最近 N 轮 | 早期信息不重要 |
| 重要性评分 | 只保留高分记忆 | 记忆量大 |
| 向量检索式压缩 | 存入向量数据库,按需检索 | 跨会话长期记忆 |
Q148:在工程实践中,为什么有时候选择「手搓」Agent,而不是直接用成熟框架?
| 维度 | 手搓 | 框架(LangGraph/CrewAI) |
|---|---|---|
| 控制力 | 完全控制 | 受框架约束 |
| 调试 | 透明 | 内部不透明 |
| 开发速度 | 慢 | 快 |
| 适用 | 核心逻辑简单但需极致优化 | 快速原型、复杂编排 |
建议:学习阶段手搓理解原理;生产项目用框架;核心业务逻辑手写,基础设施用框架。
Q149:讲讲 Agent 的反思机制?为什么要用反思?具体怎么实现?
为什么:Agent 多步推理中可能犯错,不检查就继续执行,错误会累积放大。
实现:每步执行后用 LLM 评估结果是否合理→判断"结果不理想"则回退重新规划→保持反思记录避免重复犯错→Reflexion 策略(执行→评估→反思→重新执行,循环直到成功或达到最大次数)。
Q150:如何设计多 Agent 的协作与动态切换机制?
| 机制 | 原理 |
|---|---|
| Supervisor 路由 | 主 Agent 根据任务类型分发给不同子 Agent |
| 故障转移 | 子 Agent 超时/失败时切换备用 Agent |
| 动态组队 | 根据任务复杂度动态添加/移除 Agent |
子 Agent 超时处理:设置超时时间(如 30 秒),超时后触发降级。失联检测通过心跳机制。并发冲突:乐观锁(版本号检查)或悲观锁(互斥访问)。
Q151:Agent 的上下文工程怎么设计?
System Prompt 四要素:角色定义、约束规则、工具描述、输出格式。
上下文窗口管理:滑动窗口(只保留最近 N 轮)、摘要压缩(LLM 压缩早期对话)、重要性筛选(按相关性过滤历史消息)、分层存储(热数据在上下文,冷数据在向量数据库)。
Q152:Agent 为什么会出现路径震荡、重复调用和死循环?怎么检测和治理?
原因:工具返回结果不明确、反思能力不足、缺乏全局视角。
治理:设置最大迭代次数、维护"已执行动作"列表检测重复、超过阈值后强制输出当前最佳结果、Trace 日志监控。
Q153:线上 Agent 延迟明显升高时,如何通过 Trace 定位和优化?
用 Langfuse/LangSmith 记录每步的输入、输出、耗时、Token 数。定位方法:查看 Trace 中哪一步耗时异常→是 LLM 调用慢(Token 太多)还是工具调用慢(API 超时)→针对性优化(压缩上下文/设置超时/缓存结果)。
Q154:Multi-Agent 系统如何处理子 Agent 超时、失联和并发修改冲突?
超时:设置超时时间,超时后降级(切换备用 Agent 或 Supervisor 直接处理)。失联:心跳机制定期检查。并发冲突:乐观锁(版本号检查)或悲观锁(互斥访问),LangGraph 的 State 天然支持状态隔离。
Q155:Agent 的「任务幻觉」是什么?如何避免没有执行工具却声称任务已经完成?
Agent 未实际执行工具,却在回答中声称任务已完成。原因:LLM 对自身知识过度自信、Prompt 没有强制要求"必须通过工具获取"。
防御:System Prompt 明确"实时数据必须通过工具获取";输出后验证工具调用记录与回答的一致性。
Q156:大模型或 Agent 连接数据库时,如何防止越权、敏感数据泄漏和查询幻觉?
| 风险 | 防御策略 |
|---|---|
| 越权访问 | 只读连接 + 查询白名单(只允许 SELECT) |
| 敏感数据泄漏 | 结果脱敏(PII 字段掩码)+ 输出审计 |
| 查询幻觉 | SQL 审核层 + 结果合理性校验 |
17. LangChain 与框架进阶
Q157:LangChain 的底层架构与实现原理是什么?
核心是 Runnable 协议——所有组件都实现 Runnable 接口,支持统一的 invoke/stream/batch 调用。LCEL 用 | 运算符将多个 Runnable 组合成 RunnableSequence,调用 invoke 时按顺序执行。
chain = prompt | llm | output_parser
result = chain.invoke({"input": "什么是 RAG?"})
Q158:LangChain 和 LlamaIndex 有什么区别?
| 维度 | LangChain | LlamaIndex |
|---|---|---|
| 定位 | 通用 LLM 应用框架 | RAG 专用框架 |
| 核心能力 | Chain/Agent/Tool/Memory | 索引/检索/查询引擎 |
| 适用场景 | 复杂 Agent、多工具编排 | RAG 为主的知识问答 |
选型:RAG 为主→LlamaIndex;Agent + 工具编排→LangChain;可混用。
Q159:Deep Research 的实现逻辑和适用场景是什么?
Deep Research = 多轮搜索+迭代分析+综合生成。
流程:理解研究问题→拆分子问题→多轮网络搜索→信息提取与交叉验证→迭代深入(3-10 轮)→生成研究报告。
与普通 RAG 的区别:普通 RAG 是"一次检索→一次生成",Deep Research 是"多轮搜索→迭代分析→综合生成"。适合需要跨多个信息源深入分析的复杂研究任务。