AI 工程基础体系 · 第 1/100 篇。内容覆盖机器学习、深度学习与生成式 AI;模型、数据、评测、权限和成本会作为同一生产系统处理。

AI 工程完整学习路线:从机器学习与 Transformer 到 RAG、Agent 和生产治理

人工智能工程不是“会调用一个大模型 API”。一个可交付的 AI 系统至少包含六类对象:

  1. 数据:输入从哪里来,标签或知识如何形成,是否允许使用;
  2. 模型:如何从输入产生预测、表示或文本;
  3. 评测:怎样判断输出是否正确、稳定、合规;
  4. 系统:请求如何经过网关、检索、工具、队列和存储;
  5. 治理:谁可以调用什么模型、读取什么数据、执行什么动作;
  6. 成本与运维:延迟、Token、GPU、失败重试和版本回滚如何控制。

“AI 工程”因此不是某个框架的用法,而是把学习算法、神经网络、生成模型和生产系统放入同一个可观测、可验证、可恢复的生命周期中。下面按照依赖关系,从机器学习基础开始,逐步推导到 Transformer、RAG、Agent 和生产治理。


一、先建立完整的学习地图

一条合理的学习路线不是按名词排列,而是按依赖关系排列:

flowchart TD
    A[编程与数学基础] --> B[机器学习任务与数据]
    B --> C[损失函数与优化]
    C --> D[泛化与实验]
    D --> E[深度学习基础]
    E --> F[Transformer]
    F --> G[预训练与生成式AI]
    G --> H[RAG]
    G --> I[Agent]
    H --> J[生产系统]
    I --> J
    J --> K[评测、权限、成本与治理]

每一层解决的问题不同:

  • 机器学习回答:如何从数据中学习一个预测函数;
  • 深度学习回答:如何用多层可训练函数学习复杂表示;
  • Transformer回答:如何高效建模序列中不同位置之间的关系;
  • 生成式 AI回答:如何根据上下文生成概率意义上的后续内容;
  • RAG回答:如何在生成前引入外部、可更新、可审计的知识;
  • Agent回答:如何让模型在循环中选择工具、观察结果并完成任务;
  • 生产治理回答:这个系统如何在真实权限、延迟、故障和成本约束下运行。

如果跳过前面的层次,后面的系统很容易变成“能跑但不能解释”。例如,不理解数据泄漏,就无法判断 RAG 评测是否可信;不理解概率生成,就容易把模型输出误认为数据库查询结果;不理解状态和权限,就会把 Agent 的工具调用当作普通函数调用。


二、机器学习:从任务、数据到可泛化的模型

2.1 机器学习的形式化对象

机器学习通常要学习一个函数:

fθ:XYf_\theta: \mathcal{X}\rightarrow\mathcal{Y}

其中:

  • X\mathcal{X} 是输入空间,例如用户特征、图像像素或文本表示;
  • Y\mathcal{Y} 是输出空间,例如类别、实数或词元序列;
  • θ\theta 是模型参数;
  • fθ(x)f_\theta(x) 是模型对输入 xx 的预测。

训练数据写成:

D={(xi,yi)}i=1nD=\{(x_i,y_i)\}_{i=1}^{n}

模型并不是直接“记住正确答案”,而是最小化训练目标:

θ^=argminθ1ni=1n(fθ(xi),yi)+λΩ(θ)\hat{\theta} = \arg\min_{\theta} \frac{1}{n}\sum_{i=1}^{n}\ell(f_\theta(x_i),y_i) +\lambda\Omega(\theta)

第一项是经验损失,表示预测与标签的差异;第二项是正则化项,通常用于限制模型复杂度;λ\lambda 控制正则化强度。

这里必须区分三个概念:

  • 参数:训练过程中由优化算法更新,例如线性回归的权重;
  • 超参数:训练前或训练过程中设定,例如学习率、树深度、正则化系数;
  • 指标:用于评估模型,不一定直接参与训练,例如准确率、召回率、BLEU 或人工评分。

2.2 任务类型决定数据和损失

回归

回归的目标是预测连续值。例如预测房价:

y^=wx+b\hat{y}=w^\top x+b

均方误差为:

MSE=1ni=1n(y^iyi)2\mathrm{MSE} = \frac{1}{n}\sum_{i=1}^{n}(\hat{y}_i-y_i)^2

平方会放大离群点影响。若标签中存在极端噪声,平均绝对误差:

MAE=1ni=1ny^iyi\mathrm{MAE} = \frac{1}{n}\sum_{i=1}^{n}|\hat{y}_i-y_i|

通常更稳健,但在零点不可导,需要优化器使用次梯度或平滑近似。

二分类

二分类模型输出 p(y=1x)p(y=1|x),常用 Sigmoid:

p=σ(z)=11+ezp=\sigma(z)=\frac{1}{1+e^{-z}}

二元交叉熵为:

=ylogp(1y)log(1p)\ell = -y\log p-(1-y)\log(1-p)

它不是简单地惩罚“分类错了”,而是惩罚概率分布与真实分布之间的差异。真实标签 y=1y=1 时,若模型给出 p=0.9p=0.9,损失较小;给出 p=0.01p=0.01,损失很大。

多分类

对于 KK 个类别,模型输出 logits:

z=(z1,,zK)z=(z_1,\ldots,z_K)

Softmax 将其转换为概率:

pk=ezkj=1Kezjp_k=\frac{e^{z_k}}{\sum_{j=1}^{K}e^{z_j}}

真实类别为 tt 时,交叉熵是:

=logpt\ell=-\log p_t

实际计算应使用数值稳定的 log_softmax,而不是先直接计算指数。因为当 logits 很大时,eze^{z} 可能溢出。

2.3 一个完整的机器学习实验

下面的例子使用 scikit-learn 内置数据完成二分类。它展示了数据切分、标准化、训练、评估和错误诊断的生命周期。

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import (
    classification_report,
    confusion_matrix,
    roc_auc_score,
)

X, y = load_breast_cancer(return_X_y=True)

X_train, X_test, y_train, y_test = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=42,
    stratify=y,
)

model = Pipeline([
    ("scale", StandardScaler()),
    ("clf", LogisticRegression(max_iter=2000)),
])

model.fit(X_train, y_train)

