搜索文章

输入关键词开始搜索

如何设计项目AI改造Skill

AI#AI#AI Coding#Agent#Skill#工程化

最近在 AgentInfra 里做了一个新的 Skill,名字叫 harness-builder

把项目约束沉淀为可执行 Skill 的改造流水线

这个 Skill 的目标不是帮某个项目生成一份漂亮的 AGENTS.md,而是做一件更实际的事:当我拿到一个新项目,或者一个已经跑了很久的老项目时,如何把它改造成一个 AI 更容易接手、也更不容易乱改的项目。

一开始我脑子里的需求其实有点大:

  • 检查并优化项目里的 AGENTS.md
  • 把 Karpathy 风格的编码约束放进去;
  • 吸收一个已有项目里的 CLAUDE.md.claude 目录设计;
  • 把一篇关于 Claude Code 记忆系统的文章落地;
  • 老项目还要跑一次整体代码体检;
  • 最后生成项目文档导航,让后面的 AI 能快速进入状态。

这个需求如果直接写,很容易写成一个“万能改造器”。看起来很强,实际上大概率会很危险。

因为老项目最怕的不是没有规则,而是被一个看似懂项目的工具,直接重写了规则。

一开始容易走偏的地方

我最开始下意识会把这个 Skill 想成一个自动化工具:

给我一个项目路径,我自动扫描,自动生成 AGENTS.md,自动加 hooks,自动生成项目 skills,自动把外部文章重新读取并总结,最后自动改完。

这个方向看起来很顺,但里面有几个问题。

第一个问题是,项目改造不是纯生成任务。

一个老项目里原来可能已经有 AGENTS.mdCLAUDE.md、Cursor rules、CI、测试命令、团队历史约束。这些内容不一定写得好,但它们是项目事实的一部分。直接用模板覆盖,等于把历史上下文删掉。

第二个问题是,外部资料不能每次重新理解。

这次参考了三类材料:

  • multica-ai/andrej-karpathy-skills 里的编码代理行为约束;
  • 一个 AimeClaw 项目里的 CLAUDE.md、rules、skills、hooks 示例;
  • 一篇关于 Claude Code 自我学习和记忆系统的文章。

这些材料的价值不是“每次执行时再去读一遍”,而是把里面稳定的设计原则提炼出来,变成 Skill 自己的固定参考资料。否则这个 Skill 每次运行都会带着不稳定输入,今天总结成这样,明天又总结成另一个样子。

第三个问题是,hooks 和记忆系统不能默认安装。

那篇记忆系统文章里有一个判断我觉得很对:Skill 依赖模型主动调用,Hook 更确定。比如工具调用前后记录 observation,会话结束后分析规律,下次会话开始前注入记忆,这些事情用 Hook 更合适。

但反过来,Hook 一旦安装,就是在改变用户的运行时环境。默认安装格式化、记录、Stop 分析、SessionStart 注入,听起来很完整,实际很容易变成新的干扰源。

所以最后的设计不是“自动安装记忆系统”,而是“默认生成轻量的项目记忆和 bug-pattern 机制,Hook 只作为模板和建议,用户确认以后再装”。

最后收敛成一个原则

这个 Skill 最后收敛成一个很简单的流程:

diagnose -> report -> confirm -> apply -> validate

先诊断,再报告,再确认,再落地,最后验证。

这里最重要的是前两步。项目 AI 改造不是上来就改文件,而是先回答几个问题:

  • 这是新项目还是老项目?
  • 有没有 Git 历史和已有代码?
  • 有没有 AGENTS.mdCLAUDE.md.cursor/rules 之类的入口?
  • 有没有 docs/README.md 这种文档地图?
  • package.json 里有没有 testlinttypecheckbuild
  • 有没有 CI?
  • 有没有项目本地 skills?
  • 有没有 hooks?
  • 有没有明显的私有路径、secret 或运行时缓存风险?

这些问题不应该靠模型凭感觉回答,所以我给 Skill 加了两个脚本。

第一个是:

node capabilities/skills/engineering/harness-builder/scripts/scan-project.mjs <project-path> --json

它只读扫描项目,输出项目分类、入口文件、文档状态、包管理器、命令、CI、hooks、项目 skills 和风险标记。

第二个是:

node capabilities/skills/engineering/harness-builder/scripts/validate-harness.mjs <project-path> --json

