Back to Agent Zero

Create an Agent Zero Agent Profile

skills/a0-create-agent/SKILL.md

1.1320.4 KB
Original Source

Create an Agent Zero Agent Profile

[!IMPORTANT] Do not create new profiles in /a0/agents/ — that directory is reserved for core framework profiles (default, agent0, developer, hacker, researcher, _example). User profiles belong in /a0/usr/agents/<profile_name>/.

Related skills: /a0/skills/a0-development/SKILL.md (broader framework guide) | /a0/skills/a0-create-plugin/SKILL.md (bundle a profile inside a plugin).

Primary references:

  • /a0/agents/_example/ — the canonical reference profile (tool + extension + prompt overrides)
  • /a0/agents/default/ — the base profile every other profile inherits from
  • /a0/docs/agents/AGENTS.plugins.md — plugin-distributed profiles + per-profile config

Existing Profile Pattern

The built-in profiles are intentionally split into two layers:

  1. agent.yaml is tiny metadata for discovery and delegation:
    • title
    • description
    • context
  2. The actual profile behavior usually lives in prompts/agent.system.main.specifics.md.

Use the shipped profiles as calibration:

ProfilePattern to copy
agent0Minimal top-level assistant identity
developerRich capabilities, methodology, output requirements
researcherRich capabilities, methodology, evidence standards
hackerShort, direct operational identity plus optional environment override
_exampleMinimal demo of prompt/tool/extension override surfaces

For most new profiles, create agent.yaml plus one strong agent.system.main.specifics.md. Add other prompt overrides, tools, or extensions only when the blueprint explicitly needs them.


Step 0: Progressive Intake

Do not ask the user a long form. New users are easily overwhelmed. Guide them with lossy compression: ask only the next highest-value question, one or two questions per turn maximum.

Default assumptions unless the user says otherwise:

  • Scope: user profile in /a0/usr/agents/<name>.
  • Models: inherit global/project _model_config.
  • Response contract: keep the standard Agent Zero JSON tool-call contract.
  • Extras: no custom tools or lifecycle extensions.
  • Prompt strategy: agent.yaml plus prompts/agent.system.main.specifics.md.

Recommended interview flow:

  1. First ask only:
    • "What should this agent be excellent at?"
    • Optionally: "Do you already have a name/title in mind?"
  2. After the purpose is clear, propose a short summary with inferred name, title, description, and context, then ask for confirmation or corrections.
  3. Ask about behavior only if needed:
    • "Should it work more like a concise specialist, a rigorous researcher, a code-heavy implementer, or something else?"
  4. Ask about advanced options only when the user's request implies them:
    • custom output format
    • profile-specific Main/Utility models
    • custom tools
    • lifecycle extensions
    • plugin/project scope
  5. Before writing files, show the compact blueprint summary and ask for confirmation.
  6. Only after confirmation, produce the full AgentProfileBlueprint JSON in Step 1 and write files from it.

Never open with all blueprint fields. Do not mention obscure paths until they matter. Hide defaults, but use them.

If the user gives a broad idea, infer sensible defaults and mark uncertainties in validation.open_questions instead of stalling.


Step 1: Create an AgentProfileBlueprint JSON

Before writing files, produce exactly one valid JSON object in a fenced json block using this schema. This blueprint is the source of truth. Do not require a utility model or prose post-processing to extract fields.

