Appearance
功能规格说明:Agent 技能支持
创建日期:2024-12-19
用户场景与测试 (必填)
用户故事:创建个人 Agent 技能(优先级:P1)
开发者希望为个人工作流创建可跨所有 Wave 项目使用的可复用技能。他们需要将自己的专业知识打包为可发现的能力,以便 Wave 在相关时自主调用。
为什么是这个优先级:这是核心价值主张——使用户能够用自己的专业知识扩展 Wave 的能力。
独立测试:可以通过创建包含 SKILL.md 文件的个人技能目录结构并验证 Wave 可以跨多个项目发现和使用它来完整测试。
验收场景:
- 假设我想创建个人技能,当我在
~/.wave/skills/my-skill-name/创建带有有效 SKILL.md 文件的目录时,则Wave 应该识别并使此技能在我所有项目中可用 - 假设我已创建了带有正确 YAML frontmatter 的个人技能,当我在任何项目中与 Wave 交互时,则Wave 应该基于我的请求自主决定何时调用此技能
- 假设我有包含辅助文件的个人技能,当Wave 调用该技能时,则它应该可以访问所有引用的文件(脚本、模板、文档)
用户故事:技能正文的目录占位符与 frontmatter 解析(优先级:P1)
技能作者需要用 ${WAVE_SKILL_DIR} 之类的占位符在正文里引用技能目录内的脚本与模板(如 node ${WAVE_SKILL_DIR}/tool.mjs),也需要用 YAML 的多行写法描述「何时该用这个技能」。前者必须替换成可直接执行的绝对路径,后者的多行文本必须按 YAML 语义解析成真实描述。
为什么是这个优先级:两者都直接决定技能能不能用——占位符不替换,正文里的命令在模型手上就是一条跑不通的路径;描述被解析成 >- 这类语法符号,「何时该用我」的信息整段丢失,技能就不会被主动调用(比"锦上添花"重要得多)。
独立测试:写一个正文含 ${WAVE_SKILL_DIR}/tool.mjs、frontmatter 用 description: >- 加多行描述的技能,确认调用后模型看到的首行是 Base directory for this skill: <绝对路径>、正文里没有字面量占位符,且可用技能列表与调用结果里展示的是折叠后的完整描述。
验收场景:
- 假设技能正文含
${WAVE_SKILL_DIR}或${CLAUDE_SKILL_DIR},当技能被调用(Skill工具或/skill-name)时,则交给模型的正文首行是Base directory for this skill: <该技能目录的绝对路径>,且正文中这些占位符已全部替换为同一路径;正文含${WAVE_PLUGIN_ROOT}/${CLAUDE_PLUGIN_ROOT}时替换为该技能所属插件的根目录。 - 假设技能的 frontmatter 用 YAML 块标量写多行值(
>/>-/|/|-等),当技能被加载时,则description等字段必须是折叠/保留后的真实文本(不含>、|、-这类指示符),续行不得被解析成独立的 frontmatter 键;可用技能列表里展示的描述与技能管理界面用的描述都是这样解析后的结果。 - 假设技能的 frontmatter 只有单行值(
description: 一句话),当技能被加载时,则解析结果与块标量路径完全一致(单行不能被块标量处理改坏,含引号包裹的值仍去掉引号)。
用户故事:创建项目特定 Agent 技能(优先级:P2)
开发团队希望创建共享技能,封装项目特定知识、团队约定和工作流。这些技能应进行版本控制并自动对所有团队成员可用。
为什么是这个优先级:通过技能实现团队协作和知识共享,建立在个人技能的基础之上。
独立测试:可以通过在 .wave/skills/ 目录中创建项目技能、提交到 git 并验证团队成员自动获得访问权来测试。
验收场景:
- 假设我想创建项目技能,当我在
.wave/skills/my-skill-name/创建带有有效 SKILL.md 文件的目录时,则该技能应对所有参与此项目的团队成员可用 - 假设我将项目技能提交到 git,当团队成员克隆或拉取仓库时,则他们应该无需额外设置即可自动访问这些技能
- 假设存在项目技能,当任何团队成员在此项目中与 Wave 交互时,则Wave 应该将项目特定技能与个人技能一起考虑
用户故事:技能发现与调用(优先级:P1)
Wave 需要根据用户请求和技能描述自主发现何时使用可用技能,无需用户显式命令。
为什么是这个优先级:这是使技能有用的核心机制——基于上下文的自动智能调用。
独立测试:可以通过创建具有特定描述的技能并验证 Wave 对匹配请求适当调用它们来测试。
验收场景:
- 假设我有带有描述性 YAML frontmatter 的技能,当我发出匹配技能用途的请求时,则Wave 应该自主决定调用该技能
- 假设多个技能可能适用于一个请求,当Wave 评估可用技能时,则它应该基于描述和上下文选择最相关的技能
- 假设技能有辅助文件,当Wave 调用该技能时,则它应该渐进式地仅加载特定请求所需的文件
用户故事:技能管理与验证(优先级:P3)
用户需要验证其技能定义、了解技能结构要求并有效管理其技能集合。
为什么是这个优先级:虽然对可用性很重要,但这建立在核心功能之上,可以在基本技能支持工作后实现。
独立测试:可以通过创建无效技能并验证适当的错误消息以及管理技能集合来测试。
验收场景:
- 假设我创建了带有无效 YAML frontmatter 的 SKILL.md 文件,当Wave 尝试加载该技能时,则它应该提供关于需要修复内容的清晰错误消息
- 假设我有多个可用技能,当我请求有关技能的信息时,则Wave 应该能够列出并描述可用的个人和项目技能
- 假设我修改了技能的 SKILL.md 文件,当我与 Wave 交互时,则它应该自动重新加载更新后的技能定义
用户故事:用户可调用的带参数技能(优先级:P2)
用户希望使用斜杠命令语法显式调用技能并提供参数替换到技能内容中。他们还希望技能能够执行 bash 命令以提供动态信息。
为什么是这个优先级:增强技能的灵活性和能力,使其像自定义斜杠命令一样运行,同时保持其可发现性。
独立测试:可以通过使用 /skill-name arg1 arg2 调用技能并验证 $1 和 $ARGUMENTS 被正确替换,以及 bash 命令如 !pwd 和 ! pwd 被执行且输出上限为 30K 字符来测试。
验收场景:
- 假设我有带参数占位符(如
$1、$ARGUMENTS)的技能,当我使用/skill-name arg1 arg2调用时,则Wave 应该在处理前用提供的参数替换占位符 - 假设我有带 bash 命令占位符(如 !
pwd或! pwd)的技能,当技能被调用时,则Wave 应该执行 bash 命令并用其原始 stdout 输出替换占位符(不带任何额外格式或代码块)。超过 30,000 字符的输出将被截断并附带预览和临时文件路径 - 假设技能已注册,当我在聊天中输入
/时,则该技能应出现在斜杠命令建议中 - 假设我有不含参数占位符的技能,当我使用
/skill-name arg1 arg2调用时,则Wave 应该自动将参数追加到技能内容末尾
用户故事:限制技能的工具访问(优先级:P2)
用户希望在调用技能时限制 AI 可用的工具,无论是通过斜杠命令手动调用还是 AI 自主调用。这确保 AI 仅使用特定任务的预期工具,提高安全性和可靠性。
为什么是这个优先级:通过将 AI 的工具集限制为技能所需的工具来增强安全性和可靠性。
独立测试:可以通过在 frontmatter 中创建带有 allowed-tools 的技能并验证 AI 在技能调用时被限制为仅使用这些工具来测试。
验收场景:
- 假设我有在 frontmatter 中指定了
allowed-tools的技能,当我使用斜杠命令调用时,则Wave 应该将 AI 限制为仅在该轮次中使用指定的工具 - 假设带有
allowed-tools的技能被 AI 通过Skill工具自主调用,当技能执行时,则Wave 应该在 AI 该轮次的剩余时间内执行工具限制 - 假设技能将
allowed-tools指定为 YAML 列表或逗号分隔的字符串,当技能被解析时,则Wave 应该正确识别并执行所有指定的工具
用户故事:将技能派生到子代理(优先级:P2)
用户希望在独立的子代理中执行复杂技能,以提供全新上下文或使用专门的代理类型。这有助于隔离技能的执行并利用特定的代理专业知识。
为什么是这个优先级:通过允许技能在专门上下文中运行来增强技能的能力,提高复杂任务结果的质量。
独立测试:可以通过在 frontmatter 中创建带有 context: fork 和可选 agent 字段的技能并验证 Wave 在指定类型的子代理中执行技能来测试。
验收场景:
- 假设我有在 frontmatter 中带有
context: fork的技能,当技能被调用时(通过斜杠命令手动或 AI 自主),则Wave 应该在新子代理实例中执行技能内容 - 假设我有带有
context: fork和agent: general-purpose的技能,当技能被调用时,则Wave 应该使用general-purpose子代理执行技能 - 假设技能被派生到子代理,当子代理运行时,则Wave 应该在工具的 short result(AI 调用)或用户消息中的 ToolBlock(手动调用)中提供子代理进度的实时更新(使用的工具、消耗的 token)
- 假设我有带有
model: gpt-4o的技能,当技能被调用时(手动或自主),则Wave 应该使用指定模型执行 - 假设派生技能被手动调用,当子代理完成时,则其最终结果应作为用户消息中的 ToolBlock 展平到主对话中,且主代理不应被自动触发
用户故事:控制技能调用和可见性(优先级:P2)
用户希望控制技能的调用方式以及它们是否在斜杠命令菜单中可见。这允许仅由 AI 使用的"内部"技能或 AI 不应自动触发的"手动"技能。
为什么是这个优先级:为复杂的技能生态系统提供必要的控制,其中某些技能可能太强大或太具体而不适合 AI 自主调用,或某些技能仅作为 AI 的构建块。
独立测试:可以通过设置 disable-model-invocation: true 和 user-invocable: false 的各种组合并验证 / 菜单和 AI 工具提示中的可见性来测试。
验收场景:
- 假设技能在 frontmatter 中带有
disable-model-invocation: true,当Wave 为 AI 生成工具提示时,则此技能应从可用技能列表中排除 - 假设技能带有
disable-model-invocation: true,当AI 尝试通过Skill工具调用时,则Wave 应该阻止执行并向 AI 返回错误 - 假设技能在 frontmatter 中带有
user-invocable: false,当我在聊天中输入/时,则该技能不应出现在斜杠命令建议中 - 假设技能带有
user-invocable: false,当我尝试通过/skill-name执行时,则Wave 不应将其识别为有效命令
边界情况
- 当技能的 SKILL.md 文件有格式错误的 YAML frontmatter 时会发生什么?
- Wave 如何处理同名的个人技能和项目技能之间的冲突?
- 当引用的辅助文件(脚本、模板)缺失或不可访问时会发生什么?
- Wave 如何处理辅助文件中有循环引用的技能?
- 当技能名称超过 64 个字符或包含无效字符时会发生什么?