1. Per Anthropic's taxonomy, what distinguishes a workflow from an agent?
A Workflows are limited to a single LLM call per run, while agents chain multiple calls together — the moment a system makes a second model call it has crossed into agent territoryB Workflows can't use tools; agents canC In a workflow, your code defines the path through predefined steps; in an agent, the LLM dynamically directs its own process and tool usageD Agents apply more compute per task, so they are strictly more accurate; a workflow is just the cost-optimized fallback you deploy when you can't afford to run an agent on every request
2. You must translate a 200-page document into 6 languages, and each translation is independent. Which workflow pattern fits best?
A Parallelization (sectioning) — run the six independent translations concurrently and collect the resultsB Evaluator-optimizer — pair each translation with a judge that critiques it against a rubric and loops until all six languages converge on qualityC Orchestrator-workers — have a lead model inspect the document at runtime, decide how the translation work should be divided, and delegate one worker per languageD Prompt chaining — translate into language 1, then from 1 into 2, and so on
3. What distinguishes orchestrator-workers from plain parallelization?
A Orchestrator-workers executes its subtasks one at a time so the lead model can inspect each result before delegating the next, while parallelization's whole point is running everything concurrentlyB In orchestrator-workers, an LLM decides at runtime how to decompose the task and delegates; in parallelization, your code predefines the independent subtasksC Parallelization requires several different models voting on the same task, whereas orchestrator-workers routes all of the work through a single modelD They are two names for the same pattern
4. Why is a max-iterations cap insufficient as your only hard termination guard?
A Because the model can talk its way past it — once the model explains mid-run that it genuinely needs a few more iterations to finish, the harness must either grant them or discard a nearly-complete answer, so the cap is soft in practiceB Because iteration caps make the model stop mid-sentenceC Because providers already impose a server-side limit on how many tool-use rounds a conversation may contain, so a local cap is redundant — the API ends the loop before your own guard ever firesD Because iterations aren't the real resource — one iteration with a huge context or a hanging tool can blow the cost or latency budget alone, so you must also bound dollars and wall-clock time
5. Your agent keeps calling the same failing tool with the same arguments. Which set of defenses addresses this directly?
A Raise the temperature and prompt the model to vary its arguments — more sampling randomness means it will eventually stumble onto inputs that work, fixing the spiral without any harness changesB Feed back specific error messages (including what exists instead), enforce a per-tool failure budget that disables the tool after N failures, and short-circuit exact repeats of already-failed (tool, args) callsC Wrap the tool in a retry decorator with exponential backoff and jitter, since tool failures are almost always transient — given enough automatic retries the call eventually succeeds and the model never needs to see the error at allD Remove error handling so the exception stops the loop
6. What is ReAct, and how does modern native tool calling differ from the original technique?
A ReAct interleaves verbalized reasoning with actions and observations; originally implemented via prompting, stop sequences, and text parsing — native tool calling formalizes the same loop with schema-validated tool_use/tool_result messages instead of regex-parsed textB ReAct is a 2022 fine-tuning method that trained models to emit Thought/Action traces; it became obsolete once RLHF-tuned models learned to act directly, which is why modern tool calling drops the reasoning step entirely — verbalizing thoughts before acting no longer improves tool choiceC ReAct requires a team of cooperating agents — one to reason, one to act, one to observe — while native tool calling collapses all three roles into a single modelD ReAct is the internal name for OpenAI's function-calling API
7. Which trio of techniques keeps context from exploding across a 15-iteration run?
A Raise max_tokens so long outputs arrive in one call instead of several, lower the temperature to keep responses terse, and disable streaming to cut per-call overheadB Move to a model with a bigger context window so growth stops mattering, split the task across two agents so each history stays half the size, and rely on the provider to prune old turns server-side — context pressure is a capacity problem, not a design problemC Truncate tool outputs at the source (with a note on how to get more), compact old tool results into stubs once the model has used them, and keep the system prompt lean with a stable cached prefixD Delete the system prompt after the first call and drop all assistant turns
8. When does adding an upfront 'plan first' step help, and when does it hurt?
A It always helps — the plan is one short output, so its cost is negligible, and a model with a checklist pinned in context never wanders or misses coverage; a wrong plan costs nothing because the model simply skips steps that don't applyB It helps on long or coverage-sensitive tasks (roughly >5 tool calls), but hurts short tasks by adding cost, latency, and context weight — and a wrong plan anchors the model unless re-planning is an explicit actionC It only helps in multi-model setups where a stronger model writes the plan and a cheaper model executes it — with a single model, planning merely duplicates reasoning the model would have done anywayD It hurts whenever tools are involved, since plans and tools conflict
9. What belongs in an agent's trace log, and what's the right format?
A Only errors and the final answer, stored in a database — successful steps are noise, and the runs you will be asked to explain are the ones that failedB The full message array re-dumped after every call, pretty-printed into one JSON file per run — the messages are literally what the model saw, so replaying them beats logging derived numbers like token counts, latency, or stop_reason, which can always be recomputed laterC Just cumulative cost, since that's the only thing budgets needD Every LLM call and tool call as one JSONL record each: run id, iteration, timestamp, tokens, cumulative cost, latency, stop_reason, tool name/args, result size, is_error, plus a termination record with reason and complete flag
10. A high-volume task (100k runs/day) currently uses an agent that works. Why argue for converting it to a workflow?
A At volume, an agent's per-run variance compounds: unpredictable cost and latency multiply by 100k, rare failure modes become daily events, and debugging emergent paths doesn't scale — if the paths the agent takes are actually enumerable, a workflow gives the same output with bounded cost, testable steps, and auditable behaviorB Workflows produce higher-quality answers, because each hand-tuned step outperforms decisions the model improvises at runtimeC Providers throttle agentic traffic: because each agent run makes an unpredictable number of model calls, rate limits effectively cap agents at about 1,000 runs per day, and only a workflow's fixed call count can be provisioned past that ceilingD Because workflows orchestrate steps through predefined code paths, they barely need the model at all — extraction, validation, and routing become deterministic functions, so converting eliminates most LLM spend outright: at 100k runs/day the API bill collapses to near zero and rate limits stop being a concern, whatever the task's complexity
11. In an evaluator-optimizer loop, what failure mode must you actively defend against?
A The generator and evaluator deadlocking over API rate limits: the two alternate calls against the same quota, so each round doubles the queue delay until the loop stalls waiting on capacityB The generator refusing to accept any criticismC The generator learning to please the LLM judge rather than meet the actual goal — padding, rubric-echoing, confident hedging — i.e., reward hacking the judgeD The evaluator gradually taking over generation — after a few rounds its critiques contain so much corrected text that the generator is just transcribing them, collapsing the loop into a single-model system
12. Why add an explicit finish(answer, citations) tool instead of just accepting the model's end_turn text as the final answer?
A Because once tools are in the request, the API only ends an agent conversation cleanly through a tool call — an end_turn from a tool-enabled model is treated as an incomplete response, so a finish tool is mandatory plumbing rather than a design choiceB It forces a structured, complete ending: you get machine-readable citations you can validate (and reject if missing), a clear signal separating 'done' from 'just chatting', and on budget exhaustion you can distinguish a real finish from a best-effort fallbackC It reduces token costs because tool calls are cheaper than textD It physically prevents premature endings: a model that must call finish cannot leave the loop until your validation accepts its answer, so half-finished responses become structurally impossible
13. An agent loop returns its final answer with resp.content[0].text. It works today. Why is this a latent bug, and what's the robust version?
A It's fine as written — the API guarantees the first content block is always the text answer; thinking and tool_use blocks are appended after it precisely so that existing content[0].text code keeps working across model upgrades and feature launchesB content is a list of typed blocks and position is not a contract — enable thinking (or any feature that adds block types) and content[0] stops being text; extract by type: next(b.text for b in resp.content if b.type == 'text')C The risk is only stylistic — iterating the list to find a block by type is slower and wordier than direct indexing, so positional access is the recommended fast path once you know the response shapeD content[0] returns the system prompt, not the answer
14. You add context compaction that rewrites old tool results into stubs before every API call. Context shrinks, but per-run cost goes UP. What happened?
A Compaction turns input into output: every stubbed message must be re-generated by the model on the next call, and output tokens bill at several times the input rate, so each pass adds expensive output tokens that outweigh the input savingsB Each rewritten message is re-tokenized from scratch, and re-tokenization is billed separately from normal input processingC Prompt caching is an exact prefix match — every compaction pass edits early messages, invalidating the cached prefix, so each call re-processes the whole history at full price instead of reading ~90% from cache; compact rarely and in batches on a threshold insteadD The stubs backfire: seeing an elision notice makes the model assume the data is lost, so it re-runs the original tools to recover it, and the duplicate calls' fresh results re-inflate both the context and the bill
15. What's the correct relationship between telling the model its remaining budget ('~4 tool calls left, start converging') and enforcing the budget in your loop?
A Telling the model replaces enforcement — frontier models are trained to respect stated budgets, so once the prompt says '~4 calls left' the loop's own check is redundant, and the native task-budget parameter exists precisely so harness-level guards can be deletedB They're complementary: model awareness is advisory (it improves pacing and makes best-effort answers better because the model chooses what to sacrifice), while harness enforcement at the top of the loop is the actual guaranteeC Never tell the model — a model that knows its budget rushes to converge, skips verification steps, and produces worse answers than one left to investigate freely until the harness cuts it offD Enforcement is unnecessary if you use a finish tool
16. Your loop bails out mid-iteration when the budget trips — right after an assistant response containing tool_use blocks — and the final wrap-up call returns a 400. Why, and what's the fix?
A Bailing mid-iteration fires two requests back-to-back, and the second one trips the per-minute rate limit — the 400 is throttling, so the fix is a short sleep before the wrap-up callB The wrap-up call switched to a cheaper model mid-conversation, and a message history can't be replayed across model tiersC The history ends with unanswered tool_use blocks, violating the strict tool_use/tool_result pairing; either check the budget at the top of the loop (before paying for a response you'd discard), or append synthetic is_error tool_results ('not executed: budget exhausted') to make the array legal firstD best_effort must always start a fresh conversation with no history — the model can't produce a wrap-up answer from a context polluted by tool chatter, and the 400 is the API telling you the conversation has grown too long to continue
17. A user asks about a topic with no matches, search returns an empty list, and the agent confidently summarizes notes that don't exist. What's the highest-leverage fix?
A Lower the temperature to near zero — hallucination is a sampling artifact of high randomness, so a more deterministic model sticks to the evidence it was given instead of inventing plausible notes from its training dataB Add 'do not hallucinate' to the system promptC Fix the tool: return an explicit absence observation with grounding — 'No results for X. The database contains topics like: A, B, C' — because a model told what does exist stops guessing about what doesn'tD Increase max iterations and prompt the model to keep trying query variations — with enough searches it can convince itself the topic is absent and stop guessing