json
{
  "schema": "agent_zero.agent_profile_blueprint.v1",
  "status": "draft",
  "profile": {
    "scope": "user",
    "root": "/a0/usr/agents",
    "name": "data-analyst",
    "title": "Data Analyst",
    "description": "Agent specialized in data analysis, visualization, and statistical modeling.",
    "context": "Use this agent for data analysis tasks, creating visualizations, statistical analysis, and working with datasets in Python."
  },
  "behavior": {
    "role": "You are a specialized data analysis agent.",
    "primary_capabilities": [
      "Python data analysis with pandas, numpy, and scipy",
      "Data visualization with matplotlib, seaborn, and plotly",
      "Statistical modeling and hypothesis testing"
    ],
    "operating_principles": [
      "Inspect data before drawing conclusions",
      "Prefer reproducible code and explicit assumptions",
      "Explain uncertainty and limitations"
    ],
    "workflow": [
      "Clarify the question and available data",
      "Profile and clean the dataset",
      "Run analysis with appropriate methods",
      "Visualize and interpret results"
    ],
    "output_preferences": [
      "Concise findings first",
      "Tables or charts when useful",
      "Reproducible code when analysis is performed"
    ]
  },
  "prompt_strategy": {
    "base_pattern": "specifics_only",
    "override_rationale": [
      "Use agent.system.main.specifics.md for role, expertise, and process.",
      "Keep the inherited communication contract unchanged."
    ],
    "root_prompt_overrides": [
      {
        "file": "agent.system.main.communication.md",
        "reason": "Only include if the profile needs a different response JSON schema or output format."
      }
    ]
  },
  "llm_config": {
    "enabled": false,
    "path": "/a0/usr/agents/data-analyst/plugins/_model_config/config.json",
    "source": "inherit_global",
    "chat_model": null,
    "utility_model": null,
    "embedding_model": null,
    "notes": [
      "Do not put model settings in agent.yaml.",
      "Only create this config file if the user wants profile-specific Main or Utility models.",
      "Scoped _model_config config is not deep-merged; include a complete config with chat_model, utility_model, and embedding_model."
    ]
  },
  "files": [
    {
      "path": "/a0/usr/agents/data-analyst/agent.yaml",
      "kind": "yaml",
      "content": "title: Data Analyst\ndescription: Agent specialized in data analysis, visualization, and statistical modeling.\ncontext: Use this agent for data analysis tasks, creating visualizations, statistical analysis, and working with datasets in Python.\n"
    },
    {
      "path": "/a0/usr/agents/data-analyst/prompts/agent.system.main.specifics.md",
      "kind": "markdown",
      "content": "## Your role\n\nYou are a specialized data analysis agent.\n\n## Expertise\n- Python data analysis with pandas, numpy, and scipy\n- Data visualization with matplotlib, seaborn, and plotly\n- Statistical modeling and hypothesis testing\n\n## Process\n1. Clarify the question and available data\n2. Profile and clean the dataset\n3. Run analysis with appropriate methods\n4. Visualize and interpret results\n"
    }
  ],
  "optional_components": {
    "extra_prompt_overrides": [],
    "tools": [],
    "extensions": []
  },
  "validation": {
    "needs_user_confirmation": true,
    "unique_name_checked": false,
    "yaml_valid": false,
    "open_questions": []
  }
}

Rules for the blueprint:

  • Output strict JSON: no comments, no trailing commas, no markdown inside string values except the intended file content.
  • profile.name must be lowercase letters, numbers, hyphens, or underscores only.
  • prompt_strategy.root_prompt_overrides must list any inherited root /prompts files being considered or replaced and why.
  • If a root prompt override is only a possibility, list it in prompt_strategy but do not add it to files until confirmed.
  • llm_config.enabled controls whether a profile-scoped _model_config/config.json file is created. Keep it false when models should inherit from global/project settings.
  • files[*].content must be the exact file content to write.
  • Include only files that should actually be created.
  • Set status to draft until all required choices are known; set it to ready only after resolving open questions.
  • Ask the user to confirm or edit the blueprint before writing files unless they explicitly authorized immediate creation.

Step 2: Required Fields

The blueprint must contain these required profile inputs:

InputRuleExample
name (directory name)lowercase letters, numbers, hyphens or underscores; must be unique across profile search pathsdata-analyst
titlehuman-readable display name shown in the UIData Analyst
descriptionone-line specialization summaryAgent specialized in data analysis, visualization, and statistical modeling.
contextinstructions telling the superior agent when to delegate to this profileUse this agent for data analysis tasks, creating visualizations, statistical analysis, and working with datasets in Python.

[!NOTE] agent.yaml has only these three content fields (title, description, context). Do not add model, temperature, or allowed_tools fields to agent.yaml. Profile-specific model settings live in a companion _model_config plugin config file, and tool availability is controlled by plugin activation.


Step 3: Write Files from the Blueprint

After the user confirms the blueprint, create exactly the paths listed in files.

<PROFILE_ROOT>/<name>/
├── agent.yaml                # Required
├── prompts/                  # Optional — prompt overrides
├── tools/                    # Optional — profile-specific tools
└── extensions/               # Optional — profile-specific extensions

agent.yaml:

yaml
title: Data Analyst
description: Agent specialized in data analysis, visualization, and statistical modeling.
context: Use this agent for data analysis tasks, creating visualizations, statistical
  analysis, and working with datasets in Python.

A profile with only agent.yaml is valid — it inherits everything from default/. Add the sections below only when you need to change something.


Step 4: Optional profile-specific LLM config

Agent Zero does not read Main/Utility model settings from agent.yaml. The _model_config plugin is always enabled and supports per-agent-profile config. If the user wants this profile to use specific LLMs, create a companion config file:

