1. Run a simple agent
A model, a system prompt, a user prompt. No tools. The model answers from what it knows.id is the session: Albus creates it on the first run and
continues it on every later run, so the next prompt to support-1234 sees this
one. agent_name groups runs into an agent; the agent object is its
configuration. Albus supplies the model until you bring your own
key. The current date and time are prepended to
system_prompt; omit it and a server default applies.
2. Make the run retry-safe
Add aninvocation_key. Retrying with the same key re-attaches to the same run
instead of starting a new one, so a network failure, a 504 from a long wait,
or a lost response costs nothing.
Idempotency-Key header. It is unique in your
organization and is how you read the run back later: GET /traces/{invocation_key}. The response always returns the effective key in
Idempotency-Key, including when the server generated it.
Session id. Match
^[0-9a-zA-Z._:-]+$, 2–100 characters. Use an id you
already have: the ticket (support-1234), the pull request (pr-987), the job
(nightly:2026-08-11). Then you can find the session without storing a
mapping, and the conversation continues where the work does.
Invocation key. Derive it from the thing that must happen exactly once: the
id of the event that triggered the run, or the session id plus a turn counter
(support-1234-triage-1). Do not use a timestamp or a random value generated
on each retry; each one starts a new run, which is exactly what the key is
meant to prevent. The same key re-attaches even to a failed run. Reuse the key
to recover a lost response; use a new key to run again.
3. Add web search and a terminal
Add the two built-in tools. The agent can now search the web and run commands in a persistent Linux sandbox, and the model decides when to call each. Runs take longer and answers are grounded in what the tools return.tools is an allowlist. Include a tool’s block to offer it; leave it out and
the model never learns the tool exists. A prompt that says “do not run
commands” is not a substitute: the model can ignore instructions, but it
cannot call a tool it was never given. web_search appears in traces as
WEB_SEARCH, terminal as TERMINAL. Details in Built-in
tools.
Tool calls take steps. Set max_steps to cap how many model steps a run may
take before it stops.
4. Add a secret and an MCP server
Give the agent your own tools through an MCP server, authenticated with a secret. The agent can now act on your systems — here, search GitHub issues — and the credential never appears in the configuration, the audit log, or a revision. Store the credential first. Secrets are administration, so the CLI is the right tool. The value is the full header value the server expects,Bearer
included:
/-separated segments of [a-zA-Z0-9_-]. Group them
like files.
Reference the secret from the agent as albus.sh/secrets/<name>:
http(s) URL; stdio servers need
an HTTP front.
A server you host yourself needs no headers entry: when headers has no
Authorization entry, Albus sends a signed identity token, which your server
verifies against your organization’s issuer. See
Authenticate Albus to your MCP server.
References resolve when the run starts, not when the request is validated. A
reference to a missing secret fails the run, not the request, so create the
secret first. Rotate with
albus secrets update: references keep working, the
next run picks up the new value, and the agent configuration does not change.
5. Configure memory
Add a memory group. What the agent learns now outlives the session: every run configured with the samegroup reads the same memories, whichever session it
runs in, and writes new ones at the points you list.
generation says when memories are written: end_of_invocation after the
run answers, agent whenever the agent decides mid-run that something is worth
keeping. Scope a group however you like: one per customer, per team, per agent.
Without memory, a session still remembers its own last 1000 messages; memory
carries knowledge between sessions. Read and prune a group with GET /memories?group=support and DELETE /memories?group=support, or in the
console under Memories. More in Built-in
tools.
6. Read the trace and iterate
Every run is recorded as a trace: the run, each step, the model call in each step, and the tool calls it requested, as spans with inputs, outputs, timings, and token usage. The trace is how you find out what the agent did, and the fastest loop for fixing a prompt or a tool. Point a coding agent at it.inv4 is the fourth run of the session,
inv4.attempt1.step1.tool1 the first tool call the first step requested. A
model_call span’s input is exactly what the model was given and its
output what it said, including the tool calls it asked for. A tool_call
span’s input is the arguments and its output the tool’s result. Long
payloads are cut with an [omitted: …] marker and carry the full byte count
and SHA-256.
Questions to ask a trace:
- Did the agent call the tool you expected? If
WEB_SEARCHfires wheregithub__search_issuesshould have, the tool’s description (from the MCP server) or yoursystem_promptdid not make the choice obvious. Name the tool and when to use it in the prompt, or tightenallowed_tools. - Did the tool give the agent what it needed? Read the
tool_calloutput. A tool that returns 40 KB of JSON for a one-line answer wastes steps and tokens. A tool that returns an error the model cannot act on gets retried. Fix the tool, not the prompt. - Where did the steps go? Count
stepspans and readusageon eachmodel_call. The same tool called in a loop with slightly different arguments means the task is underspecified. Amax_stepsstop means the budget or the prompt is wrong. - Why did it fail? A
FAILEDspan carrieserror; the run carries afailure. A retried run has more than one attempt. Pass--attempts allto see the superseded ones; their tool calls still had their effects.
albus traces list shows runs across sessions, newest first, filtered by
--agent-name, --agent-revision, --status, --session, --since, and
--until. --status FAILED on an agent name is the first thing to look at
when a job goes wrong. Spans are kept for 90 days. The console shows the same
under Traces, one run per /traces/<invocation_key>.
Change the prompt or a tool, run again with a new invocation key, compare
the traces. Which raises what “change” means.
7. Every change is a revision
You never create an agent. You name one on a run and Albus records the configuration. Every distinctagent object under one agent_name is a
revision, identified by a hash of the configuration. Each step in this
guide created a new revision of support-triage; running the same
configuration again reuses the existing one.
get_agent returns the current revision’s full configuration plus every
revision, newest first. get_agent_revision returns one revision’s exact
model, prompt, tools, MCP servers, and memory. In the console, Agents lists
them; each revision lives at /agents/<name>/revisions/<revision>.
Every session response carries session.agent_revision. Every trace and audit
event carries agent_revision. GET /traces?agent_name=…&agent_revision=…
lists every run of one configuration. That is the link from an answer you do
not like back to the configuration that produced it.
Keep agent_name stable per job (support-triage, pr-reviewer), not per
run or per customer, so the revision list is the agent’s history. Per-run
identity belongs in the session id. Record the revision next to your own
results. A revision is configuration only; credentials are references, so
rotating a secret does not create one.
8. The audit log
The audit log is the security record of a session: an immutable, time-ordered account of every run, model call, and tool call, arguments and results included, and how each run ended. A trace is for understanding and iterating. The audit log answers what did this agent do, on whose request, with which configuration.
Events created before the rename to
invocation_* keep their old run_*
names. Every event carries session_id, the invocation_key it belongs to,
the agent_revision that ran, event_time, and a payload shaped by its
type. Model output, tool output, and tool arguments are stored up to 32 KiB
each, with the complete value’s byte count, SHA-256 digest, and a truncation
flag (contentBytes, contentSha256, contentTruncated), so a stored value
can be checked against the original. Secrets never appear: references resolve
at run time and the values are not written anywhere the API returns.
--after/--limit (default 100), passing the response’s
next_cursor as the next after. The log is per session. For the same events
across sessions, filtered by agent, revision, status, or time, use
traces.
Clean up
Where next
- Bring your own key — run on your own model provider account.
- Built-in tools — web search, the terminal, and memory in detail.
- Errors — every status a run can return, and the fix.