第十四章 代码质量清单:从“能跑”到“可交付”
本文提出了一份提升代码质量的交付清单,旨在将数据分析与AI项目从"能跑"升级为"可交付"的标准。文章将"可交付"拆解为四个层级:能跑、可复现、可验证和可运维,并针对每个层级给出了具体实施建议。核心内容包括:规范项目结构、编写清晰README、统一代码风格、建立测试体系、明确接口类型、分层错误处理、完善日志配置、管理依赖环境等。最后提供了一

第十四章 代码质量清单:从“能跑”到“可交付”
-
- 0. 本章目标与适用场景
- 1. 交付的定义:不是“能跑”,而是“可控”
- 2. 项目结构清单:入口清晰,依赖可控
- 3. README 交付清单:让别人 10 分钟跑通
- 4. 代码规范清单:减少“风格争论”,提高一致性
- 5. 测试清单:数据/AI工程的“最小测试金字塔”
- 6. 类型与接口清单:输入/输出要“讲得清楚”
- 7. 错误处理清单:可恢复 vs 不可恢复(别全靠 raise)
- 8. 日志与可观测性清单:别让 print 负责上线
- 9. 配置与环境清单:把“魔法常量”赶出代码
- 10. 依赖与可复现清单:能装、能锁、能升级
- 11. CI 自检清单:让质量“自动发生”
- 12. 一份可直接复制的交付检查表(Review 用)
- 13. 小结:质量清单的价值,是“让团队省时间”
你一定见过这种项目:
- 本地能跑,换台机器就报错(路径、依赖、环境变量全靠缘分)。
- 脚本能出结果,但没人敢改(改一行崩一片,回滚靠记忆)。
- 代码写完“交付”给同事,结果对方问的第一句是:入口在哪?怎么复现?
数据分析与 AI 工程的真实门槛,从来不是“写出第一版”。
而是能不能把它变成:可复现、可验证、可监控、可维护的交付物。
本章给你一份可直接落地的「代码质量清单」,把“工程化”这件事从抽象口号变成可执行检查项。
0. 本章目标与适用场景
学完你应该能做到:
- 把一个脚本型项目,整理成“可交付工程包”的最小形态
- 为数据/AI项目建立质量门槛:格式、测试、类型、日志、配置、性能
- 用一套清单驱动 Code Review,减少“个人风格争论”
- 把交付物写成“别人 10 分钟能跑通”的标准
1. 交付的定义:不是“能跑”,而是“可控”
我把“可交付”拆成四个层级:
大部分 AI/数据项目停在 A。
真正可交付,至少要到 C;上线服务要到 D。
2. 项目结构清单:入口清晰,依赖可控
2.1 最小工程结构(建议)
这套结构适用于训练脚本、离线特征、RAG 数据管道、小型推理服务:
myproj/
src/myproj/
__init__.py
cli.py
config.py
pipeline/
utils/
tests/
scripts/
data/ (可选:仅放小样本/示例)
pyproject.toml (或 requirements.txt)
README.md
硬要求:
- 业务代码放
src/,避免 import 混乱 README.md必须能让别人跑通tests/至少有一组“最小回归”
3. README 交付清单:让别人 10 分钟跑通
README 不需要写长,但必须写对:
- 项目一句话用途(解决什么问题)
- 环境要求(Python 版本/系统)
- 安装方式(一个命令)
- 运行方式(一个命令)
- 示例输入/输出(最好有一行示例)
- 常见问题(最容易踩坑的 3 个)
你可以用这个模板:
# myproj
## What
一句话说明:做什么、输入是什么、输出是什么。
## Setup
python -m venv .venv && source .venv/bin/activate
pip install -U pip
pip install -e .
## Run
python -m myproj.cli run --config configs/dev.yml
## Example
输入:data/sample.csv
输出:out/result.parquet
## FAQ
1) ...
2) ...
3) ...
4. 代码规范清单:减少“风格争论”,提高一致性
质量不是“写得优雅”,而是一致。
4.1 格式化与静态检查(必选)
建议工具组合:
ruff:lint + 部分格式能力(快)black:统一格式(可选,看团队习惯)isort:导入排序(如果不用 ruff 的 import 规则)
原则:不靠人记规范,靠工具强制。
4.2 命名与模块边界(工程规则)
pipeline/放流程编排,不放复杂逻辑utils/只能放通用工具,禁止放业务规则(后面会讲怎么拆)- 数据字段/特征名集中管理(避免散落全项目)
5. 测试清单:数据/AI工程的“最小测试金字塔”
你不需要一开始就写很多测试,但必须有“能兜底”的那几类:
最低交付线:
- 核心函数的边界/异常测试(例如分母为 0、字段缺失、NaN)
- 一条小样本集成测试(几十行数据跑完整链路)
- 一条回归断言(输出 schema 不变、关键指标不退化)
6. 类型与接口清单:输入/输出要“讲得清楚”
数据工程最常见的事故来自“接口不清晰”:
- 入参类型漂移(int→str)
- 约束缺失(允许空?允许 NaN?)
- 输出 schema 靠猜(列名/单位/范围不稳定)
建议每个模块都明确三件事:
- 输入类型
- 输出类型
- 边界与异常策略
可以抽象成:
f : X → Y , X 需满足约束 ; C ( X ) f: X \rightarrow Y,\quad X \text{需满足约束} ; \mathcal{C}(X) f:X→Y,X需满足约束;C(X)
当约束不满足时,你要么抛异常,要么返回可恢复的错误对象(见下一节)。
7. 错误处理清单:可恢复 vs 不可恢复(别全靠 raise)
交付的本质是“出了问题能定位”。
建议把错误分层:
最低交付线:
- IO 操作必须有超时与重试策略(至少在代码层预留接口)
- 异常必须带上下文(哪个文件、哪个batch、哪个样本)
- 不允许“吞异常后继续跑”,除非明确写了降级规则
8. 日志与可观测性清单:别让 print 负责上线
数据/AI工程一旦上线,问题通常出在:
- 某批数据 schema 变了
- 某个上游接口返回异常
- 某次模型版本切换导致指标下滑
最低交付线:
- 使用
logging,不要用print - 日志至少包含:
run_id/batch_id/step/time_cost - 关键输出要做“摘要统计”:行数、缺失率、分位数、topK 类别
- 对外服务要有请求级 trace(哪怕先做简版)
9. 配置与环境清单:把“魔法常量”赶出代码
最常见的“不可交付”原因:配置散落在代码里。
建议分层:
config.yml:业务参数(阈值、路径、开关)- 环境变量:密钥/连接串(禁止写死)
- 代码:默认值与校验规则
并建立“配置校验入口”:启动即校验(fail fast)。
10. 依赖与可复现清单:能装、能锁、能升级
最低交付线:
- 明确 Python 版本范围(例如
>=3.10,<3.13) - 依赖要锁版本(至少在生产环境)
- 给出一键安装命令(
pip install -e .或pip-sync)
进阶(付费栏目的工程建议):
- 区分 dev/prod 依赖
- 提供 Dockerfile(哪怕是基础版)
- 用 CI 跑 lint + test + minimal pipeline
11. CI 自检清单:让质量“自动发生”
CI 的本质是:把质量检查变成默认路径。
最低 CI 流程:
你不需要一次把 CI 做到很复杂,但至少要做到:
“有人提交代码,就自动告诉你会不会把项目弄坏”。
12. 一份可直接复制的交付检查表(Review 用)
你可以把它贴到 PR 模板里:
- README:新人 10 分钟能跑通
- 入口明确:
cli.py或main()清晰 - 配置外置:路径/阈值/开关不写死
- 日志齐全:step + run_id + time_cost
- 测试最小集:单元 + 小样本集成 + 回归断言
- schema 稳定:输入输出列名/类型/单位有定义
- 依赖可复现:版本范围与锁定策略明确
- CI 通过:lint/test/smoke 均绿
- 性能有底线:至少有 baseline(见第13章)
13. 小结:质量清单的价值,是“让团队省时间”
很多人把工程化理解成“更复杂”。
但真正的工程化是:让沟通成本降低,让变更风险可控,让交付变得可复制。
脚本能跑很容易;
把它变成可交付资产,才是你在数据/AI工程里真正的竞争力。
更多推荐




所有评论(0)