Advanced Patterns
Once the fundamentals hold, a handful of patterns push agents further — reflection, tool retrieval at scale, subagents, and code-execution. Each is powerful and each has a cost. The advanced skill isn't knowing they exist; it's knowing the specific situation each earns its keep, and measuring that it did.
Reflection / self-critique — quality for steps
Reflection adds a step where the agent critiques its own draft before finalizing: "Does this answer the question? Is every claim supported? What's missing?" then revises. On tasks with quality that's hard to get right in one pass — complex reasoning, code, structured outputs — reflection measurably lifts quality. On a set of code-generation tasks, a single reflection pass raised correctness from roughly 68% to 82%. But it isn't free: it's at least one extra model call (often more), so it adds latency and cost to every task, including the ones that were already right. The discipline: apply reflection where a measured quality lift justifies the extra step, not reflexively. On simple tasks it's pure overhead — and over-reflection can even talk a correct answer into a wrong "improvement."
Reflection buys quality with steps (cost + latency). Gate it: reflect on high-stakes or historically-error-prone tasks, skip it on simple ones. Always A/B it on your task set (Ch. 8) — measure the quality lift and the added cost, and keep it only where the trade is worth it.
Tool retrieval — when the agent has too many tools
Everything in Chapter 2 assumed a handful of tools. Real systems can have hundreds, and you can't put 200 tool definitions in every prompt — it bloats context, slows the model, and degrades selection (more choices, more confusion). The fix mirrors RAG: keep tools in a store and retrieve the relevant few for each query, exposing only those to the model. An agent that selects poorly among 60 always-loaded tools often selects well among the 5 retrieved for the specific task — same model, smaller, sharper menu. Tool retrieval is how agent engineering and search engineering converge.
Subagents as a tool
A clean way to manage complexity: expose an entire agent as a tool to another agent. The parent calls research_agent(query) like any tool; the child runs its own loop with its own tools and clean context and returns a result. This is orchestrator–worker (Ch. 6) framed as composition, and it inherits both the benefit (isolation, focus) and the cost (token multiplication). Used judiciously it keeps each agent's context small and its job legible; used everywhere it's an expensive tangle.
Code execution — the highest-leverage tool
Giving an agent a sandboxed code interpreter is often worth more than a dozen bespoke tools: instead of you predicting every operation and building a tool for it, the agent writes and runs code to do arbitrary computation, data manipulation, and analysis. It turns "I need a tool for that" into "the agent writes it." The cost is real: a code-execution tool is a serious security boundary (arbitrary code!) that must be sandboxed, resource-limited, and network-restricted. It's the pattern behind data-analysis and coding agents — enormous capability, gated behind serious isolation.
A/B reflection — measure the quality lift and its cost
You'll evaluate a task set with and without a reflection pass, measuring both the correctness lift and the extra steps it costs — so you can decide where reflection earns its place instead of applying it blindly.
Setup: mock-only; reflection fixes some initially-wrong tasks but adds a step to all.
Step 1. Score the task set with no reflection (correctness, steps).
Step 2. Score it with one reflection pass (higher correctness, +1 step each).
Step 3. Print both, and the cost of each corrected task.
Your goal: "no-reflect C1 @ S1, reflect C2 @ S2" and a one-line rule for when to enable it.
Starter code
# Per task: (correct_without, correct_with_reflection, base_steps)
TASKS = [(True,True,3),(False,True,3),(True,True,2),(False,True,4),
(True,True,3),(False,False,4),(True,True,2),(True,True,3)]
def score(reflect):
correct = sum((cw if reflect else c0) for c0,cw,_ in TASKS)/len(TASKS)
steps = sum(s + (1 if reflect else 0) for _,_,s in TASKS)/len(TASKS)
return correct, steps
# TODO: print both configs; compute how many tasks reflection fixed and the
# extra steps spent across ALL tasks to fix them.
c0,s0 = score(False); c1,s1 = score(True)
fixed = sum((not a) and b for a,b,_ in TASKS)
print(f"no-reflect {c0:.0%} @ {s0:.1f} steps")
print(f"reflect {c1:.0%} @ {s1:.1f} steps (+1 step on ALL {len(TASKS)} tasks, fixed {fixed})")
# => no-reflect 62% @ 3.0 steps
# reflect 88% @ 4.0 steps (+1 step on ALL 8 tasks, fixed 3)
What you should see: reflection lifts correctness (62% → 88%) but adds a step to every task — you spent 8 extra steps to fix 3 tasks. Whether that's a good trade depends on the cost of a wrong answer here. On high-stakes tasks, cheap; on a high-volume, low-stakes endpoint, that blanket +33% step cost may not be worth 3 fixes. The measurement — not a rule of thumb — makes the call.
The engineering read. Every advanced pattern in this chapter is this same shape: real capability, real cost, and a decision that should be measured on your task set, not adopted because it's fashionable. Reflection, tool retrieval, subagents, code execution — reach for each when its specific problem appears (hard-to-one-shot quality; too many tools; complexity that needs isolation; open-ended computation), and prove the lift with the harness from Chapter 8.
Going further (optional): gate reflection on a cheap difficulty heuristic (only reflect when the draft is long or low-confidence) and re-measure: you may keep most of the quality lift at a fraction of the step cost — targeted, not blanket, reflection.
Sentinel: a second pair of eyes
Sentinel's agent produced code changes that looked plausible but shipped subtle errors — a wrong edge case, a missed import — roughly 1 in 4 times. Adding a bigger model barely moved it, because the failure was overconfidence, not raw capability. The advanced pattern that helped: a verifier / reflection step, where a separate check (run the tests, or a critic pass that re-reads the change against the requirement) gates the result before the agent declares done.
With a self-check-then-fix loop, the agent caught and repaired many of its own mistakes before they surfaced; error rate fell from 25% to 9%. The cost was extra steps, which they measured and deemed worth it. The lesson about advanced patterns generally: reflection, verifiers, and the like are powerful but not free — adopt them when the numbers show a real error class they fix, not because they're fashionable.
Before closing a ticket, Ridgeline's agent runs a quick self-check: does the resolution actually match what the customer asked, and were all steps completed? That verify-before-done pass catches premature "resolved" replies and bumps real completion a few points.
Quiz · Chapter 11 — reasoning, not recall
- Reflection raised code correctness 68%→82% but should still be gated because:
- With 200 available tools, putting all definitions in every prompt is bad because:
- Exposing a whole agent as a tool to another agent is:
- A sandboxed code-execution tool is high-leverage because:
- The unifying rule for all advanced patterns is: