Loading
0x70Lesson 8 of 8

Capstone: build an agent controller

Write the controller that runs a scripted agent safely - budgets, stuck detection, approvals - then summarize its trace.

35 min 5-question quiz 2 code exercises
By the end of this lesson you can
  • Combine step budgets, stuck detection and approval gates in one controller
  • Simulate an environment whose results change as the agent acts
  • Summarize a run trace into an operator report

Time to build the part of an agent that you own: the controller. The model’s decisions are given as a script, so you can focus on what the controller must enforce on every step:

  1. Stop on a final answer.
  2. Stop when the step budget is used up.
  3. Gate consequential actions on approval.
  4. Execute against the environment and record the result.
  5. Stop when the same action keeps returning the same result.

Then write the report an operator would want after the run: steps, errors, time, slowest call, tools used and why it stopped.

environment.py
1results = {"run_tests()": ["1 failing", "all pass"]}
2calls = {}
3for _ in range(3):
4    index = calls.get("run_tests()", 0)
5    calls["run_tests()"] = index + 1
6    print(results["run_tests()"][min(index, 1)])
Output
1 failing
all pass
all pass

Key takeaways

  • The controller enforces budgets, approvals and stuck detection on every step.

  • Results come from the environment, which changes as the agent acts.

  • Every run ends with a clear stop reason and a report.

Lesson quiz

5 questions · pass with 4 correct · up to 50 XP

Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.

Practice: write Python

Write Python in the editor and run it against sample inputs. Python runs locally in your browser using a WebAssembly runtime.

Exercise 1

Step 1: the controller

+25 XP

Line 1: JSON config {"max_steps", "stuck_threshold", "approvals"} (approvals maps tool names to true/false). Line 2: JSON environment mapping each call to a list of results - the Nth call returns the Nth result (the last one repeats). Then one proposed action per line.

For each action, in order:

  1. answer: TEXT → print final: TEXT and stop.
  2. If max_steps steps already ran → print stopped: step budget reached and stop.
  3. If the tool (the name before () is in CONSEQUENTIAL and its approval isn’t true → print step N: ACTION -> blocked: needs approval and stopped: approval denied for TOOL, and stop.
  4. Run it: print step N: ACTION -> RESULT (error: unknown tool call if not in the environment).
  5. If this action has now returned this result stuck_threshold times → print stopped: stuck on ACTION and stop.

If the actions run out, print stopped: no answer.

  • Fixes the bug
  • Gets stuck
  • Blocked deploy
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Exercise 2

Step 2: the operator report

+25 XP

Each line is a JSON event {"step", "action", "status", "ms"}, except the last, which is {"stop": REASON}. Print:

1steps: N
2errors: E
3total time: T s            (1 decimal)
4slowest: ACTION (X s)      (1 decimal; first one on ties)
5tools: NAME COUNT, ...     (tool = name before "(", sorted by name)
6stop: REASON
  • A stuck run
main.py
Loading editor…

Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.

Questions about this lesson

Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.

Loading posts…

Did you like the lesson? 😆👍
Consider a donation to support our work: