过去一年,我观察到一个很有意思的分水岭:同样在用 AI 写代码,有些团队把它当高级补全工具,有些团队却能用它快速交付完整功能。造成这种差距的关键,不只是模型能力,而是一套让 AI“把事情干完”的方法。这篇文章会把这套方法拆开来讲:什么是 Do Work Skill,怎么构建可复现的 AI Coding 工作流,并通过一个批量重命名 CLI 工具的完整案例,展示从任务定义、上下文封装、代码生成到测试验证的全过程。
适合正在尝试把 AI 编码工具接入真实项目的工程师,也适合想从“AI 生成代码片段”进阶到“AI 交付任务”的开发者。读完你会掌握一套可复用的任务拆解方法,知道怎么写清晰的任务说明书,也能理解为什么“让 AI 跑通测试”比“让 AI 写出更长的代码”更有价值。
1. AI Coding 与 Do Work Skill 到底是什么
1.1 从自动补全到智能体
AI Coding 这个说法,经历过三个阶段的变化。
最早是自动补全。模型根据你光标前面的代码,预测下一个 token,本质是“更聪明的输入法”。典型场景是写 SQL、写 boilerplate、补一个函数签名。这个阶段 AI 不承担需求理解,也不会主动修改多个文件。
然后是对话式生成。你在对话框里描述需求,AI 一次性生成一段代码甚至一个文件。相比自动补全,它已经能理解自然语言,但生成结果是静态的,需要你自己复制到编辑器,自己运行,自己发现问题。
到了 Agent 阶段,工具的边界明显变了。AI 不再只是回答问题,而是可以读取项目文件、执行命令、运行测试、根据报错修改代码,甚至在指定目录里新建文件。它具备了一个“初级开发者在本地环境里做事”的基本能力。这也是当前 AI Coding 生态里讨论最多、进展最快的方向。
1.2 为什么代码生成不等于任务完成
很多工程师对 AI Coding 的失望,来自同一个误区:以为让 AI 生成代码,就等于让 AI 完成任务。
举一个很常见的例子。你让 AI“写一个批量重命名脚本”,它能很快给你一份 Python 代码,看起来逻辑完整。但你真正要的,可能是一个能处理文件名冲突、支持试运行、测试覆盖充分、README 写清楚用法的小工具。这两者之间的差距,不是代码行数,而是工程完整度。
我把这种差距概括为“写代码”和“做工作”的区别:
- 写代码:输出一段语法正确、逻辑基本通顺的代码。
- 做工作:理解需求,产出方案,实现功能,处理边界,运行验证,补充文档,交付可维护的结果。
“Do Work Skill”就是一套让 AI 从前者走向后者的方法。它不是指某个模型能力,而是指我们在使用 AI Coding 工具时,如何定义任务、提供上下文、建立验证闭环,让 AI 真正把工作推进到“可交付”状态。
这个能力是可以被刻意训练的。只要你把流程标准化,一次成功的工作流,可以被复用到下一个任务里。
1.3 Do Work Skill 能解决什么问题
在实际项目中,Do Work Skill 最擅长处理的一类任务是:需求明确、有边界、结果可以自动验证的小型开发工作。
典型的例子包括:
- 编写一个独立的命令行工具或脚本。
- 给已有模块补充单元测试。
- 修复带有明确报错信息的 bug。
- 搭建项目脚手架。
- 编写数据迁移脚本并进行试运行。
- 把一段过程式代码重构成多个小函数。
这类任务的共同特点是,它们可以通过测试、构建、lint 等命令来验收。AI 做完了没有,跑一遍测试就知道。这正是 Do Work Skill 能发挥价值的核心条件。
反过来,如果需求本身含糊不清,或者没有自动验证手段,AI Coding 的效率会明显下降。这一点决定了我们后续设计工作流时的整体思路:尽量把模糊需求变成可验证任务,把主观判断变成客观检查和人工 Review。
2. 当前 AI Coding 工具链的几种形态
2.1 IDE 插件与对话式工具
先把当前常见的 AI Coding 工具形态梳理一遍。
第一类是基于 IDE 的插件。它们嵌入在 VS Code、JetBrains 等编辑器里,提供代码补全、内联生成、选中代码解释、生成测试等能力。这类工具的优势是距离代码最近,适合在写码过程中快速获得建议。它的限制是缺乏“全局任务”的执行能力,很难主动跑测试并迭代修改。
第二类是对话式网页工具。你可以在网页里描述需求,它会返回代码并附带解释。适合快速验证想法、学习语法、生成一次性脚本。但它的代码没有和你的仓库关联,验证成本高,交付链路也长。
第三类是编码智能体工具,比如当前比较常见的 Coding Agent。它们通常拥有终端执行、文件读写、代码检索等能力,可以在一个工作目录里自主完成“读文件、写代码、跑测试、修 bug”的循环。这是构建 Do Work Skill 最理想的载体。
2.2 Agent 型工具与云端开发平台
Agent 型工具通常有两种运行方式。
一种是本地运行。Agent 直接在你本机的项目目录里操作,读取真实代码,运行真实命令。这种方式的好处是环境真实,坏处是权限边界如果不控制,AI 可能做出超出预期的操作。
另一种是云端开发平台。平台会提供一个隔离的在线环境,AI 在云端容器里完成修改,再把结果同步回来。比如 Vercel 等公司在 AI 编码平台上的探索,本质上就是把“开发环境 + AI 执行 + 预览部署”打包在一起,降低使用门槛。
国内也能看到类似的需求趋势,比如 GLM Coding Plan 这类面向实际开发场景的 Coding 产品,更强调订阅计划、任务量、长期使用成本,说明 AI Coding 正从“尝鲜功能”变成“日常研发工具”。
不过这类工具迭代非常快,不同产品能力差异也很大。选型时我更建议关注底层能力,而不是只看宣传。
2.3 选型时的核心判断标准
如果你打算把 AI Coding 接入工作流,可以从四个维度判断工具是否可用:
一是可执行环境。AI 能不能真的运行命令,能不能读取文件系统。如果只能输出代码,那它仍停留在“写代码”阶段。
二是上下文长度。工具能不能装下你整个项目结构、关键文件、错误信息。上下文大小直接决定了 AI 能不能理解全局。
三是权限控制。能不能限制 AI 只能修改某个目录,能不能禁止它执行危险命令。这是工程安全的关键。
四是可观察性。AI 做了什么操作,改了哪些文件,跑出了什么结果,是否全部有日志。没有日志的 AI 工具,出问题时根本无法排查。
这四个标准,后面的实战案例都会用到。
3. 构建 Do Work Skill 的四个关键步骤
3.1 第一步:任务拆解
不要一下子给 AI 一个很大的需求,比如“给我做一个用户系统”。你应该把它拆成多个可独立交付的小任务。
一个合格的任务描述,应该包含三个要素:
- 输入:任务基于什么环境、什么代码、什么数据。
- 动作:AI 需要做什么,修改哪些文件。
- 验收:做完之后,用什么命令或标准判断任务完成。
举个例子,同样是写一个用户注册接口,不要这样描述:“帮我写注册功能”。可以拆成:
- 在
app/api/auth.py中新增POST /register接口,接收用户名和密码。 - 密码使用强哈希算法存储,不允许明文入库。
- 用户名已存在时返回 409,参数缺失时返回 400。
- 完成实现后运行
pytest tests/test_auth.py -v,保证新增测试全部通过。
任务越小,验收越明确,AI 的完成质量就越高。
3.2 第二步:上下文封装
AI 没有长期记忆,它只能根据当前对话里的上下文做判断。所以,你要把必要的信息写进任务说明书,而不是让 AI 猜。
上下文至少应该包括:
- 项目技术栈和语言版本。
- 项目目录结构,尤其是 AI 需要改动的位置。
- 关键文件的核心逻辑。
- 运行命令,比如如何安装依赖、如何跑测试、如何启动服务。
- 代码规范,比如命名风格、是否需要类型标注。
我习惯把这些统一写进一个spec.md文件。每次让 AI 做事之前,先把 spec 内容贴给它。这样一来,任务描述是稳定的,AI 不需要在多次对话中反复问同样的问题。
3.3 第三步:反馈闭环
这是整个 Do Work Skill 里最重要的一步。
AI 必须能“看到”自己的执行结果。写完代码,跑测试;测试失败,看报错;根据报错改代码;改完再跑测试。这个“执行-观察-修改-再执行”的循环,就是反馈闭环。
没有闭环的 AI Coding,就像闭着眼睛改 bug。AI 生成代码,你把代码复制到项目里,手动跑一遍发现报错,再复制回去让它改。这种来回成本很高,而且效率完全取决于你的耐心。
有闭环的 AI Coding,是一个自治系统:AI 自己写代码,自己执行,自己看结果,自己迭代。你要做的,是在任务说明书里明确要求它完成这一整套循环。
比如在任务越权范围里写明:
完成代码后,必须执行 python -m pytest tests/test_bulk_rename.py -v。 如果测试失败,阅读错误信息,修改代码后重新执行,直到全部通过。这句话看似简单,但它把一个“生成代码”的 AI 变成了“交付任务”的 AI。
3.4 第四步:权限边界
给 AI 权限时,遵循最小权限原则。
不要让它能访问整个服务器,不要让它能改任何文件。在任务里指定它只能操作某个目录,只能修改关键文件,不能执行rm -rf等破坏性命令,不能连接生产数据库。
权限边界不只是为了安全,也是为了让 AI 更专注。当 AI 的可操作范围被约束到一个仓库、一个模块、几个文件时,它的决策空间变小,出错率也会显著下降。
如果你的 AI Coding 工具支持分支、沙箱或者审批机制,尽量开启。让 AI 在独立分支上工作,最后通过 Pull Request 由人工审查合入,是当前比较稳妥的工程实践。
4. 完整实战:让 AI 交付一个批量重命名 CLI 工具
接下来通过一个完整案例,展示整套流程怎么落地。
我们给 AI 的任务是:开发一个 Python 命令行工具,批量重命名指定目录下的.txt文件,新文件名为前缀_序号.txt。
4.1 需求与验收标准
第一步不是写代码,而是定义需求。
需求描述:
- 工具名:
bulk-rename - 功能:扫描指定目录下所有
.txt文件,按文件名字典序排序,然后重命名为{prefix}_{序号:03d}.txt - 安全要求:默认只打印计划,不实际改名;加
--apply才真正执行 - 冲突处理:如果新文件名已经存在,不能覆盖,必须报错
- 技术限制:只使用 Python 3.9+ 标准库,不引入第三方依赖
- 交付物:
bulk_rename.py、test_bulk_rename.py、README.md
验收方式:测试文件全部通过,手工运行 dry-run 模式能正确输出改名计划。
这个需求不复杂,但它包含了边界条件、安全约束和验收标准,足够用来演示 Do Work Skill 的核心方法。
4.2 编写任务说明书 spec.md
把上面的需求,整理成一个任务说明书。
# 任务:批量重命名 CLI 工具 ## 目标 实现一个 Python 命令行工具,批量重命名指定目录下的 .txt 文件。 ## 约束 1. 使用 Python 3.9+ 标准库,不引入第三方依赖。 2. 默认 dry-run,只打印重命名计划,加 --apply 才真正执行。 3. 新文件名格式:`{prefix}_{序号:03d}{原后缀}`。 4. 按原始文件名字典序处理,保证顺序稳定。 5. 如果目标文件已存在,必须报错,不能覆盖任何文件。 6. 提供 pytest 测试和 README 文档。 ## 交付物 - bulk_rename.py - test_bulk_rename.py - README.md ## 验证命令 python -m pytest test_bulk_rename.py -vspec.md的价值在于,它把模糊的口头需求,变成了 AI 可以直接执行的工作指令。
4.3 给 Agent 的初始提示词
有了 spec.md,接下来的提示词就简单了。核心是三点:读 spec、按计划执行、必须跑测试。
你负责完成以下开发任务,要求产出可运行代码,不能只给思路。 1. 先阅读仓库里的 spec.md 文件,列出你的实现计划。 2. 根据 spec 实现 bulk_rename.py。 3. 编写 test_bulk_rename.py,覆盖正常重命名、dry-run 模式、目标文件已存在三种场景。 4. 完成代码后,必须执行: python -m pytest test_bulk_rename.py -v 5. 如果测试失败,阅读错误信息,修改代码后重新运行,直到全部通过。 6. 不要修改 spec.md 文件。 7. 所有操作都在当前仓库目录下进行,不要创建无关文件。这段提示词的关键,不是命令 AI 写代码,而是要求它建立反馈闭环:实现、测试、失败、修改、再测试。
4.4 审查后的最终代码
AI 可能会给出多种实现。下面是我认为比较合理且符合约束的一版,你可以把它保存为bulk_rename.py。
#!/usr/bin/env python3 """批量重命名指定目录下的 .txt 文件。""" import argparse from pathlib import Path def collect_files(directory: Path, suffix: str = ".txt") -> list[Path]: """收集目录下指定后缀的文件,按名称字典序排序。""" return sorted( [p for p in directory.iterdir() if p.is_file() and p.suffix == suffix] ) def build_plan( files: list[Path], prefix: str, start: int = 1 ) -> list[tuple[Path, Path]]: """生成原路径到新路径的重命名计划。""" plan = [] for index, src in enumerate(files, start=start): dst = src.with_name(f"{prefix}_{index:03d}{src.suffix}") plan.append((src, dst)) return plan def apply_plan(plan: list[tuple[Path, Path]]) -> None: """按计划执行重命名,目标文件已存在时主动报错。""" errors = [] for src, dst in plan: try: if dst.exists() and dst != src: raise OSError(f"目标文件已存在: {dst}") src.rename(dst) print(f"renamed: {src.name} -> {dst.name}") except OSError as exc: errors.append((src, dst, exc)) if errors: for src, dst, exc in errors: print(f"ERROR: {src.name} -> {dst.name}: {exc}") raise SystemExit(1) def main() -> None: parser = argparse.ArgumentParser(description="批量重命名 .txt 文件") parser.add_argument("--directory", required=True, help="目标目录") parser.add_argument("--prefix", required=True, help="新文件前缀") parser.add_argument("--suffix", default=".txt", help="要重命名的后缀,默认 .txt") parser.add_argument("--start", type=int, default=1, help="起始序号,默认 1") parser.add_argument( "--apply", action="store_true", help="真正执行重命名,不加则只打印计划" ) args = parser.parse_args() directory = Path(args.directory) if not directory.is_dir(): parser.error(f"目录不存在: {directory}") files = collect_files(directory, args.suffix) if not files: print("未找到匹配的文件。") return plan = build_plan(files, args.prefix, args.start) print("重命名计划:") for src, dst in plan: print(f" {src.name} -> {dst.name}") if not args.apply: print("\n这是 dry-run 模式,未执行任何操作。加 --apply 才真正重命名。") return apply_plan(plan) if __name__ == "__main__": main()这段代码最重要的设计是默认 dry-run。批量重命名是高风险操作,一旦改错文件名,恢复成本很高。让用户先看计划,再决定是否执行,这是命令行工具应该有的基本安全意识。
4.5 测试与运行验证
接下来是测试文件test_bulk_rename.py。它覆盖了三个场景:正常收集文件、生成正确的新文件名、目标文件冲突保护。
import tempfile from pathlib import Path from bulk_rename import build_plan, collect_files def test_collect_files(): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "b.txt").write_text("b") (root / "a.txt").write_text("a") (root / "c.log").write_text("c") files = collect_files(root, ".txt") assert [p.name for p in files] == ["a.txt", "b.txt"] def test_build_plan(): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) (root / "a.txt").write_text("a") (root / "b.txt").write_text("b") plan = build_plan(collect_files(root, ".txt"), prefix="note", start=1) assert plan[0][1].name == "note_001.txt" assert plan[1][1].name == "note_002.txt" def test_apply_plan_conflict(): with tempfile.TemporaryDirectory() as tmp: root = Path(tmp) src = root / "a.txt" dst = root / "note_001.txt" src.write_text("a") dst.write_text("existing") import pytest with pytest.raises(SystemExit): from bulk_rename import apply_plan apply_plan([(src, dst)])在终端运行验证命令:
python -m pytest test_bulk_rename.py -v预期输出包含:
test_collect_files PASSED test_build_plan PASSED test_apply_plan_conflict PASSED再手工试一下 dry-run 模式:
mkdir -p /tmp/bulk_demo touch /tmp/bulk_demo/a.txt /tmp/bulk_demo/b.txt /tmp/bulk_demo/c.txt python bulk_rename.py --directory /tmp/bulk_demo --prefix note输出:
重命名计划: a.txt -> note_001.txt b.txt -> note_002.txt c.txt -> note_003.txt 这是 dry-run 模式,未执行任何操作。加 --apply 才真正重命名。最后加--apply执行:
python bulk_rename.py --directory /tmp/bulk_demo --prefix note --apply输出:
renamed: a.txt -> note_001.txt renamed: b.txt -> note_002.txt renamed: c.txt -> note_003.txt到这里,AI 交付的工具通过了测试,也通过了实际运行验证。
4.6 本次实战的关键复盘
这个案例并不复杂,但整个流程可以复用到更大的任务上。
从结果往回看,真正决定成败的节点有三个:
第一个是需求定义。我明确了默认 dry-run、冲突报错、只使用标准库这三个约束。没有这些约束,AI 很可能写出一版“上来就把文件名改了”的危险工具。
第二个是反馈闭环。我明确要求 Agent 必须执行 pytest,失败就改代码。这一步把 AI 从“单次生成”逼成了“迭代交付”。
第三个是人工审查。我没有直接信任 AI 的全部输出,而是在交付前检查了代码逻辑,尤其是文件覆盖保护和 dry-run 逻辑。这个审查动作,在任何 AI Coding 流程里都不应该省。
5. 常见问题与排查思路
5.1 高频问题速查表
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| AI 只输出代码,不执行命令 | 工具的 Agent 能力未开启,或提示词没有要求执行 | 换成支持终端执行的工具,并在任务中明确要求运行验证命令 |
| AI 改了 A 文件,导致 B 文件报错 | 上下文不足,AI 没有读完依赖文件 | 让 AI 先读项目结构和关键文件,再开始修改 |
| 测试一直失败 | 环境差异,或 AI 没有真正看报错信息 | 要求 AI 把报错信息复制到任务中,分析后再改 |
| AI 修改了无关文件 | 权限边界过大 | 设置最小权限,只允许修改指定目录 |
| 生成代码风格和项目不一致 | 没有在任务里声明代码规范 | 在 spec.md 中写明 lint 命令和风格要求 |
| 任务交付结果不符合业务预期 | 验收条件定义模糊 | 把每个任务都写成“可测试、可验证”的验收标准 |
5.2 几个典型问题的深入分析
第一个高频问题是“AI 只给代码不执行”。这通常不是因为模型笨,而是因为提示词没有给 AI 执行命令的许可和指令。你需要在任务里明确写“完成代码后必须运行 pytest,失败则修改后重试”。如果工具本身不支持命令执行,再好的提示词也无法形成闭环。
第二个高频问题是“上下文不够”。AI 只看到你贴给它的代码片段,没有看到项目里其它相关模块。解决方法是让 AI 先做侦察,比如执行find . -type f -name "*.py",或者明确要求它阅读某个核心模块后再动手。
第三个高频问题是“环境和本地不一致”。AI 在云端环境里测试通过,你本地跑却报错。这种情况下不要急着让 AI 改代码,先对比 Python 版本、依赖版本、环境变量。你可以把本地的pip freeze结果贴给 AI,让它基于真实环境调整。
第四个高频问题是“AI 改出了安全问题”。比如生成代码里硬编码了密钥,或者执行了有副作用的操作。唯一的解决办法是人工审查和最小权限并行。不要因为 AI 效率高就跳过代码审查,尤其是涉及文件删除、数据库写入、外部请求的代码。
6. 工程化最佳实践
6.1 建立可复用的任务模板
如果团队里有多个人在用 AI Coding,一定要把任务说明书做成模板,而不是靠每个人自由发挥。
我的推荐目录结构是这样的:
ai-tasks/ ├── templates/ │ ├── spec_template.md │ └── agent_prompt.md ├── tasks/ │ └── bulk-rename/ │ ├── spec.md │ ├── agent_prompt.md │ └── result/spec_template.md定义任务目标、约束、交付物、验证命令;agent_prompt.md定义给 AI 的固定提示词框架;result目录放 AI 交付的代码和人工审查记录。
把一次成功的任务保存下来,下次遇到类似需求时,直接复制模板,替换业务描述即可。
6.2 安全和审查不能省
AI Coding 最容易被忽视的问题,是安全边界。
使用 AI 工具时,需要注意几个原则:
- 不要把生产数据库的连接串、云厂商密钥、用户隐私数据写进任务描述。
- 涉及删除、覆盖、批量修改的操作,先让 AI 提供 dry-run,再由人确认执行。
- AI 生成的外部依赖,要检查版本和来源,不要盲目安装。
- 涉及权限变更、支付逻辑、数据迁移等高风险代码,必须由有经验的工程师人工审查。
- 让 AI 在独立分支或沙箱环境中工作,不要在主干分支上直接修改。
这些原则看起来是常识,但在 AI 编码的快节奏里,很容易被忽略。越是用 AI 提效,越要在安全和审查上守住底线。
6.3 让 AI 在分支上工作
在实际项目中,我建议把 AI Coding 的流程和 Git 工作流结合起来。
一个推荐的流程是:
- 在仓库中新建一个分支,比如
feat/ai/bulk-rename。 - 在分支下编写
spec.md和agent_prompt.md。 - 让 AI 在分支目录下执行任务。
- AI 交付后,人工审查代码并运行测试。
- 确认无误后,通过 Pull Request 合入主干。
这样做的好处是:AI 的每次改动都可以被追溯,出问题时可以随时回滚;人工审查也有清晰的 diff 作为依据。
6.4 版本化管理 Prompt 和任务
很多团队已经把代码纳入版本管理,但还没有把 Prompt 和任务说明书纳入版本管理。
在我看来,这些文本应该和代码一样被保存、被 review、被迭代。因为它们本质上也是工程资产。一次好的任务拆分,可以让 AI 在数小时内完成过去需要数周的开发工作;而一次糟糕的 Prompt,可能让团队浪费一整天。
把 spec.md、agent_prompt.md、README 都提交到 Git 仓库里。几个月后再看,你会惊讶于这些“文本资产”给项目带来的帮助。
7. 总结与学习路线
手工重跑一遍本文的案例,收获会比我直接讲结论大得多。你可以创建一个临时目录,把spec.md放进仓库,然后打开一个支持 Agent 的 AI Coding 工具,把agent_prompt.md的内容粘贴进去,观察 AI 如何完成从实现到测试的整个循环。
整个过程中,你只需要盯着三件事:AI 有没有读懂 spec?AI 有没有真正执行测试?AI 在面对失败时是怎么修复的?这三件事,基本决定了一个 AI Coding 任务能否被认定为“交付”。
如果本篇文章对你有帮助,可以先收藏备用。后续可以继续研究几个方向:如何把 AI Coding 接入 CI 流水线、如何设计更细粒度的权限控制、如何为复杂项目编写更完善的任务说明书。这些都是在真实工程里提升 AI 交付质量的关键路径。