Profile scopeModel config path
User profile/a0/usr/agents/<profile>/plugins/_model_config/config.json
Plugin-distributed profile/a0/usr/plugins/<plugin>/agents/<profile>/plugins/_model_config/config.json
Project-scoped profile<project>/.a0proj/agents/<profile>/plugins/_model_config/config.json

Scoped _model_config/config.json files are selected as a whole; they are not deep-merged with broader global/project config. Therefore, if you create this file, include a complete effective model config. When the user only wants to customize Main or Utility, copy the other sections from the current effective config.

Minimal complete profile-scoped config:

json
{
  "allow_chat_override": true,
  "chat_model": {
    "provider": "openrouter",
    "name": "anthropic/claude-sonnet-4.6",
    "api_base": "",
    "ctx_length": 200000,
    "ctx_history": 0.7,
    "vision": true,
    "rl_requests": 0,
    "rl_input": 0,
    "rl_output": 0,
    "kwargs": {}
  },
  "utility_model": {
    "provider": "openrouter",
    "name": "openai/gpt-5.4-mini",
    "api_base": "",
    "ctx_length": 128000,
    "ctx_input": 0.7,
    "rl_requests": 0,
    "rl_input": 0,
    "rl_output": 0,
    "kwargs": {}
  },
  "embedding_model": {
    "provider": "huggingface",
    "name": "sentence-transformers/all-MiniLM-L6-v2",
    "api_base": "",
    "rl_requests": 0,
    "rl_input": 0,
    "kwargs": {}
  }
}

Rules:

  • Ask the user whether Main/Utility should inherit defaults or be profile-specific.
  • Do not store API keys in this file; API keys are managed globally through settings/secrets.
  • Include chat_model, utility_model, and embedding_model in the generated file if any profile-scoped model config is created.
  • If only Main or Utility is customized, copy the non-customized model sections from the current effective _model_config config.
  • Use provider IDs and model names exactly as _model_config expects.
  • Add this file to files only when llm_config.enabled is true.

Step 5: Override prompts (the most common customization)

Profiles inherit all prompts from /a0/prompts/ and from /a0/agents/default/. To change behavior, drop a file with the same filename into <PROFILE_ROOT>/<name>/prompts/. The loader searches profile-specific prompts first and falls back to the defaults.

The canonical override: agent.system.main.specifics.md

This is the designated extension slot for profile-specific role, identity, and behavior instructions. The file ships empty in both /a0/prompts/agent.system.main.specifics.md and /a0/agents/default/agent.system.main.specifics.md precisely so profiles can fill it in without fighting the base prompt. It is included from agent.system.main.md right after agent.system.main.role.md, so whatever you put here layers on top of the inherited role.

Every shipped profile in /a0/agents/ overrides this file — a good sanity check that this is the right place for your specialization. Look at the existing profiles for concrete shape:

ProfileWhat its agent.system.main.specifics.md does
/a0/agents/agent0/prompts/agent.system.main.specifics.mdEstablishes the top-level user-facing agent's behavior
/a0/agents/developer/prompts/agent.system.main.specifics.mdFull "Master Developer" role + process spec (most elaborate example)
/a0/agents/hacker/prompts/agent.system.main.specifics.mdConcise red/blue team pentester identity
/a0/agents/researcher/prompts/agent.system.main.specifics.mdResearch methodology and deliverable expectations
/a0/agents/_example/prompts/agent.system.main.specifics.mdMinimal demo override (fictional "Agent Zero" persona)

Start by copying whichever existing profile's specifics.md is closest to your target, then rewrite.

Example agent.system.main.specifics.md for a data analyst:

markdown
## Your role

You are a specialized data analysis agent.
Your expertise includes:
- Python data analysis (pandas, numpy, scipy)
- Data visualization (matplotlib, seaborn, plotly)
- Statistical modeling and hypothesis testing
- SQL queries and database analysis
- Data cleaning and preprocessing

## Process
1. Understand the data and the question
2. Choose appropriate tools and methods
3. Execute analysis with `code_execution_tool`
4. Visualize results when applicable
5. Provide clear interpretation of findings

High-value inherited prompt levers

The root /a0/prompts directory contains powerful defaults. A profile can override any of these by placing a file with the same name in <PROFILE_ROOT>/<name>/prompts/. Use this when the requested profile needs a different protocol, not just a different specialty.

