Help us shape the future of Go! Take the 2026 Go Developer Survey

skill

package
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package skill 技能内容与元数据:SKILL.md 解析(frontmatter 围栏 + canonical checksum)、进程内技能库(多根扫描、热替换)、版本区间约束(decl/version)、 决策式按需加载(decision.go 的 use_skill 渐进披露)。 内容文件解析带路径遍历保护(`..` 段拒绝;注意 symlink 不在防护范围——root 应为可信目录);文件解析部分零外部依赖,决策使用依赖 eino。

Index

Constants

View Source
const (
	DefaultListBudget = 20_000  // RenderList 清单预算(字节)
	DefaultContentCap = 100_000 // use_skill 全文上限(字节)
)

预算缺省(两级渐进披露的预算面,批次五十三自 bianque 沉淀): 清单渲染超预算确定性降级;use_skill 全文超上限截断并声明。 调用方显式传值覆盖(0=回落缺省,负=不限的语义在 RenderList/Cap 侧)。

View Source
const (
	ModeStatic     = "static"    // 全文注入系统提示
	ModeOnDemand   = "on_demand" // 决策式:清单 + use_skill 按需加载
	DefaultVersion = "0.0.0"

	MaturityExperimental = "experimental"
	MaturityStable       = "stable"
	MaturityFrozen       = "frozen"
	MaturityDeprecated   = "deprecated"
)

技能生命周期常量(通用概念,非特定平台专属)。

Variables

This section is empty.

Functions

func AsSkillTool

func AsSkillTool(p Provider, allowed []string, opts ...ToolOption) (tool.BaseTool, error)

AsSkillTool 把"决策使用"包成 use_skill eino 工具:提示词只注入 可用 skill 清单(名称+描述,经 ListSkills),agent 按任务相关性自主 决定加载哪个全文——skill 多/大时不撑爆系统提示词。

allowed 限定可加载的 skill 名(空 = 目录全量);与静态注入互斥使用。 与 rag.KnowledgeService.AsTool 同范式。

opts 可选:WithContentCap 限定单次返回全文上限(超限截断 + 尾部声明—— LLM 可感知的诚实形态,不静默吞内容;缺省 DefaultContentCap,≤0 = 不限)。

func Format

func Format(ctx context.Context, content string, vars map[string]any) (string, error)

Format 按 eino FString(pyfmt,{var} 占位)渲染 skill 内容。 底层复用 schema.Message 的 MessagesTemplate 实现——与 eino 提示词模板同语义:

content := "以 {language} 审查,输出不超过 {max_items} 条。"
out, err := skill.Format(ctx, content, map[string]any{"language": "Go", "max_items": 5})

func ListPrompt

func ListPrompt(metas []Meta) string

ListPrompt 渲染可用 skill 清单(注入提示词的决策依据,不含正文)。 Description 经 fence.EscapeUntrusted 中和(markdown 结构/HTML 注释边界)—— Name/Title/Description 来自仓库内 markdown,属半可信内容,恶意描述可夹带 提示词注入指令;消毒在出口统一兜底,不依赖调用方自觉(目录写权限仍应收敛)。 无 skill 返回空串;有则渲染为 markdown 列表。 加载名(Name)作为加粗主词——模型回填 use_skill 的名称必须与它一致; 展示名(Title,frontmatter name)仅作括注。

func RenderList

func RenderList(metas []Meta, budget int) string

RenderList 清单渲染 + 确定性预算降级(对标 ZCode skills.ts 的预算-降级形态: 降级是确定性行为而非异常——超预算的形态可测试、可预期)。

budget≤0 = 不限(等价 ListPrompt);>0 = 预算字节。降级两级: 全额(名称+描述,ListPrompt 同款)→ 超预算降级为纯名单(name only)→ 仍超则按预算截断 + 末尾注明。多字节字符按完整名回退,不截半个字。

func RewriteBody

func RewriteBody(content, body string) (string, error)

RewriteBody 保留 frontmatter 围栏(原文不动),仅替换正文——编辑器路径。 无 frontmatter 或未闭合 → 报错(围栏是元数据的唯一保护壳,不整段重建)。

func RewriteMode

func RewriteMode(content, mode string) (string, error)

