Documentation
¶
Overview ¶
Package skill 实现 Agent Skills 开放标准(https://agentskills.io)。
一个技能就是一份带 YAML frontmatter 的 markdown 文档(SKILL.md):frontmatter 声明 name / description 等元信息,正文是指令内容。技能只做「上下文注入」,不是 可执行工具——采用渐进式披露(progressive disclosure):
- 仅把技能元信息(name / description)以 XML 注入系统提示词;
- 正文(Instructions)不注入,模型判断需要时调用 get_skill 工具加载;
- 技能目录下的参考文档 / 脚本 / 模板等附属资源通过 load_skill_resource 工具按需读取。
设计参考 crush/internal/skills 与 opencode/internal/skills。
Index ¶
- Constants
- func BuiltinNames() []string
- func DiscoverWithStates(paths []string) ([]*Skill, []*SkillState)
- func EnsureBuiltinSkills(dir string) error
- func GetSkill(resolver runtimecontext.SkillResolver) tool.Tool
- func IsBuiltin(name string) bool
- func LoadSkillResource(resolver runtimecontext.SkillResolver) tool.Tool
- func SetBuiltinSkillDir(dir string)
- func ToPromptXML(skills []*Skill) string
- type DiscoveryState
- type GetSkillInput
- type GetSkillOutput
- type LoadSkillResourceInput
- type LoadSkillResourceOutput
- type Manifest
- type Registry
- func (r *Registry) Filter(names ...string) *Registry
- func (r *Registry) Get(name string) (*Skill, bool)
- func (r *Registry) Has(name string) bool
- func (r *Registry) List() []*Skill
- func (r *Registry) Names() []string
- func (r *Registry) PromptBlock(selected ...string) string
- func (r *Registry) Register(s *Skill)
- func (r *Registry) Resolver() runtimecontext.SkillResolver
- func (r *Registry) Unregister(name string)
- type Skill
- func (s *Skill) ListResources() []string
- func (s *Skill) ManifestPath() string
- func (s *Skill) Marshal() ([]byte, error)
- func (s *Skill) ReadResource(rel string) (string, string, error)
- func (s *Skill) ReadSkillResource(path string) (string, string, error)
- func (s *Skill) ResolveResource(rel string) (string, error)
- func (s *Skill) SkillInfo() runtimecontext.SkillInfo
- func (s *Skill) SkillResources() []string
- func (s *Skill) SkillVersion() string
- func (s *Skill) Validate() error
- func (s *Skill) Version() string
- type SkillState
- type Store
Constants ¶
const ( // BuiltinSkillDir 是内置技能源码目录(相对工作目录,与内置提示词一致)。 BuiltinSkillDir = "builtin/skills" // BuiltinAnalysisScriptSkillName 是「创建分析脚本流程」内置技能名。 BuiltinAnalysisScriptSkillName = "analysis-script-workflow" // BuiltinAnalysisNodeScriptSkillName 是「分析节点脚本修改」内置技能名。 BuiltinAnalysisNodeScriptSkillName = "analysis-node-script-editing" // BuiltinAnalysisScriptSpecSkillName 是「分析脚本修改规范」内置技能名。 BuiltinAnalysisScriptSpecSkillName = "analysis-script-spec" )
内置技能:源码位于仓库 builtin/skills/<name>/SKILL.md(与内置提示词同处 builtin/ 目录), 由 go:embed 打包进二进制;系统启动时读出并覆盖写入用户技能目录 ($BaseDir/.skills/<name>/SKILL.md)。
为什么用「启动时覆盖写文件」而不是内存注入:技能的加载 / 热更新 / 前端查看 / 删除 都只走一条路径(磁盘 + Discover),内置技能因此不需要额外的合并逻辑;同时运维可以 直接打开对应文件查看模型实际拿到的内容。
注意:内置技能写入后与用户技能同处一个目录,前端删除后在下次启动时会再次出现。
const ( // SkillFileName 是技能描述文件的文件名。 SkillFileName = "SKILL.md" // MaxNameLength 是技能名允许的最大长度。 MaxNameLength = 64 // MaxDescriptionLength 是技能描述允许的最大长度。 MaxDescriptionLength = 1024 )
const ( // ManifestFileName 是技能目录下声明版本等元信息的可选清单文件。 ManifestFileName = "manifest.json" // MaxResourceBytes 是 load_skill_resource 单次返回的资源大小上限。 MaxResourceBytes = 256 * 1024 )
技能附属资源相关常量。
const ( // GetSkillToolName 是「加载技能指令」工具名。 GetSkillToolName = "get_skill" // LoadSkillResourceToolName 是「加载技能附属资源」工具名。 LoadSkillResourceToolName = "load_skill_resource" )
技能工具的入参 / 出参定义。
技能本身仍以 SKILL.md 为唯一真实来源,但正文不再由模型「读文件」获取,而是通过 工具调用按需加载(渐进式披露):
- get_skill:按名称(可选版本)加载 SKILL.md 的指令正文与必要元信息;
- load_skill_resource:加载技能目录内的附属资源(参考文档 / 脚本 / 模板 / Schema)。
两者都是只读工具,免授权(技能来自 $BaseDir/.skills,属于框架受控目录)。
Variables ¶
This section is empty.
Functions ¶
func DiscoverWithStates ¶ added in v0.1.5
func DiscoverWithStates(paths []string) ([]*Skill, []*SkillState)
DiscoverWithStates 发现给定路径下所有合法技能,并返回每个文件的发现状态。
func EnsureBuiltinSkills ¶ added in v0.2.0
EnsureBuiltinSkills 把内置技能写入 dir(通常为 $BaseDir/.skills),每次启动都覆盖。
写入内容来自 builtin/skills 下的 SKILL.md 原文(不再重新序列化),保证磁盘与源码一致。 dir 为空时无操作;写入失败只记录第一个错误,不影响其他技能继续写入。
func GetSkill ¶ added in v0.2.0
func GetSkill(resolver runtimecontext.SkillResolver) tool.Tool
GetSkill 返回「按名称加载技能指令」工具。
func LoadSkillResource ¶ added in v0.2.0
func LoadSkillResource(resolver runtimecontext.SkillResolver) tool.Tool
LoadSkillResource 返回「加载技能附属资源」工具。
用于读取参考文档、脚本源码、模板、Schema 等附属文件,而不是再次读取完整的技能 指令(那应该用 get_skill)。只允许访问技能目录内部的文件。
func SetBuiltinSkillDir ¶ added in v0.2.0
func SetBuiltinSkillDir(dir string)
SetBuiltinSkillDir 覆盖内置技能源码目录(空串表示恢复默认:相对当前工作目录)。 仅用于测试或自定义部署目录;非并发安全,应在服务启动前调用。
func ToPromptXML ¶ added in v0.1.5
ToPromptXML 生成注入系统提示词的 <available_skills> XML。
仅包含元信息(name / description),刻意不含指令正文与文件路径——正文与附属资源 都由模型通过工具(get_skill / load_skill_resource)按需加载,避免一次性塞满 上下文。DisableModelInvocation 的技能会被排除。
Types ¶
type DiscoveryState ¶ added in v0.1.5
type DiscoveryState int
DiscoveryState 表示单个技能文件的发现结果。
const ( // StateNormal 表示技能解析并校验成功。 StateNormal DiscoveryState = iota // StateError 表示扫描 / 解析 / 校验失败。 StateError )
type GetSkillInput ¶ added in v0.2.0
type GetSkillInput struct {
// Name 是技能名(即 SKILL.md frontmatter 的 name)。
Name string `json:"name"`
// Version 是可选的版本约束;当前只支持精确匹配(与 manifest.json /
// frontmatter 的 version 比对),留空表示使用已发现的当前版本。
Version string `json:"version,omitempty"`
}
GetSkillInput 是 get_skill 工具的入参。
type GetSkillOutput ¶ added in v0.2.0
type GetSkillOutput struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Version string `json:"version,omitempty"`
SkillPath string `json:"skill_path,omitempty"`
Resources []string `json:"resources,omitempty"`
Instructions string `json:"instructions"`
Error string `json:"error,omitempty"`
}
GetSkillOutput 是 get_skill 工具返回给模型的结果。
func ResolveSkillOutput ¶ added in v0.2.0
func ResolveSkillOutput(ctx context.Context, resolver runtimecontext.SkillResolver, name, version string) (GetSkillOutput, error)
ResolveSkillOutput 是「按名称获取技能内容」的单一实现(get_skill 工具与 HTTP 接口共用)。
它解析技能并用 ctx 中注入的 RuntimeContext 变量渲染指令正文,保证工具执行期与 前端 / 调试接口看到的技能内容一致。
返回 error 仅表示调用方环境缺失(如未注入 SkillResolver);技能不存在、版本不匹配、 渲染失败等业务错误通过 GetSkillOutput.Error 返回(与工具反馈给模型的口径一致)。
type LoadSkillResourceInput ¶ added in v0.2.0
type LoadSkillResourceInput struct {
// Name 是技能名。
Name string `json:"name"`
// Path 是相对技能目录的资源路径,如 references/design.md。
Path string `json:"path"`
// Version 语义同 get_skill.Version(可选)。
Version string `json:"version,omitempty"`
}
LoadSkillResourceInput 是 load_skill_resource 工具的入参。
type LoadSkillResourceOutput ¶ added in v0.2.0
type LoadSkillResourceOutput struct {
Name string `json:"name"`
Path string `json:"path"`
AbsPath string `json:"abs_path,omitempty"`
Content string `json:"content,omitempty"`
Error string `json:"error,omitempty"`
}
LoadSkillResourceOutput 是 load_skill_resource 工具返回给模型的结果。
type Manifest ¶
type Manifest struct {
Version string `json:"version"`
}
Manifest 是技能目录下 manifest.json 的结构(全部字段可选)。
现有实现只使用 version(供 get_skill 的版本选择与展示)。
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry 持有一组已发现的技能,提供按名解析与提示词注入。
技能按名称唯一;同名后注册者覆盖先注册者(用户技能覆盖内置技能)。
Registry 支持在程序运行期热更新(Register / Unregister),因此内部用读写锁 保护:一次 Agent 运行读取技能元信息的同时,前端可以新增 / 修改 / 删除技能。
func NewRegistryWith ¶
NewRegistryWith 创建注册表并注册给定技能。
func (*Registry) PromptBlock ¶ added in v0.1.5
PromptBlock 把技能元信息(selected 为空表示全部)拼接为注入系统提示词的 markdown 块。
仅注入 name / description / location,不含指令正文;无匹配技能时返回空字符串。
func (*Registry) Resolver ¶ added in v0.2.0
func (r *Registry) Resolver() runtimecontext.SkillResolver
Resolver 返回实现 runtimecontext.SkillResolver 的视图,供技能工具(get_skill / load_skill_resource)在执行期按名称解析技能。
func (*Registry) Unregister ¶ added in v0.1.5
Unregister 按名称移除技能;不存在时无操作。
type Skill ¶
type Skill struct {
Name string `yaml:"name" json:"name"`
Description string `yaml:"description" json:"description"`
ManifestVersion string `yaml:"version,omitempty" json:"version,omitempty"`
UserInvocable bool `yaml:"user-invocable" json:"user_invocable"`
DisableModelInvocation bool `yaml:"disable-model-invocation" json:"disable_model_invocation"`
// DisableRender 为 true 时,get_skill / load_skill_resource 原样返回技能文本,
// 不按本轮 RuntimeContext 的业务变量做 pongo2 模板渲染。
//
// 零值(false)表示启用渲染:技能正文 / 附属资源中出现 {{ var }} 时会用当前场景
// 变量替换;但若技能文本本身含有不希望被替换的花括号(如代码示例中的模板语法),
// 将该开关置为 true 即可关闭渲染。
DisableRender bool `yaml:"disable-render" json:"disable_render"`
// 以下字段不参与 frontmatter 解析,由加载过程填充。
Instructions string `yaml:"-" json:"instructions,omitempty"` // 指令正文
Path string `yaml:"-" json:"path,omitempty"` // 技能目录
SkillFilePath string `yaml:"-" json:"skill_file_path,omitempty"` // SKILL.md 路径
}
Skill 表示一份解析后的 SKILL.md。
func Builtin ¶ added in v0.2.0
func Builtin() []*Skill
Builtin 读取全部内置技能(磁盘优先,缺失时回退到 go:embed 副本)。
读取 / 解析失败的技能会被跳过,不影响其余技能。
func Deduplicate ¶ added in v0.1.5
Deduplicate 按名称去重;同名时后出现的覆盖先出现的(用户技能覆盖内置技能)。
func ParseContent ¶ added in v0.1.5
ParseContent 从原始字节解析 SKILL.md。
func (*Skill) ListResources ¶ added in v0.2.0
ListResources 递归列出技能目录下的附属资源(相对技能目录的斜杠路径,已排序)。
SKILL.md 与 manifest.json 属于技能描述本身,不在资源列表内。
func (*Skill) ManifestPath ¶ added in v0.2.0
ManifestPath 返回技能目录下 manifest.json 的路径。
func (*Skill) Marshal ¶ added in v0.1.5
Marshal 把技能序列化为 SKILL.md 内容(YAML frontmatter + 正文)。
与 Parse / ParseContent 互逆:Save 出来的文件应能被 Parse 原样读回。
func (*Skill) ReadResource ¶ added in v0.2.0
ReadResource 读取技能附属资源文件内容(大小上限 MaxResourceBytes)。
func (*Skill) ReadSkillResource ¶ added in v0.2.0
ReadSkillResource 读取技能目录内的附属资源,返回内容与绝对路径。
func (*Skill) ResolveResource ¶ added in v0.2.0
ResolveResource 把技能目录内的相对路径解析为绝对路径,并拒绝目录穿越。
只允许访问技能目录内部的文件;越界、绝对路径或不存在都会返回错误。
func (*Skill) SkillInfo ¶ added in v0.2.0
func (s *Skill) SkillInfo() runtimecontext.SkillInfo
SkillInfo 返回技能的最小元信息与指令正文。
func (*Skill) SkillResources ¶ added in v0.2.0
SkillResources 返回技能目录下的附属资源相对路径(不含 SKILL.md / manifest.json)。
func (*Skill) SkillVersion ¶ added in v0.2.0
SkillVersion 返回技能版本(manifest.json 优先,回退 frontmatter version)。
type SkillState ¶ added in v0.1.5
type SkillState struct {
Name string
Path string
State DiscoveryState
Err error
}
SkillState 描述单个技能文件的最新发现状态。
type Store ¶ added in v0.1.5
type Store struct {
// contains filtered or unexported fields
}
Store 把技能以 SKILL.md 的形式持久化到某个根目录(通常为 $BaseDir/.skills)。
磁盘是用户技能的唯一真实来源:运行期新增 / 修改 / 删除都会落盘,进程重启后 由 Discover 重新加载。这样既能保证「程序运行中也能改技能」,又不会因为进程 重启而丢失改动。内存中的 Registry 只是磁盘内容的一份可热更新的缓存。
func (*Store) Contains ¶ added in v0.1.5
Contains 报告 path 是否位于该 Store 的根目录之下。 用于限制只允许删除 / 修改存储在用户技能目录内的技能,避免误删内置或外部技能。