AI 编码工具发展到这个阶段,真正拉开差距的就不再是“谁的提示词写得更长”,而是“你能不能把 AI 从聊天窗口里拉出来,让它真正去干活”。所谓 Do Work Skill,不是让 AI 多写几段注释,而是把一个真实工程任务拆成可执行、可验证、可让模型自动推进的工作流——问题分析、代码修改、测试运行、结果反馈、循环修正,全部串成一条链路。
这次我们直接聊一套能落地的构建方法:从技能定义、环境准备、工作流编排,到与 Cursor、Copilot、Claude Code 这类 AI 编码工具的集成,再到测试和排错。无论你用的是编辑器内置助手,还是自己封装的大模型 API,这套思路都可以迁移过去。文章不绑定某个具体产品,所有命令示例都是通用模板,实际使用时要按你所用的工具、模型和本机路径调整。
1. 核心能力速览
在正式展开之前,先给一张整体能力表,帮助快速判断这篇文章介绍的方法论适不适合你的现状。
| 能力项 | 说明 |
|---|---|
| 核心目标 | 把 AI 从“对话生成代码”升级为“执行真实工程任务” |
| 适用对象 | 已经有基础编码经验的工程师,不是零基础入门教程 |
| 模型要求 | 推荐具备工具调用(Function Calling / Tool Use)能力的大模型 |
| 最低技术门槛 | 会写命令行、会读日志、了解 Git 基本操作 |
| 依赖环境 | Python / Node.js 环境、Git、终端、AI 编码工具或大模型 API |
| 核心产物 | 可复用的技能描述文件、编排脚本、验收清单 |
| API 能力 | 支持通过 CLI、HTTP API、编辑器插件三种方式接入 |
| 批量任务 | 支持通过脚本批量执行目录级任务,但需要设计幂等和重试逻辑 |
| 显存/GPU | 使用云端大模型 API 时不依赖本机 GPU;若本地部署模型则按模型规格评估 |
| 适合场景 | 批量代码重构、仓库级知识整理、自动化测试补充、Release 前安全检查、重复性工程杂务 |
这张表需要强调一点:本文不教“怎么安装某个特定 AI 工具”,而是教“怎么围绕自己的工程需求,构建一套 AI 能自主执行的 Skill 体系”。工具是载体,方法才是核心。
2. 什么是 Do Work Skill,它解决什么问题
先厘清概念。Do Work Skill 不是某款软件里的一个按钮,而是一种工程化的 AI 使用方式:把某项需要反复执行的工作,拆解成模型可以按步骤完成的“技能”。
2.1 为什么 AI 编码助手经常“聊得很好,活没干完”
大部分工程师使用 AI 编码助手时遇到的真实问题是这样:
- 让 AI 改一个模块,它给了代码,但没改对调用方。
- 让 AI 写测试,它写出来了,但根本没跑过,一执行全是语法错误。
- 让 AI 做代码审查,它只会说“整体设计良好,小问题若干”,这种结论无法驱动任何行动。
- 同一类任务,今天让 AI 做一遍,下周又得重新组织语言再描述一遍。
根因在于:聊天是自由度的,干活是约束的。模型没有明确的任务边界、验收标准、可用工具和失败重试策略,就只能输出“看起来对”的文字,而不是真正可交付的代码变更。
Do Work Skill 要做的,就是把这些缺失的约束补上。
2.2 一个技能应该包含哪些要素
一个完整可执行的 Skill,至少需要五部分:
| 要素 | 作用 | 示例内容 |
|---|---|---|
| 目标定义 | 让模型知道这次任务的成功标准是什么 | “将 src/legacy 下所有 Python 2 语法迁移为 Python 3 兼容写法” |
| 上下文输入 | 告诉模型从哪些文件、目录、配置里读取信息 | 指定仓库路径、文件列表、依赖描述 |
| 执行步骤 | 把大任务拆成模型能做的小动作 | 扫描目录 -> 解析语法 -> 生成补丁 -> 运行编译检查 |
| 验收标准 | 明确什么结果算通过 | 编译通过、测试通过、无新增警告、变更文件列表不超过预期 |
| 失败恢复 | 定义出错时怎么反馈给模型或人工 | 重试、跳过当前文件、记录日志、终止 |
2.3 什么样的任务适合构建成 Skill
结合真实工程场景来看,适合做成技能的任务通常具备以下特征:
- 重复频率高:每周或每个版本迭代都会做一次。
- 规则明确:可以用清单式描述界定范围。
- 结果可验证:有构建、测试、命令输出等硬指标。
- 流程较长且步骤稳定:不是一句话能说清,但每个步骤本身都是机械操作。
- 涉及多文件:遍历式处理比人工一个个改更值得自动化。
典型的候选包括:多模块接口参数统一调整、引入新 lint 规则后全仓库修复、API 文档与代码同步校准、测试文件骨架生成、依赖升级后的兼容性扫查。这些任务不需要很强的设计感,但非常消耗时间,正好适合交给 AI 以技能方式执行。
3. 环境准备与前置条件
构建 Do Work Skill 之前,先把环境理顺。这里给的是通用检查清单,版本号不建议盲目锁定。
3.1 基础环境清单
| 环境项 | 推荐配置 | 说明 |
|---|---|---|
| 操作系统 | macOS / Linux / Windows 均可 | 主要影响脚本语法和路径写法,思路一致 |
| 终端 | 支持 UTF-8 和长命令输出 | Windows 推荐 PowerShell 7 或 Windows Terminal |
| Git | 已安装并完成基础配置 | 后续用 Git 做变更回滚和 diff 审查 |
| Python 或 Node.js | 至少安装一个 | 用于写编排脚本、调用 API、处理文件 |
| AI 编码工具 | Cursor / Claude Code / Aider / Copilot CLI 之一 | 如果只用自制 API,则准备一个可用的 HTTP 调用环境 |
| 大模型 API Key | 能调用支持工具调用的模型 | 不同的模型对工具调用的能力和稳定性差异很大 |
3.2 验证环境是否可用
在正式开始之前,先跑三个基础检查命令:
# 检查 Git 是否可用 git --version # 检查 Python 环境 python3 --version # 检查 Node 环境(二选一即可) node --version如果你准备调用大模型 API,还需要准备一个可以发送 HTTPS 请求的环境,并用一个最小请求验证 API Key 是否有效:
# 通用 API 调用模板,实际 URL 和请求体需按模型服务商文档调整 curl -X POST "https://your-model-provider.example.com/v1/chat/completions" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "your-model-name", "messages": [{"role": "user", "content": "ping"}], "max_tokens": 16 }'能返回正常 JSON 响应,说明链路可用。注意这里的域名和字段仅是示例,不能直接复制到具体服务上。
3.3 网络与服务访问说明
使用在线大模型 API 时,需要保证网络能正常访问对应服务商域名。如果所在团队的开发环境有网络限制,需要提前申请白名单。涉及企业内部代码仓库时,必须确认代码外发到模型服务商的权限边界,建议优先使用已经完成数据安全备案的企业服务或私有化部署方案。不要为了省事把生产代码直接传到一个没有任何授权的第三方服务里,这是合规底线。
4. 构建第一个 Do Work Skill:完整流程拆解
这一步是文章的核心部分。我们以“批量重命名模块内函数调用”为例,演示如何从零到一构建技能。任务背景很简单:某个 SDK 的接口从get_user_info改成了query_user_profile,仓库里大量模块还在用旧函数名,需要全量替换并保证编译通过。
4.1 第一步:写技能描述文件
不要一开始就打开编辑器让 AI 写代码,先把技能定义写清楚。技能描述可以用 Markdown 或 YAML 保存,推荐放在仓库的.ai-skills/目录下,随仓库版本管理。
以 YAML 格式为例:
name: migrate-sdk-function-call description: 批量迁移 SDK 函数调用,将旧函数名替换为新函数名,并保持参数结构不变。 inputs: repo_path: description: 目标仓库路径 required: true old_function: "get_user_info" new_function: "query_user_profile" file_extensions: - ".py" - ".js" - ".ts" steps: - scan: 在目标仓库内搜索所有包含旧函数名的文件。 - filter: 排除测试生成目录、node_modules、.git 等不需要修改的路径。 - replace: 执行精确替换,保留调用参数和缩进。 - compile_check: 按项目类型运行语法检查或编译命令。 - report: 输出修改文件列表、剩余匹配项、失败项。 acceptance_criteria: - 代码中不再出现旧函数名的直接调用。 - 语法检查或编译命令执行成功。 - 每个文件修改都有对应的 diff 记录。 failure_recovery: - 如果编译失败,定位失败文件并回滚该文件的修改。 - 单文件失败不影响其他文件继续执行。 - 所有失败文件汇总到 errors.log。这个描述文件解决了两个问题:一是模型看到任务后不用反复追问“目录在哪、范围是什么、成功标准是什么”;二是人工可以审查步骤,在真正执行前发现边界问题。
4.2 第二步:设计可执行脚本骨架
技能描述文件是给模型看的,执行还是需要脚本把它与真实代码环境连接起来。这里给一个 Python 编排脚本的通用框架,核心逻辑是四段:收集输入、执行步骤、收集结果、输出报告。
import json import subprocess import sys from pathlib import Path def run_step(step_name, command): """执行子进程命令并返回输出,按需替换为具体命令""" print(f"[step] {step_name}") result = subprocess.run(command, shell=True, capture_output=True, text=True) return { "step": step_name, "success": result.returncode == 0, "stdout": result.stdout[-2000:], "stderr": result.stderr[-2000:], } def scan_files(repo_path, extensions): """扫描仓库内指定扩展名的文件,排除通用目录""" exclude_dirs = {".git", "node_modules", "dist", "build", ".venv"} files = [] for ext in extensions: files.extend(Path(repo_path).rglob(f"*{ext}")) return [f for f in files if not any(part in exclude_dirs for part in f.parts)] def main(): repo_path = sys.argv[1] if len(sys.argv) > 1 else "." old_func = sys.argv[2] if len(sys.argv) > 2 else "get_user_info" new_func = sys.argv[3] if len(sys.argv) > 3 else "query_user_profile" extensions = sys.argv[4].split(",") if len(sys.argv) > 4 else [".py"] files = scan_files(repo_path, extensions) print(json.dumps({"scanned_files": len(files)}, ensure_ascii=False)) # 此处应插入真实替换逻辑:读文件、精确替换、写回 # 建议使用 AST 或正则 + 人工 review diff,避免误替换注释中的内容 # 执行语法检查示例,按实际语言替换 check_result = run_step("compile_check", f"python -m compileall {repo_path}") with open("skill_report.json", "w", encoding="utf-8") as fp: json.dump({"scan_count": len(files), "compile_check": check_result}, fp, ensure_ascii=False, indent=2) if __name__ == "__main__": main()这里有一个非常重要的工程判断:函数名替换这类任务,看似简单,实际容易误伤。注释、字符串、变量名里都可能出现同名文本。因此真正的实现不能简单用字符串替换,要用语言自带的抽象语法树(AST)工具做代码级替换,或者生成 diff 后人工审阅。脚本骨架只展示了流程结构,目的不是让读者直接复制到生产环境。
4.3 第三步:设计提示词把技能交给 AI
脚本是自动化路径,但在很多 AI 编码工具里,技能是由模型在对话中执行工作的。因此还需要一份“给模型看的提示词模板”。它的作用是唤起模型的执行模式,而不是让模型自由发挥。
你现在是一个执行技能"SERVER-SKILL/migrate-sdk-function-call"的工程代理。 任务背景:SDK 接口名已变更,需要全量替换仓库内的旧函数名。 仓库路径:{REPO_PATH} 旧函数名:{OLD_FUNCTION} 新函数名:{NEW_FUNCTION} 文件范围:{FILE_EXTENSIONS} 执行要求: 1. 先扫描仓库,输出所有包含旧函数名的文件清单。 2. 排除 node_modules、.git 等目录。 3. 只修改函数调用位置的代码,不修改注释、字符串文档里的历史描述。 4. 逐个文件生成修改后的 diff。 5. 最后运行语法检查并向用户输出汇总。 6. 如果某个文件无法自动处理,跳到下一个文件,最后单独列出。 不要输出与任务无关的代码优化建议。 不要一次性重写整个文件,尽量做最小改动。 每一步完成后告诉我当前进度,不要等我追问。这段话术的关键是给了 AI“跳过机制”和“最小改动原则”。否则模型很容易在一碰到障碍时停下,或者在可以局部修改时强行重写整个文件。
5. 将这个 Skill 接入 AI 编码工具
Do Work Skill 构建好之后,下一步是让它进入日常开发工具链。常见的接入方式有三种:CLI 调用、HTTP API 调用、编辑器内嵌入。这里分别说明通用路径。
5.1 接入 CLI 工具
Aider、Claude Code 这类 CLI 型 AI 编码工具,通常会在启动时加载项目上下文。可以把技能描述文件所在目录加入项目的.aider.conf或类似配置中,然后在对话里用一句话唤起技能。实际命令因工具而异,无法给出统一命令。但通用的工作方式是:
# 进入项目目录后启动 CLI 工具,示例名称仅为通用写法 # ai-coding-cli --project . --skill .ai-skills/migrate-sdk-function-call.yaml # 启动后输入:执行 migrate-sdk-function-call 技能,仓库路径为当前目录这种方式的优点是变更过程可见,AI 每一步会解释意图,工程师可以随时打断纠正。缺点是 CLI 工具读文件目录可能受配置文件限制,要确认技能描述文件在模型可访问的上下文里。
5.2 接入 HTTP API
如果你希望把技能系统化地集成到内部工具链里,比如 CI 或者批量任务平台,正确的做法是在自己的服务里写一个调度器,把技能描述文件转成请求消息,再发给模型服务商的 API。下面是一个通用 Python 调用示例:
import requests api_url = "https://your-model-provider.example.com/v1/chat/completions" headers = { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" } skill_prompt = open(".ai-skills/migrate-sdk-function-call.yaml", encoding="utf-8").read() payload = { "model": "your-model-name", "messages": [ {"role": "system", "content": "你是一个严格按技能描述执行任务的工程代理。"}, {"role": "user", "content": f"{skill_prompt}\n\n请开始执行任务。"} ], "tools": [ { "type": "function", "function": { "name": "run_shell", "description": "在仓库目录下执行 shell 命令并返回输出", "parameters": { "type": "object", "properties": { "command": {"type": "string"} }, "required": ["command"] } } } ], "temperature": 0.1 } resp = requests.post(api_url, headers=headers, json=payload, timeout=180) print(resp.json())注意:不同服务商的 tools 参数格式不一样,有些是tools,有些是functions,有些通过tool_choice控制模型是否必须调用工具。必须按实际文档调整。temperature建议调低,执行类任务需要确定性,不需要创造性。
5.3 接入编辑器插件
Cursor、Copilot 这类编辑器集成工具不适合跑复杂技能,但适合把技能描述文件.ai-skills/目录放在项目中,然后在对话里用@.ai-skills/xxx.yaml引用。编辑器插件的好处是模型能直接看到当前打开的代码文件,适合“小步快跑”式的单文件技能,例如:
- 给当前文件补测试。
- 分析当前文件的复杂度。
- 修复 lint 错误。
但要注意:编辑器对话上下文窗口有限,仓库级任务不建议在里面执行,否则模型读到一半就忘了前面的文件内容。
6. 功能测试与效果验证
技能不是写出来就能用的,必须有系统化的验证流程。这里把测试分成三层,每一层都有自己的通过标准和失败处理方法。
6.1 第一层:脚本功能测试
在接入模型之前,先测试脚本本身。测试方法是准备一个小型临时仓库,里面构造三种文件:需要修改的正常文件、包含同名注释的干扰文件、故意留下语法错误的失败文件。然后执行脚本:
# 以 Python 脚本为例,按实际入口调整 python skill_runner.py ./tmp_repo get_user_info query_user_profile ".py,.js,.ts"这个测试的目的有两个。第一,确认扫描路径是否正确;第二,确认真实替换逻辑不会误伤注释里的文本。查看skill_report.json中的扫描数量和修改列表,如果干扰文件被错误修改,说明替换逻辑需要加强。
6.2 第二层:模型执行测试
脚本没问题后,再用模型执行一次相同的任务。观察点包括:
- 模型是否按照技能描述的顺序执行。
- 模型是否会调用预设的工具函数。
- 模型遇到错误时是否继续执行,还是卡住等待。
- 模型输出的 diff 是否最小,有没有顺便改掉无关代码。
- 模型最终报告里是否包含明确的文件清单和失败项。
这一层测试建议手动执行并记录结果。推荐用表格记录多次运行的表现:
| 运行次数 | 是否按步骤执行 | 是否误改无关代码 | 是否成功运行语法检查 | 失败处理表现 |
|---|---|---|---|---|
| 第 1 次 | 是 | 否 | 是 | 自动跳过异常文件 |
| 第 2 次 | 是 | 是 | 是 | 无跳过,全部处理 |
| 第 3 次 | 否 | 否 | 否 | 卡住,需要人工干预 |
如果连续两次运行失败率高,说明技能定义还不够细,或者模型对工具调用的理解不足,需要回到描述文件里增加示例。
6.3 第三层:真实仓库灰度验证
把自己正在维护的真实仓库切到一个新分支,然后在受限目录范围内执行技能任务。这里要特别强调:不要直接在主干分支上跑,也不要先跑全量。应当指定一个子目录作为灰度范围,成功后再逐步扩大范围。验证完成后,通过 Git diff 审查所有变更:
# 查看全部变更,必须逐行审阅 git diff 分支名 --stat git diff 分支名审查时要关注以下几点:
- 是否所有变更都与任务目标相关。
- 是否有二进制文件被意外修改。
- 是否有文件编码格式被篡改。
- 是否有测试文件被无意纳入。
如果没有问题,再提交代码,并清理临时日志文件。这不是可有可无的步骤,尤其是当模型具备修改多个文件的能力时,人工 diff 审查是最后一道也是最重要的一道防线。
7. 接口 API 与批量任务设计
当技能验证稳定后,下一步通常是把任务从“手动触发”变成“批量自动执行”。举例来说:每两周要把全仓库的废弃 TODO 清理一遍,这种任务不可能每次都在聊天框里点点点。这时候需要把技能脚本封装成可批量执行的服务。
7.1 设计批量任务目录结构
推荐使用目录扫描式批处理,而不是将任务列表硬编码在脚本里。原因很简单:目录结构可以复用,还可以通过文件命名来区分任务状态。
./workflows/ ├── pending/ # 等待执行的任务队列 │ └── task1/ │ ├── skill.yaml # 本次任务要执行的技能定义 │ └── repo_patch/ # 待处理代码的最新补丁 ├── running/ # 正在执行中的任务 ├── completed/ # 执行成功的任务 └── failed/ # 执行失败的任务调度器按顺序把pending/下的任务移动到running/,执行完成后根据结果移动到completed/或failed/。这样即使中途服务崩溃,重启后也能从running/残留目录里判断出哪些任务没有完成。
7.2 批量任务调度脚本模板
import json import shutil import time from pathlib import Path TASK_DIR = Path("./workflows") def move_task(task_name, target_dir): shutil.move(str(TASK_DIR / "running" / task_name), str(TASK_DIR / target_dir / task_name)) def execute_task(task_name): task_path = TASK_DIR / "running" / task_name if not task_path.exists(): return False # 这里加载 skill.yaml,调用模型 API 或本地脚本 # 按实际实现补充真实执行逻辑 time.sleep(2) return True def scheduler(): TASK_DIR.joinpath("pending").mkdir(parents=True, exist_ok=True) TASK_DIR.joinpath("running").mkdir(parents=True, exist_ok=True) TASK_DIR.joinpath("completed").mkdir(parents=True, exist_ok=True) TASK_DIR.joinpath("failed").mkdir(parents=True, exist_ok=True) pending = sorted(TASK_DIR.joinpath("pending").iterdir()) # 注意:这里仅展示目录切换逻辑,不是可运行的生产实现 pending_count = len(pending) print(json.dumps({"pending_tasks": pending_count}, ensure_ascii=False)) if __name__ == "__main__": scheduler()7.3 批量任务的重试与幂等设计
批量任务最容易踩的坑是重试导致重复修改。解决方案是给每个任务生成一个唯一的task_id,并且让任务执行具有幂等性:同样的输入,无论执行多少次,最终结果一致。为了实现这一点,建议在技能设计中加入“执行前检查当前状态”的步骤。比如迁移任务,第一次执行后旧函数名已经没了,第二次执行扫描结果为空,就应该直接返回“无需修改”,而不是全仓库报错。
另一个坑是 API 调用超时。建议给每次调用设置较长超时时间,并实现指数退避重试:
# 伪代码:重试策略 # 第1次失败:等待 5 秒 # 第2次失败:等待 15 秒 # 第3次失败:等待 45 秒 # 超过 3 次:把任务标记为 failed,写入日志,留给人工处理不要让批量任务无限重试,否则某个意图错误的技能会在整个仓库里反复横跳,最终产生无法恢复的代码变更。
8. 资源占用与性能观察
虽然使用云模型不涉及本机 GPU 显存,但“资源”在这里有另一层含义:上下文窗口、Token 消耗、任务执行时长和 API 成本。这四项才是在真实工程中真正需要监控的指标。
8.1 上下文窗口的占用
仓库级任务最怕的问题就是上下文溢出。如果技能描述文件很长、仓库文件很多,模型的上下文窗口可能很快被占满。建议在发消息前先估算文件大小,并让技能脚本在传入上下文之前自动截断超大文件。可以设置一个阈值:单文件超过 500 行就先让模型读取前 100 行,再按需读取后续内容。这比一次性把整个文件塞进去更稳。
8.2 Token 消耗与成本控制
Token 消耗通常是 Cost-Per-Task 而不是 Cost-Per-Character。影响消耗的因素主要有四个:
- 技能描述文件长度。
- 被扫描文件数量。
- 模型是否反复阅读同一批文件。
- 工具调用返回的 stdout 是否过长。
建议在每个步骤中限制子进程命令的输出长度。比如git diff输出可能非常大,如果全部返回给模型,不仅浪费 Token,还容易让模型被无关信息干扰。可以在脚本里截断到最近若干行,并只返回失败摘要。
8.3 执行时长观察
影响执行时长的因素更多在模型推理速度。同一任务在不同模型下的表现差异很大,不能只按模型名判断。观察时建议记录三个数字:首次响应时长、平均单步执行时长、总完成时长。如果某个步骤明显慢于其他步骤,检查是不是该步骤要求的工具调用输出的数据量过大。
以下是一个简单的性能观察记录格式:
| 执行阶段 | 耗时 | Token 消耗 | 是否成功 |
|---|---|---|---|
| 任务扫描 | 3s | 500 | 是 |
| 替换阶段 | 42s | 5200 | 是 |
| 语法检查 | 5s | 300 | 是 |
| 汇总报告 | 8s | 800 | 是 |
9. 常见问题与排查方法
下面整理一份在真实环境里最高频出现的故障清单,每一条都对应明确的排查路径。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 模型拿到技能描述后不执行,只给建议 | Skill 描述缺少明确的执行指令 | 检查描述文件中的 steps 是否清晰 | 增加“不要输出建议,直接执行”等约束 |
| 模型扫描文件时漏掉子目录 | 文件扫描逻辑忽略嵌套目录 | 查看脚本中的 rglob 行为 | 使用递归遍历,并打印全路径日志 |
| 替换函数时误改注释和字符串 | 使用了简单的字符串替换 | 查看 diff 中是否包含注释改动 | 改用 AST 或加入“跳过注释”逻辑 |
| 模型篡改无关代码 | 提示词未定义“最小改动”边界 | 对比实际 diff 和任务目标 | 在技能描述中加强最小改动原则 |
| API 调用频繁超时 | 上下文太长或工具输出过多 | 查看调用时长和返回字节数 | 截断工具输出、减少传入文件数量 |
| 批量任务执行到一半卡住 | 重试循环没有退出条件 | 查看任务状态目录是否停留在 running | 配置最大重试次数和超时退出 |
| 模型报告成功但代码无法编译 | 验收标准缺失 | 检查是否真的运行了编译命令 | 在技能里增加强制编译检查,失败则拒绝提交 |
| 多次运行结果不一致 | 模型 temperature 过高或工具调用不稳定 | 对比两次运行日志 | 将 temperature 调低,并为工具调用增加确定性结果缓存 |
10. 最佳实践与使用建议
到这里,Do Work Skill 的核心链路已经完整了。最后给出几条实战建议,这些建议来自通用工程经验,适合在团队里直接落地。
10.1 先小后大,先手后自
不要第一次就把整条技能全自动跑起来。建议先让模型在人工监督下执行,确认每个步骤的输出符合预期后,再移除人工确认环节。批量任务一开始也在子目录小范围执行,连续成功多次后再扩大范围。这样可以避免模型在失控时对全仓代码造成不可逆影响。
10.2 每次执行都保留完整日志
技能的稳定性判断不能靠感觉,要靠日志。每次执行至少保留三个信息:被扫描文件列表、产生的 diff 摘要、每一步的模型输出。把这些日志按任务 ID 归档,后续排查问题时才能找到依据。
10.3 技能描述文件要纳入版本管理
技能描述文件应当和代码一起提交到 Git 仓库,而不是放在本机的随意目录里。这样可以实现两个好处:一是同一个仓库的工程师可以共享同一套技能定义;二是当技能定义调整后,可以在代码历史里看到变更原因。推荐在仓库根目录建立.ai-skills/目录,并在团队文档中声明这个目录的用途。
10.4 权限与合规边界
最后必须强调合规。使用 AI 编码工具执行任务时,至少要确认四件事:
- 代码仓库是否允许将内容发送给外部模型服务商。
- 修改的代码是否涉及版权归属问题,尤其是企业自有代码或第三方授权代码。
- 如果任务涉及用户数据、密钥信息,模型输出内容不得成为泄露渠道。
- 自动化工具产生的代码变更在合并前必须由正式工程师审查签名。
这四条不是空话。它们决定了你的 AI Coding Skill 究竟是一个提升生产力的工程工具,还是一个随时引爆合规问题的隐患。不要因为图省事而跳过授权确认。
10.5 技能库要持续迭代
一个技能在第一版通常只能跑通 70% 的场景。真正让技能变强的是后续迭代:每执行一次,收集失败案例,把失败原因写回技能描述文件的failure_recovery部分。坚持迭代两三个版本之后,你会发现技能的执行成功率会显著上升,模型对边界情况的处理也会更稳定。这是最简单也最容易忽略的核心技巧。
11. 总结
这期内容给出一套从零构建 Do Work Skill 的完整方法:定义技能描述文件、建立执行脚本、设计模型提示词、接入编辑器或 API、完成三层测试、再扩展到批量任务。本质上是把 AI 编码助手的定位,从一个“回答代码问题的工具”转变为一个“能执行工程任务的代理”。如果你正在写这篇文章对应的实践,第一步建议先挑一个本周做过两次以上的重复性任务,把它拆成技能描述文件和脚本,跑一次全流程。最容易踩的坑不是模型不聪明,而是你给模型的任务边界太模糊,验收标准不明确,失败恢复机制缺失。这三件事补齐了,AI 编码能力会往前走一大步。下一阶段可以继续扩展的方向包括:多技能协同、技能间的依赖编排,以及把技能接入 CI/CD 流水线自动触发。希望这套方法能直接落到你的日常开发流程里。