Build agents and workflows
This guide takes you from nothing to a running multi-agent workflow: configure a model, define an agent, compose agents into a team, and run it under governance. The supported operator path is Agent Teams, declarative team specs (formations) that compile to an executable graph and run on the Orchestration executor set.
All operations run against the node
admin surface (/api/public/v1/admin/…, authenticated session, the Agent
Builder console drives the same endpoints).
The orchestration runtime
runs a graph of typed nodes, and you can launch a run with
POST /orchestration/runs, but only for a graph the cell already knows.
Persistence is not the gap: graph definitions have a durable, versioned,
cross-cell store, and the in-process library falls back to it on a miss so a
graph resolves after a restart and on a different cell. The gap is the way
in. Only the built-in graphs are ever written to that store, and there is
no operator surface to author or upload a custom one. The wired way to build your own
workflow is the formation → crew path below, which compiles a declarative team
spec down to that same executor set.
The end-to-end path
Figure: the supported build path. A model provider (green) and optional skills (neutral) feed a blueprint (an agent template); a formation composes billets into a team; a crew binds real agents to the seats; running the crew (filled) compiles the formation to an execution graph and drives it. Ceiling: every box is a wired operator endpoint; raw custom-graph authoring is owed (see the caution above).
Table equivalent
| Step | Operation | Required inputs |
|---|---|---|
| Model provider | POST /api/public/v1/admin/ai/model-providers | provider_type, default_model |
| Skill (optional) | POST /api/public/v1/admin/agent-teams/skills | name, skill_kind |
| Blueprint | POST /api/public/v1/admin/agent-teams/blueprints | name, role_label |
| Formation | POST /api/public/v1/admin/agent-teams/formations (+ /billets) | name; billet required_skills, authority_cap |
| Crew | POST /api/public/v1/admin/agent-teams/crews | formation_id |
| Run | POST /api/public/v1/admin/agent-teams/crews/{id}/runs | crew id |
Step 1: Configure a model provider
An agent reasons through a registered model provider. Secrets are stored by reference, you pass a secret id, never a raw key:
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/ai/model-providers \
-H "Content-Type: application/json" \
-d '{
"provider_type":"anthropic",
"default_model":"<model-id>",
"base_url":"https://...",
"api_key_secret_id":"secret:anthropic-key"
}'
Registration persists the config and registers it into the provider registry, which re-runs the deployment-profile allow-gates (fail-closed), a provider a sovereign or tactical posture forbids is refused at registration, not at call time. Confirm what is available:
curl https://CELL_HOST:8443/api/public/v1/admin/ai/model-providers
curl https://CELL_HOST:8443/api/public/v1/admin/ai/agent-runtimes
For local, signed on-device models see Model Serving; for distributed inference, Cognition.
Step 2: Define skills (optional)
A skill is a reusable capability an agent can wield. Create one with a name
and a skill_kind (prompt, tool, chain, model, evaluator, transformer,
classifier, or extractor):
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/skills \
-d '{"name":"summarize-incident","skill_kind":"prompt","model_preference":"<model-id>","definition":{...}}'
Step 3: Define an agent (a blueprint)
A blueprint is a reusable agent template. Create it with a role and its authority template; you attach skills by id and constrain what the agent may do through an authority envelope:
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/blueprints \
-H "Content-Type: application/json" \
-d '{
"name":"incident-triager",
"role_label":"Incident Triager",
"system_prompt_ref":"prompt:triage-v1",
"model_preference":"<model-id>",
"required_skills":["skill:summarize-incident"],
"authority_template":{
"allowed_tools":["catalog.read","messaging.send"],
"clearance_level":2,
"permission_mode":"ask",
"egress_allowlist":[]
},
"scope":"workspace"
}'
The authority envelope is the governance contract for the agent:
| Field | What it constrains |
|---|---|
allowed_tools | The named tools the agent may call (from the Tool Catalog; list them via GET /ai/tool-registry) |
clearance_level | The classification ceiling the agent operates under |
permission_mode | ask (default), or a more autonomous mode: the security floor still applies |
data_grant_ids / egress_allowlist / compartments | The data it may read, where output may go, and its compartment labels |
governing_contract_id | A governed contract the agent's actions are evaluated against |
To mint a standalone agent instance from a blueprint (or from scratch), use
POST /agent-teams/agents with source: "blueprint" and a blueprint_id. Minting
creates a whole directory identity for the agent and is gated by a standing-agent
work quota.
An agent's tools are named entries in allowed_tools, resolved from the governed
Tool Catalog. Attaching an external MCP server to an agent is wired at runtime,
not through a public operator endpoint, a "register an MCP server against this
agent" surface is owed. The Edge Agent can wield
MCP servers directly via s9 chat --mcp <URL>.
Step 4: Compose a workflow (a formation)
A formation is the workflow definition: a declarative team of billets (seats), each with required skills, a reporting line, and its own authority cap. The formation's coordination policy shapes the resulting graph:
# Create the formation
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/formations \
-d '{"name":"incident-response","coordination_policy":"manager-delegates"}'
# Add a billet (seat) to it
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/formations/<formation_id>/billets \
-d '{
"role_label":"Triager",
"required_skills":["skill:summarize-incident"],
"reports_to":"<manager_billet_id>",
"authority_cap":{"allowed_tools":["catalog.read"],"clearance_level":2,"permission_mode":"ask","budget_ceiling":100}
}'
coordination_policy | Resulting shape |
|---|---|
sequential | A pipeline of data edges |
parallel | Fan-out with a join |
consensus | Fan-out with a consensus gate |
manager-delegates | A management DAG built from each billet's reports_to |
A child billet's authority is validated to be a subset of its parent's, you cannot delegate authority you do not hold.
Step 5: Instantiate a crew and run it
A crew binds a real agent to every billet in a formation; running the crew compiles the formation to an execution graph and drives it:
# Instantiate a crew from the formation (fills each seat with an agent)
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/crews \
-d '{"formation_id":"<formation_id>"}'
# Run it
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/crews/<crew_id>/runs -d '{...}'
# Track and recover
curl https://CELL_HOST:8443/api/public/v1/admin/agent-teams/crews/<crew_id>/runs/<run_id>
curl -X POST https://CELL_HOST:8443/api/public/v1/admin/agent-teams/crews/<crew_id>/runs/<run_id>/recover
Under the hood the formation is compiled by a deterministic compiler (its content
hash is the replay anchor) into an ExecutionGraph and executed on the
orchestration executors
agent, tool, skill, conditional, parallel, join, consensus, human_approval, gate,
and the rest. The run writes a durable, signed journal, so a peer cell can
resume a dead coordinator and an auditor can replay the run.
What a workflow node can do
The compiled graph draws from the fourteen registered executors, including a
gate node (a Net Potential Gain
decision boundary that can refuse), human_approval (holds for quorum or
two-person confirmation), conditional (a sandboxed DSL that never runs arbitrary
code), and consensus (reconcile several agents' answers). See
The workflow graph for the
full set and the placement ladder that treats clearance and topology as hard
constraints.
Verify it worked
| # | Check | How |
|---|---|---|
| 1 | The agent exists as a principal | It appears in the directory with its own identity, not as a configuration row |
| 2 | It holds only what you granted | Its tool surface matches the skills you bound, and nothing else |
| 3 | The run reached a terminal state | Completed, failed or refused. A run still showing as in flight after its budget is the thing to chase |
| 4 | The journal records it | Each step carries an input hash, an output hash and a signature |
| 5 | It was charged | The run appears against the agent in agent economics, not against a service account |
Step 2 is the one worth doing deliberately. An agent that can reach more than you intended usually looks fine until the day it matters.
When it does not work
| Symptom | Most likely cause | What to do |
|---|---|---|
| The agent cannot be minted | No authority to create a principal, or a quota ceiling | Population is governed. Check the quota before assuming a permission problem |
| A tool the agent should have is missing | It is permitted but not advertised | Surface and authority are separate. The agent can find it through tool search; see belt, box and shed |
| A tool call is refused | The grant does not carry it, or the value gate declined | The refusal names which. A gate refusal is a decision with a record, not an error |
| A run refuses immediately | No budget ledger is registered for the agent | Fail-closed by design: an unbudgeted agent is not an unbounded one |
| A team fails to compile | A seat asks for more authority than its manager holds | Rejected at author time deliberately. Narrow the seat or widen the manager |
| A resumed run is refused | The formation changed since the run started | Graph-hash enforcement. Start a new run rather than resuming under a different program |
Across the deployment matrix
- Single-cell: the whole build-and-run path is local.
- Multi-cell: placement scores candidate cells with clearance and topology as hard constraints; a durable journal lets a peer cell resume a dead coordinator's run.
- Sovereign / air-gapped: provider allow-gates enforce the posture at registration; a fully offline device reasons with a local signed model instead of a cloud provider.
- Cloud-enabled: cloud model providers are available, subject to the same fail-closed allow-gates.
Related
- Orchestration & agent teams: teams, the blackboard mesh, and distributed jobs.
- The workflow graph: the executor set, the sandboxed edge DSL, the durable journal, and placement.
- Agent runtime, the durable, resumable single-agent runtime a crew inherits.
- Tools & MCP, the governed tool surface an agent wields.
- Model serving & provisioning, how an agent gets a model to reason with.