Create your first agent
By the end of this page you will have an agent named assistant that answers questions, can
search the web and remember things, and asks before doing anything consequential. It is about
twenty lines of configuration.
The walkthrough assumes you have a checked-out axl-config directory and an AXL server you can
restart. Everything below happens inside that directory.
Register the agent
Registration tells the server which directories to load. Edit axl-config/agents.toml:
skills_dir = "skills"
[[agents]]
config_dir = "agents/assistant"The path is relative to the config root. Registration only makes the directory visible - it says nothing about the agent's behavior, which lives in the next file.
Give it an identity and tools
Create axl-config/agents/assistant/agent.toml:
key = "assistant"
display_name = "Assistant"
description = "A helpful general-purpose assistant"
identity = "You are a concise, practical assistant."
toolsets = ["web", "memory"]
skills = ["onboarding"]
response_format = [
"Use markdown formatting for readability",
"Lead with the answer",
]toolsets takes tool set names, not tool names - the agent receives every tool in each set
it lists. axl tools list prints what your deployment registered, and
Give agents tools explains where individual tool names go instead. Skill
names likewise have to be installed and enabled in your deployment.
description is how a person picks this agent out of a list, and it sets an expectation before
anyone types a word. Keep it honest, like "A helpful general-purpose assistant" here, instead of
overpromising with something like claiming the agent knows everything about the company.
tools and skills must name things your deployment actually has. A tool set has to be
registered by the server and listed here before the agent can use it - listing a name the
server does not provide is a configuration error. See
built-in tools for what ships in the box.
Add an intent contract
This step is optional. intent.toml states what the agent is for and how much autonomy it has,
and AXL enforces the autonomy level in code rather than trusting the prompt.
Create it beside agent.toml:
[objective]
problem = "Help the team answer product-support questions"
why = "Reduce time spent searching internal guidance"
success_criteria = "Answers cite the relevant source when available"
[constraints]
no_invention = "Do not invent account-specific facts"
[autonomy]
"issue_refund" = "forbidden"
"send_*" = "require_approval"
[stop_rules]
missing_context = "Stop when the question is answered or required context is missing"Every section except [objective] is a table of name = "value" pairs, not a list. The name is
yours to choose and shows up in the agent's prompt.
Autonomy is per tool, and it is enforced in code rather than suggested to the model. Keys
are tool names or prefix* globs. When a tool matches more than one glob, the most restrictive
level wins.
Any tool you do not list runs at full. List the ones you want to restrict; the rest are
unrestricted. AXL warns at boot when a key here matches no tool the agent actually has, so a
typo surfaces instead of quietly leaving a tool ungated.
The autonomy level is what actually controls the agent's behavior. Choose one:
| Level | What happens |
|---|---|
full | The agent acts without asking |
notify_only | The agent acts and tells you afterwards |
require_approval | A person confirms before the action runs |
forbidden | The action is refused |
require_approval is a good default while you are learning what an agent does with real
requests. It is enforced in AXL's pre-flight check, so it holds even if the model is persuaded
otherwise.
Point AXL at the config root
Start the server with CONFIG_DIR set to the directory containing agents.toml:
CONFIG_DIR=/path/to/axl-config cargo run -p axl-serverRestart the process after any change to registration or agent files - configuration is read at startup, not watched.
Confirm it works
Send the agent a request and watch what comes back:
curl -sX POST "$AXL_HOST/api/v1/agent/assistant/invoke" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"message": "What can you help me with?"}'Successful responses use AXL's standard envelope, so your payload is under data:
{ "status": 200, "msg": "OK", "data": { … } }If the agent is not found, check three things in order: the path in agents.toml, the spelling
of key, and whether CONFIG_DIR really points at the directory you edited.
What you now have
With twenty lines of configuration, the agent already comes with:
- A model-driven loop that calls tools and feeds results back until the question is answered
- Web access with SSRF protection, and long-term memory across conversations
- An explicit objective and stop rules the model is told about
- An autonomy level enforced by AXL rather than requested in a prompt
- Session history, token and cost budgets, and a loop guard, all on by default
- Every tool outcome available to the audit log
None of that required application code, and all of it is reviewable in a pull request.
Add middleware when you need it
Middleware wraps the agent's work: caching a repeated read, requiring approval only when the arguments look risky, capping how many writes a single run may perform. All of it is off unless you turn it on.
[middleware.tool_cache]
enabled = true
ttl_secs = 300Check what an agent actually resolved to with axl weave print --config <agent.toml>.
Next
- Give it your documents - so answers come from your content, not the model's training data.
- Add long-term memory - include
memoryintoolsets, then tunememory.toml. - Choose a different model - per agent, including reasoning level.
- Middleware - the full list and what each one costs you.
- Support agent walkthrough - this agent, extended into something a team can use.