pred = model.predict(X_test)
prob = model.predict_proba(X_test)[:, 1]

print(confusion_matrix(y_test, pred))
print(classification_report(y_test, pred, digits=3))
print("ROC-AUC:", roc_auc_score(y_test, prob))

这段代码中,Pipeline 不是形式上的封装,而是防止数据泄漏的关键:

  1. StandardScaler.fit 只在训练集上计算均值和标准差;
  2. 测试集只调用 transform,不能参与统计量计算;
  3. 分类器在标准化后的训练特征上拟合;
  4. 测试集用于估计泛化性能。

如果先对完整数据调用 fit_transform,再切分训练集和测试集,测试集的均值和方差已经影响了训练过程。即使标签没有泄漏,特征统计量也泄漏了。

混淆矩阵:

预测负预测正真实负TNFP真实正FNTP\begin{array}{c|cc} & \text{预测负} & \text{预测正}\\ \hline \text{真实负} & TN & FP\\ \text{真实正} & FN & TP \end{array}

由此得到:

Precision=TPTP+FP\mathrm{Precision}=\frac{TP}{TP+FP}

表示预测为正的样本中有多少是真的正;召回率为:

Recall=TPTP+FN\mathrm{Recall}=\frac{TP}{TP+FN}

表示所有真实正样本中有多少被找出。医疗筛查、风控拦截和搜索召回对二者的取舍不同,不能只看准确率。

2.4 泛化、偏差与方差

训练误差低不等于模型有用。目标是降低对未知分布 P(X,Y)P(X,Y) 的期望风险:

R(θ)=E(X,Y)P[(fθ(X),Y)]R(\theta)=\mathbb{E}_{(X,Y)\sim P}[\ell(f_\theta(X),Y)]

训练集只能估计这个期望。泛化误差通常受到以下因素影响:

  • 偏差:模型表达能力不足,训练集和测试集都表现差;
  • 方差:模型过度依赖训练样本,训练集好而测试集差;
  • 不可约噪声:输入信息本身无法确定标签。

一个典型反例是:用一个非常深的决策树把训练集准确率做到 100%。如果训练数据少且存在噪声,树可能记住样本特有的划分,测试准确率反而下降。增加树深度降低了训练损失,却可能提高方差。

因此实验至少需要:

  1. 训练集:更新参数;
  2. 验证集:选择模型和超参数;
  3. 测试集:在决策冻结后进行最终估计。

当数据量有限时,可以使用交叉验证。KK 折交叉验证将数据划分为 KK 份,每次用 K1K-1 份训练、剩余一份验证,最后对 KK 个分数求平均。交叉验证能减少一次随机切分带来的偶然性,但它不能自动修复时间泄漏、重复样本或错误标签。

2.5 特征工程和数据分布

特征工程不是“多造几个字段”,而是把可用信息转换为模型能利用的表示。必须检查:

  • 特征在预测时是否真的可获得;
  • 特征是否包含未来信息;
  • 训练和线上分布是否一致;
  • 缺失值、类别值和异常值的处理是否一致;
  • 标签定义是否稳定。

例如预测“用户是否会在未来七天购买”,若特征中包含“未来七天订单金额”,模型指标会非常高,但这是标签泄漏,不是模型能力。

分布变化至少有三类:

  • 协变量偏移P(X)P(X) 变了,但 P(YX)P(Y|X) 近似不变;
  • 标签偏移P(Y)P(Y) 变了;
  • 概念漂移P(YX)P(Y|X) 本身变了。

线上监控不能只监控平均分数,还应监控特征分布、缺失率、预测置信度、分桶指标和真实标签延迟到达后的效果。


三、深度学习:表示学习、反向传播与训练稳定性

深度学习使用多层参数化函数:

h0=x,hl=ϕ(Wlhl1+bl)h_0=x,\qquad h_l=\phi(W_lh_{l-1}+b_l)

其中 ϕ\phi 是非线性激活函数。若没有非线性,多层线性变换仍可合并为一个线性变换,深度不会增加表达能力。

3.1 反向传播的核心

设单个样本的损失为:

L=(fθ(x),y)L=\ell(f_\theta(x),y)

梯度下降更新:

θt+1=θtηθL\theta_{t+1}=\theta_t-\eta\nabla_\theta L

其中 η\eta 是学习率。

反向传播本质上是链式法则。例如:

z=wx+b,y^=σ(z),L=ylogy^(1y)log(1y^)z=wx+b,\quad \hat{y}=\sigma(z),\quad L=-y\log\hat{y}-(1-y)\log(1-\hat{y})

逐步求导:

Lz=Ly^y^z=y^y\frac{\partial L}{\partial z} = \frac{\partial L}{\partial \hat y} \frac{\partial\hat y}{\partial z} = \hat y-y

因此:

Lw=(y^y)x,Lb=y^y\frac{\partial L}{\partial w} = (\hat y-y)x,\qquad \frac{\partial L}{\partial b} = \hat y-y

这解释了为什么 Sigmoid 与交叉熵组合后梯度形式简洁,也说明输入尺度过大时梯度可能不稳定。

3.2 常见训练失败

  • 学习率过大:损失震荡或变成 NaN
  • 学习率过小:损失下降极慢,容易误判为模型无效;
  • 梯度消失:深层网络前部几乎不更新;
  • 梯度爆炸:参数或激活值快速发散;
  • 过拟合:训练损失继续下降,验证损失上升;
  • 类别不平衡:模型只预测多数类也能获得表面上的高准确率。

诊断顺序应先看数据和标签,再看损失曲线、梯度范数、预测分布,最后再调模型结构。直接增加层数或训练轮数,可能掩盖数据问题。


四、Transformer:从 Attention 到生成和 KV Cache

Transformer 是一种以注意力机制为核心的序列模型架构。它不依赖循环逐步处理序列,而是允许一个位置直接与其他位置计算关系。

4.1 Token、Embedding 和位置

文本首先被分词为 token:

x1,x2,,xnx_1,x_2,\ldots,x_n

token 可以是词、子词或字符片段。每个 token 被映射为向量:

eiRdmodele_i\in\mathbb{R}^{d_{\text{model}}}

由于自注意力本身不表示顺序,需要注入位置信息。常见做法是加入位置编码:

