编写 agent skill

发布: (2026年3月19日 GMT+8 17:02)
7 分钟阅读
原文: Dev.to

抱歉,我需要您提供要翻译的具体文本内容(除保留的 Source 链接外)。请把文章的正文粘贴在这里,我就可以为您完成简体中文翻译。

DRY 原则

DRY(Don’t Repeat Yourself)原则已经存在很久了。
如果你在多个地方复制粘贴代码,而出现了 bug,你必须在所有地方都修复它。重复越多,修复时遗漏的可能性就越大。

编码助手中的 DRY

在使用编码助手时,DRY 的含义有所不同:

  • 你不需要在每次会话中都让助手分析你的项目。
  • 你不必每次都重复你的语言的编码约定。
  • 你不需要提醒助手你的项目倾向于不可变性。

当新开发者加入一个优秀的项目时,他们会被告知项目的特性、架构和约定。在优秀的项目中,这些约定会 以书面形式正式化,并且有时会保持最新。你的编码助手就像其他团队成员一样:它需要书面文档。

我使用的两款编码助手都支持使用此类指令(我假设所有助手都支持)。例如,GitHub Copilot 会自动读取 .github/instructions.md 文件。

保持指令文件小巧

如果助手自动读取指令且范围过于宽泛,就会用无关数据污染上下文。
结论: 保持文件相对较小,并专注于 通用 信息。

大小建议

SourceRecommendation
docs.factory.ai 700 行太长

我的建议:从小开始,必要时逐步增加,分析结果,并在文件变得过大时进行重构。

令牌才是真正的资源

如今,关键资源不再是 CPU、RAM 或存储,而是 令牌。令牌是有限且昂贵的。我预测开发者很快将以令牌使用量来衡量:使用最少令牌而实现相似结果的开发者将被视为更优秀。

大多数代理加载默认指令文件:

  • GitHub Copilot → AGENTS.md
  • Claude → CLAUDE.md

文件越小,在上下文中消耗的令牌就越少。

一个好的上下文应包含 所有必要的令牌,但不多余——这正是 技能 发挥作用的地方。

Source:

代理技能

代理技能 是一组指令、脚本和资源的文件夹,代理可以发现并使用它们,以更准确、更高效地工作。

技能不同于 AGENTS.md,因为它们不会自动加载,从而不会占用上下文空间。根据编码助手的不同,技能可能会被自动发现并加载,也可能不会。

调用技能

  • 默认情况下,你和 Claude 都可以调用任何技能。
  • 输入 /skill-name 可直接调用。
  • 当 Claude 认为技能与对话相关时,它可以自动加载该技能。

Claude 如何判断何时调用技能

Claude 会将每个 SKILL.md 文件的 front‑matter 转换为工具定义。下面是我创建的 Kotlin 技能的 front‑matter:

---
name: kotlin
description: |
  Use this skill when working with Kotlin code in any capacity:
  - Reading, writing, editing, or reviewing Kotlin files (*.kt, *.kts)
  - Running Gradle tasks for Kotlin modules
  - Writing or debugging Kotlin/JS code that targets Node.js
  - Working with external JavaScript libraries from Kotlin
  - Writing tests for Kotlin code (@Test, @BeforeTest, @AfterTest)
  - Setting up dependency injection or mocking in Kotlin
  - Dealing with multiplatform Kotlin projects (common, jsMain, jsTest, jvmMain)
  - Troubleshooting Kotlin compilation or runtime errors
  - Any task involving Kotlin/JS modules targeting Node.js

  This skill provides Kotlin/JS technical knowledge (especially JS interop gotchas)
  and coding‑style preferences beyond the official conventions.
---

上述内容为 Claude 提供了决定何时加载该工具所需的信息。显然,这个技能是关于 Kotlin 和 Kotlin/JS 的。

技能内容

遵循与普通 AGENTS.md 文件相同的规则:

  • 你可以引用位于技能文件夹本地或在线可访问的其他文档(文本或其他形式)。
  • 我已将完整的 Kotlin 编码规范复制到一个专门的文件中。SKILL.md 概述了主要条目并链接到这些规范。
  • 完整的规范已在此技能目录下的 kotlin-coding-conventions.md 中本地缓存。

关键提醒(Kotlin)

  • 首选 val 而非 var —— 优先考虑不可变性
  • 使用不可变的集合接口(ListSetMap,而不是 MutableList 等)
  • 对简短的 lambda 使用 it;对嵌套或复杂的 lambda 使用具名参数
  • 优先使用表达式形式的 ifwhentry,而非语句形式
  • 优先使用函数式风格(filtermap)而非命令式循环

1. External Interfaces vs. Kotlin Classes

问题: Kotlin 类的方法位于其原型上。外部接口期望方法直接挂在对象上。不能使用 unsafeCast 在两者之间进行转换。

// ❌ WRONG: This will fail at runtime
class MockSql {
    fun unsafe(query: String) = /* … */
}
val sql: Sql = mockSql.unsafeCast()  // Throws: sql.unsafe is not a function
// ✅ CORRECT: Use an extension function to build a plain JS object
fun MockSql.toExternal(): Sql {
    val obj = Any().asDynamic()
    val mock = this

    obj.unsafe = { query: String -> mock.unsafe(query) }
    obj.end = { mock.end() }

    return obj.unsafeCast()
}

// Then use it:
val sql: Sql = mockSql.toExternal()

✅ 正确:使用扩展函数来构建普通的 JS 对象

然后使用它:

val sql: Sql = mockSql.toExternal()

Bottom line

技能对于避免一次又一次重复相同指令非常有用。技能指令 的主要区别在于,当不需要时,技能 不会膨胀上下文。明智地使用它们,保持指令文件小巧,并观察你的 token 使用量下降。

进一步了解

代理技能

  • 为 Claude 添加技能
  • 方法论开发技能
  • 超赞技能

AGENTS.md

最初发表于 A Java Geek,2026年3月15日。

0 浏览
Back to Blog

相关文章

阅读更多 »