RewriteMode 结构化切换 mode:解析 frontmatter → 改 mode → yaml 序列化写回, 正文与其余元数据字段(嵌套 requires_mcp/provides 等)原样保留。 无 frontmatter 或未闭合 → 报错(不猜格式,与解析 fail-fast 同哲学)。

func VersionInRange

func VersionInRange(version, expr string) (bool, error)

VersionInRange 版本是否满足区间表达式(技能/依赖的声明式约束):区间语法与 Masterminds/semver 一致(">=1.0.0 <2.0.0" 空格=AND,逗号亦同)。校验语义 (失败/警告分级)由调用方定——本函数只回答「满足/不满足 + 表达式本身是否合法」。 expr 空=任意(恒真)。 区间或版本本身非法时返回错误,错误信息带期望/实际。

Types

type AliasResolver

type AliasResolver interface {
	CanonicalName(ctx context.Context, name string) (string, bool)
}

AliasResolver 可选能力:把展示别名归一化为规范引用名(渐进披露链路闭环: 清单可能展示 frontmatter name,模型会原样回填给 use_skill)。

type Decl

type Decl struct {
	Name     string `yaml:"name" json:"name"`
	Version  string `yaml:"version,omitempty" json:"version,omitempty"`
	Optional bool   `yaml:"optional,omitempty" json:"optional,omitempty"`
}

Decl 技能的结构化声明引用(agent.yaml skills / pack.yaml depends_on.skills 等 装配声明的列表元素)。兼容两种 yaml 形态:裸串(=仅名字,无约束)与 {name, version, optional} 映射。version 是 semver 区间表达式 (">=1.0.0 <2.0.0",空格=AND);空=不约束。Optional=true 表示引用缺失时 允许警告降级(是否降级由装配方决定,本包不做存在性检查)。

func (*Decl) UnmarshalYAML

func (d *Decl) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML 兼容裸串与映射两种形态(yaml.v3)。

type Deprecated

type Deprecated struct {
	Reason      string `yaml:"reason,omitempty" json:"reason,omitempty"`
	ReplacedBy  string `yaml:"replaced_by,omitempty" json:"replaced_by,omitempty"` // 替代技能名(可空)
	RemoveAfter string `yaml:"remove_after,omitempty" json:"remove_after,omitempty"`
}

Deprecated 弃用窗口(maturity=deprecated 时 RemoveAfter 必填,YYYY-MM-DD)。

type FileProvider

type FileProvider struct {
	Root string
	// contains filtered or unexported fields
}

FileProvider file 来源实现:root/<name>/SKILL.md 或 root/<name>.md。

func NewFileProvider

func NewFileProvider(root string) *FileProvider

NewFileProvider 创建文件来源的内容解析器。

func (*FileProvider) CanonicalName

func (p *FileProvider) CanonicalName(ctx context.Context, name string) (string, bool)

CanonicalName 把展示名(frontmatter name)归一化为规范引用名(目录名/文件名)。 未命中返回 ("", false)。别名表懒扫描构建(进程内 skill 目录通常不变); 首次扫描为全目录磁盘 I/O,ctx 取消随链透传。

func (*FileProvider) ListSkills

func (p *FileProvider) ListSkills(ctx context.Context) ([]Meta, error)

ListSkills 枚举目录下全部 skill 的元数据(不含正文)。 供提示词注入"可用 skill 清单"——agent 据此决策加载哪个(经 use_skill 工具)。 实现 Lister 接口。

func (*FileProvider) Resolve

func (p *FileProvider) Resolve(ctx context.Context, ref Ref) (*Skill, error)

Resolve 解析引用,返回内容(带缓存)。磁盘读取前检查 ctx 取消。

type LibEntry

type LibEntry struct {
	Full string // 全文(含 frontmatter)
	Body string // 剥 frontmatter 正文
	Meta LibMeta
	// contains filtered or unexported fields
}

LibEntry 库内单技能。

type LibMeta

