工具链升级后,我的简历终于不再被筛掉了
每天早上8点,我雷打不动坐在工位上,泡好咖啡,打开终端——这不是自律,纯粹是因为住得离公司近,通勤时间省下来能多睡半小时。作为小红书推荐算法组的一名两年经验工程师,我最近被“工具”这件事狠狠教育了一回。
事情起源于上个月投简历的事。别笑,虽然我在小红书干着推荐算法,但跳槽这事儿谁没想过?尤其看到脉脉上同行晒的offer数字,手就有点痒。结果投了几家大厂,连面试题挑战都没等到,简历直接石沉大海。HR朋友偷偷告诉我:“你们组的技术栈写得太‘老派’了,连个现代MLOps工具链都没体现。”
我当场愣住。我们线上系统跑得好好的啊!AB测试稳如老狗,特征工程也挺规范……但回头一看简历,确实全是“熟悉Python、Sklearn、TensorFlow”,连个像样的工具名都拿不出手。这年头,光会写模型不够,你得会“造轮子+搭流水线+搞监控”,否则简历系统直接给你打低分。
于是,我下定决心:不为跳槽,也为技术尊严,必须把本地那套“脚本拼凑式”开发流程升级成工业级工具链。目标很明确:让每次实验可复现、可追溯、可对比,并且——能写进简历里。
一场由“特征漂移”引发的工具革命
导火索发生在双11前两周。我们上线了一个新召回通道,结果第二天CTR暴跌3%。排查半天,发现是离线训练用的特征和线上推理的特征版本对不上——因为特征生成脚本被另一个同学改了,而我没拉最新代码。
当时真的想砸电脑。更气人的是,测试同学甩过来一句:“你们算法能不能搞个feature registry?别老靠口头同步。”
行吧,被逼到墙角了。我花了三天时间调研,最终选定 MLflow + DVC + Feast 这套组合拳:
- MLflow:跟踪实验、注册模型
- DVC:管理数据集和模型文件(替代Git LFS)
- Feast:统一特征存储,线上线下一致
听起来高大上,其实落地过程全是坑。
坑1:MLflow 的 tracking server 怎么部署?
一开始我本地跑 mlflow ui,美滋滋。但团队要用,就得上服务。我试着用公司K8s部署,结果权限卡死。运维大哥白了我一眼:“你们算法又想搞基础设施?”
最后妥协方案:用公司内部封装的轻量级Web服务框架搭了个简易tracking server,数据库接的是团队共用的PostgreSQL实例。虽然不如官方方案优雅,但能跑就行——毕竟deadline在追命。
# 实验记录示例
import mlflow
mlflow.set_tracking_uri("http://internal-mlflow.myteam.svc:5000")
with mlflow.start_run(run_name="recall_v2_with_new_features"):
mlflow.log_param("model_type", "TwoTower")
mlflow.log_param("feature_version", "feat_v3_20241015")
mlflow.log_metric("auc", 0.872)
mlflow.log_artifact("model.pkl") # 实际用DVC存,这里简化
关键不是代码多酷,而是每次跑实验,自动打上特征版本、代码commit ID、超参——这些全都能在UI里查,再也不用翻Slack聊天记录。
坑2:DVC 和 Git 的协作让人头秃
DVC 要求你把大文件替换成 .dvc 指针文件,然后提交到Git。但团队里有人忘了装DVC hook,直接把原始pkl文件push上来,仓库直接爆炸。
解决方案?写了个 pre-commit hook 强制检查:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: forbid-large-files
name: forbid large files
entry: python scripts/check_large_files.py
language: python
types: [file]
配合CI流水线,在merge request阶段自动扫描是否有 >10MB 的非 .dvc 文件。一旦发现,直接 block 合并——产品经理看了都说“这比需求评审还严格”。
坑3:Feast 的 feature view 写错一个字段,线上炸了
Feast 要求 offline 和 online 的 feature view 定义一致。我第一次写的时候,offline 用了 user_click_count_7d,online 却写成 user_click_cnt_7d,结果线上特征全为null。
监控告警倒是及时触发了(感谢SRE团队),但回滚花了两小时。从此我养成了一个习惯:所有 feature view 必须通过单元测试验证一致性。
def test_feature_consistency():
from feast import FeatureStore
store = FeatureStore(repo_path=".")
offline_df = store.get_historical_features(...)
online_val = store.get_online_features(...).to_dict()
# 断言关键特征值在合理范围内
assert abs(offline_df["click_rate"].mean() - online_val["click_rate"]) < 0.01
现在,这个测试成了MR(Merge Request)的强制检查项。虽然写起来烦,但比起半夜被oncall叫醒,这点麻烦算什么。
面试题挑战?现在我能出题了
工具链跑顺之后,最大的惊喜不是效率提升(虽然确实快了40%),而是——我终于能在面试中聊点有深度的东西了。
以前被问“你们怎么保证实验可复现?”,我只能尬笑说“我们用Git tag”。现在我可以掏出MLflow截图,讲清楚从数据版本、代码版本、特征版本到模型版本的全链路追踪。
上周参加公司内部的技术分享会,我甚至被邀请去给校招生做“算法工程化实践”的讲座。讲完后有个实习生跑来问:“学长,这些工具是不是只有大厂才用得上?”
我笑了:“恰恰相反。越小的团队越需要自动化,否则全靠人肉记忆,迟早崩盘。”
效果与反思:工具不是银弹,但能救命
三个月下来,我们的实验迭代速度明显加快。以前一个AB实验从开发到上线要5天,现在3天搞定。更重要的是,线上事故减少了70%——大部分问题在CI/CD阶段就被拦住了。
我把这套实践整理成文档,更新到了个人简历的技术栈部分:
- 构建基于 MLflow + DVC + Feast 的 MLOps 工具链,实现特征/数据/模型全生命周期管理
- 设计自动化实验追踪与对比机制,支持日均200+模型实验
- 推动团队落地 feature consistency 单元测试,降低线上特征错误率
投出去的简历,终于开始收到面试邀约了。上周刚面完一家AI创业公司,面试官第一句就是:“看你简历里提到Feast,能讲讲你们怎么解决冷启动特征的吗?”
那一刻,我知道,这场工具升级,值了。
一点真心话
很多人觉得“工具”是运维或infra的事,算法只要调好模型就行。但在今天的小红书、抖音、快手这种亿级DAU的场景下,模型效果只是冰山一角,底下90%是工程基建。
你写的每一行代码,未来都可能变成线上服务的依赖。没有工具约束,再聪明的算法也会被混乱拖垮。
所以,别嫌麻烦。花一周时间搭好工具链,可能换来未来半年的安稳睡眠。毕竟,谁不想下班前准时关机,回家吃口热饭呢?
(当然,如果产品经理突然说“明天上线新需求”,那当我没说 😅)
| 工具 | 用途 | 是否写入简历 | 团队采纳度 |
|---|---|---|---|
| MLflow | 实验追踪 & 模型注册 | ✅ | 100% |
| DVC | 数据/模型版本管理 | ✅ | 90% |
| Feast | 特征存储与一致性保障 | ✅ | 80% |
| 自研Hook | 防止大文件误提交 | ❌(太琐碎) | 100% |
| Feature Test | 特征一致性验证 | ✅ | 70% |
最后送大家一句话:简历不是写出来的,是做出来的。你真正用过、踩过坑、优化过的工具,才是最有说服力的“项目经验”。
共勉。

评论 0