它检查改造结果是否真的落地:

  • AGENTS.md 是否存在;
  • docs/README.md 是否存在;
  • docs/ai-harness/README.md 是否存在;
  • 是否有日期化审计报告;
  • 是否生成了最小项目 skill 组;
  • skill frontmatter 是否有效;
  • Markdown 和 skill 文件里是否出现 /Users/<name>/... 这种私有路径;
  • 是否有类似 API key 的内容。

这一步很关键。没有验证脚本,Skill 很容易变成“写了一堆文件,看起来挺完整”。但下次 AI 进项目时,真正能不能用,其实没人知道。

AGENTS.md 不应该变成百科全书

这次设计里有一个我反复提醒自己的点:AGENTS.md 要短。

很多项目做 AI 改造时,最容易犯的错是把所有内容都塞进入口文件:

  • 项目背景;
  • 架构说明;
  • 编码规范;
  • 命令;
  • 历史 bug;
  • 外部文章摘要;
  • 个人偏好;
  • hooks 说明;
  • skill 说明;
  • TODO;
  • 临时计划。

最后这个文件会越来越像垃圾桶。AI 每次进来都读,但读完也不一定抓得住重点。

所以 harness-builder 的默认设计是:

  • AGENTS.md 只做主入口;
  • docs/README.md 做项目文档导航;
  • docs/ai-harness/README.md 记录 AI harness 状态;
  • docs/ai-harness/audits/YYYY-MM-DD-harness-audit.md 放诊断和改造报告;
  • 项目级重复流程放到 .agents/skills/

这其实是把“入口”和“知识库”拆开。

入口文件只告诉 AI:

这个项目是什么,不能碰什么,常用命令是什么,进一步的文档在哪里。

更长的内容放到 docs 和 project skills 里。需要的时候再读,不需要的时候不要污染上下文。

为什么要生成项目本地 Skills

另一个设计选择是:改造项目时,不只是生成文档,还要生成一组最小项目 skills。

默认是五个:

.agents/skills/<project>-router/SKILL.md
.agents/skills/<project>-onboarding/SKILL.md
.agents/skills/<project>-dev-doctor/SKILL.md
.agents/skills/<project>-quality-gate/SKILL.md
.agents/skills/<project>-audit-followup/SKILL.md

这里我没有选择“生成一大包 Skill”。因为项目刚开始改造时,最需要的不是十几个花哨能力,而是几个稳定入口。

router 负责把常见任务路由到正确文档或技能。

onboarding 负责让 AI 先读项目地图、命令、架构、风险,不要一上来就改代码。

dev-doctor 负责本地启动、依赖、命令失败的诊断。

quality-gate 负责跑和解释项目已有的 lint、typecheck、test、build。

audit-followup 负责把审计报告里的问题拆成小的、可验证的整改任务。

这些 Skill 要跟项目走,所以默认放在项目里的 .agents/skills/,并且带项目名前缀。不要放到用户全局目录里。全局 Skill 放太多项目事实,后面一定会串味。

老项目必须先体检

对新项目来说,初始化一套 harness 问题不大。真正麻烦的是老项目。

老项目里已有代码、已有命令、已有文档、已有团队习惯。它可能没有 AI 规则,但不代表它没有规则。很多规则只是散落在 README、CI、测试文件、commit 历史和目录结构里。

所以这个 Skill 里定了一个比较粗但实用的判断:

非空 Git 仓库默认按老项目处理。

老项目先跑只读诊断。如果本机有 yulifeng-codebase-audit,就用这个 Skill 做更严格的整体体检;如果没有,就跑内置的轻量检查,并明确标注扩展审计不可用。

这里的重点不是“打分”,而是后续能不能根据报告继续自迭代。

一个好的审计报告应该告诉 AI:

  • 当前项目最缺的证据是什么;
  • 哪些规则入口不可靠;
  • 哪些测试或质量门禁缺失;
  • 哪些 hooks 只是建议,不能默认安装;
  • 哪些问题应该本周修,哪些可以后面处理;
  • 每个整改项的验收标准是什么。

没有这一步,后面的 AI 优化很容易变成“我觉得可以优化一下”,然后开始乱动。

外部资料怎么进入 Skill

这次有一个比较重要的处理:外部材料不原样塞进去。

