Harness orchestration
Dispatch a coding agent as a typed worker with turn caps and schema-validated output. AForge runs by default; Claude Code, Codex, Gemini CLI, and OpenCode are one field away.
Use a harness as a step inside a regular reasoner. The harness runs a coding agent, gives it tool access, bounds the run with a turn cap, and returns a schema-validated object -- not free-form text.
Nothing to install. By default the worker is AForge, AgentField's native harness, provisioned alongside the af binary by the curl installer, AgentField Desktop, and the official agent Docker images. Export OPENROUTER_API_KEY and the example below runs. Want Claude Code, Codex, Gemini CLI, or OpenCode driving it instead? That is one field -- see Bring your own coding agent.
from pydantic import BaseModel
from agentfield import Agent, HarnessConfig
# No provider, no model -- this agent's harness calls run on AForge.
app = Agent(node_id="migrator", harness_config=HarnessConfig())
class MigrationPlan(BaseModel):
sql_statements: list[str]
rollback_steps: list[str]
risk_assessment: str
@app.reasoner()
async def plan_migration(description: str) -> dict:
# Harness reads the schema, writes SQL, validates against the Pydantic model
result = await app.harness(
f"Analyze the database schema and produce a migration plan for: {description}",
schema=MigrationPlan,
max_turns=20, # turn cap -- AForge stops cleanly when it is hit
)
if result.is_error:
return {"error": result.failure_type, "message": result.error_message}
plan: MigrationPlan = result.parsed
return {
"sql": plan.sql_statements,
"rollback": plan.rollback_steps,
"cost_usd": result.cost_usd,
"turns": result.num_turns,
}
# Swap workers per-call -- Codex for test generation, Gemini for big refactors
@app.reasoner()
async def write_tests(module: str) -> dict:
result = await app.harness(
f"Write a comprehensive test suite for {module}.",
provider="codex",
model="o4-mini",
max_turns=40,
)
return {"output": result.text, "cost_usd": result.cost_usd}
app.run()What this gives you
- A multi-turn harness looks like a regular function call -- input goes in, validated object comes out.
- The default worker ships with
af, so the first run needs no CLI install and no per-worker vendor account -- just oneOPENROUTER_API_KEY. max_turnsbounds the run: on the default AForge worker it becomes--turns, and the agent stops cleanly when the cap is hit. The USD cost capmax_budget_usdis enforced byclaude-codeonly -- on AForge, bound spend withmax_turnsplus AForge's own token budget (AFORGE_EXEC_BUDGET, default 150000 tokens).failure_typedistinguishes timeouts, crashes, schema-validation failures, and API errors.
Bring your own coding agent
The loop above is worker-agnostic. Set provider and the identical call drives Claude Code, Codex,
Gemini CLI, or OpenCode instead -- which is how you orchestrate a fleet of Claude Codes (or mix
workers) from a single AgentField reasoner.
# Same reasoner, different worker -- and claude-code is the provider that enforces max_budget_usd.
plan = await app.harness(
prompt, schema=MigrationPlan, provider="claude-code", max_budget_usd=1.00
)
# Or set it once for the whole agent.
app = Agent(node_id="migrator", harness_config=HarnessConfig(provider="claude-code"))Each override brings its own install and credential (Claude Code differs per SDK):
provider | Install | Credential |
|---|---|---|
aforge (default) | ships with af -- nothing to do | OPENROUTER_API_KEY |
claude-code | Python: pip install 'agentfield[harness-claude]' · TypeScript: npm install @anthropic-ai/claude-agent-sdk · Go: the claude CLI (npm install -g @anthropic-ai/claude-code) | ANTHROPIC_API_KEY |
codex | npm install -g @openai/codex | OPENAI_API_KEY |
gemini | npm install -g @google/gemini-cli | GEMINI_API_KEY |
opencode | curl -fsSL https://opencode.ai/install | bash | opencode auth login |
AGENTFIELD_HARNESS_PROVIDER shifts the default for a whole process without touching code; an
explicit provider on the config or the call still wins. Verify a worker before you depend on it:
af harness doctor --provider aforge # or claude-code / codex / gemini / opencode
Next