FileOverride when the user wants...
agent.system.main.communication.mdA different response contract, such as no thoughts array, a different JSON schema, plain Markdown answers, or a domain-specific output envelope. This is the main lever for output format changes.
agent.system.main.solving.mdA different problem-solving loop, delegation policy, verification standard, or autonomy level.
agent.system.main.tips.mdDifferent file-handling, skill-use, memory, or operational best-practice defaults.
agent.system.main.environment.mdA different runtime/environment description than the default Kali/Docker Agent Zero environment.
agent.system.main.role.mdA fundamentally different base identity. Rare; prefer specifics.md unless replacing the base role is intentional.
agent.system.tool.response.mdDifferent final-response tool instructions, such as stricter final formatting or use of includes for long output.
fw.user_message.md / fw.ai_response.mdDifferent framework message wrapping. Advanced and fragile; override only with a clear reason.

When a blueprint includes any of these, add an entry to prompt_strategy.root_prompt_overrides and include the exact override file in files.

Secondary overrides (use only when needed)

FileWhen to overrideShipped example
agent.system.main.role.mdReplace the base role framing wholesale (rare — most profiles layer via specifics.md instead)/a0/agents/agent0/prompts/agent.system.main.role.md
agent.system.main.communication.mdChange reply format / communication style/a0/agents/developer/prompts/agent.system.main.communication.md, /a0/agents/researcher/prompts/...
agent.system.main.environment.mdDescribe a non-default runtime environment/a0/agents/hacker/prompts/agent.system.main.environment.md (Kali/Docker)
agent.system.tool.<name>.mdDocument a profile-specific tool (see Step 6)/a0/agents/_example/prompts/agent.system.tool.example_tool.md

[!TIP] Only override what you actually need to change. Copying unchanged prompt files creates silent drift when the framework updates the originals — specifics.md is safe to own because its default is empty by design.


Step 6 (optional): Profile-specific tools

Drop a Python tool class in <PROFILE_ROOT>/<name>/tools/<tool_name>.py:

python
from helpers.tool import Tool, Response

class ExampleTool(Tool):
    async def execute(self, **kwargs):
        test_input = kwargs.get("test_input", "")
        return Response(
            message=f"Example tool executed with test_input: {test_input}",
            break_loop=False,
        )

Two important rules:

  1. To make the tool visible in the system prompt, add prompts/agent.system.tool.<tool_name>.md describing its usage and JSON call schema. The prompt loader auto-includes every file matching agent.system.tool.*.md.
  2. Placing a file with the same name as a core tool (e.g. tools/response.py) replaces the core tool for this profile only. See /a0/agents/_example/tools/response.py for a redefinition example.

Step 7 (optional): Profile-specific extensions

Lifecycle hooks go in <PROFILE_ROOT>/<name>/extensions/<hook_point>/_NN_<name>.py. The _NN_ prefix controls execution order.

Example — rename the agent at init (/a0/agents/_example/extensions/agent_init/_10_example_extension.py):

python
from helpers.extension import Extension

class ExampleExtension(Extension):
    async def execute(self, **kwargs):
        self.agent.agent_name = "SuperAgent" + str(self.agent.number)

Available hook points mirror the framework's own /a0/extensions/python/<point>/ directories — see a0-development/SKILL.md for the full list.


Step 8: Test the new profile

  1. The profile is picked up on next agent initialization — no restart of individual conversations needed, but a fresh agent/subordinate spawn is required.
  2. From the superior agent, delegate to it via call_subordinate using the profile's directory name (not the title).
  3. Verify:
    • Title appears correctly in the UI agent selector.
    • Role override (if any) takes effect in the new agent's system prompt.
    • Profile-specific tools are callable and their prompt files are included.

If the profile does not appear, check:

  • Directory name matches the ^[a-z0-9_-]+$ pattern and is unique.
  • agent.yaml parses as valid YAML.
  • It is placed in one of the recognized search paths (see Step 0).

Reference: Complete _example profile layout

/a0/agents/_example/
├── agent.yaml
├── prompts/
│   ├── agent.system.main.specifics.md     # role override
│   └── agent.system.tool.example_tool.md  # tool usage prompt
├── tools/
│   ├── example_tool.py                    # new tool
│   └── response.py                        # redefines core response tool
└── extensions/
    └── agent_init/
        └── _10_example_extension.py       # init-time hook

Copy this shape when in doubt — it demonstrates every customization surface a profile supports.


Quick checklist

  • Confirmed profile scope (user / plugin / project)
  • Produced and confirmed agent_zero.agent_profile_blueprint.v1 JSON
  • Confirmed whether Main/Utility models inherit defaults or need _model_config/config.json
  • Directory name is unique and matches allowed characters
  • agent.yaml contains exactly title, description, context
  • Prompt overrides only include files that actually change behavior
  • Any new tool has a matching agent.system.tool.<name>.md
  • Profile tested via call_subordinate in a fresh conversation