hi(0)=ei+pih_i^{(0)}=e_i+p_i

位置编码可以是固定函数,也可以是可学习向量;具体形式属于实现选择,并非 Transformer 的唯一规范。

4.2 Self-Attention 的完整计算

给定输入矩阵:

XRn×dmodelX\in\mathbb{R}^{n\times d_{\text{model}}}

通过三个投影得到:

Q=XWQ,K=XWK,V=XWVQ=XW_Q,\qquad K=XW_K,\qquad V=XW_V

其中 QQ 是查询,KK 是键,VV 是值。注意力分数为:

S=QKdkS=\frac{QK^\top}{\sqrt{d_k}}

除以 dk\sqrt{d_k} 是为了控制点积方差。若 dkd_k 很大而不缩放,点积绝对值会变大,Softmax 变得过于尖锐,梯度变小。

加入掩码 MM 后:

A=softmax(S+M)A=\mathrm{softmax}(S+M)

最后:

Attention(Q,K,V)=AV\mathrm{Attention}(Q,K,V)=AV

其中对不允许关注的位置,MijM_{ij} 可设为负无穷,使对应 Softmax 概率接近零。

一个小型算例

设某个查询对三个位置的未归一化分数为:

s=[1,2,0]s=[1,2,0]

Softmax 为:

softmax(s)=[e1,e2,e0]e1+e2+e0[0.245,0.665,0.090]\mathrm{softmax}(s) = \frac{[e^1,e^2,e^0]}{e^1+e^2+e^0} \approx [0.245,0.665,0.090]

若三个 value 是标量 [10,20,30][10,20,30],加权结果为:

0.245×10+0.665×20+0.090×3018.450.245\times10+0.665\times20+0.090\times30 \approx18.45

这说明注意力输出不是选择一个固定位置,而是对 value 做连续加权。分数越高的位置影响越大,但除非使用特殊机制,否则并不是真正的离散选择。

4.3 多头注意力

单个注意力空间可能只能表达一种关系。多头注意力将表示分成多个头:

headi=Attention(XWiQ,XWiK,XWiV)\mathrm{head}_i = \mathrm{Attention}(XW_i^Q,XW_i^K,XW_i^V)

然后拼接并投影:

MHA(X)=Concat(head1,,headh)WO\mathrm{MHA}(X) = \mathrm{Concat}(\mathrm{head}_1,\ldots,\mathrm{head}_h)W^O

不同头可能学习局部邻近关系、指代关系或句法关系,但“每个头必然对应一种人类可解释关系”并不是规范保证。

标准自注意力的计算和显存复杂度通常随序列长度 nn 近似呈 O(n2)O(n^2) 增长,因为需要构造 n×nn\times n 的位置关系矩阵。这是长上下文成本上升的根本原因之一。

4.4 残差、归一化和前馈网络

一个 Transformer 层通常包含注意力子层和前馈子层:

H=Norm(H+Attention(H))H'=\mathrm{Norm}(H+\mathrm{Attention}(H))

Hout=Norm(H+FFN(H))H_{\text{out}} = \mathrm{Norm}(H'+\mathrm{FFN}(H'))

前馈网络常写为:

FFN(x)=W2ϕ(W1x+b1)+b2\mathrm{FFN}(x) = W_2\phi(W_1x+b_1)+b_2

残差连接让子层学习“对输入的修正”,并为梯度提供更直接的路径。归一化控制中间表示的尺度,减少训练不稳定。实际架构可能采用 Post-LN 或 Pre-LN,不能把某一种排列当作所有模型的统一实现。

4.5 Encoder、Decoder 和掩码

Transformer 家族中常区分:

  • Encoder-only:双向读取输入,适合分类、检索表示等任务;
  • Decoder-only:使用因果掩码,只允许当前位置读取过去,适合自回归生成;
  • Encoder-decoder:Encoder 编码输入,Decoder 生成输出,适合翻译和条件生成。

对于 decoder-only 模型,位置 ii 不能读取未来位置 j>ij>i。因果掩码可表示为:

