Writing a skill
A skill is a folder containing aSKILL.md with YAML frontmatter. Any other files in the folder are bundled resources the skill can point the model at.
SKILL.md
Giving skills to an agent
Load a directory withhastekit.NewSkillRegistryFromDir and set it on AgentConfig.Skills:
Tools. There is no way to end up advertising a skill the model has no way to open.
Pass several directories to draw from more than one library — a shared set plus this agent’s own:
The read_skill tool
The prompt carries only each skill’s name, description and location. To get the instructions themselves, the model calls read_skill:
Reading a skill’s instructions also returns an index of the files that skill bundles, so the model can follow up with
read_skill(name: "changelog", file: "references/style.md") even when the SKILL.md never mentions them.
The tool is annotated read-only, non-destructive, idempotent and closed-world (see Tool Annotations), so a permission policy can let it run unattended.
Shipping skills inside the binary
Where the skills are part of the program rather than of its deployment,go:embed puts the whole tree in the binary — no folder to mount, copy, or keep in sync:
SKILL.md sits, so there is no fs.Sub to get right. NewSkillRegistry takes any fs.FS, so this is also the hook for skills that come from somewhere else entirely.
Rules
- A folder holding a
SKILL.mdis one skill, and everything below it belongs to that skill — so aSKILL.mdbundled as an example or a template stays a bundled file rather than becoming a second, half-formed skill. - The name comes from the frontmatter, or from the folder when the frontmatter omits it.
- Loading fails loudly on a skill with no description, on broken frontmatter, on a directory that isn’t there, and on the same name defined twice. Skills decide how the agent behaves, so a bad one should stop startup rather than go quietly missing at runtime.
- Only files a skill actually bundles are reachable through the tool. A path that tries to traverse out of the skill folder is refused, so one skill cannot read another or the rest of the filesystem the skills were read from.
- Skills work the same under Temporal and Restate. The durable agent registers and wraps the reader tool along with the rest, so a
read_skillcall is journaled like any other tool call and replays from the journal rather than re-reading the folder.
Skills from somewhere else
AgentConfig.Skills takes an agents.SkillProvider — a source that lists its skills, supplies the tool that reads them, and introduces them to the model:
SkillHint is the whole of the section’s prose and goes in verbatim — the resolver writes the ## Skills heading and the catalogue, nothing else. Only the provider can write that hint honestly: a SkillRegistry names its own read_skill tool, while a host serving skills its own way names whatever the model actually has.
A source that returns no tool is one the model can already reach. agents.SkillList lists such skills and adds nothing — for skills staged into a sandbox the agent already browses:
agents.SkillsWithHint is the same, plus the prose — for a host that serves skill files through a tool of its own:
The agents.Skill struct
Complete Example
Next Steps
- Compose the prompt yourself with prompt resolvers
- Gate what a skill’s tools may do with Hooks