Three Kinds of Agents

Who this is for: developers choosing an agent architecture for a new task, or evaluating whether to refactor an existing one.


The short answer

agent_framework supports three distinct execution patterns for agents:

Kind Control flow Who decides what’s next When to use
Standalone Reactive decision loop The model, every turn Open-ended tasks; emergent behavior
Programmatic workflow Python-driven state machine The developer, in code Deterministic orchestration; fixed topology
Planning Model-generated plan + batched execution The model, up front then at each reflect Structured multi-step tasks with data dependencies

None of these is universally best. Each one makes a different tradeoff between flexibility and predictability, and between model-consumed tokens and developer-written code.


Kind 1: Standalone agents

What it is

A standalone agent runs the default reactive loop: call model → parse AgentDecision → execute (call tool, call sub-agent, invoke skill) → append result → repeat. The model decides what to do next at every turn, based on the full conversation history.

This is the default. No configuration is needed. Every agent in agent_framework is a standalone agent unless you add something.

When to use it

Use a standalone agent when:

Advantages

Disadvantages

Example use cases

Implementation

Write a markdown file with a system prompt and the relevant tools listed. No planning: block. No Python behavior class unless you need custom lifecycle hooks.

---
id: my_agent
role: assistant
tools:
  - search
  - read_file
---

You are a research assistant. Answer questions by searching and reading relevant documents.
Use search first, then read the most relevant results, then answer.

Kind 2: Programmatic workflow executors

What it is

A programmatic workflow agent uses a Python AgentBehavior to build a ProgrammaticWorkflow — a code-defined state machine that routes to sub-agents based on structured conditions. The agent’s LLM loop is bypassed entirely; the Python code controls which child agents run and in what order.

See Programmatic Workflow Agents for the full API reference.

When to use it

Use a programmatic workflow agent when:

Advantages

Disadvantages

Example use cases

Implementation

Write a markdown file for the agent definition (minimal content, since the behavior class overrides the loop), then write a Python AgentBehavior:

class ReviewPipelineBehavior(AgentBehavior):
    def before_run(self, agent, host, *, run, caller_id):
        workflow = ProgrammaticWorkflow(
            entry_step="intake",
            steps={
                "intake": WorkflowCallSubagentStep(
                    step_id="intake",
                    subagent_id="intake_agent",
                    parameters=lambda state: {"input": run.parameter_values["input"]},
                    next_step="review",
                ),
                "review": WorkflowCallSubagentsStep(
                    step_id="review",
                    calls=lambda state: (
                        SubagentCallSpec("reviewer_a", {"doc": run.parameter_values["input"]}, "review_a"),
                        SubagentCallSpec("reviewer_b", {"doc": run.parameter_values["input"]}, "review_b"),
                    ),
                    mode="parallel",
                    next_step="finish",
                ),
                "finish": WorkflowReturnStep(
                    step_id="finish",
                    value=lambda state: AgentResult(
                        status="completed",
                        message=str(state.require_step_result("review")),
                    ),
                ),
            },
        )
        result = agent.execute_programmatic_workflow(
            host=host, run=run, caller_id=caller_id, workflow=workflow,
        )
        return AgentHookDecision(final_result=result)

Register the behavior in an initializer and attach it to the agent.


Kind 3: Planning agents

What it is

A planning agent uses PlanningTurnDriver — enabled by a planning: block in the agent’s frontmatter — to separate plan generation from plan execution. The model emits an explicit plan (a list of steps with data dependencies), the runtime executes ready batches in parallel, resolves `` token substitutions, and after each batch gives the model a reflect turn to evaluate results and decide whether to continue, revise, or finalize.

See How Agents Plan for the conceptual background, and How to Create a Planning Agent for the implementation guide.

When to use it

Use a planning agent when:

Advantages

Disadvantages

Example use cases

Implementation

Add a planning: block to the agent’s frontmatter and write a prompt that describes both the planning contract and the step schema:

planning:
  enabled: true
  parallel_execution: true
  max_steps: 30
  max_plan_revisions: 3

The system prompt should explain how to structure a plan and what decisions to make during the reflect phase. See How to Create a Planning Agent for full prompt templates.


Choosing between the three

The decision tree is short:

Is the top-level control flow deterministic and code-expressible? → Yes: use a programmatic workflow executor. Skip the model on orchestration. → No: continue.

Does the task have structured steps with data dependencies between them, or could it benefit from parallel execution? → Yes: use a planning agent. → No: use a standalone agent.

When in doubt, start with a standalone agent. If you find the model is spending turns figuring out what to do next when you could have told it, switch to a programmatic workflow. If you find the model is executing steps sequentially when many could run in parallel, or if intermediate results are driving the next set of actions in a structured way, switch to a planning agent.

Mixing the three

The three kinds compose naturally in a multi-agent tree:

A common architecture is a programmatic workflow at the top (deterministic routing between phases), planning agents inside each phase (structured execution with data dependencies), and standalone specialist agents at the leaves (domain-specific reasoning).


Next steps