type LibMeta struct {
	Name        string   `yaml:"name,omitempty" json:"name"`
	Title       string   `yaml:"-" json:"-"` // frontmatter name(展示名);目录名规范
	Description string   `yaml:"description,omitempty" json:"description"`
	Mode        string   `yaml:"mode" json:"mode"`
	Version     string   `yaml:"version,omitempty" json:"version,omitempty"`
	Maturity    string   `yaml:"maturity,omitempty" json:"maturity,omitempty"`
	RequiresMCP []MCPDep `yaml:"requires_mcp,omitempty" json:"requires_mcp,omitempty"`
	// RequiresConfig 技能依赖的集成配置类型(bianque 集成平面):如 [rag, s3]。
	// 声明级契约——缺失由调用方告警,不拦截加载。
	RequiresConfig []string    `yaml:"requires_config,omitempty" json:"requires_config,omitempty"`
	Deprecated     *Deprecated `yaml:"deprecated,omitempty" json:"deprecated,omitempty"`
	Provides       []string    `yaml:"provides,omitempty" json:"provides,omitempty"` // 能力标签(登记/展示;重复声明由调用方告警)
	Compatibility  string      `yaml:"compatibility,omitempty" json:"compatibility,omitempty"`
	Source         string      `yaml:"-" json:"source"` // 来源前缀标签
	Path           string      `yaml:"-" json:"-"`      // SKILL.md 相对路径
}

LibMeta 技能完整元数据(渐进披露清单 + 生命周期管理)。 JSON 标签即对外 API 契约(名册/血缘面),变更须同步消费方。 yaml 标签即 SKILL.md frontmatter 契约(omitempty 与 marshalFrontmatter 「缺省字段不写回防膨胀」约定一体),解析/序列化均以本结构体为唯一事实源。

func ParseRichFrontmatter

func ParseRichFrontmatter(dirName, content string) (LibMeta, string, error)

ParseRichFrontmatter 用 yaml 解析 SKILL.md frontmatter(name/description/mode/ version/maturity/requires_mcp/deprecated/compatibility)。返回元数据与正文。 frontmatter name 写入 Title(展示名);目录名仍作规范 Name。 严格策略:起始围栏出现但未闭合 → 报错(Library fail-fast,与 FileProvider 宽松回退相对)。

func (LibMeta) DeprecationExpired

func (m LibMeta) DeprecationExpired(now time.Time) bool

DeprecationExpired 弃用窗口是否已过(remove_after 当日结束算未过期)。

func (LibMeta) Validate

func (m LibMeta) Validate() error

Validate 元数据硬校验(加载期 fail-fast;错误信息带「字段: 消息」定位)。

  • mode/maturity 枚举;version 须为 SemVer(缺省 0.0.0 合法);
  • maturity=deprecated 必须带 deprecated.remove_after(YYYY-MM-DD)——弃用必须有窗口终点;
  • requires_mcp[].server 非空。

type Library

type Library struct {
	// contains filtered or unexported fields
}

Library 进程内技能库(可热替换;装载后只读,热替换=换新实例)。 实现 Provider / Lister / AliasResolver。

func LoadFromFS

func LoadFromFS(fsys fs.FS, opts ...LoadOption) (*Library, error)

LoadFromFS 扫描 FS 构建技能库。 布局:`_shared/skills/<名>/SKILL.md`(共享)与 `<包>/skills/<名>/SKILL.md`(包自带)。 名字取目录名,全局唯一;重名报错(fail-fast)。

func (*Library) Body

func (l *Library) Body(name string) (string, bool)

Body 取剥离 frontmatter 的正文。

func (*Library) CanonicalName

func (l *Library) CanonicalName(_ context.Context, name string) (string, bool)

CanonicalName 实现 AliasResolver:frontmatter name(展示名)→ 目录名。 纯内存查询,ctx 仅随接口签名透传(无取消点)。

func (*Library) DeprecatedExpiredInUse

func (l *Library) DeprecatedExpiredInUse(used map[string][]string, now time.Time) []string

DeprecatedExpiredInUse 列出「弃用窗口已过且仍被 used 引用」的技能名(调用方的 reload/lint 失败清单)。used 为 技能名 → 引用方列表;未引用的过期弃用不阻塞加载。

func (*Library) Describe

func (l *Library) Describe(name string) LibMeta

Describe 技能元数据(未知名字返回仅含名字的零值)。

func (*Library) Get

func (l *Library) Get(name string) (string, bool)

Get 取技能全文(含 frontmatter)。

