Model-Driven vs Hard-Coded Decisions
The central architectural choice in any agentic system is: who decides the next step — the model, or your code? Get this wrong and you either build a brittle decision tree that breaks on the first unanticipated input, or hand the model control over a step that demanded a guarantee.
Two ends of a spectrum
Hard-coded control flow is ordinary software: if/else, a state machine, a fixed pipeline. The path is decided at design time. It is deterministic, testable, cheap, and auditable — but it can only handle cases you anticipated.
Model-driven control flow lets Claude choose which tool to call, in what order, and when to stop — using stop_reason and the agentic loop. It is flexible and handles open-ended, ambiguous inputs — but it is probabilistic, harder to test, and costs tokens per decision.
When to hard-code
Hard-code the decision when any of these hold:
- The decision is simple and stable — a known set of categories, a fixed sequence of stages.
- The step needs a guarantee (a compliance check, an auth gate, "always run the linter before commit"). Determinism beats probability here.
- You need auditability or low cost — a regex or a switch statement is free and never hallucinates.
A classic mistake is asking the model to "decide whether to validate" when validation must always happen. That belongs in code (or a hook — see Module 3), not in a prompt.
When to let the model decide
Let the model drive when:
- The input space is open-ended and you cannot enumerate the branches (free-form user requests, unstructured documents).
- The order of steps depends on intermediate results — e.g. "search, and if results are thin, broaden the query, then summarize."
- You want graceful degradation on inputs you did not foresee, instead of a fall-through
elsethat errors.
The pragmatic answer: combine them
Real systems are hybrid. Hard-code the skeleton and the guarantees; let the model fill the adaptive middle. A support agent might hard-code "always check the account is authenticated" and "always log the resolution," while letting the model decide how to diagnose the issue in between.
A useful heuristic: push determinism to the edges, flexibility to the center. Validate inputs deterministically, gate side effects deterministically, and reserve model judgment for the genuinely ambiguous reasoning in the middle.
The anti-pattern in both directions: a sprawling hard-coded decision tree that tries to anticipate every branch (unmaintainable, brittle), or a fully model-driven flow over a task that had only three known states (slow, costly, non-deterministic where you needed a guarantee).
Exam focus: Hard-code stable, simple, or guarantee-requiring decisions (auth, validation, compliance, fixed pipelines) for determinism and low cost. Let the model decide open-ended, result-dependent, or unanticipated branches for flexibility. Best systems are hybrid: deterministic skeleton + guarantees at the edges, model judgment in the middle.