系列:AI 工程化实践(核心 1/5)------ 基础设施篇
写在系列开头:我做这套东西的真实起点
这个系列核心 5 篇 + 3 篇延伸------核心讲我做的 4-skill + 熵管理全闭环;延伸讲相邻项目的设计哲学、个人成长故事和可量化原则。这一篇是核心系列的第 1 篇,会从 4 个 skill 自闭环讲到熵管理方法论的源头------所有这些产出都源自一个非常具体的工作场景。
我刚进腾讯团队那段时间,周一到周五经常干到晚上 11-12 点 ------业务 feature 加 bug 单推着走。但大概 2 周后我意识到这样不可持续 ------不是身体扛不住,是我根本没时间做自己想做的有杠杆的事,每天都在做"机械工作量",能力一点都不增长。
所以我做了一个决定------主动找 mentor 谈,转向做 skill 提效。
我管这个决策叫 "提效优先级原则":
忙不过来的时候,先想哪些重复步骤可以写 skill 提效,而不是硬撑着把活做完。
等效率上去了,才有空闲时间去做真正硬的活------比如性能优化、架构升级。
听起来很普通对吧?但 99% 的工程师在压力下的本能反应是反的------忙了就加班,活多了就硬刚,结果是越干越累,越累越没时间优化,最终被淹没。
这篇文章是这个原则落地的第一个产物 ------/git-commit skill。它解决的是"每次 commit 占 3 分钟"这件最普通、但每天发生 10+ 次的事。
做完这个 skill 之后,我每天解锁 30 分钟可支配时间 ------这点时间看起来不多,但它是后面整个 4-skill 自闭环 + 熵管理方法论生长出来的种子。
背景:你每天在 commit 上浪费了多少时间?
如果你在一个多包仓库里干活,每次提交大概会经历这几步:
- 切到对应的子仓库目录
git status/git diff看改了啥- 想一个符合团队规范的 commit message
- 加上 story / bug ID 前缀( story 代表需求)
- 决定推到
main还是某个stable分支 - 如果是 stable 分支,要单独建 hotfix 分支、提 MR、等 review
- 最后回 Tapd 把单子状态改一下
我做过粗略的估计:在一个 monorepo 项目里,单次提交平均 3~5 分钟 ,一周 20+ 次 commit,纯仪式性时间 2 小时。
更糟糕的是这套流程几乎全是"机械记忆" ------一旦记错(比如 stable 分支错走了 main,或者忘了加 --bug= 前缀),CI 直接打回,又是 10 分钟。
我的判断:任何"纯流程性、无创造性、规则明确"的工作,都应该从人手里拿走。
这篇文章讲的就是我怎么把这套流程压成一个 /git-commit 命令,让 Cursor 一键搞定。
一、目标:3 个核心约束
在动手设计之前,我先把目标拆清楚:
约束 1:单一入口,零认知负担
用户只需要输入 /git-commit,剩下的全靠 AI 主动问。
约束 2:多分支路由必须 100% 正确
我们仓库的分支策略是:
| 分支类型 | 处理方式 |
|---|---|
main / dev / 自定义 |
Path B:直接 commit + push |
stableYYYYMMDD(如 stable20260409) |
Path A:从 stable 拉 hotfix 分支 → 提 MR |
releaseYYYYMMDD |
委托给 git-bugfix skill(branch-policy-v1) |
走错一次,CI 报错,整个流水线回滚------容错率 = 0。
约束 3:Tapd 状态自动流转
提交完代码不是结束。Bug 单要变 已解决、Story 要变 开发完成待验收,否则测试同学没法接手。人手动改,有概率会忘。
二、整体架构
整个 skill 的执行流程是这样的:
vbnet
用户输入 /git-commit
↓
Step 1: AskQuestion 收集信息(包名 + 类型 + ID + 目标分支多选)
↓
Step 2: Validate(stable 分支只接受 bug 修复等约束)
↓
Step 3: 展示 diff + 用户确认要 stage 的文件
↓
Step 4: 分支路由
├─ main / dev → Path B:直接 commit + push
├─ stable* → Path A:拉 hotfix 分支 + push + 创建 MR
└─ release* → 委托给 git-bugfix skill
↓
Step 5: TAPD 状态流转(bug → 已解决 / story → 开发完成待验收)
↓
最终:输出 summary 表格
下面挑几个真正难的部分展开。
三、关键设计 1:用 AskQuestion 实现"结构化对话"
最早我让 AI 自己读对话上下文 来推断"用户要往哪个分支提"------结果非常不稳定:用户说"提到 main 和 stable",AI 可能漏掉一个、可能解析出 stable 但没跟具体日期,也曾对此进行了一些简单的测试,错误率超过 30%。
后来改成 强制结构化提问:
json
{
"title": "Git commit --- target branch(es)",
"questions": [
{
"id": "target_branches",
"prompt": "目标分支(可多选):选 main 则直接 push;选 stableYYYYMMDD 则走 hotfix + MR。",
"options": [
{ "id": "main", "label": "main --- 直接 commit + push(Path B)" },
{ "id": "stable20260409", "label": "stable20260409 --- hotfix + MR(Path A)" },
{ "id": "stable20260325", "label": "stable20260325 --- hotfix + MR(Path A)" },
{ "id": "other", "label": "其他分支(在聊天里写明分支名)" }
],
"allow_multiple": true
}
]
}
关键点:
allow_multiple: true:支持同时推到main和多个stable,这是真实业务里最常见的诉求(修个 bug 既要进主干又要进当前发布分支)- stable 选项动态生成 :用
git branch -r拉最近 5 条严格匹配^stable[0-9]{8}$的分支,避免老分支污染选项 - labels 里直接写明"会做什么" :
Path A/Path B让用户对副作用有预期
经验:让 AI 推断 vs 让用户结构化选,在工程化场景永远选后者。LLM 的不确定性是工具链的灾难。
四、关键设计 2:双路径执行 + cherry-pick 兜底
最有意思的设计是 当用户同时勾选 main 和 stable 时怎么办。
错误的做法
最初我让 AI 在每个分支上独立 commit:
bash
# 错误版本:分别在 main 和 stable 上做 stash + commit
git checkout main && git stash pop && git add ... && git commit ...
git checkout stable20260409 && git stash pop && git add ... && git commit ...
第一周就翻车 :因为 stash pop 在第二次操作时已经空了。
正确的做法:先做主干,再 cherry-pick
markdown
1. fetch origin
2. 先在 main 上完成 Path B(stage → commit → push)
→ 记录 COMMIT_SHA = $(git rev-parse HEAD)
3. 对每个 stable 分支:
- 从 origin/<stable> 拉 hotfix 分支
- git cherry-pick $COMMIT_SHA ← 关键
- push + 创建 MR
为什么 cherry-pick 是对的?
- ✅ commit 内容完全一致(同一个 SHA 派生)
- ✅ 工作区不需要
stash来回腾挪 - ✅ 冲突时 git 能直接报告,不会静默吞掉
多个 stable 分支的命名也要细心:
bash
fix/bug-133058995-stable20260409
fix/bug-133058995-stable20260325
加上 stable 后缀,避免远端已存在分支冲突。
五、关键设计 3:Commit Message 自动生成
这一块是 LLM 真正能发挥的地方。
我给 AI 的 prompt 是:
- 读取
git diff --cached的 staged 内容- 分析改动的本质(功能 / 修复 / 重构 / 文档 / 配置)
- 生成简洁的英文描述(<= 72 字符)
- 套用 Conventional Commits 格式 + 团队约定的 ID 前缀
输出形如:
sql
--story=133058995 feat: add template selector component
--bug=133058995 fix: resolve websocket reconnection timeout
--story=133058995 refactor: extract shared validation logic
chore: update eslint config and add prettier rules
避坑点:
- type 必须从 diff 推 ,不能让用户选------我试过让用户选
feat / fix / refactor,结果很多同事的 story 都被勾成feat,但实际上很多是refactor。LLM 看 diff 比人看 diff 更客观。 --story=/--bug=必须放在第 1 行第 1 个位置,团队的 CI 校验是 prefix-based 的,错位置直接 reject。- 多行 commit message 只在第 1 行带前缀:
vbnet
--bug=133058995 fix: prevent duplicate event listeners on reconnect
Remove stale listeners before registering new ones in the WebSocket
manager to avoid exponential handler accumulation.
六、关键设计 4:MR 自动创建 + reviewer 指派
stable 分支必走 MR 流程。这一段是纯 API 编排:
bash
# 1. 解析 remote 拿到 host 和 project_path
REMOTE_URL=$(git remote get-url origin)
# git@git.tencent.com:aw/marketplace.git → HOST=git.tencent.com, PROJECT_PATH=aw/marketplace
# 2. 查 project ID
PROJECT_ID=$(curl -s -H "PRIVATE-TOKEN: $TOKEN" \
"https://git.tencent.com/api/v3/projects?search=$PROJECT_NAME" | \
jq -r --arg path "$PROJECT_PATH" '.[] | select(.path_with_namespace == $path) | .id')
# 3. 创建 MR
curl -s -H "PRIVATE-TOKEN: $TOKEN" \
-X POST -d '{
"source_branch": "fix/bug-133058995",
"target_branch": "stable20260409",
"title": "--bug=133058995 fix: ...",
"remove_source_branch": true
}' \
"https://git.tencent.com/api/v3/projects/$PROJECT_ID/merge_requests"
# 4. 自动添加固定 reviewer
REVIEWER_ID=$(curl -s -H "PRIVATE-TOKEN: $TOKEN" \
"https://git.tencent.com/api/v3/users?username=simonsliu" | jq -r '.[0].id')
curl -s -H "PRIVATE-TOKEN: $TOKEN" \
-X PUT -d "{\"reviewer_ids\": [$REVIEWER_ID]}" \
"https://git.tencent.com/api/v3/projects/$PROJECT_ID/merge_requests/$MR_ID"
踩过的坑:
- 内网走
git.tencent.com,走git.woa.com的某些仓库 API v3 不支持自动创建 MR,要降级成"打印手动创建 URL"。否则脚本会卡死在 401。 - token 放在
~/.tokens/git.tencent.com/token,避免每次都 prompt 用户输入。 - reviewer 的 username 不是 ID,要先查一次
/users?username=xxx拿到 ID。
七、关键设计 5:Tapd 状态流转(best-effort)
提交代码后还有一个"软依赖":把 Tapd 单子的状态改掉。
bash
# Bug → 已解决
curl -s -u "$TAPD_AUTH" -X POST \
-d "id=${TAPD_BUG_ID}&workspace_id=${TAPD_WS}&status=resolved" \
"${TAPD_API}/bugs"
# Story → 开发完成待验收
curl -s -u "$TAPD_AUTH" -X POST \
-d "id=${TAPD_STORY_ID}&workspace_id=${TAPD_WS}&v_status=开发完成待验收" \
"${TAPD_API}/stories"
关键的工程取舍:TAPD 是 best-effort,不能挂 git 流程
我设计的优先级是:
perl
git commit & push ← 主干,必须成功
↓
MR 创建 ← 主干,失败时降级到手动 URL
↓
TAPD 状态流转 ← 旁支,失败只 print warning,绝不阻塞
理由:网络抖动、TAPD API 偶尔挂、credentials 过期......这些都不应该让用户的代码白提交一次。
实现上:
bash
if [ -n "$TAPD_CLIENT_ID" ] && [ -n "$TAPD_CLIENT_SECRET" ]; then
TAPD_AUTH="$TAPD_CLIENT_ID:$TAPD_CLIENT_SECRET"
elif [ -f ~/.tokens/tapd/credentials ]; then
TAPD_AUTH=$(cat ~/.tokens/tapd/credentials)
else
echo "⚠️ TAPD credentials not found. Skipping."
# 不抛错,不退出,继续主流程
fi
工程经验 :辅助系统出错 → 警告 + 降级;核心系统出错 → 中止 + 报错。永远不要让辅助挂掉主干。
八、最终效果:从 3 分钟到 30 秒
接入后我自己 1 个月的统计:
| 指标 | 接入前 | 接入后 |
|---|---|---|
| 单次 commit 时间 | 3~5 分钟 | 30 秒 |
| 走错分支被 CI 打回 | 周均 2 次 | 0 次 |
| TAPD 状态遗忘 | 20%左右 | 0% |
| commit message 风格一致度 | 60% | 100% |
更重要的是 认知负担变成 0 :我现在写完代码,敲一句 /git-commit,盯着屏幕回 3 个问题,剩下的全自动跑完。
九、方法论升华:什么样的工作适合"AI 化"
写这个 skill 的过程中,我提炼了一套判断标准------不是所有工作都适合交给 AI:
| 维度 | 适合 AI 接管 | 不适合 |
|---|---|---|
| 流程明确度 | 步骤、分支、规则全部可枚举 | 需要主观判断 |
| 副作用 | 可回滚 / 可幂等 | 不可逆操作(删数据) |
| 错误成本 | 错了能立刻发现 | 错了几个月后才暴露 |
| 频率 | 每天 / 每周高频 | 一年一次 |
git-commit 在这 4 个维度上 全部命中:
- ✅ 流程:分支策略 + commit 格式 + Tapd 流转,完全可枚举
- ✅ 副作用:每一步都能
git reset或撤回 MR - ✅ 错误成本:CI 当场报错,5 分钟修复
- ✅ 频率:日均 4~6 次
这就是为什么这个 skill 是我在 AI 工程化路上的"第一个杀手锏"------它把一件高频、机械、容错为零的事,从我手上彻底拿走了。
下一篇预告
/git-commit 解决的是 "我已经知道要修什么 → 把代码送出去" 的问题。
但更前面的链路是:Bug 现场 → 我怎么知道要修什么? 这就需要:
- 把 Bug 现场(DOM / 日志 / 操作链路)结构化抓下来
- 让 AI 自己读 Tapd / 蓝盾日志,定位问题位置
整个系列在试图回答一个问题:
当 AI 已经能写代码,工程师还能为团队增加什么价值?
我的答案是:让 AI 写代码这件事本身,变成一件"工程化"的事------可观测、可重放、可验证、可治理。
如果这篇对你有帮助,欢迎关注,后续几篇会陆续放出。也欢迎在评论区聊聊你团队里"最值得 AI 化"的流程是什么。