Karpathy guidelines 进入 Skill 后,只保留几个稳定原则:

  • 先说清假设;
  • 保持改动小;
  • 不做无关重构;
  • 定义可验证目标;
  • 需求不清先停下来问。

AimeClaw 的 CLAUDE.md.claude 目录,也没有原样复制。里面有很多 AG-UI、适配层、shadcn、端口等项目专用内容,复制到别的项目就是污染。真正有价值的是结构:

  • 入口文件说明项目职责边界;
  • rules 单独拆文件;
  • skills 编码重复流程;
  • code-review agent 对照项目规则检查;
  • hooks 做格式化或质量门禁,但本地配置不能变成通用模板。

微信文章里的记忆系统,也没有直接照搬成完整向量库方案。它真正给我的启发是:

  • 规则要能长期积累;
  • bug pattern 要能回流到项目;
  • Hook 比 Skill 更适合确定性触发;
  • 但默认改造必须轻量,不能上来就装一套 observation + embedding + Qdrant。

所以 harness-builder 里只把它转成轻量版本:项目记忆、bug-pattern、文档导航、可选 hook 模板。完整向量召回系统以后可以做,但不应该是默认路径。

又从 v3 workflow 里补了一刀

后来我又看了一份 v3.zip

这里面有一套更完整的 AI coding workflow,从 Phase 0 到后面的实现、校验、交接都有。第一反应当然是:这么完整,是不是应该全塞进 harness-builder

但仔细看完以后,我觉得不应该。

一方面,里面的 prototype-workflow/ 其实已经和 AgentInfra 里的 workflows/ai-coding-v3/ 对上了。也就是说,它不是一个缺失的新素材,而是已经存在的一套完整工作流。再把它复制进 harness-builder,只会让两个地方同时维护同一套东西。

另一方面,harness-builder 的定位不是“替项目安装一套完整 AI 开发流程”,而是先把项目变成 AI 能稳定接手的状态。它应该补的是项目的地基,不是直接规定每次开发都要走六个阶段。

所以最后只吸收了 v3 里最必要的三类东西。

第一类是 .docs4agents 上下文包。

它默认包含三个文件:

.docs4agents/codebase-inventory.md
.docs4agents/forbidden-list.md
.docs4agents/implementation-rules.md

这几个文件解决的是同一个问题:不要把项目事实只留在当前对话里。

codebase-inventory.md 记录组件、接口、路由、状态、hooks、工具函数这些项目地图。没有就写没有,不确定就写 unknown,而不是让 AI 猜。

forbidden-list.md 记录不能做的事情,而且必须带 SourceVerification。因为“不要动这个目录”本身不够,后面的 AI 还要知道这条规则从哪里来、怎么验证有没有违反。

implementation-rules.md 记录项目级实现边界,比如怎么改、怎么验、遇到不确定信息时放到哪里。

第二类是决策记录和开放问题。

新增两个文件:

docs/ai-harness/decision-log.md
docs/ai-harness/open-questions.md

decision-log.mdDEC-001 这种 ID 记录长期有效的决定,比如 hooks 为什么默认不安装、质量门禁以哪个命令为准。

open-questions.mdQ-001 记录没证据的问题,比如 CI 里的某个命令是不是本地也必须跑。这个文件很重要,因为 AI 最大的坏习惯之一就是“看起来很确定地补全未知信息”。把未知问题显式写下来,就是在给后面的 AI 留刹车。

第三类是验证门槛。

我没有只在文档里说“请创建这些文件”,而是把它加进了 validate-harness.mjs

  • .docs4agents 三件套必须存在;
  • codebase-inventory.md 至少要有组件、接口、路由等基本栏目;
  • forbidden-list.md 必须有 RuleSourceVerification
  • decision-log.md 必须有 DEC-* 记录;
  • open-questions.md 必须有 Q-* 记录;
  • 审计报告不能只是观察,必须有风险、行动和验收标准。

这次补完以后,harness-builder 的边界更清楚了:它不复制 v3 的完整开发流程,只借它最实用的“文件化上下文”和“可验证交接”思想。

这也是我觉得做 Skill 时很容易被忽略的一点:看到好东西不要马上全加。先问一句,这个东西是在降低下一次接手项目的混乱,还是在给默认路径增加新的复杂度。

