Skills
View SourceA skill packages the instructions for one kind of task. The model sees only each skill's name and description, and loads the full instructions when a task needs them. An agent can therefore carry many procedures without sending all of them on every request.
ExAgent reads the Agent Skills directory format used
by other agent harnesses, so the same SKILL.md files can serve your
application and your coding agents.
Write a skill
A skill is a directory with a SKILL.md. The frontmatter's name and
description form the catalog entry. The Markdown body holds the instructions:
priv/skills/
release-notes/
SKILL.md
references/style.md
incident-report/
SKILL.md---
name: release-notes
description: Write release notes. Use when asked to summarise changes for a release.
---
# Release notes
1. Group user-visible changes first; read references/style.md for tone.
2. ...Write the description for the model: say what the skill does and when to use it. Names use lowercase letters, digits and single hyphens (at most 64 characters). Descriptions are at most 1024 characters.
Attach skills to an agent
skills = ExAgent.Skills.from_dir!(Application.app_dir(:my_app, "priv/skills"))
agent =
ExAgent.new(
model: model,
instructions: "You are the release assistant.",
skills: skills
):skills adds a load_skill tool whose description lists the catalog. When the
model calls it, the result contains the skill's instructions and a list of its
other files. That result is an ordinary tool return, so the skill stays in the
conversation:
- for the rest of the run;
- on later
ExAgent.Serverturns; - in snapshots and continuations.
ExAgent.Skills.loaded/1 lists the skills a conversation has loaded. For a
LiveView, call ExAgent.Skills.loaded(ExAgent.Server.history(server)) after a
turn, or watch tool events whose tool name is load_skill.
SKILL.md is read again on each load, so edits apply without restarting. The
catalog is built with the agent; rebuild the agent to add or remove skills. If a
load fails (the file was removed, or its instructions exceed the size limit),
the model receives a retry message and can continue without that skill.
Skills can also be defined in code:
ExAgent.Skill.new(
name: "refund-policy",
description: "Refund rules. Use when a customer asks for a refund.",
content: "Refunds within 30 days need ..."
)Read skill files
When a skill comes from a directory, the agent also gets read_skill_file. It
reads a UTF-8 text file by its path relative to that skill directory. The load
result lists up to 200 files and marks the list when it is truncated. The
following are rejected:
- absolute paths;
- paths that leave the directory through
..or a symlink; - hidden files or directories (names starting with
.), which are also left out of the file list; - binary files and files over the size limit.
Each rejection reaches the model as a retry so it can correct the path. As with any tool, repeated failures beyond the tool's retry budget end the run.
ExAgent does not execute skill scripts. If a skill needs to run code, expose that operation as your own tool, with your own permissions and limits.
Unlock tools with a skill
A skill can carry tools that the model sees only after loading it:
skills =
ExAgent.Skills.from_dir!(dir,
tools: %{"deploy" => DeployTools.tools()}
)The keys are skill names from the frontmatter. Until deploy is loaded, an
ExAgent.Skills.Gate omits its tools from model requests, so they cannot be
executed. The catalog does not name them; the load result announces them. A call
made before loading is treated like a call to any tool the request did not
offer. With the default retry budget, that ends the run. The tools remain in the
agent's tool inventory, so persisted continuations restore them as usual.
The gate runs before the agent's own capabilities. A capability that removes a
tool from function_tools therefore keeps the final say, even after the skill
is loaded. A capability that rebuilds the tool set from the agent inventory can
also offer gated tools early. The gate decides what the model is offered; it is
not an authority boundary. Use ExAgent.Permissions for that.
A tool listed both in :tools and in a skill is gated. A different tool with
the same name as a skill tool raises ArgumentError. So does a tool named
load_skill or read_skill_file when :skills is used.
Compaction
When an ExAgent.Compaction.Capability summarises older messages, a loaded
skill's instructions could otherwise be summarised away. ExAgent.Skills.Restore
runs after the agent's own capabilities. If the request projection no longer
contains a loaded skill, it puts that skill's instructions back as one
user-level message. That message goes in the same position as a compaction
summary: before the first message that is not instructions-only. When the first
request carries both the instructions and the prompt, that position comes before
it. The stored history is never modified. The restored text is added after the
compaction threshold was evaluated.
Compose it yourself
ExAgent.Skills.tools/2 and ExAgent.Skills.capabilities/1 return the pieces
that :skills adds. Use them to:
- change the order, for example to place a capability that measures the final
request after
:restore; - change
:max_file_bytes(default 256 KiB), which bounds both the loaded instructions and files read withread_skill_file.
Keep :gate before capabilities that restrict tools, and :restore after
compaction.
Limits
- The catalog is part of the
load_skilltool definition. Each description adds tokens to every request. Write descriptions to be concise. - The frontmatter reader supports the YAML used by skill metadata. Unsupported
constructs in
nameordescriptionare an error. Malformed structure, such as a top-level line that is not akey:, is also an error. Other fields are best effort: strings, lists or maps of strings, or the raw text of a value outside the subset. - Skill names follow the Agent Skills rule. The frontmatter
nameidentifies the skill even when it differs from the directory name. allowed-toolsand other frontmatter fields are informational. Skills never grant permissions; useExAgent.Permissionsand your own tools for that.- Skill content is trusted host content, like
:instructions. Do not load skills from untrusted sources.
API: ExAgent.Skills, ExAgent.Skill, ExAgent.Skills.Gate,
ExAgent.Skills.Restore.