1. 这个项目到底在解决什么问题
1.1 从一个真实困境说起
做前端或者全栈开发的朋友,这两年应该都有一个共同的感受:AI 工具越来越多,但真正能把它用好的团队少之又少。你可能已经习惯了用 AI 补全代码、生成单元测试、写文档注释,甚至让它帮你重构一个几百行的组件。但问题在于,每个人用 AI 的方式都不一样,有人写一大段提示词,有人随手丢一句“帮我优化一下”,还有人干脆把整个文件贴进去让模型自由发挥。结果就是:同一个项目里,AI 产出的代码质量参差不齐,风格五花八门,review 的时候比手写还累。
这个项目标题里提到的“AI 工程技能目录”,本质上就是在回应这个问题。它不是某个具体的框架或者库,而是一套结构化的、可复用的技能定义集合。你可以把它理解成一份“AI 协作说明书”——告诉 AI 在什么场景下应该做什么、怎么做、做到什么程度才算合格。27.8 万星登顶 GitHub 日榜,说明这个痛点不是个例,而是整个开发者社区都在寻找答案。
1.2 为什么是 TypeScript 社区先跑出来
这里有一个很有意思的现象:这套技能目录的发起者,是一位在 TypeScript 教育领域深耕多年的开发者。为什么是 TypeScript 社区而不是 Python 或者 Java 社区先搞出这种东西?我的理解是,TypeScript 本身就带有强烈的“契约”基因。类型系统、接口定义、声明文件,这些东西本质上都是在用结构化的方式描述“什么是什么”。当这群人开始思考“怎么让 AI 更好地写代码”时,他们很自然地会想到:能不能用类似的方式,把“技能”也定义成一种可组合、可验证的结构?
另一个原因是,TypeScript 在前端和 Node.js 生态里的覆盖面太广了。从 React 到 Vue,从 Next.js 到 NestJS,几乎所有的现代 Web 项目都绕不开它。这意味着一个通用的技能目录一旦成型,可以迅速被大量项目复用。相比之下,Python 社区虽然 AI 工具用得更早,但 Web 开发、数据科学、自动化脚本之间的差异太大,很难形成一套统一的技能描述方式。
1.3 这套技能目录适合谁用
如果你是一个独立开发者,平时一个人负责从数据库到前端的全部工作,这套东西能帮你把 AI 的输出稳定在一个可接受的范围内,减少反复修改的时间。如果你在一个小团队里做技术负责人,你可以用它来统一团队的 AI 使用规范,让每个人的 AI 助手都按照同一套标准来工作。如果你是大公司里的平台工程师,你可以把它集成到内部的开发工具链里,作为 AI 辅助编码的默认配置。
甚至,如果你只是对 AI 工程实践感兴趣,想看看别人是怎么把“提示词”这件事工程化的,这套技能目录也值得你花时间读一读。它的价值不在于代码本身有多复杂,而在于它提供了一种思考方式:把 AI 协作从“玄学”变成“工程”。
2. 核心设计思路拆解
2.1 技能不是提示词模板
很多人第一次听到“AI 技能目录”这个词,会下意识地认为它就是一堆提示词模板的集合。这个理解不能说错,但太浅了。提示词模板解决的是“怎么说”的问题,而技能目录解决的是“做什么、为什么做、做到什么程度”的问题。
我举个例子。假设你要让 AI 帮你写一个 React 组件。一个普通的提示词模板可能是这样的:“你是一个资深 React 开发者,请帮我写一个按钮组件,支持 disabled 和 loading 状态。”而一个技能定义会包含更多维度:这个组件的职责边界是什么?它应该接受哪些 props?这些 props 的类型约束是什么?它需要处理哪些边界情况?它的可访问性要求是什么?它的测试覆盖率应该达到什么标准?它的样式方案应该遵循什么约定?
换句话说,技能定义把“写一个组件”这件事拆解成了一组可检查、可验证的约束条件。AI 不是在自由发挥,而是在一个明确的框架内工作。这就是为什么它比单纯的提示词模板更有价值。
2.2 目录结构背后的逻辑
这套技能目录的组织方式,我观察下来有几个关键设计。第一是按领域分层,比如前端组件、API 设计、数据库操作、测试编写、文档生成等,每个领域下面再细分具体的技能。第二是每个技能都有明确的输入输出定义,告诉 AI 这个技能需要什么上下文、会产生什么结果。第三是技能之间可以组合,一个复杂的任务可以拆解成多个技能的串联。
这种设计的好处是,你可以根据项目的实际需要,只启用相关的技能,而不是一股脑地把所有规则都塞给 AI。比如你在做一个纯后端的项目,就不需要加载前端组件相关的技能,这样可以减少上下文长度,提高 AI 的响应速度和准确性。
2.3 为什么用 TypeScript 来定义技能
这里有一个技术选型的问题:为什么不用 YAML 或者 JSON 来定义技能,而是用 TypeScript?我的理解是,TypeScript 提供了类型检查的能力。当你定义一个技能的时候,你可以用接口来约束它的结构,用泛型来描述它的输入输出类型,用联合类型来枚举可能的状态。这意味着技能定义本身是可以被编译器验证的,不会出现拼写错误或者结构不一致的问题。
另外,TypeScript 的生态里有很多工具可以处理这些定义,比如自动生成文档、自动生成测试用例、自动生成 AI 可读的 schema。这些工具链的复用,大大降低了维护成本。如果你用 YAML 来定义,虽然写起来更简单,但失去了类型检查这一层保障,长期维护起来会更容易出错。
3. 核心细节解析与实操要点
3.1 技能定义的基本结构
一个典型的技能定义,通常包含以下几个部分。首先是元信息,包括技能名称、版本号、适用领域、依赖关系等。这部分看起来简单,但很重要,因为它决定了技能如何被索引和检索。其次是上下文描述,告诉 AI 这个技能在什么场景下应该被触发,需要哪些前置条件。然后是执行步骤,把任务拆解成一系列有序的操作。最后是验收标准,定义什么样的输出是合格的。
我实际用下来,最容易出问题的地方是验收标准。很多人写验收标准的时候太模糊,比如“代码应该清晰易读”,这种标准 AI 根本没法判断。好的验收标准应该是可量化的,比如“函数长度不超过 50 行”、“每个导出函数都有 JSDoc 注释”、“单元测试覆盖所有分支路径”。只有这样,AI 才能明确知道自己有没有做到。
3.2 上下文管理的关键技巧
AI 的上下文窗口是有限的,这是所有 AI 工程实践都绕不开的约束。技能目录在设计的时候,必须考虑如何高效地利用上下文。我的经验是,不要把整个技能定义一次性全部塞给 AI,而是根据当前任务的需要,动态加载相关的技能片段。
具体来说,你可以把技能定义拆分成多个粒度。粗粒度的技能描述用于让 AI 理解整体目标,细粒度的操作步骤用于指导具体执行。当任务比较简单的时候,只加载粗粒度描述就够了;当任务比较复杂的时候,再逐步加载细粒度的步骤。这种按需加载的方式,可以显著减少上下文占用,提高 AI 的响应质量。
3.3 技能之间的依赖与冲突处理
当你有几十个技能定义的时候,技能之间的依赖关系和潜在冲突就会成为一个问题。比如一个技能要求“所有函数都必须有显式返回类型”,另一个技能要求“优先使用类型推断以减少冗余代码”,这两个技能在某些场景下就会产生矛盾。
处理这种冲突的方式,通常有两种。一种是优先级机制,给每个技能定义一个优先级,当冲突发生时,高优先级的技能覆盖低优先级的。另一种是条件触发机制,给技能定义适用条件,只有当条件满足时才启用该技能。我个人的建议是,尽量用条件触发而不是优先级覆盖,因为优先级机制会让 AI 的行为变得难以预测,而条件触发可以让每个技能在明确的边界内工作。
注意:技能定义不是越多越好。我见过一些团队,一开始热情很高,写了上百个技能定义,结果 AI 的响应变得非常慢,而且经常出现规则冲突。后来他们精简到二十几个核心技能,效果反而更好。质量比数量重要得多。
4. 实操过程与核心环节实现
4.1 从零开始搭建技能目录
假设你现在要从零开始,为自己的项目搭建一套 AI 技能目录。第一步不是写代码,而是梳理你的项目里有哪些重复性的、有明确标准的任务。比如代码格式化、单元测试编写、API 文档生成、组件脚手架创建、数据库迁移脚本编写等。把这些任务列出来,按照频率和复杂度排序,优先处理那些高频且规则明确的任务。
第二步是为每个任务定义技能。我建议从一个最简单的技能开始,比如“生成符合项目规范的 React 函数组件”。这个技能的定义应该包含:组件的文件命名规则、组件的 props 类型定义方式、组件的样式方案、组件的测试文件位置和命名规则、组件的导出方式。把这些规则写清楚,然后让 AI 按照这个技能定义生成一个组件,看看输出是否符合预期。
第三步是迭代优化。第一次生成的技能定义肯定不完美,你需要根据 AI 的实际输出,不断调整验收标准和执行步骤。这个过程可能需要反复几次,但每次调整都会让技能定义更精确。
4.2 一个完整的技能定义示例
下面我用一个虚构的示例来展示技能定义的结构。假设我们要定义一个“生成 API 请求函数”的技能。
interface ApiRequestSkill { name: "generate-api-request"; version: "1.0.0"; domain: "frontend/data-fetching"; context: { trigger: "当需要为某个后端接口创建前端请求函数时"; prerequisites: [ "已存在对应的 TypeScript 接口定义", "已确定请求库(如 fetch 或 axios)" ]; }; steps: [ "根据接口定义生成请求参数类型", "生成请求函数,包含错误处理和加载状态", "生成对应的单元测试,覆盖成功和失败场景", "导出函数并添加到模块的 index 文件" ]; acceptance: { typeSafety: "所有参数和返回值必须有明确的类型标注"; errorHandling: "必须捕获网络错误和业务错误,并返回统一的错误格式"; testCoverage: "单元测试必须覆盖至少 80% 的分支"; naming: "函数名必须遵循 camelCase,并以动词开头"; }; }这个示例展示了技能定义的基本要素:名称、版本、领域、触发条件、前置条件、执行步骤和验收标准。实际使用的时候,你可以根据项目的具体情况调整这些内容。
4.3 集成到开发工作流
技能目录写好了,接下来要解决的问题是怎么让它融入日常开发。最直接的方式是把它作为 AI 编码助手的配置文件。现在很多 AI 编码工具都支持自定义指令或者规则文件,你可以把技能定义转换成这些工具能识别的格式。
另一种方式是把技能目录做成一个内部工具。比如你可以写一个 CLI 命令,当你需要生成某个类型的代码时,运行这个命令,它会自动加载相关的技能定义,然后调用 AI 生成代码。这种方式的好处是,技能定义和代码生成过程是解耦的,你可以随时更新技能定义而不影响已有的代码。
还有一种更轻量的方式,就是把技能定义作为团队文档的一部分,放在项目的 README 或者 CONTRIBUTING 文件里。虽然这种方式没有自动化,但至少能让团队成员有一个统一的参考标准。
5. 常见问题与排查技巧实录
5.1 AI 不按技能定义执行怎么办
这是最常见的问题。你明明写了详细的技能定义,但 AI 生成的结果还是不符合要求。原因通常有几个:一是技能定义太长,AI 在生成过程中“忘记”了前面的规则;二是技能定义里的验收标准不够具体,AI 无法判断自己有没有做到;三是技能定义和 AI 的默认行为冲突,AI 倾向于按照训练数据里的常见模式来生成代码。
解决这个问题的第一步是简化技能定义。把最核心的规则放在最前面,用加粗或者列表的方式突出显示。第二步是把验收标准转化成可检查的条目,比如“函数参数不超过 3 个”比“函数参数应该尽量少”更有效。第三步是在技能定义里明确说明“如果与你的默认行为冲突,请优先遵循本技能定义”。
5.2 技能定义之间的冲突怎么排查
当你有多个技能定义的时候,冲突是难免的。排查冲突的方法很简单:把两个技能定义放在一起,逐条对比它们的规则,找出相互矛盾的地方。比如技能 A 要求“所有函数必须有显式返回类型”,技能 B 要求“优先使用类型推断”,这两条规则在“函数返回值”这个场景下就是矛盾的。
解决冲突的方式取决于你的项目需求。如果你更看重类型安全,就保留技能 A,修改技能 B 的适用范围。如果你更看重代码简洁,就反过来。关键是要有一个明确的决策依据,而不是让 AI 自己随机选择。
5.3 技能目录的维护成本
技能目录不是写完就一劳永逸的。随着项目的发展,代码规范会变,技术栈会升级,团队成员的偏好也会变。这意味着技能定义需要定期更新。我的建议是,把技能目录的维护纳入到常规的技术债务管理流程里,每个季度或者每个大版本发布前,花半天时间 review 一下技能定义,看看有没有需要调整的地方。
另外,技能定义的变更应该像代码变更一样,有版本记录和变更说明。这样当 AI 的输出出现异常时,你可以快速定位到是哪次技能定义的修改导致的。
| 常见问题 | 排查思路 | 解决方案 |
|---|---|---|
| AI 忽略技能定义 | 检查技能定义长度和位置 | 精简定义,核心规则前置 |
| 技能之间规则冲突 | 逐条对比矛盾点 | 明确优先级或限定适用范围 |
| 输出质量不稳定 | 检查验收标准是否可量化 | 将模糊标准改为可检查条目 |
| 上下文超限 | 检查加载的技能数量 | 按需加载,拆分技能粒度 |
| 技能定义过时 | 对比当前项目规范 | 定期 review 并更新版本 |
提示:技能目录的维护成本主要不在于写,而在于改。一开始就设计好版本管理和变更记录机制,后面会省很多事。
6. 这套实践对 AI 工程化的启示
6.1 从提示词到技能定义的演进
回顾过去两年 AI 辅助开发的演进路径,我看到的趋势是从“随意对话”到“结构化协作”。最开始大家只是把 AI 当成一个更聪明的搜索引擎,问一句答一句。后来开始有人整理提示词模板,把常用的指令固化下来。再后来出现了技能定义这种更工程化的方式,把任务拆解、上下文管理、验收标准都纳入进来。
这个演进背后的逻辑是:AI 的能力越强,我们对它的期望就越高,就越需要一套机制来确保它的输出是可预测、可复现、可维护的。技能定义就是这套机制的一种实现形式。
6.2 对团队协作的影响
在一个多人团队里,AI 的使用方式如果不统一,会带来很多隐形成本。比如 A 用 AI 生成的代码风格和 B 用 AI 生成的代码风格不一致,review 的时候就要花额外的时间去协调。再比如 C 用 AI 生成了一个有安全隐患的代码片段,但因为没有统一的检查标准,这个问题可能要到上线后才被发现。
技能目录的价值在于,它把个人的 AI 使用经验转化成了团队的共同资产。每个人都可以贡献自己的技能定义,也可以受益于别人定义的技能。这种共享机制,可以让团队的 AI 使用水平快速拉齐。
6.3 未来的扩展方向
这套技能目录的框架,目前主要聚焦在代码生成和代码审查上。但它的设计思路可以扩展到更多场景。比如代码迁移,你可以定义一个技能来描述“如何把旧版本的 API 调用迁移到新版本”。比如性能优化,你可以定义一个技能来描述“如何识别和修复常见的性能瓶颈”。比如安全审计,你可以定义一个技能来描述“如何检查代码中的常见安全漏洞”。
甚至,你可以把技能目录和 CI/CD 流程结合起来。在代码提交的时候,自动运行相关的技能检查,如果 AI 生成的代码不符合技能定义,就阻止合并。这样就把 AI 协作从“建议”变成了“约束”,进一步提高了代码质量的下限。
我个人在实际操作中的体会是,技能目录最大的价值不是让 AI 写出更好的代码,而是让团队对“什么是好代码”有一个更清晰的共识。当你把规则写下来的时候,你不得不去思考那些平时被忽略的细节。这个过程本身,就是对团队工程能力的一次提升。
最后再分享一个小技巧:如果你觉得从零开始写技能定义太麻烦,可以先从记录自己平时给 AI 的提示词开始。把你最常用的那几条提示词整理出来,按照技能定义的结构重新组织一下,就是一个最基础的技能目录了。先跑起来,再慢慢优化,比一开始就追求完美要实际得多。