这个 Skill 最后长什么样

最终在 AgentInfra 里,harness-builder 是一个 core engineering skill。

它的结构大概是:

capabilities/skills/engineering/harness-builder/
  SKILL.md
  agents/openai.yaml
  references/
    source-digests.md
    harness-output-spec.md
  scripts/
    scan-project.mjs
    validate-harness.mjs

SKILL.md 负责流程和边界。

source-digests.md 固化前面几类参考材料,不让执行时每次重新联网理解。

harness-output-spec.md 规定目标项目应该生成什么、AGENTS.md 怎么合并、项目 skills 怎么命名、hooks 怎么处理、验收标准是什么。

scan-project.mjsvalidate-harness.mjs 负责确定性检查。

同时它被注册到 manifests/assets.json 里,作为 core-engineering profile 的一部分。这样后续 AgentInfra 生成 Codex、Claude、Cursor 等目标适配时,它会跟着核心工程能力一起输出。

这一步也有一个设计边界:harness-builder 是 AgentInfra 的通用能力,但它生成的项目 skills 应该留在目标项目里。不要把某个项目的 onboarding、dev-doctor、quality-gate 全都装到用户全局目录。

自测为什么重要

这次不是只写了 Skill 文档,还给脚本补了测试。

测试里覆盖了几个场景:

  • 空目录应该识别成新项目;
  • 非空 Git repo 应该识别成老项目;
  • 能识别 AGENTS.mdCLAUDE.md、CI、hooks、项目 skills;
  • 能识别 .docs4agents 上下文包和 harness 决策记录;
  • 能从 package.json 里识别 testlinttypecheckbuild
  • 完整 harness 应该通过验证,包括 .docs4agents、决策日志、开放问题和可执行审计;
  • 缺少 v3 派生的上下文记录时应该报错;
  • 缺 docs 或出现 /Users/alice/... 这种私有路径时应该报错。

最后跑的验证包括:

node --test tests/*.test.js
node scripts/agentinfra/inventory.js
node scripts/agentinfra/validate.js
node scripts/agentinfra/build-target.js --target codex --profile core-engineering --dry-run
git diff --check

这里还有一个小插曲:本机 shell 里没有全局 node,所以最后用的是 Codex runtime 里的 Node 路径。这个细节也提醒我,项目 harness 里不能假设环境一定完整。缺依赖、命令不存在,本身就是诊断结果的一部分。

这次的经验

这次做完以后,我对“项目 AI 改造 Skill”有几个比较明确的判断。

第一,Skill 不是大 prompt。

如果只是把一堆原则写进 SKILL.md,让 AI 自己发挥,那它不稳定。真正容易出错、容易重复的部分,要变成脚本或明确的验收规则。

第二,项目改造要先读项目,而不是先套模板。

尤其是老项目,原来的文档和规则可能很乱,但不能默认它们没价值。正确做法是保留项目事实,压缩重复内容,把入口变短,把长内容迁移到 docs 和 skills。

第三,hooks 要克制。

Hook 很强,但强就意味着风险也大。默认输出模板和建议,用户确认后再安装,比“一键全装”更稳。

第四,记忆系统应该先轻量落地。

先有项目记忆、bug-pattern、审计报告、整改清单。等这些基础东西真的用起来,再考虑 observation、embedding、向量召回。否则很容易为了“智能”引入一堆新的维护成本。

第五,最终要能验证。

AI-friendly 不是一个形容词。至少要能回答:

  • 入口文件是否存在;
  • 文档地图是否存在;
  • .docs4agents 上下文包是否存在;
  • 决策日志和开放问题是否存在;
  • 项目 skills 是否存在;
  • 审计报告是否存在;
  • 审计报告里有没有风险、行动和验收标准;
  • 是否有私有路径和 secret 风险;
  • 项目已有的质量命令有没有跑过。

如果这些都回答不了,那就还只是“看起来改造过”。

后面我如果继续优化这个 Skill,会继续看两件事。

一是让它生成更好的整改任务,把审计报告里的问题拆成一批小 PR 级别的任务。

二是补一套真实项目回放测试。拿几个不同类型的项目跑一遍,看它生成的 harness 是不是实际可用,而不是只在临时 fixture 里通过。

这类工具最后拼的不是概念,而是能不能减少下一次接手项目时的混乱。