Lesson 12 · Domain 4 — Prompt Engineering & Structured Output (20% of exam)
Closing out Domain 4 with two efficiency questions: when should a workload run asynchronously instead of live, and when should review happen in a different "mind" than the one that generated the work?
50% cheaper, up to a 24-hour processing window, no latency SLA. That's the whole shape of the decision. It fits non-blocking, latency-tolerant workloads well — overnight reports, weekly audits, nightly test generation. It's the wrong tool the moment something is on a blocking path, like a pre-merge CI check that needs to complete in minutes: there's no guarantee it will, and occasionally it won't.
One structural limit to remember: the Batch API doesn't support multi-turn tool calling within a single request — it can't execute a tool mid-request and reason over the result inside that same batched call.
const batch = await client.messages.batches.create({
requests: documents.map((doc) => ({
custom_id: doc.id, // correlates each response back to its request
params: {
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: extractionPrompt(doc) }],
tools: [extractionTool],
},
})),
});
// Poll (or wait up to 24h), then match results back to documents via custom_id.
custom_id is what makes batch results usable at scale — it's how you know which response belongs to which original request once results come back out of order. When a batch partially fails, resubmit only the failed custom_ids (with whatever fix they needed — chunking a document that exceeded context limits, say) rather than resubmitting the whole batch. And refine your prompt against a small sample before scaling to the full volume — a batch is expensive to iterate on once it's already 24 hours deep.
A model that just generated something carries its own reasoning forward in context. It's not lying to itself exactly — it's that the reasoning that led to a decision is still right there, making that decision feel settled rather than something to re-examine. An independent instance, with none of that prior reasoning in its context, catches more — it has nothing invested in the original answer being right.
A single pass over a large multi-file change dilutes attention and tends to produce vaguer, sometimes contradictory findings. Splitting the work — a focused per-file pass for local issues, plus a separate cross-file integration pass for things like data flowing incorrectly between files — produces sharper results than either alone. This is the same "attention dilution" idea from Lesson 4's task decomposition, applied specifically to review work.
Primary source: Anthropic's Claude API docs cover the Message Batches API directly, including custom_id correlation and processing windows — this lesson closes Domain 4, compressing Task Statements 4.5 and 4.6.
That's all of Domain 4. Ready for Domain 5, the last one — context management and reliability? Say the word when you're ready.