Skill (Agent Skills)
Agent Skills package reusable workflows as folders with a SKILL.md
spec plus optional docs and scripts. During a conversation, the agent
injects a low‑cost “overview” first, then loads the full body/docs only
when actually needed, and runs scripts inside an isolated workspace.
Background references: - Engineering blog: https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills - Open Skills repository (structure to emulate): https://github.com/anthropics/skills
Overview
🎯 What You Get
- 🔎 Overview injection (name + description) to guide selection
- 📥
skill_loadto pullSKILL.mdbody and selected docs on demand - 📚
skill_select_docsto add/replace/clear docs - 🧾
skill_list_docsto list available docs - 🏃
skill_runto execute commands, returning stdout/stderr and output files - 🗂️ Output file collection via glob patterns with MIME detection
- 🧩 Pluggable local or container workspace executors (local by default)
- 🧱 Declarative
inputs/outputs: map inputs and collect/inline/ save outputs via a manifest
Three‑Layer Information Model
1) Initial “overview” (very low cost)
- Inject only name and description from SKILL.md into the
system message so the model knows what skills exist.
2) Full body (on demand)
- When a task truly needs a skill, the model calls skill_load and
the framework injects that skill’s full SKILL.md body.
3) Docs/Scripts (selective + isolated execution) - Docs are included only when requested; scripts are not inlined but executed inside a workspace, returning results and output files.
File Layout
Repository and parsing: skill/repository.go
Quickstart
1) Requirements
- Go 1.21+
- Model provider API key (OpenAI‑compatible)
- Optional Docker for the container executor
Common env vars:
2) Enable Skills in an Agent
Provide a repository and an executor. If not set, a local executor is used for convenience during development.
Key points:
- Request processor injects overview and on‑demand content:
[internal/flow/processor/skills.go]
(https://github.com/trpc-group/trpc-agent-go/blob/main/internal/flow/processor/skills.go)
- Tools are auto‑registered with WithSkills: skill_load,
skill_select_docs, skill_list_docs, and skill_run show up
automatically; no manual wiring required.
- By default, the framework appends a small Tooling and workspace guidance:
block after the Available skills: list in the system message.
- Disable it (to save prompt tokens): llmagent.WithSkillsToolingGuidance("").
- Or replace it with your own text: llmagent.WithSkillsToolingGuidance("...").
- If you disable it, make sure your instruction tells the model when to use
skill_load, skill_select_docs, and skill_run.
- Loader: tool/skill/load.go
- Runner: tool/skill/run.go
3) Run the Example
Interactive demo: examples/skillrun/main.go
GAIA benchmark demo (skills + file tools): examples/skill/README.md
It includes a dataset downloader script and notes on Python dependencies
for skills like whisper (audio) and ocr (images).
Quick start (download dataset JSON into examples/skill/data/):
To also download referenced attachment files:
Sample skill (excerpt): [examples/skillrun/skills/python_math/SKILL.md] (https://github.com/trpc-group/trpc-agent-go/blob/main/examples/skillrun/skills/python_math/SKILL.md)
Natural prompts:
- Say what you want to accomplish; the model will decide if a skill is
needed based on the overview.
- When needed, the model calls skill_load for body/docs, then
skill_run to execute and return output files.
SKILL.md Anatomy
SKILL.md uses YAML front matter + Markdown body:
Recommendations:
- Keep name/description succinct for the overview
- In the body, include when‑to‑use, steps/commands, output file paths
- Put scripts under scripts/ and reference them in commands
For more examples, see: https://github.com/anthropics/skills
Tools in Detail
skill_load
Declaration: tool/skill/load.go
Input:
- skill (required)
- docs (optional array of doc filenames)
- include_all_docs (optional bool)
Behavior:
- Writes session-scoped temp:* keys:
- temp:skill:loaded:<name> = "1"
- temp:skill:docs:<name> = "*" or JSON array
- Request processor injects SKILL.md body and docs into system message
Notes: - Safe to call multiple times to add or replace docs. - These keys are stored on the session state and can remain effective across turns in the same session until overwritten/cleared or the session expires. - The keys store only selection metadata, not full doc contents.
skill_select_docs
Declaration: tool/skill/select_docs.go
Input:
- skill (required)
- docs (optional array)
- include_all_docs (optional bool)
- mode (optional string): add | replace | clear
Behavior:
- Updates temp:skill:docs:<name> accordingly:
- * for include all
- JSON array for explicit list
skill_list_docs
Declaration: tool/skill/list_docs.go
Input:
- skill (required)
Output: - Array of available doc filenames
Note: These keys are managed by the framework; you rarely need to touch them directly when driving the conversation naturally.
skill_run
Declaration: tool/skill/run.go
Input:
- skill (required)
- command (required; by default runs via bash -c)
- cwd, env (optional)
- output_files (optional, legacy collection): glob patterns (e.g.,
out/*.txt). Patterns are workspace‑relative; env‑style prefixes
like $OUTPUT_DIR/*.txt are also accepted and normalized to
out/*.txt.
- inputs (optional, declarative inputs): map external sources into
the workspace. Each item supports:
- from with schemes:
- artifact://name[@version] to load from the Artifact service
- host://abs/path to copy/link from a host absolute path
- workspace://rel/path to copy/link from current workspace
- skill://<name>/rel/path to copy/link from a staged skill
- to workspace‑relative destination; defaults to
WORK_DIR/inputs/<basename>
- mode: copy (default) or link when feasible
outputs(optional, declarative outputs): a manifest to collect results with limits and persistence:globsworkspace‑relative patterns (supports**and env‑style prefixes like$OUTPUT_DIR/**mapping toout/**)inlineto inline file contents into the resultsaveto persist via the Artifact servicename_templateprefix for artifact names (e.g.,pref/)- Limits:
max_files(default 100),max_file_bytes(default 4 MiB/file),max_total_bytes(default 64 MiB)
timeout(optional seconds)save_as_artifacts(optional, legacy path): persist files collected viaoutput_filesand returnartifact_filesin the resultomit_inline_content(optional): withsave_as_artifacts, omitoutput_files[*].contentand return metadata onlyartifact_prefix(optional): prefix for the legacy artifact path- If the Artifact service is not configured,
skill_runkeeps returning inlineoutput_filesand reports awarningsentry.
- If the Artifact service is not configured,
Optional safety restriction (allowlist):
- Env var TRPC_AGENT_SKILL_RUN_ALLOWED_COMMANDS:
- Comma/space-separated command names (for example, ls,cat,ifconfig)
- When set, skill_run rejects shell syntax (pipes/redirections/
separators) and only allows a single allowlisted command
- Because the command is no longer parsed by a shell, patterns like
> out/x.txt, heredocs, and $OUTPUT_DIR expansion will not work;
prefer running scripts or using outputs to collect files
- You can also configure this in code via
llmagent.WithSkillRunAllowedCommands(...).
Optional safety restriction (denylist):
- Env var TRPC_AGENT_SKILL_RUN_DENIED_COMMANDS:
- Comma/space-separated command names
- When set, skill_run also rejects shell syntax (single command only)
and blocks denylisted command names
- You can also configure this in code via
llmagent.WithSkillRunDeniedCommands(...).
Output:
- stdout, stderr, exit_code, timed_out, duration_ms
- primary_output (optional) with name, ref, content, mime_type
- Convenience pointer to the "best" small text output file (when one
exists). Prefer this when there is a single main output.
- output_files with name, ref, content, mime_type
- ref is a stable workspace://<name> reference that can be passed
to other tools
- warnings (optional): non-fatal notes (for example, when artifact
saving is skipped)
- artifact_files with name, version appears in two cases:
- Legacy path: when save_as_artifacts is set
- Manifest path: when outputs.save=true (executor persists files)
Typical flow:
1) Call skill_load to inject body/docs
2) Call skill_run and collect outputs:
- Legacy: use output_files globs
- Declarative: use outputs to drive collect/inline/save
- Use inputs to stage upstream files when needed
Environment and CWD:
- When cwd is omitted, runs at the skill root: /skills/<name>
- A relative cwd is resolved under the skill root
- cwd may start with $WORK_DIR, $OUTPUT_DIR, $SKILLS_DIR,
$WORKSPACE_DIR, $RUN_DIR (or ${...}) and will be normalized to
workspace‑relative directories
- Runtime injects env vars: WORKSPACE_DIR, SKILLS_DIR, WORK_DIR,
OUTPUT_DIR, RUN_DIR; the tool injects SKILL_NAME
- Convenience symlinks are created under the skill root: out/,
work/, and inputs/ point to workspace‑level dirs
- File tools accept inputs/<path> as an alias to <path> when the
configured base directory does not contain a real inputs/ folder
Executor
Interface: codeexecutor/codeexecutor.go
Implementations: - Local: [codeexecutor/local/workspace_runtime.go] (https://github.com/trpc-group/trpc-agent-go/blob/main/codeexecutor/local/workspace_runtime.go) - Container (Docker): [codeexecutor/container/workspace_runtime.go] (https://github.com/trpc-group/trpc-agent-go/blob/main/codeexecutor/container/workspace_runtime.go)
Container notes:
- Writable run base; $SKILLS_ROOT mounted read‑only when present
- Network disabled by default for repeatability and safety
Security & limits:
- Reads/writes confined to the workspace
- Timeouts and read‑only skill trees reduce risk
- stdout/stderr may be truncated (see warnings)
- Output file read size is capped to prevent oversized payloads
Events and Tracing
Tools emit tool.response events and may carry state deltas (used by
skill_load). Merging/parallel execution logic:
[internal/flow/processor/functioncall.go]
(internal/flow/processor/functioncall.go)
Common spans:
- workspace.create, workspace.stage.*, workspace.run
- workspace.collect, workspace.cleanup, workspace.inline
Rationale and Design (brief)
- Motivation: Skills often contain lengthy instructions and scripts. Inlining all of them is costly and risky. The three‑layer model keeps the prompt lean while loading details and running code only when needed.
- Injection & state: Tools write temporary keys (via
StateDelta), and the next request processor builds the system message accordingly. - Isolation: Scripts run within a workspace boundary and only selected output files are brought back, not the script source.
Troubleshooting
- Unknown skill: verify name and repository path; ensure the overview
lists the skill before calling
skill_load - Nil executor: configure
WithCodeExecutoror rely on the local default - Timeouts/non‑zero exit codes: inspect command/deps/
timeout; in container mode, network is disabled by default - Missing output files: check your glob patterns and output locations
References and Examples
- Background:
- Blog: https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
- Open repo: https://github.com/anthropics/skills
- This repo:
- Interactive demo: [examples/skillrun/main.go] (https://github.com/trpc-group/trpc-agent-go/blob/main/examples/skillrun/main.go)
- Sample skill: [examples/skillrun/skills/python_math/SKILL.md] (https://github.com/trpc-group/trpc-agent-go/blob/main/examples/skillrun/skills/python_math/SKILL.md)