Mij={0,ji,j>iM_{ij}= \begin{cases} 0,&j\le i\\ -\infty,&j>i \end{cases}

如果错误地允许读取未来 token,训练时模型会“偷看答案”,推理时却没有未来 token,导致训练和推理条件不一致。

4.6 生成、解码与 KV Cache

语言模型通常输出下一个 token 的条件概率:

P(xt+1xt)P(x_{t+1}|x_{\le t})

整段序列的概率分解为:

P(x1,,xT)=t=1TP(xtx<t)P(x_1,\ldots,x_T) = \prod_{t=1}^{T}P(x_t|x_{<t})

训练常用 teacher forcing:在预测第 tt 个 token 时直接提供真实的前缀。推理时则把模型刚生成的 token 加入前缀,这造成训练与推理之间的条件差异。

解码策略包括:

  • 贪心解码:选择概率最高的 token;
  • Temperature:将 logits 除以温度 TTT>1T>1 使分布更平,T<1T<1 更尖;
  • Top-k:只在概率最高的 kk 个 token 中采样;
  • Top-p:选择累计概率达到 pp 的最小候选集合后采样;
  • Beam search:维护多个高概率候选序列,适合部分条件生成任务,但不等于事实性更高。

KV Cache 用于自回归推理。生成第 t+1t+1 个 token 时,过去位置的 Key 和 Value 不需要重新计算,只需计算新 token 的 Q,K,VQ,K,V,并把新的 K,VK,V 追加到缓存中:

第 1 步:计算 token1 的 K1,V1,缓存 [K1,V1]
第 2 步:只计算 token2 的 K2,V2,缓存 [K1,K2]、[V1,V2]
第 3 步:只计算 token3 的 K3,V3,缓存 [K1,K2,K3]、[V1,V2,V3]

KV Cache 降低了重复计算,但会占用显存,且缓存大小随层数、头数、每头维度和上下文长度增长。长上下文并不只是“输入 token 变多”,还意味着缓存和注意力计算成本增加。


五、生成式 AI:概率生成不是事实数据库

生成式 AI 是根据条件分布产生新内容的模型。语言模型生成文本时,输出的是:

argmax或采样自 P(next tokencontext)\arg\max \text{或采样自 } P(\text{next token}\mid\text{context})

这和数据库查询不同。数据库返回满足条件的记录;语言模型寻找高概率的语言延续。即使一句话语法正确、表达自信,也不代表它对应真实事实。

需要区分三类能力:

  1. 参数记忆:训练期间压缩到模型参数中的统计规律和知识;
  2. 上下文学习:运行时从提示词和示例中临时利用的信息;
  3. 外部工具或检索:运行时从数据库、搜索系统或 API 获取的信息。

模型输出的事实性还受提示词、上下文质量、解码策略、模型版本和数据新鲜度影响。因此不能仅通过“要求模型不要幻觉”解决事实错误。


六、RAG:把外部知识接入生成流程

RAG(Retrieval-Augmented Generation,检索增强生成)是先从外部知识源检索相关内容,再把检索结果放入生成上下文的系统模式。

基本数据流是:

sequenceDiagram
    participant U as 用户
    participant G as 网关
    participant R as 检索器
    participant V as 向量/关键词索引
    participant L as 语言模型
    participant A as 审计与评测

    U->>G: 问题与身份
    G->>R: 问题、租户、权限过滤条件
    R->>V: 关键词/向量检索
    V-->>R: 候选文档与元数据
    R-->>G: 排序后的证据
    G->>L: 问题 + 证据 + 输出约束
    L-->>G: 回答与引用
    G->>A: 请求、证据、延迟、Token、结果
    G-->>U: 最终回答

6.1 离线索引流程

文档入库通常包括:

  1. 读取原始文档;
  2. 清洗格式和无关内容;
  3. 按语义或结构切分;
  4. 为每个片段生成 embedding;
  5. 将向量和元数据写入索引;
  6. 记录文档版本、来源和更新时间。

一个片段不应只有文本,还应包含:

{
  "text": "退款申请应在订单完成后七天内提交。",
  "source": "policy/refund.md",
  "version": "2025-01-10",
  "tenant_id": "tenant-a",
  "acl": ["support", "finance"],
  "chunk_id": "refund-003"
}

acl 是访问控制元数据。如果检索阶段不带权限条件,而是在生成后才尝试“让模型忽略无权文档”,敏感内容已经进入上下文,系统已经失守。

6.2 查询流程和相似度

文本被映射为向量 qq,文档片段被映射为 did_i。余弦相似度为:

cos(q,di)=qdiqdi\cos(q,d_i)=\frac{q\cdot d_i}{\|q\|\|d_i\|}

它衡量方向相似度,不直接衡量事实正确性。一个语义相近但版本过期的文档,仍然可能获得高分。

常见检索方式:

  • 关键词检索:对精确术语、编号、错误码有效;
  • 向量检索:对语义改写和同义表达有效;
  • 混合检索:结合关键词和向量;
  • 重排序:用更强模型重新判断问题与候选片段的相关性。

RAG 的两个核心召回指标是:

  • Recall@k:前 kk 个结果是否包含所需证据;
  • Precision@k:前 kk 个结果中有多少真正相关。

如果正确证据根本没有被召回,生成模型再强也无法可靠回答。若召回了大量无关片段,模型可能被噪声干扰,或者因上下文过长增加成本。

6.3 切分不是越大越好

片段过小会丢失条件和上下文:

片段 A:退款可以申请。
片段 B:订单完成七天内。

单独检索片段 A 时,结论不完整。

片段过大则会:

  • 降低相似度定位精度;
  • 占用更多上下文;
  • 增加输入 Token 成本;
  • 把多个主题混在一起。

较可靠的切分依据是标题、段落、列表项、表格行和语义边界,而不是固定字符数。固定窗口和重叠窗口可以作为基线,但需要用离线问答集验证,而不是凭直觉选择。

6.4 RAG 的失败边界

检索为空时,系统不应让模型自由补全。可返回“没有找到足够依据”,或升级到人工/搜索流程。

检索到冲突文档时,必须利用版本和生效时间判断,不能把多个结论简单拼接。

文档包含提示词注入时,文档内容应被视为不可信数据,而不是系统指令。检索内容只能提供事实候选,不能改变工具权限和系统策略。

引用存在但不支持结论时,属于“引用幻觉”。评测不能只检查回答是否包含链接,还要判断引用片段是否真正蕴含结论。


七、Agent:带状态、工具和控制边界的决策循环

Agent(智能体)不是“更聪明的聊天机器人”,而是一个能够根据当前状态选择动作、观察结果并继续决策的系统。

可以将 Agent 抽象为:

st=(g,ht,ot,p)s_t=(g, h_t, o_t, p)

其中:

  • gg:用户目标;
  • hth_t:历史消息和中间轨迹;
  • oto_t:最近一次工具或环境观察;
  • pp:策略、权限和预算。

在第 tt 步,策略选择动作:

atπ(ast)a_t\sim\pi(a|s_t)

动作可能是:

  • 直接回答;
  • 调用只读查询工具;
  • 调用写入工具;
  • 请求用户确认;
  • 终止并报告失败。

工具结果形成新状态:

st+1=T(st,at,ot+1)s_{t+1}=T(s_t,a_t,o_{t+1})

这比“模型输出一段文本”多了状态、转移和副作用。

7.1 一个受控的 Agent 状态机

stateDiagram-v2
    [*] --> Received
    Received --> Planning
    Planning --> NeedRetrieval: 需要知识
    Planning --> NeedTool: 需要外部动作
    Planning --> Responding: 信息充分
    NeedRetrieval --> Planning: 返回证据
    NeedTool --> AwaitApproval: 高风险写操作
    NeedTool --> Executing: 低风险或已授权
    AwaitApproval --> Executing: 用户确认
    AwaitApproval --> Cancelled: 用户拒绝/超时
    Executing --> Planning: 工具成功
    Executing --> Failed: 超时/权限拒绝/参数错误
    Failed --> Responding: 可解释降级
    Responding --> [*]
    Cancelled --> [*]

关键点是:工具调用不是普通文本生成。工具必须有明确的输入 schema、权限检查、超时、重试策略和幂等语义。

例如退款工具可以定义:

{
  "name": "create_refund",
  "input_schema": {
    "type": "object",
    "required": ["order_id", "amount", "request_id"],
    "properties": {
      "order_id": {"type": "string"},
      "amount": {"type": "number", "minimum": 0},
      "request_id": {"type": "string"}
    }
  }
}

request_id 用于幂等。网络超时后,Agent 可能不知道第一次请求是否已经成功。如果直接重试,可能重复退款。服务端应使用 request_id 去重,并返回同一业务结果。

7.2 工具权限必须独立于模型

模型可以提出“调用退款工具”,但不能自行决定是否有权限。实际执行前应由策略引擎验证:

用户身份
  → 租户隔离
  → 角色权限
  → 资源归属
  → 参数范围
  → 风险等级
  → 是否需要人工确认
  → 工具执行

将权限判断放在提示词中是不可靠的,因为模型输出属于不可信输入。即使系统提示词写着“不能访问其他租户”,数据库查询仍必须在服务端强制附加 tenant_id 条件。

7.3 并发、循环和故障

Agent 通常包含循环:

规划 → 调用工具 → 观察结果 → 重新规划

必须设置:

  • 最大步数;
  • 最大总耗时;
  • 最大输入和输出 Token;
  • 单工具超时;
  • 重试次数;
  • 预算上限;
  • 检测重复动作的机制。

工具调用可以并发,但只有在动作相互独立时才安全。例如查询天气和查询日历可以并发;“创建订单”和“扣款”通常存在顺序和事务依赖。并发执行若没有状态版本控制,可能出现竞态:两个步骤都基于旧余额判断并同时扣款。


八、AI 生产系统:网关、模型、RAG、Agent、队列和存储

一个可治理的 AI 系统通常分为控制面和数据面:

  • 控制面:模型版本、提示词版本、权限策略、评测集、配额和发布配置;
  • 数据面:真实请求、检索、推理、工具调用和结果返回。

典型架构如下:

flowchart LR
    C[客户端] --> G[API网关]
    G --> Auth[认证/授权/限流]
    Auth --> O[编排服务]
    O --> R[RAG检索]
    R --> S[(文档与向量存储)]
    O --> M[模型路由]
    M --> L1[模型服务A]
    M --> L2[模型服务B]
    O --> T[工具执行器]
    T --> DB[(业务数据库)]
    O --> Q[异步队列]
    Q --> W[批处理/评测/索引Worker]
    G --> Obs[日志/指标/追踪]
    O --> Obs
    T --> Obs

8.1 网关职责

网关不只是转发 HTTP 请求,它应处理:

  • 身份认证;
  • 租户识别;
  • 请求大小限制;
  • 速率限制;
  • 配额;
  • 请求编号;
  • 超时和取消;
  • 审计字段注入。

速率限制可以按用户、租户、模型和 IP 分层。只限制请求数不够,因为一次请求可能包含不同数量的输入和输出 Token。成本控制应至少记录:

cost=ninputcinput+noutputcoutput+cretrieval+ctool\mathrm{cost} = n_{\text{input}}\cdot c_{\text{input}} + n_{\text{output}}\cdot c_{\text{output}} + c_{\text{retrieval}} + c_{\text{tool}}

其中单价 cc 取决于模型或服务版本。不能把某个时期的价格硬编码为永久事实,应从配置或账单系统读取并带版本。

8.2 同步请求与异步任务

适合实时返回的请求通常是:

请求 → 检索 → 模型 → 返回

长任务应使用队列:

提交任务 → 返回 job_id
Worker 获取任务 → 执行 → 持久化结果
客户端轮询或接收回调

任务状态可以是:

QUEUED → RUNNING → SUCCEEDED
                  └→ FAILED
                  └→ CANCELLED

状态更新必须考虑重复消费。队列通常只能提供至少一次投递语义,因此 Worker 可能重复执行。解决方案包括:

  • 任务表中的唯一业务键;
  • 执行前检查状态;
  • 写入结果时使用幂等更新;
  • 外部副作用使用幂等请求号;
  • 对不可重试错误直接失败。

8.3 存储分工

不同数据不应全部塞进一个存储:

  • 关系数据库:用户、权限、任务状态、版本、审计索引;
  • 对象存储:原始文档、评测数据、模型文件;
  • 向量索引:embedding 和相似度检索;
  • 缓存:短期会话、KV Cache 外部引用或热点结果;
  • 日志系统:结构化事件和调试信息。

对话历史也不能无限增长。系统需要区分:

  • 原始消息,用于审计;
  • 压缩摘要,用于继续对话;
  • 检索证据,用于引用;
  • 工具轨迹,用于诊断;
  • 敏感字段,用于脱敏或访问控制。

九、评测:从离线指标到线上证据

评测应分层,否则一个总分会掩盖故障来源。

9.1 传统机器学习评测

分类至少包括:

  • 混淆矩阵;
  • Precision、Recall、F1;
  • ROC-AUC 或 PR-AUC;
  • 概率校准;
  • 不同人群或时间切片上的指标。

类别极不平衡时,PR-AUC 往往比准确率更有解释力。若模型输出概率用于风险排序,还需要检查校准:预测为 0.8 的样本是否大约有 80% 为正例。

9.2 RAG 评测

RAG 至少拆成两段:

  1. 检索评测:正确证据是否进入 Top-k;
  2. 生成评测:回答是否被证据支持,是否完整、引用是否正确。

可构造如下数据集:

{
  "question": "退款申请期限是多少?",
  "expected_chunks": ["refund-003"],
  "expected_answer": "订单完成后七天内。",
  "must_not_use": ["旧政策文档"]
}

当召回错误时,应诊断切分、embedding、查询改写、过滤条件和索引更新;当召回正确但回答错误时,应诊断上下文排序、提示模板、模型推理和解码。

9.3 Agent 评测

Agent 不能只看最终文本,还要评估:

  • 工具选择是否正确;
  • 参数是否符合 schema;
  • 是否越权;
  • 是否在失败后合理恢复;
  • 是否重复调用;
  • 是否超过步数和预算;
  • 是否在高风险动作前请求确认。

线上必须保留结构化轨迹,例如:

{
  "trace_id": "t-123",
  "step": 2,
  "tool": "query_order",
  "arguments": {"order_id": "o-9"},
  "authorized": true,
  "latency_ms": 84,
  "result_status": "success"
}

原始内容可能包含个人数据,应按权限存储和脱敏,不能为了调试而无限制记录所有提示词和业务数据。


十、权限、安全和提示词注入

AI 系统的安全边界至少包括三层:

  1. 身份认证:请求来自谁;
  2. 授权:这个主体能访问哪些资源、执行哪些动作;
  3. 内容安全:输入和输出是否包含恶意、违法或敏感内容。

RAG 和 Agent 引入了额外攻击面:

  • 文档中的提示词注入;
  • 用户诱导模型泄露系统提示;
  • 工具参数篡改;
  • 跨租户检索;
  • 恶意文件触发解析器漏洞;
  • 通过长上下文消耗预算;
  • 通过循环调用造成资源耗尽。

防御原则不是让模型“自己小心”,而是把约束放在模型之外:

  • 数据库查询强制附加租户和权限过滤;
  • 工具服务重新验证用户身份和参数;
  • 高风险动作采用人工确认;
  • 文件解析使用隔离环境和资源限制;
  • 网络访问采用域名白名单;
  • 每步和每个任务设置预算;
  • 对模型输出进行 schema 校验;
  • 将外部文本标记为数据,不当作指令执行。

输出结构化并不等于输出可信。JSON Schema 可以验证字段类型和必填项,但不能证明金额、权限或业务逻辑正确。业务服务仍需二次校验。


十一、成本、延迟与模型路由

AI 系统的成本通常由模型推理、检索、存储、工具和运维共同构成。一个简单的延迟分解是:

Ttotal=Tqueue+Tretrieval+Tmodel+Ttool+TserializationT_{\text{total}} = T_{\text{queue}} + T_{\text{retrieval}} + T_{\text{model}} + T_{\text{tool}} + T_{\text{serialization}}

模型延迟又可区分:

  • 首 Token 延迟:从请求到第一个输出 token;
  • 生成吞吐:后续 token 的生成速度;
  • 总完成时间:直到结束的时间。

长上下文可能同时增加输入成本、注意力计算和 KV Cache 占用。压缩历史、减少无关检索片段、限制输出长度,通常比盲目更换模型更直接。

模型路由可以按任务分级:

简单分类/改写 → 小模型
需要复杂推理 → 强模型
高风险动作 → 强模型 + 规则校验 + 人工确认
批量离线任务 → 异步模型或批处理

路由不能只依据平均成本,还要看错误代价。例如客服摘要错误可能只需要人工修改,而错误退款可能产生真实财务损失。应使用风险加权成本:

Ctotal=Ccompute+Clatency+Chuman-review+CerrorC_{\text{total}} = C_{\text{compute}} + C_{\text{latency}} + C_{\text{human-review}} + C_{\text{error}}


十二、发布、版本和可恢复性

AI 系统的版本不只有模型权重,还包括:

  • 模型版本;
  • tokenizer;
  • 系统提示词;
  • 工具 schema;
  • 检索算法;
  • embedding 模型;
  • 文档索引版本;
  • 安全策略;
  • 评测集和阈值。

如果只记录模型名称,出现线上回归时无法复现。

发布流程应能回答:

  1. 新版本使用了哪些模型、提示词和索引;
  2. 离线评测与旧版本相比变化多少;
  3. 是否进行小流量或按租户灰度;
  4. 哪些指标触发自动回滚;
  5. 回滚后旧索引和旧工具 schema 是否仍兼容。

回滚不只是把模型换回去。如果新版本改变了输出 schema、缓存格式或任务状态,服务端也可能无法处理旧请求。因此发布必须考虑协议兼容和未完成任务的恢复。


十三、按阶段执行的学习路线

阶段一:编程、数学和实验基础

掌握 Python、数据结构、Linux、Git、HTTP、JSON、SQL。数学重点不是形式化证明竞赛,而是能解释:

  • 向量和矩阵乘法;
  • 概率分布、条件概率和期望;
  • 导数、梯度和链式法则;
  • 采样、置信区间和误差。

用 NumPy 手写线性回归、逻辑回归和梯度下降,再用 scikit-learn 复现同一实验,能够发现“算法实现”和“框架调用”之间的差异。

阶段二:机器学习完整基础

围绕任务、特征、模型、损失、优化、泛化和实验流程学习。至少完成:

  • 回归和分类;
  • 树模型与线性模型;
  • 交叉验证;
  • 特征预处理 Pipeline;
  • 类别不平衡;
  • 数据泄漏;
  • 指标和阈值选择;
  • 模型保存、加载和线上输入校验。

官方的 scikit-learn User Guide 适合按模块查阅 API 和算法说明;Google Machine Learning Crash Course 适合建立监督学习、损失、泛化和生产注意事项的整体框架。

阶段三:深度学习和 Transformer

先学习张量、自动微分、优化器、批处理、归一化和训练循环,再学习:

  • embedding;
  • self-attention;
  • multi-head attention;
  • 残差和归一化;
  • causal mask;
  • encoder、decoder;
  • teacher forcing;
  • 解码策略;
  • KV Cache;
  • 上下文长度和显存成本。

建议实现一个小型 decoder-only Transformer,并打印每层张量形状:

输入 token:        [batch, seq]
Embedding:         [batch, seq, d_model]
Q/K/V:             [batch, heads, seq, d_head]
注意力分数:         [batch, heads, seq, seq]
输出 logits:        [batch, seq, vocab_size]

只要形状、掩码和因果关系无法解释,就还没有真正理解 Transformer。

阶段四:生成式 AI 应用机制

掌握 tokenization、上下文窗口、采样、结构化输出、批处理、流式输出和错误重试。重点是认识到:

  • 生成文本是概率采样结果;
  • temperature 不能增加事实知识;
  • 更长提示词不必然更准确;
  • 结构化输出仍需业务校验;
  • 模型调用必须有超时、配额和日志。

阶段五:RAG

从一个本地文档集开始,依次实现:

  1. 文档解析;
  2. 结构化切分;
  3. embedding;
  4. 向量检索;
  5. 权限过滤;
  6. 重排序;
  7. 带引用生成;
  8. 检索和生成分层评测;
  9. 索引版本和增量更新。

不要先追求复杂框架。先能回答“正确证据为什么被召回”“为什么旧文档没有被过滤”“引用是否真的支持答案”,再引入更复杂的检索组件。

阶段六:Agent

先实现单工具、单轮、只读 Agent,再增加:

  • 多步循环;
  • 工具错误恢复;
  • 并发只读调用;
  • 任务队列;
  • 幂等写操作;
  • 人工确认;
  • 权限策略;
  • 步数、时间和成本预算。

Agent 的复杂度主要来自状态和副作用,而不是提示词长度。每增加一个工具,都应增加对应的 schema、权限规则、失败测试和审计字段。

阶段七:生产治理

最后学习网关、模型路由、缓存、队列、存储、监控、灰度发布和回滚。以一个完整系统作为练习目标:

用户请求
→ 身份认证与租户隔离
→ 请求预算与限流
→ 检索或工具规划
→ 模型调用
→ 输出校验
→ 业务动作确认
→ 结果与轨迹持久化
→ 指标、成本和审计

验收标准不是“回答看起来不错”,而是能够解释:

  • 数据从哪里进入;
  • 哪个版本的模型和索引处理了请求;
  • 检索证据是什么;
  • 工具为何被允许调用;
  • 失败后是否重复执行;
  • 一次请求花费多少;
  • 如何定位错误并恢复。

十四、常见误解与诊断顺序

误解一:模型越大,系统越可靠

大模型可能提高语言表达和复杂推理能力,但不能修复错误数据、越权检索、过期索引或重复扣款。先定位是数据、检索、模型、工具还是治理层的问题。

误解二:RAG 等于把文档塞进提示词

RAG 包含索引、切分、查询、召回、排序、权限、版本和引用。只把全文拼接到上下文,既可能超出窗口,也无法保证相关性和权限隔离。

误解三:Agent 只是函数调用

函数调用只有输入和输出;Agent 还涉及目标、历史状态、动作选择、观察、循环、预算和副作用。没有幂等、超时和权限的 Agent,在网络故障下可能重复执行真实动作。

误解四:离线指标高就可以上线

离线数据可能存在泄漏,线上分布可能变化,真实用户还会产生攻击性输入和长尾任务。上线前需要切片评测、对抗测试、灰度和线上监控。

误解五:有引用就代表答案正确

引用可能与结论无关,也可能来自过期版本。应检查“结论是否被引用片段蕴含”,并记录检索时的文档版本和权限过滤结果。

遇到线上问题时,可以按以下因果顺序诊断:

请求是否被正确认证?
→ 输入是否被截断或污染?
→ 检索是否返回正确且有权限的证据?
→ 模型是否遵守输出约束?
→ 工具参数是否通过业务校验?
→ 外部服务是否超时或重复执行?
→ 版本、成本和资源是否异常?

这个顺序能避免把所有故障都归因于“模型不够聪明”。


结语

完整的 AI 工程学习路线,核心不是从一个框架跳到另一个框架,而是逐步建立一条可解释的因果链:

数据表示模型预测或生成检索与工具权限和业务动作评测、成本与恢复\text{数据} \rightarrow \text{表示} \rightarrow \text{模型} \rightarrow \text{预测或生成} \rightarrow \text{检索与工具} \rightarrow \text{权限和业务动作} \rightarrow \text{评测、成本与恢复}

机器学习让你理解模型如何从数据中泛化;Transformer 让你理解现代语言模型如何处理序列;RAG 让生成系统连接可更新的外部知识;Agent 让模型参与多步决策;生产治理则确保这些能力不会越权、失控或无法复现。

当模型、数据、评测、权限和成本被作为同一个生产系统处理时,AI 应用才从“演示程序”变成了真正可维护的工程系统。

完整学习目录

一、机器学习基础

  1. AI 数学基础:向量矩阵、概率统计、微积分与优化直觉
  2. 机器学习完整基础:任务、特征、模型、损失、泛化和实验流程
  3. 机器学习数据工程:采集、清洗、切分、特征、泄漏和版本治理
  4. 监督学习:线性模型、树模型、分类回归、正则化和误差分析
  5. 无监督学习:聚类、降维、异常检测、表示与评估边界
  6. 机器学习评测:指标、交叉验证、阈值、校准、偏差和统计显著性

二、深度学习与 Transformer

  1. 深度学习基础:神经网络、反向传播、激活、归一化和泛化
  2. 深度学习训练:优化器、学习率、批次、混合精度和稳定性
  3. PyTorch 工程基础:Tensor、Autograd、Dataset、训练循环和检查点
  4. Tokenization 与 Embedding:词表、子词、位置、池化和语义空间
  5. Transformer 完整原理:Attention、残差、归一化、解码和 KV Cache

三、LLM 应用开发

  1. 大语言模型生命周期:预训练、指令微调、对齐、推理和版本评测
  2. Prompt 工程:指令层级、上下文、Few-shot、结构化输出和测试
  3. LLM API 工程:客户端、流式输出、取消、重试、限流和兼容层
  4. LLM 结构化输出与工具调用:Schema、循环、幂等、授权和确认
  5. 多模态 AI 工程:图片、音频、视频、文档输入和结果验证

四、RAG 与知识系统

  1. AI 向量检索基础:Embedding、切块、ANN、过滤和召回评测
  2. RAG 完整流水线:摄取、解析、切块、检索、重排、上下文和引用
  3. RAG 权限与评测:ACL、版本、缓存、忠实度、无答案和删除

五、Agent 与协议

  1. AI Agent 基础:状态机、计划、工具、循环、终止和人工确认
  2. Agent 记忆系统:短期上下文、摘要、长期记忆、身份与删除
  3. AI 工作流与多 Agent 编排:DAG、事件、并发、重试和一致性
  4. MCP 完整基础:Tools、Resources、Prompts、传输、授权和安全
  5. AI 编程 Agent 与 Skills:上下文、工具、补丁、验证和仓库边界

六、生产与治理

  1. 模型微调与适配:SFT、LoRA、数据治理、评测和何时不该微调
  2. AI 模型服务:批处理、连续批次、KV Cache、量化和 GPU 容量
  3. 本地模型与推理引擎:Ollama、llama.cpp、vLLM、量化和部署取舍
  4. LLM 与 Agent 评测:数据集、规则、Judge、轨迹、回归和统计
  5. AI 可观测性与成本治理:Trace、Token、TTFT、预算、缓存和降级
  6. AI 安全工程:提示注入、数据泄漏、越权工具、模型供应链和红队
  7. 负责任 AI:偏差、隐私、版权、透明度、人类监督和风险分级
  8. AI 生产系统架构:网关、模型、RAG、Agent、队列、存储和发布

一、机器学习基础

  1. AI 线性代数:向量、矩阵、张量、特征分解与几何直觉
  2. AI 概率统计:随机变量、分布、估计、贝叶斯与不确定性
  3. AI 微积分与自动微分:梯度、链式法则、Jacobian 和反向传播
  4. AI 优化基础:凸性、梯度下降、约束、鞍点与收敛判断
  5. AI 信息论基础:熵、交叉熵、KL 散度、互信息与编码直觉
  6. AI 数值计算:浮点误差、稳定性、向量化、条件数与精度选择
  7. 机器学习实验可复现:随机种子、数据版本、环境、指标与追踪
  8. 机器学习特征工程:编码、缩放、交叉、选择、泄漏与线上一致性
  9. 线性回归完整原理:最小二乘、正则化、诊断与置信区间
  10. 逻辑回归完整原理:对数几率、损失、阈值、校准与解释
  11. 决策树完整原理:划分、剪枝、缺失值、过拟合与可解释性
  12. 集成学习:Bagging、Random Forest、Boosting、Stacking 与误差来源
  13. 支持向量机与核方法:最大间隔、软间隔、核技巧和参数选择
  14. KNN 与近邻方法:距离、索引、维度灾难、分类和回归
  15. 贝叶斯机器学习:先验、似然、后验、共轭与近似推断
  16. 聚类算法:K-Means、层次、DBSCAN、GMM 与聚类评估
  17. 降维方法:PCA、SVD、t-SNE、UMAP 与可视化边界
  18. 异常检测:统计方法、Isolation Forest、One-Class 与阈值治理
  19. 不平衡学习:采样、代价敏感、指标、阈值与概率校准
  20. 时间序列机器学习:窗口、特征、回测、漂移与泄漏防护
  21. 推荐系统基础:召回、排序、协同过滤、冷启动与离线评测
  22. 模型可解释性:特征重要性、SHAP、局部解释与误用边界
  23. 因果推断基础:相关与因果、DAG、混杂、实验和反事实

二、深度学习与 Transformer

  1. 深度学习张量与形状:维度、广播、布局、批次和调试方法
  2. 自动微分与反向传播:计算图、梯度累积、截断和数值检查
  3. 卷积神经网络:卷积、感受野、池化、残差与视觉任务
  4. 序列模型:RNN、LSTM、GRU、Teacher Forcing 与长依赖
  5. 深度学习损失与正则化:目标设计、Dropout、权重衰减和早停
  6. 神经网络初始化与归一化:Xavier、Kaiming、BatchNorm 和 LayerNorm
  7. 深度学习数据管道:Dataset、采样、增强、预取与吞吐诊断
  8. 分布式训练:数据并行、模型并行、梯度同步与故障恢复
  9. AI GPU 与 CUDA 基础:核函数、显存、带宽、算子和性能证据
  10. 混合精度训练:FP16、BF16、Loss Scaling、溢出与精度验证
  11. 模型检查点与训练恢复:状态、随机数、分片、容错和一致性
  12. TensorFlow 工程基础:Tensor、GradientTape、tf.data、训练与导出
  13. JAX 工程基础:JIT、Grad、Vmap、Pmap、纯函数和设备执行
  14. ONNX 与模型互操作:导出、算子集、动态形状、验证和部署
  15. Attention 数学细解:QKV、缩放点积、Mask、多头与复杂度
  16. Transformer 位置编码:绝对位置、RoPE、ALiBi 与长度外推
  17. Tokenizer 训练与诊断:BPE、Unigram、特殊符号和多语言覆盖
  18. LLM 预训练数据工程:采集、去重、过滤、配比、版权与污染
  19. 模型 Scaling Law:参数、数据、算力、损失与训练预算
  20. MoE 模型原理:路由、专家负载、容量、通信与推理成本
  21. 指令微调:样本格式、数据混合、损失、灾难遗忘和评测
  22. 偏好对齐:RLHF、DPO、奖励模型、数据偏差与上线评测
  23. 模型量化:PTQ、QAT、INT8、INT4、精度损失与硬件适配
  24. LLM KV Cache:内存计算、分页管理、复用、失效与容量估算
  25. LLM 连续批处理:调度、Prefill、Decode、公平性与吞吐延迟
  26. 推测解码:草稿模型、接受率、正确性与加速边界
  27. LLM 长上下文工程:位置外推、注意力成本、检索与有效上下文
  28. Prompt Cache 工程:前缀复用、缓存键、隔离、失效和成本

四、RAG 与知识系统

  1. RAG 文档解析:PDF、Office、HTML、OCR、版面与结构恢复
  2. RAG 切块策略:固定、语义、层次、表格与上下文窗口
  3. Embedding 模型选型:维度、语言、归一化、领域与评测
  4. 向量 ANN 索引:HNSW、IVF、PQ、召回率、内存和构建成本
  5. 混合检索:BM25、向量、过滤、融合排序和权重调优
  6. RAG 重排:Cross Encoder、Late Interaction、候选规模和延迟
  7. RAG 查询改写:扩展、分解、HyDE、多轮上下文和回退
  8. RAG 上下文压缩:去重、摘要、证据选择与信息损失
  9. RAG 引用与溯源:证据定位、忠实度、冲突和可验证回答
  10. RAG 增量索引:变更捕获、版本、删除、重嵌入和一致性
  11. Graph RAG:实体关系、图构建、社区摘要、检索与适用边界

五、Agent 与协议

  1. Agent 规划与任务分解:ReAct、计划执行、反思和终止条件
  2. Agent 工具沙箱:文件、命令、网络、凭证、审批与审计
  3. Agent 人工介入:确认点、升级、接管、恢复和责任边界
  4. 浏览器 Agent:页面理解、定位、动作、等待、验证和抗变化
  5. 多 Agent 协作模式:角色、路由、共享状态、冲突和评测

系列导航与关联阅读

官方资料

本文依据研究论文、标准组织与主流框架官方文档重新梳理;正文、示例与工程清单由 WR BLOG 编写。