ArkTeam
ArkTeam is the unified execution primitive in ark-operator. It covers every multi-agent pattern — from strict sequential pipelines to fully autonomous delegating teams. The mode is determined by which fields you set.
| Mode | When | Use case |
|---|---|---|
| Pipeline | spec.pipeline is set | Sequential or parallel DAG — like a CI workflow |
| Dynamic | No spec.pipeline, roles use canDelegate | Autonomous delegation — agents decide at runtime |
| Mixed | Both set | Pipeline with per-step sub-delegation |
Roles
A role is a named position in the team. Each role can be:
A) Inline — define model and prompt directly:
roles:
- name: researcher
model: llama3.2
systemPrompt: "Research the topic thoroughly."
limits:
maxTokensPerCall: 8000
The operator auto-creates an ArkAgent named {team-name}-{role-name} with an owner reference.
B) Reference to an existing ArkAgent:
roles:
- name: writer
arkAgent: my-writer-agent
C) Reference to another ArkTeam (cross-team composition):
roles:
- name: legal-review
arkTeam: legal-team # the entire legal-team runs as a single step
Pipeline mode
Steps run in DAG order. Steps with no shared dependsOn ancestor run in parallel. Template expressions connect outputs to the next step’s inputs.
apiVersion: arkonis.dev/v1alpha1
kind: ArkTeam
metadata:
name: content-pipeline
namespace: my-org
spec:
output: ""
roles:
- name: researcher
model: llama3.2
systemPrompt: "Research the given topic thoroughly."
- name: writer
model: llama3.2
systemPrompt: "Write a detailed article from the research."
- name: editor
model: llama3.2
systemPrompt: "Edit and polish the article."
pipeline:
- role: researcher
inputs:
prompt: ""
- role: writer
dependsOn: [researcher]
inputs:
research: ""
- role: editor
dependsOn: [writer]
inputs:
draft: ""
Template expressions
| Expression | Resolves to |
|---|---|
| `` | A value from spec.input or the trigger payload |
| `` | Raw output string from a completed pipeline step |
| `` | Typed field from a step with outputSchema |
| `` | Output from a dynamic role (dynamic mode) |
Conditional steps
Skip a step based on a previous step’s output:
- role: escalate
dependsOn: [triage]
if: ""
inputs:
issue: ""
The if: expression is evaluated as a Go template; falsy values ("", "false", "0") skip the step. A skipped step satisfies downstream dependsOn checks.
Loop steps
Repeat a step until a condition is met:
- role: refine
dependsOn: [draft]
loop:
condition: ""
maxIterations: 5
inputs:
draft: ""
Typed output schemas
Instruct the agent to respond in a specific JSON format and access fields downstream:
- role: triage
outputSchema: |
{"type":"object","properties":{"severity":{"type":"string"},"summary":{"type":"string"}}}
inputs:
prompt: "Triage this issue: "
Access typed fields from subsequent steps:
- role: escalate
inputs:
severity: ""
summary: ""
Dynamic delegation mode
Agents decide what to delegate and when. The operator injects a delegate(role, prompt) tool into every role with a non-empty canDelegate list.
apiVersion: arkonis.dev/v1alpha1
kind: ArkTeam
metadata:
name: engineering-dept
namespace: my-org
spec:
entry: cto
output: ""
roles:
- name: cto
arkAgent: cto-agent
canDelegate: [tech-lead]
- name: tech-lead
arkAgent: techlead-agent
canDelegate: [backend, frontend]
- name: backend
arkAgent: backend-agent
canDelegate: []
- name: frontend
arkAgent: frontend-agent
canDelegate: []
canDelegate values:
| Value | Meaning |
|---|---|
omit or [] | Pure worker — no delegate() tool injected |
["role-a", "role-b"] | Can only delegate to these roles |
["*"] | Fully autonomous — can delegate to any role in this team |
entry is the role that receives inbound tasks. Required in dynamic mode.
When the LLM calls delegate(role, prompt):
- The agent runtime submits the task to that role’s isolated Redis queue
- It blocks until the target agent completes
- The result is returned to the LLM as the tool output
Cost controls
spec:
maxTokens: 100000 # hard stop per run; fails with BudgetExceeded
limits:
maxDailyTokens: 500000 # rolling 24h cap; scales replicas to 0 when reached
Token usage is tracked per step (pipeline mode) or per role (dynamic mode) and accumulated in status.totalTokenUsage.
Status
status:
phase: Succeeded # Pending | Ready | Running | Succeeded | Failed
output: "Final result..."
steps:
- name: researcher
phase: Succeeded
taskID: "1710000001-0"
tokenUsage:
inputTokens: 320
outputTokens: 1240
totalTokens: 1560
totalTokenUsage:
inputTokens: 1520
outputTokens: 4640
totalTokens: 6160
Validation
The operator performs these checks at reconcile time:
- All
canDelegatereferences point to roles defined inspec.roles - No delegation cycles exist (DFS cycle detection)
- All referenced
ArkAgentandArkTeamresources exist in the same namespace spec.entryis set in dynamic mode and refers to a defined rolepipeline[]steprolevalues resolve to entries inspec.rolesdependsOnchains form a valid DAG (no cycles)
Migration from ArkFlow
ArkFlow was deprecated in v0.9. Every ArkFlow maps directly to an ArkTeam with spec.pipeline. The only change is one template variable:
→
Step output references (``) are unchanged.
See also
- ArkTeam spec reference — complete field reference
- Building a Pipeline guide — step-by-step pipeline construction
- Autonomous Delegation example — full dynamic mode example