AI工程全景:从问题定义到可交付系统
把 AI 项目做成“可交付系统”,和做一个“指标漂亮的模型”是两件事。前者要求你把问题定义、数据、建模、评估、部署、监控、迭代串成闭环,并且在每个环节都能留下可审计、可复现、可回滚的工程证据:谁在什么环境下用什么数据训练了哪个模型,离线与线上差距为何产生,出现漂移时如何定位,业务成本与收益是否成立。本章的目标,是建立全书共同语言与工程视角,帮助你在项目早期就把“能不能落地”“怎么验收”“出了事怎么兜底”讲清楚。
---
1.1 术语边界:AI、ML、DL、生成式 AI 与数据科学到底差在哪
很多团队沟通成本高,不是因为技术难,而是因为“同词不同义”。先把边界立住,后面讨论生命周期、交付物和验收才不会各说各话。
1.1.1 五个常见概念的工程化定义
- **AI(人工智能)**:让系统表现出“智能行为”的总称,包含规则系统、搜索、规划、机器学习、知识图谱、生成式模型等。工程上更关注“系统能力”而不是“算法类别”。
- **ML(机器学习)**:从数据中学习映射或策略的技术集合。工程上通常意味着:数据集、训练过程、评估指标、模型版本与推理服务。
- **DL(深度学习)**:ML 的子集,以多层神经网络为核心。工程上通常意味着:大规模训练、GPU/加速器、框架(PyTorch 等)、训练稳定性与推理性能优化。
- **生成式 AI(Generative AI)**:能生成文本/图像/代码等内容的模型与应用形态。工程上常见模式是 **RAG(检索增强生成)**、工具调用、对话编排、安全对齐与可观测性。
- **数据科学(Data Science)**:强调用数据解释与决策(统计推断、实验设计、指标体系、因果与相关的区分)。工程上常见交付是:指标看板、A/B 实验结论、策略建议,而不一定交付模型服务。
> 侧边栏:同一项目往往同时需要数据科学与 ML 工程 > 例如“智能客服”项目,数据科学负责定义“转人工率”“首次响应时长”“解决率”等指标口径并设计实验;ML 工程负责训练意图模型、上线推理服务、监控漂移与回滚。
1.1.2 关系图:别把“会用模型”当成“会交付系统”
```mermaid graph TD A[AI] --> B[规则/搜索/规划] A --> C[机器学习 ML] C --> D[深度学习 DL] A --> E[生成式AI] E --> D F[数据科学 DS] --> G[指标体系/实验设计/分析] F --> C C --> H[MLOps/工程化交付] E --> I[LLMOps/安全与观测] ```
工程上一个实用的判断标准是:你交付的是否是“可运行、可监控、可迭代”的系统,而不是“一个 notebook 里的结果”。
---
1.2 从需求到可验收:把业务目标翻译成工程指标
AI 工程最容易翻车的地方,不在训练,而在“需求定义”。一句“做个智能客服”背后至少包含:目标、范围、约束、成功标准、失败兜底、数据可得性与合规边界。
1.2.1 需求澄清的五个问题(建议作为评审模板)
1. 要改善哪个业务指标?(例如转人工率降低、平均处理时长 AHT 降低、客服满意度提升) 2. 当前基线是多少?(没有基线就无法衡量改进) 3. 约束条件是什么?(延迟、成本、可解释性、合规、可用性 SLA、灰度策略) 4. 失败时怎么办?(降级、回滚、转人工、提示补充信息) 5. 上线后如何持续验证?(监控指标、报警阈值、复盘机制、再训练触发)
1.2.2 指标树:离线指标只是“代理变量”
以“意图识别”为例:
- **离线指标**(模型视角):Macro-F1、Top-k Accuracy、混淆矩阵、长尾意图召回
- **线上指标**(系统视角):转人工率、首次解决率、平均会话轮数、用户满意度(CSAT)、平均延迟 P95
- **成本指标**(工程视角):单次推理成本、GPU/CPU 占用、峰值 QPS、标注与迭代成本
一个常见误区是把离线 F1 当作最终目标。更稳妥的做法是建立一个“收益-成本”粗算模型,用来约束方案空间:
$$ \text{净收益} \approx N \cdot r \cdot (c_h - c_{ai}) - (c_{label}+c_{train}+c_{serve}) $$
其中 $N$ 为月会话量,$r$ 为可被自动化覆盖的比例,$c_h$ 为人工处理单价,$c_{ai}$ 为自动处理单价。这个公式不求精确,但能迫使团队把“上线后的账”算出来。
---
1.3 AI 项目生命周期:从需求到监控的闭环(以及每步交付物)
把生命周期画清楚,你就能知道每个阶段应该产出什么、用什么“闸门”决定是否进入下一阶段。
1.3.1 生命周期总览(图 1-1)
```mermaid graph LR A[需求定义] --> B[数据获取与治理] B --> C[特征/表示与基线] C --> D[训练与调参] D --> E[离线评估与误差分析] E --> F[部署与集成] F --> G[线上监控与反馈] G --> H[迭代与再训练] H --> B E -->|不达标| C F -->|线上问题| E ```
1.3.2 阶段闸门:中级团队必须建立“可拒绝上线”的机制
- **需求闸门**:验收指标、数据来源、合规边界、回滚方案明确;否则不进入建模。
- **数据闸门**:数据字典完成;训练/验证/测试切分可复现;泄漏检查通过;否则不训练。
- **模型闸门**:误差分析覆盖关键切片;与基线对比显著;推理成本与延迟满足约束;否则不上线。
- **上线闸门**:灰度策略、监控面板、报警阈值、回滚开关具备;否则不放量。
- **迭代闸门**:漂移与性能回退有因可查;再训练触发条件明确;否则不盲目重训。
> 侧边栏:为什么“闸门”是工程能力而不是流程负担 > 没有闸门的团队会把风险推到线上与客服同学身上;有闸门的团队把风险前置,用制度换稳定性。
---
1.4 中级读者常见误区:指标、线上、数据三座“暗礁”
下面这些坑,往往不是新手犯的,而是“能跑通训练但没交付过系统”的团队容易踩的。
1.4.1 只看指标不看成本:最贵的是“不可控”
- **反模式**:用更大模型把离线 F1 提高 1%,但推理成本翻倍、P95 延迟超标,导致无法放量或需要更多机器。
- **工程化解法**:把成本指标纳入验收;建立“性能-成本”帕累托前沿;先做能上线的基线,再逐步升级。
1.4.2 离线好线上差:分布偏移与系统差异的叠加
常见原因包括:
- **数据切分不当**:随机切分掩盖时间漂移;同一用户会话同时出现在训练与测试(信息泄漏)。
- **线上输入与离线不一致**:线上缺字段、编码不同、预处理版本不一致。
- **反馈回路**:模型上线后改变用户行为,分布随之变化(例如用户更愿意简写问题)。
解法要点:
- 用 **时间切分** 或按用户/会话切分;对关键字段做一致性校验;把预处理封装为同一份可版本化代码(训练与推理共享)。
1.4.3 忽视数据漂移与偏差:模型不是“上线即终点”
- **漂移(Drift)**:输入分布变了(新业务、新活动、新话术),模型性能会自然衰减。
- **偏差(Bias)**:某些人群/渠道表现显著更差,会带来投诉或合规风险。
工程建议:
- 监控不仅看总体指标,还要看 **切片指标**(渠道、地区、机型、产品线、长尾意图)。
- 对高风险任务(金融、医疗、未成年人等)建立更严格的人工兜底与审计链路。
---
1.5 基础工具链:从个人开发到团队交付的“最小可用栈”
工具链不是越多越好,而是要能支持四件事:协作、复现、自动化、可观测。下面是一套中型团队常见的“最小可用栈”,你可以按项目约束替换其中组件。
1.5.1 Python 生态:环境隔离与依赖锁定
- **Conda/Mamba**:适合需要 CUDA、系统库依赖复杂的场景。
- **uv/pip-tools/poetry**:适合纯 Python、需要快速创建环境与严格锁依赖的场景。
示例(以 `uv` 为例):
```bash uv init uv add torch scikit-learn pandas fastapi pydantic uv lock ```
如果使用 Conda,建议同时保留显式导出:
```bash conda env export --from-history > environment.yml pip freeze > requirements.txt ```
1.5.2 Jupyter 与 VS Code:探索与工程代码分离
- Notebook 用于:EDA、快速验证、可视化与结论沉淀
- 工程代码用:模块化脚本、配置化训练、可测试的预处理与推理逻辑
建议的项目结构(图 1-2):
``` project/ data/ # 仅放占位或小样本;大数据走版本管理 src/ datasets/ models/ training/ inference/ configs/ notebooks/ tests/ docker/ scripts/ README.md pyproject.toml ```
1.5.3 Git + Docker:把“能运行”变成“在哪都能运行”
- **Git**:不仅管代码,也管配置与实验记录入口(例如运行命令写入 `README` 或 `Makefile`)。
- **Docker**:把系统依赖、运行时与服务化封装起来,减少“你机器上能跑我这不行”。
最小化 `Dockerfile`(示例):
```dockerfile FROM python:3.11-slim WORKDIR /app COPY pyproject.toml uv.lock /app/ RUN pip install uv && uv sync --frozen COPY src /app/src CMD ["python", "-m", "src.inference.server"] ```
> 侧边栏:容器不是为了“炫”,而是为了让 CI/CD、灰度和回滚可控。你越早容器化,后面踩坑越少。
---
1.6 实验可复现:随机种子、环境锁定、数据版本三件套
可复现不是学术洁癖,而是工程保命:当线上指标掉了,你必须回答“到底变了什么”。
1.6.1 随机性控制:把“运气”从结果里剔除
在深度学习中,完全确定性不总是可行,但至少要做到“可解释的近似确定性”。
```python import os, random import numpy as np import torch
def set_seed(seed: int = 42): os.environ["PYTHONHASHSEED"] = str(seed) random.seed(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed_all(seed) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False ```
同时记录:
- 种子值、数据切分方式
- 框架版本、CUDA/cuDNN 版本
- 训练命令、配置文件、Git commit hash
1.6.2 环境锁定:能跑一次不代表能跑一百次
- 锁依赖(`uv.lock`/`poetry.lock`/`requirements.txt`)
- 固定基础镜像与驱动范围(容器化)
- 关键二进制依赖(如 tokenizer、ONNX Runtime、FAISS)要写清版本
1.6.3 数据版本:没有数据版本就没有“真相来源”
训练数据往往比代码更容易悄悄变化:
- 标注策略改变、清洗规则改变、字段含义改变
- 采样窗口改变(节假日、活动期)
- 线上埋点修复导致历史回填
工程上至少做到:
- 数据字典(字段、口径、缺失率、取值范围)
- 数据集快照(例如按日期/批次存档)
- 训练时记录“数据版本标识”(路径 + 时间窗口 + 哈希)
工具上可以选择 DVC、lakeFS、对象存储版本策略或数仓分区快照。关键不是用哪个,而是能追溯。
---
1.7 贯穿案例:智能客服“意图识别 + 知识库问答”如何拆解到可交付里程碑
接下来用一个贯穿案例把本章概念落到工程动作上。目标是:用户提问后,系统先判断意图(退换货/发票/物流/账户等),能直接回答的就从知识库给出答案;不确定或高风险则转人工,并把反馈用于迭代。
1.7.1 系统边界与架构(图 1-3)
```mermaid graph TD U[用户消息] --> P[预处理/脱敏] P --> I[意图识别模型] I -->|高置信| R[知识库检索] R --> A[答案生成/模板回复] A --> S[安全过滤/合规] S --> O[返回用户] I -->|低置信/高风险| H[转人工] H --> F[标注与反馈] F --> D[数据版本更新] D --> T[再训练/评估] T --> I ```
这里包含两个关键工程点:
- **置信度与兜底策略**:不是所有问题都要“强答”,低置信转人工往往更稳。
- **反馈闭环**:转人工不是失败,而是持续获取高价值标注的入口。
1.7.2 里程碑拆解:从 M0 到 M4 的递进式交付
- **M0(1–2 周):规则基线 + 监控框架**
- 交付:关键词/正则意图路由、FAQ 模板;埋点与线上指标面板
- 价值:立刻上线验证需求与数据链路,建立基线
- **M1(2–4 周):监督式意图分类器**
- 交付:意图模型 v1、混淆矩阵与长尾分析、推理服务(REST/gRPC)
- 关键:先覆盖头部意图,明确“其他/转人工”意图的定义
- **M2(2–4 周):知识库检索(BM25/向量检索)**
- 交付:文档切分策略、召回 Top-k、人工评测集、检索服务与缓存
- 关键:检索质量往往比生成模型更决定体验
- **M3(2–6 周):RAG + 生成式回答**
- 交付:提示词与模板、引用来源展示、幻觉控制策略(拒答/引用约束)
- 关键:把“可解释证据”(引用段落、链接)作为产品能力的一部分
- **M4(持续):监控漂移 + 主动学习迭代**
- 交付:漂移报警、切片指标、主动采样标注策略、再训练流水线
这种拆法的核心是:每个里程碑都能独立上线、产生业务反馈,并为下一步积累数据与基础设施。
1.7.3 验收指标:离线、线上、成本三类一起定
以“意图识别 + 知识库问答”为例,建议的验收指标组合:
- **意图识别离线**
- Macro-F1(关注长尾)
- 关键意图召回(例如“退款”“账户冻结”必须高召回)
- 置信度校准(高置信样本的准确率要稳定)
- **检索/问答离线**
- Top-k Recall(是否能把正确文档召回)
- 人工评测:正确性、可读性、引用一致性
- **线上业务**
- 转人工率下降(需配合质量指标,避免“强答导致投诉”)
- 首次解决率、平均轮数、CSAT
- **工程约束**
- P95 延迟、峰值 QPS
- 单次会话成本(检索 + 生成 + 过滤)
- 可用性(SLA)与降级策略有效性
> 经验提示:先设“护栏指标”再追“增长指标” > 护栏指标例如投诉率、人工复检通过率、敏感内容命中率;增长指标例如转人工率下降。没有护栏的增长往往是透支。
1.7.4 风险清单:提前写在纸面上,问题就少一半
- **数据与标注风险**:意图定义不一致、标注噪声高、长尾样本不足
- **合规与隐私**:会话包含手机号/地址/订单号;训练与日志需脱敏与访问控制
- **分布漂移**:活动期、新产品上线导致意图结构变化
- **幻觉与错误回答**(生成式阶段):编造政策、错误承诺(高风险)
- **知识库新鲜度**:文档更新不同步,旧答案造成客诉
- **对抗与滥用**:提示注入、越权查询、诱导泄露内部信息
- **工程稳定性**:依赖服务抖动、缓存击穿、限流与熔断缺失
把风险清单与对应缓解措施写入上线评审,是中级团队走向成熟的重要标志。
---
1.8 交付物模板:让项目“可审计、可复盘、可交接”
为了适配团队协作与长期维护,建议至少具备以下四类交付物。下面给出可直接复用的模板骨架。
1.8.1 数据字典(Data Dictionary)模板
| 字段名 | 含义/口径 | 类型 | 示例 | 缺失率 | 取值范围/约束 | 备注 | |---|---|---|---|---:|---|---| | `session_id` | 会话唯一标识 | string | `abc...` | 0% | 全局唯一 | 用于按会话切分 | | `utterance` | 用户原始文本 | string | “怎么退货” | <1% | UTF-8 | 入库前脱敏 | | `intent_label` | 人工标注意图 | enum | `refund` | 20% | 受控标签集 | 缺失表示未标注 | | `channel` | 渠道 | enum | `app/web` | 0% | 受控 | 用于切片监控 | | `timestamp` | 消息时间 | datetime | 2026-03-01 | 0% | ISO8601 | 时间切分依据 |
1.8.2 训练报告(Training Report)模板
``` 1) 任务与范围
- 目标:...
- 标签集版本:...
- 兜底策略:...
2) 数据
- 时间窗口:...
- 样本量(按标签分布):...
- 切分方式:按会话/按时间;随机种子:...
- 清洗规则与脱敏策略:...
3) 模型与训练
- 模型结构/预训练权重:...
- 超参:batch size、lr、epoch、loss、early stop...
- 训练环境:Python/框架/CUDA/镜像版本;Git commit:...
4) 评估结果
- 总体指标:...
- 关键切片指