Skip to main content

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).

Build workflows as Agent Teams, not as raw graphs

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

StepOperationRequired inputs
Model providerPOST /api/public/v1/admin/ai/model-providersprovider_type, default_model
Skill (optional)POST /api/public/v1/admin/agent-teams/skillsname, skill_kind
BlueprintPOST /api/public/v1/admin/agent-teams/blueprintsname, role_label
FormationPOST /api/public/v1/admin/agent-teams/formations (+ /billets)name; billet required_skills, authority_cap
CrewPOST /api/public/v1/admin/agent-teams/crewsformation_id
RunPOST /api/public/v1/admin/agent-teams/crews/{id}/runscrew 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:

FieldWhat it constrains
allowed_toolsThe named tools the agent may call (from the Tool Catalog; list them via GET /ai/tool-registry)
clearance_levelThe classification ceiling the agent operates under
permission_modeask (default), or a more autonomous mode: the security floor still applies
data_grant_ids / egress_allowlist / compartmentsThe data it may read, where output may go, and its compartment labels
governing_contract_idA 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.

Tools yes, MCP-server attachment owed

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_policyResulting shape
sequentialA pipeline of data edges
parallelFan-out with a join
consensusFan-out with a consensus gate
manager-delegatesA 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​

#CheckHow
1The agent exists as a principalIt appears in the directory with its own identity, not as a configuration row
2It holds only what you grantedIts tool surface matches the skills you bound, and nothing else
3The run reached a terminal stateCompleted, failed or refused. A run still showing as in flight after its budget is the thing to chase
4The journal records itEach step carries an input hash, an output hash and a signature
5It was chargedThe 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​

SymptomMost likely causeWhat to do
The agent cannot be mintedNo authority to create a principal, or a quota ceilingPopulation is governed. Check the quota before assuming a permission problem
A tool the agent should have is missingIt is permitted but not advertisedSurface and authority are separate. The agent can find it through tool search; see belt, box and shed
A tool call is refusedThe grant does not carry it, or the value gate declinedThe refusal names which. A gate refusal is a decision with a record, not an error
A run refuses immediatelyNo budget ledger is registered for the agentFail-closed by design: an unbudgeted agent is not an unbounded one
A team fails to compileA seat asks for more authority than its manager holdsRejected at author time deliberately. Narrow the seat or widen the manager
A resumed run is refusedThe formation changed since the run startedGraph-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.