Chapter 20 · goal + tools + loop
Build them once; the frameworks stop being magic.
# whitelist operators via the AST — never eval()
_OPS = {ast.Add: operator.add, ast.Mult: operator.mul, ...}
An agent is only as safe as its worst tool.
for _ in range(max_steps): # the safety rail
response = complete(goal, history, tools)
calls = tool_calls(response)
if not calls: break # no calls = the answer
for c in calls:
history += run_tool(c)
The step cap turns "got confused" into "got confused, cheaply."
"Never do math in your head — use the tool."
Models compute confidently and wrongly. Good agent design is good instruction design.
Same loop; different tools + goal.
The loop makes agents powerful; logs make them debuggable.
Goal, tools, loop — write them by hand and frameworks read as convenience. Trust comes from safe tools, a step cap, forcing tools, and logging. Next: agents talking to agents.