func (*Library) Has

func (l *Library) Has(name string) bool

Has 技能是否存在。

func (*Library) ListSkills

func (l *Library) ListSkills(_ context.Context) ([]Meta, error)

ListSkills 实现 Lister(渐进披露清单,不含正文;按 Name 字典序稳定)。

func (*Library) Names

func (l *Library) Names() []string

Names 全部技能名(字典序稳定——消费链直接拼提示词/比对清单文本,map 迭代 序的随机输出曾令字节级稳定前缀不可复现)。

func (*Library) Provider

func (l *Library) Provider() Provider

Provider 返回自身作为决策式 Provider(热替换场景每次读当前库)。

func (*Library) Resolve

func (l *Library) Resolve(_ context.Context, ref Ref) (*Skill, error)

Resolve 实现 Provider(决策式加载:剥 frontmatter 正文 + canonical checksum—— 口径与 FileProvider 一致,见 Skill.Checksum)。

type Lister

type Lister interface {
	ListSkills(ctx context.Context) ([]Meta, error)
}

Lister 可选能力:支持"发现 + 决策使用"的 Provider(渐进披露模式需要)。

type LoadOption

type LoadOption func(*loadConfig)

LoadOption LoadFromFS 选项。

func WithDefaultMaturity

func WithDefaultMaturity(f func(source string) string) LoadOption

WithDefaultMaturity 覆盖缺省成熟度推断。

func WithExtraPrefix

func WithExtraPrefix(p string) LoadOption

WithExtraPrefix 追加扫描前缀(如 "custom/skills")。

type MCPDep

type MCPDep struct {
	Server     string   `yaml:"server" json:"server"`
	Tools      []string `yaml:"tools,omitempty" json:"tools,omitempty"`
	MinVersion string   `yaml:"min_version,omitempty" json:"min_version,omitempty"`
	Comment    string   `yaml:"comment,omitempty" json:"comment,omitempty"`
}

MCPDep 技能对 MCP server 的依赖声明(静态契约:血缘展示与加载期对账用, 不做运行时派发拦截)。Tools 为本技能实际用到的工具名(血缘展示 + 清单对账); MinVersion 为对 server 契约清单 version 的下限声明(SemVer,警告级对账)。

type Meta

type Meta struct {
	// Name 规范引用名(目录名/文件名)——use_skill 加载与 allowed 清单的唯一依据。
	Name string
	// Title 展示名(frontmatter name;与 Name 相同或目录缺失时为空)。
	// 仅用于清单展示,加载仍按 Name;模型若用 Title 调用,AsSkillTool 会归一化。
	Title       string
	Version     string
	Description string
}

Meta skill 元数据(不含正文——渐进披露:提示词只注入这一层)。

type Provider

type Provider interface {
	Resolve(ctx context.Context, ref Ref) (*Skill, error)
}

Provider 内容解析接口。

type Ref

type Ref struct {
	Name    string
	Version string
	Source  string // file(v3.0 仅实现 file)
}

Ref 内容引用。

type Skill

type Skill struct {
	Name        string
	Version     string // frontmatter 声明(未声明为空串);ref.Version 是请求约束/缓存键,不回显
	Description string // frontmatter description(无则空)
	Content     string // frontmatter 之后的正文
	// Checksum 内容校验和,canonical 口径:sha256(正文) 前 16 位 hex——绑定
	// 实际注入提示词的内容(frontmatter 是元数据,不进 prompt)。
	// FileProvider 与 Library 两个 Provider 一致,观测守卫的比对基准不随 Provider 漂移。
	Checksum string
}

Skill 解析后的内容(带 checksum 防内容漂移难排查)。 SKILL.md 支持 Agent Skills 标准的 frontmatter(--- 围栏内 name/description 行): description 服务于发现与决策使用(渐进披露),正文才是消费主体。

type ToolOption

type ToolOption func(*skillToolCfg)

ToolOption AsSkillTool 装配选项。

func WithContentCap

func WithContentCap(n int) ToolOption

WithContentCap 限定 use_skill 单次返回全文上限(字节)。超限截断并在尾部 追加声明(模型可感知,不静默吞内容);≤0 = 不限。缺省 DefaultContentCap。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL