A ready-to-run example is available here!File-based agents let you define specialized sub-agents using Markdown files. Each file declares the agent’s name, description, tools, and system prompt — the same things you’d pass to
register_agent() in code, but without writing any Python.
This is the fastest way to create reusable, domain-specific agents that can be invoked via delegation.
Agent File Format
An agent is a single.md file with YAML frontmatter and a Markdown body:
Frontmatter Fields
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | - | Agent identifier (e.g., code-reviewer) |
description | No | "" | What this agent does. Shown to the orchestrator |
tools | No | [] | List of tools the agent can use |
model | No | "inherit" | LLM model profile to load and use for the subagent ("inherit" uses the parent agent’s model) |
skills | No | [] | List of skill names for this agent (see Skill Loading Precedence for resolution order). |
max_iteration_per_run | No | None | Maximum iterations per run. Must be strictly positive, or None for the default value. |
color | No | None | Rich color name (e.g., "blue", "green") used by visualizers to style this agent’s output in terminal panels |
mcp_servers | No | None | MCP server configurations for this agent (see MCP Servers) |
hooks | No | None | Hook configuration for lifecycle events (see Hooks) |
permission_mode | No | None | Controls how the subagent handles action confirmations (see Permission Mode) |
profile_store_dir | No | None | Custom directory path for LLM profiles when using a named model |
<example> Tags
Add <example> tags inside the description to help the orchestrating agent know when to delegate to this agent:
when_to_use_examples on the AgentDefinition object. They can be used by routing logic (or prompt-building) to help decide when to delegate to the right sub-agent.
Directory Conventions
Place agent files in these directories, scanned in priority order (first match wins):| Priority | Location | Scope |
|---|---|---|
| 1 | {project}/.agents/agents/*.md | Project-level (primary) |
| 2 | {project}/.openhands/agents/*.md | Project-level (secondary) |
| 3 | ~/.agents/agents/*.md | User-level (primary) |
| 4 | ~/.openhands/agents/*.md | User-level (secondary) |
my-project/
.agents
agents
code-reviewer.md
tech-writer.md
security-auditor.md
src/
...
- Only top-level
.mdfiles are loaded (subdirectories are skipped) README.mdfiles are automatically skipped- Project-level agents take priority over user-level agents with the same name
Built-in Agents
Theopenhands-tools package ships with built-in sub-agents as Markdown files in openhands/tools/preset/subagents/.
They can be registered via register_builtins_agents() and become available for delegation tasks.
By default, all agents include finish tool and the think tool.
Available Built-in Sub-Agents
| Agent | Tools | Description |
|---|---|---|
| default | terminal, file_editor, task_tracker, browser_tool_set | General-purpose agent. Used as the fallback when no agent name is specified. |
| default cli mode | terminal, file_editor, task_tracker | Same as default but without browser tools (used in CLI mode). |
| explore | terminal | Read-only codebase exploration agent. Finds files, searches code, reads source — never creates or modifies anything. |
| bash | terminal | Command execution specialist. Runs shell commands, builds, tests, and git operations. |
default agent (with browser tools) is replaced by the default cli mode agent. In non-CLI mode, default cli mode is filtered out.
Registering Built-in Sub-Agents
Callregister_builtins_agents() to register all built-in sub-agents. This is typically done once before creating a conversation:
Overall Priority
When the same agent name is defined in multiple places, the highest-priority source wins. Registration is first-come first-win.| Priority | Source | Description |
|---|---|---|
| 1 (highest) | Programmatic register_agent() | Registered first, never overwritten |
| 2 | Plugin agents (Plugin.agents) | Loaded from plugin agents/ directories |
| 3 | Project-level file-based agents | .agents/agents/*.md or .openhands/agents/*.md |
| 4 (lowest) | User-level file-based agents | ~/.agents/agents/*.md or ~/.openhands/agents/*.md |
Auto-Registration
The simplest way to use file-based agents is auto-registration. Callregister_file_agents() with your project directory, and all discovered agents are registered into the delegation system:
Manual Loading
For more control, load and register agents explicitly:Key Functions
load_agents_from_dir()
Scans a directory for .md files and returns a list of AgentDefinition objects:
agent_definition_to_factory()
Converts an AgentDefinition into a factory function (LLM) -> Agent:
- Maps tool names from the frontmatter to
Toolobjects - Appends the Markdown body to the parent system message via
AgentContext(system_message_suffix=...) - Respects the
modelfield ("inherit"keeps the parent LLM; an explicit model name creates a copy)
load_project_agents() / load_user_agents()
Load agents from project-level or user-level directories respectively:
Using with Delegation
File-based agents are designed to work with the DelegateTool. Once registered, the orchestrating agent can spawn and delegate tasks to them by name:Example Agent Files
Code Reviewer
Technical Writer
Advanced Features
MCP Servers
File-based agents can define MCP server configurations inline, giving them access to external tools without any Python code:mcp_servers field uses the same format as the MCP configuration — each key is a server name, and the value contains command and args for launching the server.
Hooks
File-based agents can define lifecycle hooks that run at specific points during execution:pre_tool_use— Runs before tool execution (can block with exit code 2)post_tool_use— Runs after tool executionuser_prompt_submit— Runs before processing user messagessession_start/session_end— Run when conversation starts/endsstop— Runs when agent tries to finish (can block)
"*"— Matches all tools- Exact name — e.g.,
"terminal"matches only that tool - Regex patterns — e.g.,
"/file_.*/"matches tools starting withfile_
Permission Mode
Control how a file-based agent handles action confirmations with thepermission_mode field:
| Mode | Behavior |
|---|---|
always_confirm | Requires user approval for all actions |
never_confirm | Executes all actions without approval |
confirm_risky | Only requires approval for actions above a risk threshold (requires a security analyzer) |
permission_mode is omitted (or set to None), the subagent inherits the confirmation policy from its parent conversation.
Permission mode is particularly useful for specialized sub-agents. For example, a “read-only explorer” agent might use
never_confirm since it only reads files, while a “deploy” agent might use always_confirm for safety.Agents in Plugins
Plugins bundle agents, tools, skills, and MCP servers into reusable packages. Learn more about plugins here.File-based agents can also be bundled inside plugins. Place them in the
agents/ directory of your plugin:
my-plugin/
.plugin
plugin.json
agents
code-reviewer.md
tech-writer.md
.md format and are registered automatically when the plugin is loaded. They have higher priority than file-based agents but lower than programmatic register_agent() calls.
Ready-to-run Example
This example is available on GitHub: examples/01_standalone_sdk/42_file_based_subagents.py
AgentDefinition directly. File-based agents are loaded into the same AgentDefinition objects (from Markdown) and registered the same way.
examples/01_standalone_sdk/42_file_based_subagents.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.Next Steps
- Sub-Agent Delegation - Learn about the DelegateTool and delegation patterns
- Skills - Add specialized knowledge and triggers to agents
- Plugins - Bundle agents, skills, hooks, and MCP servers together
- Custom Agent - Create agents programmatically for more control

