制御された自律 · Module 4 · Lesson 12 of 15
Agentic workflows with bounded autonomy

Section 01
When the model chooses the next step
An agent is a system in which the model decides part of the process — not just what to say, but what to do next. This is different from a single-generation system where the application controls the flow. With that freedom comes risk: the model may choose harmful actions, loop indefinitely, or accumulate cost.
This lesson covers how to design agentic systems that are useful without being dangerous: bounded loops, explicit state machines, tool policies, and human approval at every irreversible boundary.
Section 02
The bounded track
Picture a circular work track. A task tile enters the track and moves through stations: observe the state, propose an action, check the policy, execute the tool, record the result, update the state. At the end, the tile either exits as a finished piece or loops back for another pass.
The track has physical constraints: a stop pin that halts the loop after N steps, budget vessels that deplete with each action, an idempotency notch that prevents duplicate actions, and a human approval lever that must be pulled before any irreversible tool fires.
Where the analogy breaks: a physical track enforces its constraints mechanically. In software, the constraints are application code — and code can have bugs. The model cannot enforce its own bounds. Every constraint must be in the application layer.
Section 03
The agent state machine
Represent each agent run as an explicit, observable state machine:
Agent loop (pseudocode)
state = AgentState(task=user_request, history=[], budget=MAX_STEPS)
while state.budget > 0 and not state.done:
# 1. Observe: model reads current state
observation = model.observe(state)
# 2. Propose: model suggests next action
proposal = model.propose(observation)
# 3. Validate: application checks policy
if not policy.allows(proposal, state.user):
state.record_denial(proposal)
continue
# 4. Approve: human check for irreversible actions
if proposal.tool in IRREVERSIBLE:
if not human_approval(proposal):
state.record_denial(proposal)
continue
# 5. Execute: application runs the tool
result = execute(proposal)
# 6. Record: log everything
state.record(proposal, result)
state.budget -= 1
# 7. Check stop condition
if proposal.is_terminal:
state.done = True
return state.final_output()Section 04
Patterns: reflection, planning, multi-agent
Reflection: after generating a response, the model critiques its own output and revises. This can improve quality but adds latency and cost. It is an optional technique.
Planning: the model decomposes a complex task into subtasks before execution. Useful for multi-step problems, but plans can be wrong. Validate plans against available tools and permissions.
Multi-agent coordination: multiple agents with different roles collaborate. This can handle complex workflows but adds coordination overhead, failure paths, and cost. More agents is not automatically better.
None of these patterns is a maturity ladder. They are optional techniques. Use them when they solve a measured problem — not because they sound sophisticated.
Section 05
Budgets, stop conditions, and idempotency
Set step limits from task risk and cost, not from a universal cap. A simple Q&A agent may need 3 steps. A complex research agent may need 50. The limit should be the minimum that completes the task reliably.
Budget tracking should include both step count and dollar cost. Each tool call and model invocation costs money. An agent that loops 100 times on a difficult input can consume significant budget. Set a cost ceiling per run.
Idempotency prevents duplicate actions. If an agent calls a 'send email' tool twice because of a retry or a loop, the user gets two emails. Design tool calls to be idempotent where possible (check-then-act, or use request IDs).
Section 06
How agents fail
Infinite loops: the agent keeps trying without making progress, burning budget. Prevent with step limits and progress checks.
Cascading errors: one wrong step leads to another. The agent builds on its own mistakes. Prevent with verification at each step and rollback mechanisms.
Cost explosion: a difficult input causes the agent to make many expensive calls. Prevent with cost ceilings and early termination on low-probability paths.
Privilege escalation through tool chaining: the model uses a sequence of individually-authorized tools to achieve an unauthorized outcome. Prevent with holistic policy checks, not just per-tool authorization.
Section 07
Unscored lab: design a bounded agent
Design a customer support agent that can look up orders, issue refunds, and escalate to a human.
- Map the state machine: what are the states? What transitions are valid?
- Define tool policies: who can use which tools? Under what conditions?
- Design the budget: how many steps? What cost ceiling?
- Define stop conditions: success, failure, step limit, cost limit, human escalation.
- Which actions are irreversible? Where does human approval sit?
- Design the idempotency: how do you prevent duplicate refunds?
- Design the audit log: what gets recorded at each step?
Section 08
Six things to carry forward
An agent lets the model choose part of the process. More autonomy means more capability and more risk.
Represent each run as an observable state machine with explicit states and transitions.
Every constraint — step limits, budgets, stop conditions, tool policies — must be in the application layer. The model cannot enforce its own bounds.
Reflection, planning, and multi-agent are optional patterns, not a maturity ladder. Use them when they solve a measured problem.
Set step limits from task risk and cost. Define explicit stop conditions before deploying.
Human approval is required before irreversible actions. Do not let the model be the final decision-maker on consequential steps.