Skill Injection Behavior
Understanding where skill content appears in the prompt is critical. The behavior differs based on skill format and trigger configuration:Prompt Structure
Skills appear in different parts of the system prompt:Context Loading Methods
Always-Loaded Context
Content that’s always in the system prompt.Option 1: AGENTS.md (Auto-loaded)
Place AGENTS.md at your repo root - it’s loaded automatically. See Permanent Context.
Option 2: Inline Skill (Code-defined)
Trigger-Loaded Context
Content injected when keywords appear in user messages. See Keyword-Triggered Skills.Path-Triggered Rules
A rule is a skill with aPathTrigger (paths: glob frontmatter). Its content is injected
deterministically when the agent reads, edits, or creates a file whose workspace-relative path
matches one of the globs — no reliance on the model choosing a skill. See Path-Triggered Rules
for the conceptual overview.
Rules add zero baseline cost: they are excluded from <available_skills> and <REPO_CONTEXT>
and are never model-invocable (disable_model_invocation is forced on). Nothing is loaded until a
matching file is touched, and each rule is injected only once per conversation.
*.md file with paths: frontmatter in a skills directory
(e.g. .agents/skills/api-validation.md):
src/api/users.ts, the rule content is appended to that tool
result (not the user message) inside an <EXTRA_INFO> block, so the agent reads it on its next step:
Glob Semantics
Patterns use gitignore-style matching against the workspace-relative POSIX path (case-sensitive):- A skill is either path-triggered or model-invocable, not both: if a file declares both
paths:andtriggers:,paths:wins. - Rules are repo-scoped — touching a file outside the workspace never fires a rule.
- Injection is available for local conversations. ACP-backed conversations do not inject path rules, because the ACP server owns tool execution.
Progressive Disclosure (AgentSkills Standard)
For the agent to trigger skills, use the AgentSkills standardSKILL.md format. The agent sees a summary and reads full content on demand.
Managing Installed Skills
You can install AgentSkills into a persistent directory and manage them throughopenhands.sdk.skills. Skills are stored under
~/.openhands/skills/installed/ with a .installed.json metadata file that
records an enabled flag. list_installed_skills() returns all installed
skills, while load_installed_skills() returns only those with
enabled=true.
The public lifecycle API includes install_skill(), update_skill(),
enable_skill(), disable_skill(), and uninstall_skill(), which gives the
CLI a clean SDK surface for /skill install, /skill enable,
/skill disable, and /skill uninstall.
Installed Skill Lifecycle Example
This example mirrors the installed-plugin lifecycle example, but for AgentSkills. It installs sample skills, lists them, toggles the persistentenabled flag, and uninstalls one skill while leaving the
other available.
examples/05_skills_and_plugins/03_managing_installed_skills/main.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Installing Skills from a Marketplace
Use a marketplace when you want to install a curated mix of local and remote AgentSkills in one step. The example below shows how to define a marketplace, install all listed skills, and inspect the installed metadata.examples/01_standalone_sdk/43_mixed_marketplace_skills/main.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Full Example
Full example: examples/01_standalone_sdk/03_activate_skill.py
examples/01_standalone_sdk/03_activate_skill.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Creating Skills
Skills are defined with a name, content (the instructions), and an optional trigger:Keyword Triggers
UseKeywordTrigger to activate skills only when specific words appear:
File-Based Skills (SKILL.md)
For reusable skills, use the AgentSkills standard directory format.
Directory Structure
Each skill is a directory containing:my-skill/
SKILL.md
scripts/
helper.sh
references/
examples.md
assets/
config.json
SKILL.md Format
The SKILL.md file defines the skill with YAML frontmatter:
Frontmatter Fields
Loading Skills
Useload_skills_from_dir() to load all skills from a directory:
examples/05_skills_and_plugins/01_loading_agentskills/main.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Key Functions
load_skills_from_dir()
Loads all skills from a directory, returning three dictionaries:
discover_skill_resources()
Discovers resource files in a skill directory:
Skill Location in Prompts
The<location> element in <available_skills> follows the AgentSkills standard, allowing agents to read the full skill content on demand. When a triggered skill is activated, the content is injected with the location path:
./scripts/encrypt.sh.
Example Skill: ROT13 Encryption
Here’s a skill with triggers (OpenHands extension): SKILL.md:Loading Public Skills
OpenHands maintains a public skills repository with community-contributed skills. You can automatically load these skills without waiting for SDK updates.Automatic Loading via AgentContext
Enable public skills loading in yourAgentContext:
- Clone or update the public skills repository to
~/.openhands/cache/skills/on first run - Load all available skills from the repository
- Merge them with your explicitly defined skills
Skill Naming and Triggers
Skill Precedence by Name: If a skill name conflicts, your explicitly defined skills take precedence over public skills. For example, if you define a skill namedcode-review, the public code-review skill will be skipped entirely.
Multiple Skills with Same Trigger: Skills with different names but the same trigger can coexist and will ALL be activated when the trigger matches. To add project-specific guidelines alongside public skills, use a unique name (e.g., custom-codereview-guide instead of code-review). Both skills will be triggered together.
Programmatic Loading
You can also load public skills manually and have more control:Custom Skills Repository
You can load skills from your own repository:How It Works
Theload_public_skills() function uses git-based caching for efficiency:
- First run: Clones the skills repository to
~/.openhands/cache/skills/public-skills/ - Subsequent runs: Pulls the latest changes to keep skills up-to-date
- Offline mode: Uses the cached version if network is unavailable
Explore available public skills at github.com/OpenHands/extensions. These skills cover various domains like GitHub integration, Python development, debugging, and more.
Customizing Agent Context
Message Suffixes
Append custom instructions to the system prompt or user messages viaAgentContext:
system_message_suffix: Appended to system prompt (always active, combined with repo skills)user_message_suffix: Appended to each user message
Replacing the Entire System Prompt
For complete control, provide a custom Jinja2 template via theAgent class:
custom_system_prompt.j2):
- Use relative filenames (e.g.,
"system_prompt.j2") to load from the agent’s prompts directory - Use absolute paths (e.g.,
"/path/to/prompt.j2") to load from any location - Pass variables to the template via
system_prompt_kwargs - The
system_message_suffixfromAgentContextis automatically appended after your custom prompt
Dynamic Command Execution
Skills support inline shell command execution for injecting dynamic context at render time. This is useful for including repository state, environment information, or computed values in skill content.Basic Syntax
Use!`command` to execute a shell command and replace it with stdout:
Safety Rules
Code blocks are never executed. Both fenced and inline code blocks are preserved:Escape Syntax
Use\!`cmd` to output the literal text !`cmd` without execution:
Error Handling
Failed commands return inline error markers:Programmatic Rendering
When using skills programmatically, callrender_content() to execute commands:
working_dir parameter sets the current directory for command execution, enabling workspace-relative commands like git status.
Migrating from Legacy to AgentSkills Format
If you have legacy inline skills consuming many tokens, convert them to AgentSkills format for progressive disclosure:Before (Legacy Format)
After (AgentSkills Format)
Create a directoryapi-guidelines/SKILL.md:
Benefits
Next Steps
- Custom Tools - Create specialized tools
- MCP Integration - Connect external tool servers
- Confirmation Mode - Add execution approval

