Not every agent turn deserves a frontier model. Route boilerplate and mechanical patches to cheap draft models; reserve expensive verifiers for architecture review, security-sensitive diffs, and flaky-test RCA. You cut spend without lowering the bar on judgments that protect production.
⚡ TL;DR: Classify tasks (draft vs verify); run Haiku/Sonnet-class (or local) drafts; escalate to frontier only on risk signals (IAM, auth, migrations, public API, flaky flakes). Cache shared system prompts. Measure $ / merged PR and revert rate. Companions: prompt caching, code review bots, Cursor rules.
Task taxonomy
export type RouteClass = "draft" | "verify" | "forbid_auto";
export function classify(job: {
files: string[];
labels: string[];
locDelta: number;
}): RouteClass {
const sensitive = job.files.some(f =>
/(^|\/)(iam|auth|migration|infra)\//i.test(f) ||
/\.github\/workflows\//.test(f)
);
if (sensitive || job.labels.includes("security")) return "verify";
if (job.labels.includes("public-api")) return "verify";
if (job.locDelta > 400) return "verify";
if (job.files.some(f => f.includes("break-glass"))) return "forbid_auto";
return "draft";
}
✅ Explicit classifier you can unit test.
❌ “Let the agent decide if it needs a bigger model.”
Two-pass pipeline
DRAFT_MODEL = "anthropic.claude-haiku-4-5-20251001-v1:0"
VERIFY_MODEL = "anthropic.claude-sonnet-4-20250514-v1:0"
def handle(job):
route = classify(job)
if route == "forbid_auto":
return needs_human(job)
draft = converse(DRAFT_MODEL, build_draft_prompt(job), tool_choice="auto")
patch = execute_tools(draft)
if route == "draft" and not risk_signals(patch):
return patch # cheap path
# Expensive verifier: read-only review, may reject
verdict = converse(VERIFY_MODEL, build_verify_prompt(job, patch), tool_choice={"auto": {}})
if verdict_rejects(verdict):
return revise_or_human(job, verdict)
return patch
Verifier system prompt should focus on: authz bugs, IAM wildcards, missing tests, API breakage — not rewriting style the draft already handled.
Risk signals that force escalation
const RISK = [
/Resource\s*:\s*"\*"/,
/Action\s*:\s*"\*"/,
/ignore.*(auth|tenant)/i,
/password|secret|AKIA/,
/DROP TABLE|prisma\s+migrate\s+reset/i,
];
export function riskSignals(diff: string): boolean {
return RISK.some(r => r.test(diff));
}
Wire the same patterns into AI Code Review Bots so human PRs get equivalent scrutiny.
Economics (illustrative)
# Planning examples — not a vendor quote
# 80% of turns on draft model @ ~0.2–0.4× frontier price
# 20% verify @ full price
# Blended often lands ~0.35–0.55× all-frontier with similar revert rates
# Prompt caching on shared rules/schemas amplifies savings further
Track: tokens by model id, escalations / day, post-merge incidents tagged agent-authored.
Closing checklist
✅ Dos
– ✅ Classify draft vs verify with tested rules
– ✅ Escalate on IAM/auth/migrations/public API/large diffs
– ✅ Keep verifiers read-heavy (review), drafts write-heavy
– ✅ Log model id per turn for cost attribution
– ✅ Combine with prompt caching on shared system text
❌ Don’ts
– ❌ Don’t run security diffs only on the cheap model
– ❌ Don’t hide escalations from developers
– ❌ Don’t use verifier temperature > 0 for CI gates
– ❌ Don’t skip human review on forbid_auto paths
– ❌ Don’t optimize cost without watching revert/incident rates
Related reading
- Bedrock Prompt Caching and Batch Inference: Cut Latency and Cost
- AI Code Review Bots: IAM, Secrets, and Least-Privilege Pipelines
- Cursor Rules for TypeScript Monorepos: Make AI Edits Stick
- Amazon Bedrock Agents: Tool Use, Memory, and Production Guardrails
Last updated on September 11, 2026
Discover more from CheatCoders
Subscribe to get the latest posts sent to your email.
