← The Complete Playbook
Varritech
The Complete Digital Product Playbook

AI-Powered
Scaling.

Build for 10x without rewriting.

๐Ÿ’ก
Scaling with AI is mostly not a model problem. It is a routing problem, a cost problem, a supervision problem, and above all a verification problem โ€” because the one thing every agent and every model will do reliably is tell you it finished. This guide is the system we run across our own always-on agents and every client build.

Inside this guide you'll find the test that decides whether something should be a model call at all, the routing table we run in production, the fourteen days that cost us $498 and why every suspect was wrong, the crash loop that ran for two months, and the mechanical gate that catches an agent reporting success on work it never did.


Phase 1: Decide What the Model Is Actually For

Phase 1 ยท Placement

Four questions before you add a model

any uncomfortable answer means it's misplaced ยท loops ~16s
01What if the output is wrong?money moves โ‡’ code decides, model proposes
02Is it parsed as structured data?constrain the shape at the API, then validate
03Could a lookup table do this?frequently yes โ€” instant, free, testable
04What does one call cost, and who can call it?nobody asks until the bill arrives
ยทยทOnly then: which modelthe question everyone starts with
The three real jobs
Work code cannot do ยท work whose rules are unknowable in advance ยท a cosmetic layer over a deterministic engine.
Two of our own seven model-backed routes were scoring rules a table and twenty lines of arithmetic would have handled.
The most expensive mistake in AI scaling is adding a model where deterministic code would have been better, cheaper, and testable. The category is real, and smaller than the enthusiasm suggests.

The first and most expensive mistake in AI scaling is adding a model where deterministic code would have been better, faster, cheaper, and testable. Models are extraordinary at a narrow set of jobs and mediocre-to-dangerous at everything adjacent, and the difference is usually obvious once you name the job out loud.

The Three Jobs a Model Can Do

The Test Before You Add a Model

Four questions. If any answer is uncomfortable, the model is in the wrong place:

  1. What happens if the output is wrong? If the answer is "money moves" or "a record is deleted," the model proposes and deterministic code decides. Always.
  2. Is the output parsed downstream as structured data? Then constrain the shape at the API level rather than hoping, and validate before use. A model that must return one of five enum values cannot drift.
  3. Could a lookup table do this? Frequently yes, and the table is instant, free, and testable.
  4. What does this cost per call, and who can call it? Covered in Phase 3, and it is the question nobody asks until the bill arrives.
๐ŸŽฏ
A worked example of getting this wrong on our own site. Seven public routes call a model. An instant-quote endpoint uses a small fast model at 500 tokens, which is reasonable. A contract generator runs a large model with a 16,000-token output ceiling. A complexity scorer and an eligibility checker both call models to do what are, in practice, scoring rules โ€” the kind of thing a table and twenty lines of arithmetic would handle deterministically, testably, and for nothing. Two of those seven were never model-shaped problems; they were model-shaped because a model was the fastest thing to reach for.

Phase 2: Routing โ€” Tier by Job, Not by Prestige

Phase 2 ยท Routing

The classifier checks for tools first, then everything else

one rule carries most of the value ยท loops ~15s
Any tool call in the turn? yes → strongest model, skip classification
hardcomplex reasoninglargest
creativecopy, script, hook, briefmid
visualimage or video reasoningmid
searchresearch, latest, newssearch-native
chattrivial, under 50 charslocal
fallbackambiguous but substantivegeneral
Smaller models don't give a slightly worse answer on a tool loop โ€” they hallucinate tool names and spin, burning more than the expensive model would have.
Only the native model keeps prompt caching. Routing a long context to a cheaper backend can cost more, because you re-send the whole prefix at full price.
Defaulting every call to the largest model is the most expensive possible answer. Tier by job, and make the tool-call rule the first check rather than one branch among many.

Once you have more than one model call in a system, you have a routing decision, and defaulting every call to the largest model is the most expensive possible answer.

The Lanes

This is the actual routing table behind our own tooling, running through a proxy that classifies each request by intent and rewrites the backend before it is sent:

LaneTriggerPrimaryFallback
hardComplex reasoning, or any tool callLargest modelMid model
creativeCopy, script, hook, briefMid modelLargest
visualImage or video reasoningMid modelLargest
searchResearch, "what is", latest, newsA search-native modelGeneral โ†’ mid
chatShort and trivial, under 50 charactersLocal modelSmall hosted โ†’ mid
fallbackAmbiguous but substantiveGeneral modelMid model

The Rule That Saves You

Any turn containing a tool call goes to the strongest model, before any other classification runs.

This single rule is most of the value. Smaller and non-native models flail at a tool-calling loop: they hallucinate tool names, emit malformed arguments, and lose the thread across a multi-step sequence. The failure is not a slightly worse answer, it is a session that spins and burns more tokens than the expensive model would have used. The classifier checks for the presence of tools first and skips everything else if they are there.

Two related traps from running this in production:

Case Study: Routing the CLI Off Metered Credits

A small configuration change with a large effect, and worth stating because it is invisible in any dashboard.

Our coding CLI sessions were billing metered API credits by default. Three lines of shell configuration โ€” blanking the API key and repointing the base URL at the proxy โ€” moved every CLI run onto the flat subscription instead. Same tool, same models for the lanes that need them, and the metered spend for that entire category dropped to zero.

The reason this matters beyond the money: when we later investigated a credit burn, every local tool was already provably not the cause, which eliminated the largest and noisiest category of suspect in one step. Routing is also an attribution tool.

Case Study: A Fleet That Costs Nothing to Run

Case study ยท The fleet

Metered cost of every always-on agent: zero

not reduced, zero ยท loops ~14s
5,106session files scanned
2,553model-change events
13,171session files from one agent alone
0calls to the metered provider
Why it works
The work is well-specified: read a state, apply rules, produce short prose, write a row
That is job three from Phase 1 — a cosmetic layer over a deterministic engine
And when the credit investigation started, the loudest suspect was eliminated in one query
Log the model per call, or every cost investigation starts from zero. Explicit routing is not only a cost lever, it is the thing that makes attribution possible later.

Worth stating plainly because it is the strongest argument for routing that we have.

We run a set of always-on agents: outreach setters, engagement responders, ad-variant generators, content posters. Across 5,106 session files carrying 2,553 model-change events, every one of them was running a local open-weight model. One agent alone accounts for 13,171 session files.

The metered cost of that entire fleet is zero. Not reduced, zero. It is possible because the work those agents do is well-specified: read a state, apply rules, produce a short piece of prose, write a row. That is the third job from Phase 1 โ€” a cosmetic layer over a deterministic engine โ€” and it is the single largest category of agent work in most businesses.

The corollary is the useful part. When the credit investigation in Phase 3 began, this fleet was the loudest and most obvious suspect, and it was eliminated in one query because the routing was explicit and the session logs recorded which model actually served each turn. Log the model per call, or every cost investigation starts from zero.

Where Free and Local Models Are Actually Safe

We run several always-on agents whose model call is pure narration over a deterministic engine. Those run on free-tier or local inference and cost nothing.

The boundary is sharp, and worth writing into your own code review:

โš ๏ธ
Porting a call to a cheaper model is mostly about making the failure loud and taking work away from the model. Drop the vendor SDK, use a plain HTTP call against an OpenAI-compatible endpoint, define a fallback chain, and assert on the response shape rather than trusting it. A smaller model given a smaller job frequently matches a larger model given a vague one.

Phase 3: The Cost Model Nobody Builds Until It Hurts

Phase 3 ยท Cost

Every intuition was wrong

$498 over fourteen days ยท loops ~16s
Ruled out, verified not assumed
The coding CLI — already routed off metered credits
The agent gateways — 5,106 sessions, zero metered calls
A job dying on a missing module every 3h — burning nothing, doing nothing
A job whose schedule was never loaded — ran 13 times, stopped
Where it actually was
The production website: 7 public routes call a model
The quote route has no auth and no rate limit
The contract route runs a large model at a 16,000-token ceiling
26 + 6 requests in a single 75-second burst, on a button-driven page
The four levers, in payoff order 1 ยท gate the endpoint2 ยท cut the output ceiling3 ยท route down4 ยท cache the prefix
Alert on spend rate, not spend total. A daily total tells you after the fact; a rate alarm tells you during. Add per-key attribution so the alarm names the culprit instead of the account.

Case Study: $498 in Fourteen Days

We investigated roughly $498 of API credits burned over two weeks on our own infrastructure. The investigation is worth walking because every intuition was wrong.

Ruled out, all verified rather than assumed:

Where it actually was: the production website. Seven public routes call a model, and one of them โ€” the instant quote โ€” has no authentication and no rate limit. A twelve-minute log tail caught roughly 26 requests to that route and 6 to the expensive contract route bunched into a single 75-second burst, on a page whose requests are button-driven. Organic use does not look like that.

The Four Levers

In the order they actually pay off:

  1. Gate the endpoint. A model-backed route reachable by anyone is a denial-of-wallet vulnerability, and it will be found by automated scanning long before anyone with intent finds it. A session, a token, a challenge, or a hard provider-side budget cap.
  2. Cut the output ceiling. Cost scales with output tokens far more than input. A 16,000-token ceiling on a route that produces a two-page document is a bet that nothing ever asks for the maximum.
  3. Route down. Most calls do not need the largest model. Phase 2 is the mechanism.
  4. Cache the prefix. A long system prompt or document sent on every call is the single biggest avoidable input cost, and prompt caching removes most of it. Structure prompts so the stable part comes first.
๐Ÿ’ธ
An in-memory rate limiter on a serverless runtime is decoration. Our contract route had one: a map in module scope. Module scope is per-instance and instances are created and destroyed constantly, so every cold start gets a fresh, empty map. An attacker does not need to evade it; ordinary traffic distribution defeats it. Limiters need shared state โ€” the database, a cache, or the platform's own edge limiting.

And the monitoring rule that would have caught all of this on day one rather than day fourteen: alert on spend rate, not on spend total. A daily total tells you after the fact. A rate alarm tells you during. Add per-key attribution while you are there, so the alarm names the culprit instead of the account.


Phase 4: Agents That Run Without You

Phase 4 ยท Supervision

Restart-on-failure turned a hard failure into a silent one

ran for two months ยท loops ~15s
start→ missing module→ crash→ supervisor restarts↶
4gateways in the loop
2 monthsbefore anyone noticed
582 MBeach error log, growing ~800 B every 3s
The symptom was never the agents. It was a build failing for lack of disk.
The supervision rules every run writes a visible result, not an exit code crash loops get backoff, a ceiling, and an alarm rotate and cap logs before you need to a kill switch that needs no deploy an owner and a review date
"It processed 0 items for the 340th consecutive time" is a result. "It ran" is not. The supervisor was doing exactly what it was told; the configuration was what was wrong.

An always-on agent is a piece of infrastructure, and it fails like infrastructure rather than like code. Nothing throws in your face. It just quietly stops being useful, or quietly becomes expensive, and both states can persist for months.

Case Study: The Crash Loop That Ran for Two Months

Four agent sub-gateways sat in a crash-restart loop for over two months. Each was configured to restart on exit, and each died immediately on a missing module, so the supervisor faithfully restarted them thousands of times a day.

The visible symptom was not the agents. It was the disk: each of their error logs had reached 582 MB, growing at roughly 800 bytes every three seconds. Nobody noticed until a build failed for lack of space.

Two failures compounding, and both are common:

In the same audit, a second job's schedule had never been loaded at all. It ran 13 times, stopped, and nothing anywhere noticed for weeks.

The Supervision Rules


Phase 5: "Completed" Is a Claim, Not a Fact

Phase 5 ยท Verification

The most reliable agent behaviour is reporting that it finished

four real failure modes ยท loops ~16s
01
Idle is not delivered4 of 6 audit lanes signalled done and never sent their findings. Idle means "no work queued," not "output delivered."
02
Delivered somewhere you can't seeA fifth lane wrote its report into its own reply body. Worse than silence โ€” the agent believed it had delivered.
03
Reported success, changed nothingReturned completed with a confident summary of an unrelated task. The file was byte-for-byte unchanged.
04
The main model narrating an action it never took"I updated the file with three findings." No write call in the transcript; the file's mtime predated the session by five days.
The mechanical gate Pick a checkable side effect before dispatching. Run the check centrally, after the fact, from the coordinator. Re-dispatch on failure rather than asking the worker whether it is sure.
Treat any sentence describing a side effect as a claim, including your own. Byte count, modification time, a diff, or grep for the specific content claimed. This is not cynicism, it is the only way any of this composes.

This is the phase that matters most, and it is the one nobody expects to need. The single most reliable behaviour of an AI agent is reporting that it finished.

Case Study: Four of Six Agents Signalled Done and Sent Nothing

On a six-lane codebase audit, each lane ran as a named background agent reporting to a lead. Four of the six signalled idle without ever sending their findings. The idle signal means "no more work queued," not "output delivered," and treating them as the same thing silently drops the agent's entire contribution.

A fifth lane produced a stranger failure. When re-prompted, it explained that it had been writing its report into its own reply body, which the lead cannot see. Its words: it was finished, it just never left the terminal. That is worse than silence, because the agent itself believed it had delivered.

A sixth quirk from the same run: one report arrived as three identical consecutive deliveries. A delivery glitch, not three reports, and re-synthesising it three times would have been the natural mistake.

Case Study: The Agent That Reported Success and Changed Nothing

A background agent was given one job: shrink a file below a size cap. It returned completed, with a confident result summary. The summary was actually a restatement of an unrelated task's output, and the file was byte-for-byte unchanged.

The same failure occurs without any agent involved. In an ordinary session, a final turn stated that a memory file had been updated with three specific findings. The transcript contains no write call that turn, and the file's modification time predated the session by five days. The primary model narrated an action it never took.

๐Ÿ”
Treat any sentence describing a side effect as a claim, including your own. "I updated X", "I bumped the counter", "the report has been sent". Before relying on it or relaying it, check the artifact: byte count, modification time, a diff, or grep for the specific content that was claimed. This is not agent-specific cynicism, it is the only way any of this composes.

The Mechanical Gate

The pattern that makes fan-out safe: verify each worker's output with a check that is stricter than its own self-report, and that the worker did not write.


Phase 6: Fan-Out Without Collisions

Phase 6 ยท Fan-out

Parallelism is where throughput lives and correctness dies

the rules are few and absolute ยท loops ~15s
One writer per working treeeach writing agent gets an isolated tree and an explicit, non-overlapping file list
Read-only workers are unlimitedthe constraint is on writes, never on reading
Exactly one owner for shared manifestslockfiles and config, edited by the integrator alone
A child may drop capabilities, never add themno more tools, network, spend, or delegation depth than its parent
Check which repo your isolation targetsours pins to the current session's repo regardless of the task. Three agents were silently mis-scoped; one spent 27 minutes on good research it could not commit.
Diversity beats redundancy Three identical checkers agree with each other, including when they are wrong. Give each verifier a distinct lens: does it reproduce, is it a security issue, is it already fixed elsewhere.
Each lane's brief names the directories it owns and the ones it does not, with the sibling that owns them. Without that, three lanes audit authentication and nobody audits the build.

Parallelism is where the throughput gain lives, and it is also where correctness quietly dies. The rules are few and they are absolute.

The Concurrency Rules

Case Study: The Six-Lane Audit

The structure that has worked repeatedly for large read-only work, with each element there for a reason:

๐Ÿงญ
Diversity beats redundancy when verifying. Three identical checkers agree with each other, including when they are wrong. Give each verifier a distinct lens โ€” does it reproduce, is it a security issue, is it actually correct, is it already fixed elsewhere โ€” and you catch failure modes that redundancy structurally cannot. One of our audit lanes chased a plausible critical finding, discovered a migration had already fixed it, and dropped its own draft. That negative result is what made its other findings believable.

Phase 7: Evaluation โ€” Knowing It Got Better

Prompt changes feel like improvements. Without evaluation, that feeling is the only evidence you will ever have, and it is wrong roughly half the time.

The Golden Set

Twenty to fifty real inputs with known-good outputs, drawn from production rather than imagined. It does not need to be large; it needs to be real and fixed. Every prompt change, model change, and routing change runs against it before shipping.

Two rules that keep it honest:

Using a Model as the Judge, and Its Three Failure Modes

An LLM judge is the only practical way to score open-ended output at volume. It has known biases and you should design around them rather than discover them:

And the structural rule: the judge scores against a rubric with named criteria, not a general impression. "Rate this 1 to 10" produces noise. "Does it cite a source, does it answer the question asked, does it avoid claims not in the document" produces a signal you can act on.


Phase 8: The Infrastructure Underneath

Phase 8 ยท Infrastructure

A slow, expensive, rate-limited, flaky dependency

unlike any other call in your system ยท loops ~16s
Queuea synchronous request holding a connection for thirty seconds is an outage waiting for traffic
Idempotentretries are guaranteed; a duplicate costs twice and can double-send whatever it produces
Timeoutsshorter than the SDK default โ€” a hung call holding a worker beats a failed one that retries
Backpressureshed or defer rather than accumulating a backlog you pay to process at 3am
Jittersynchronised retries after a blip are a thundering herd against a struggling service
Per-call logprompt, model, token counts, cost โ€” without it every cost question is unanswerable
Versioned promptsthe highest-leverage, least-reviewed artifact in the system. In the repo, in review, in the golden-set run
The degraded path Fallbacks get less review than the primary path, which is where fail-open hides. When the model is unavailable, does your system degrade, queue, or silently return an empty string that something downstream writes to the database? We have found the third more than once.
Decide it deliberately and test it, because a provider outage is not a hypothetical and the answer is currently whatever nobody chose.

Model calls are slow, expensive, rate-limited, and occasionally fail. That combination makes them unlike almost any other call in your system, and the infrastructure has to reflect it.

๐Ÿงฑ
Fallbacks are a code path that gets less review than the primary one, which is where fail-open behaviour hides. When the model is unavailable, what does your system do โ€” degrade gracefully, queue, or silently return an empty result that something downstream treats as valid? Decide it deliberately and test it, because it will happen, and the answer "it returns an empty string and the caller writes that to the database" is one we have found more than once.

Phase 9: Retrieval โ€” When the Model Needs Your Data

Phase 9 ยท Retrieval

The bug that looks like a hallucination

and is two layers down ยท loops ~15s
Queryuser asks something
โ†’
Retrievalreturns nothing useful
โ†’
Modelhas no way to know its context is empty
โ†’
Answerfluent, confident, invented
The team concludes the model hallucinates and starts changing prompts. The defect is in the search.
Score floor below it, return "I don't have that" without calling the model at all
Require citations the answer references chunk ids, and code verifies they were in context
Log what was retrieved or "why was this answer bad" is unanswerable
Score retrieval and generation separately or you cannot tell a chunking problem from a prompting problem
Permissions belong in the retrieval layer, not the prompt. Telling a model to only use documents this user can see is a suggestion, and the documents are already in the context window by the time it reads it.

Most useful AI features are not the model knowing things, they are the model reading your things. Retrieval is where that happens, and it fails in ways that look like model failures and are not.

The Failure That Looks Like a Hallucination

The most common retrieval bug in production: retrieval returns nothing useful, and the model answers anyway. It has no way to know its context was empty or irrelevant, so it produces a fluent, confident, entirely invented answer. The team concludes the model hallucinates and starts changing prompts, when the actual defect is two layers down in the search.

Three guards, in order of value:

The Parts That Actually Determine Quality

๐Ÿ”Ž
Permissions belong in the retrieval layer, not in the prompt. Telling a model "only answer using documents this user can see" is not access control, it is a suggestion, and the documents are already in the context window by the time it reads the instruction. Filter at the query, before anything is retrieved, using the same authorization rules the rest of your system uses.

Evaluating Retrieval Separately From Generation

They are two systems and they fail independently, so score them independently:

A team that only measures the end-to-end answer cannot tell a chunking problem from a prompting problem, and will spend weeks tuning the wrong one. We have watched exactly that happen, and the fix once measured was a chunking change that took an afternoon.

Start simple. A single Postgres table with a vector column handles far more than people expect, keeps your data in one place, and lets you filter on metadata with plain SQL. Reach for a dedicated vector database when you have measured a reason to.


Phase 10: Building a Custom Agent โ€” The Anatomy

Phase 10 ยท Anatomy

Every agent we run is the same six parts

get all six right and it's boring ยท loops ~17s
01
The soulidentity, scope, hard rules, escalation channel, and a tone section with a real one-line sample. The sample does the work; "professional but warm" does not.
02
Tools that existconnect only what is wired; declare everything else unsupported. Never sell a 404 connector, and never let the prose name a tool the agent was not granted.
03
The triggercloud cron reaches no filesystem and no local connectors; a machine scheduler reaches everything but must stay awake; a session loop dies with the window.
04
State that outlives the processa JSON document written every run and read at the start of the next. This is what makes it restartable, debuggable, and idempotent.
05
The gatedoes it act, or propose? Ours builds the whole batch daily and emails a signed preview. Nothing spends until a human clicks Approve.
06
The surfacea health endpoint returning JSON is not a UI. Runs newest-first, what was produced, approve and reject.
Write this first Which config layer wins. If a database row overrides a source constant, that sentence belongs in the first paragraph of the runbook โ€” we have watched someone edit a source file for an hour on an agent being driven by Firestore.
The gate is the reason an agent can be switched on months before anyone fully trusts it. Propose-and-hold is not a lesser version of autonomy, it is what makes autonomy reachable.

Everything above is about running agents well. This is about building one. We run a fleet of them, and every single one is the same six parts. Get all six right and the agent is boring, which is the goal.

The Six Parts

1. The soul. The instruction document that defines the agent: who it is, what it is allowed to do, what it must never do, where it escalates, and how it writes. Ours run to roughly six thousand characters and every one carries the same required sections โ€” identity, scope, hard rules, escalation channel, and a tone section with an actual one-line sample of the voice. The sample matters more than the adjectives; "professional but warm" produces nothing, one real sentence produces a voice.

โš ๏ธ
The single most important sentence in any agent's documentation is which layer wins. If a config value in the database overrides a constant in the source, say so in the first paragraph of the runbook. We have watched people edit a source file for an hour on a live agent whose behaviour was being set by a row in Firestore. Whichever layer wins, write it down where someone will read it before they start debugging.

2. Tools, and only tools that exist. An agent should be given the smallest set of actions that lets it finish its job. Two rules from productising ours: connect only what is actually wired, and be honest about the rest. We support nine integrations; every other tool a role might want is declared explicitly as unsupported and shown as "coming soon" rather than offered and broken. Never sell a 404 connector.

The related defect is subtler and we shipped it twice: a soul that names a tool in its instructions which is neither connected nor declared unsupported. The agent then confidently plans work it cannot perform. Cross-check every tool named in the prose against the tools actually granted.

3. The trigger, chosen by what the agent must touch. Three mechanisms, three lifecycles, and picking wrong is a silent failure:

MechanismRuns whenCan reach
Cloud cron / routinesAlways, machine-independentWeb and hosted APIs only. No filesystem, no local env, no interactively-authenticated connectors
A scheduler on a real machineOnly while that machine is awakeEverything local: repos, env files, authenticated connectors
A session-bound loopOnly while that session is openEverything, but it dies when the window closes

Most of our agents need local connectors and repos, so they run on a machine scheduler and the machine has to stay awake. That is a real constraint and it belongs in the design conversation, not discovered later.

4. State that outlives the process. Anything serverless will cold-start, so in-process memory is not state. Ours persist a JSON document to object storage or a database on every run, and read it back at the start of the next one. That single decision is what makes an agent restartable, debuggable, and idempotent. It is also where the range-query trap from Guide 3 lives: a due-work query on a nullable timestamp will happily match every already-completed record.

5. The gate. The most important design decision in the whole agent, and it is binary: does this thing act, or does it propose?

Our ad-generation agent runs daily, does the full pipeline, and then emails a preview and stops. Nothing spends money until a human clicks Approve. The approve link is signed, and a forged link is rejected. That gate is why the agent could be turned on months before anyone fully trusted it.

6. The surface. A health endpoint returning JSON is not a user interface. Every agent that a human is expected to supervise needs a page that lists recent runs newest-first, shows what was produced, and carries the approve and reject controls. We added one to the ad agent after being asked, reasonably, "is this a UI?"


Phase 11: Training an Agent โ€” Which Knob Actually Moves Quality

Phase 11 ยท Training

Exhaust the ladder from the top

fine-tuning is almost never the answer ยท loops ~16s
1Better contextmost bad output is an agent that did not have the informationfree
2Better instructionsname the failure cases: "never contact anyone who replied in 30 days"free
3Better toolsif it always makes the same three calls in order, that is one toolcheap
4Real examplestwo or three correct outputs from production, in the prompt. Highest leverage, least used.cheap
5Route the hard lane upa bigger model for the 10% that need it, not for everything$
6Fine-tunefixes style reliably, knowledge rarely, and freezes you to a model version$$$
Self-report is honest, and narrower than the claim. Every writer truthfully reported its own 8 files clean. The README nobody owned broke the same rule throughout. Run the gate over the whole artifact.
A threshold is not an approval gate. "Never send to more than ten people" read as code licenses nine unreviewed sends, every time. Six agents had this. All six now draft and hold.
Most "the model isn't good enough" conclusions are rungs 1 to 4 skipped. And pinned model ids rot: 54 of 62 agents were a generation behind and nothing broke, which is exactly why nobody noticed.

"Training" is the word everyone reaches for, and fine-tuning is almost never the answer. There is a ladder, and you should exhaust it from the top.

The Ladder, Cheapest First

  1. Give it better context. Most bad agent output is an agent that did not have the information. Retrieval, prior state, the actual record it is acting on. This fixes more than everything below it combined.
  2. Give it better instructions. Specific, bounded, with the failure cases named. "Never send to a contact who replied in the last 30 days" beats "be respectful of the recipient."
  3. Give it better tools. One action that does the right thing beats five actions it has to compose. If an agent keeps making the same three calls in the same order, that sequence should be one tool.
  4. Give it real examples. Two or three examples of correct output, taken from production rather than invented, in the prompt. This is the highest-leverage change most teams never make.
  5. Route the hard lane up. Per Phase 2. A bigger model for the ten percent of calls that need it, not for everything.
  6. Fine-tune. Last. Justified when you need a consistent format or voice at high volume and have hundreds of real examples. It fixes style reliably and knowledge rarely, and it freezes you to a model version.
๐ŸŽ“
Most "the model is not good enough" conclusions are rungs 1 through 4 skipped. Before you conclude a model is the constraint, check that it was given the record, told the rule, handed the right action, and shown one correct example. We have never once had a production agent where fine-tuning was the answer and those four were already done.

Writing the Soul Spec Once, Then Enforcing It

When we deepened 62 agent souls at once, the thing that made it work was writing a spec first and then verifying against it mechanically. Every file had to pass, independently of what any writer claimed:

That last check is the one that catches the honesty bug from Phase 10, and it caught two more instances than manual review did.

Two Findings Worth Stealing

Self-report is scoped to what the reporter looked at, and is honest within that scope. Every writer truthfully reported its own files clean against a style rule. The package README, which no writer owned, violated the same rule throughout. Nobody lied; the scope of "all clear" was smaller than the scope of the claim. Run the gate over the whole artifact, not over the union of what each worker checked.

A threshold is not an approval gate. Reviewing those same agents, we found six that would send external messages with no human in the loop. One had a guard reading "never send to more than ten people at once" โ€” which, read as code, explicitly licenses sending to nine unreviewed recipients every time. We rewrote all six so that anything externally visible and hard to reverse is drafted and held. There is no recipient count at which unreviewed sending becomes acceptable.

And a maintenance note that will apply to you within months: pinned model ids rot. Of those 62 agents, 54 were pinned to a model that had been superseded and 5 to another. Nothing broke, and the whole fleet was quietly a generation behind. Put the model id sweep on a calendar.


Phase 12: Productising Agents as Presets

Phase 12 ยท Productising

Presets, not a blank form

62 roles, one fan-out ยท loops ~15s
One agent per role62 in parallel, schema-validated output
โ†’
Deduped into one source filesoul, model, and tool map per preset
โ†’
Deterministic slugone shared helper, so the marketing link and the config lookup cannot drift
โ†’
Customer picks a roleand edits something that already works
The three traps
Two independent slug implementations is a bug you find in production, not in review
A preset listing a connector you have not built is a support ticket and a refund
Repointing one customer's record is not shipping the new version โ€” the default pointer is a separate step
When the product is a file behind a link, the release is the default pointer. We rebuilt a bundle, verified the upload byte-for-byte, fixed the affected customer, and left every future buyer on v1.

The step from "we run agents" to "our customers run agents" is smaller than it looks and has three specific traps.

Presets, not blank canvases. Nobody configures an agent from an empty form. We ship 62 role presets, each carrying a production-quality soul, a model, and a pre-selected tool map. A customer picks a role and gets something that works, then edits. The generation itself was a fan-out: one agent per role, schema-validated output, deduped and emitted into a single source file.

Deterministic slugs. Every preset is addressable by a slug derived from its position by a shared helper, so the link generated on the marketing page and the lookup performed by the configuration page cannot drift. Two independent slug implementations is a bug you will find in production, not in review.

Honest capability. Covered in Phase 10 and repeated here because it is the one customers notice: a preset that lists a connector you have not built is a support ticket and a refund. Declare it unsupported.

๐Ÿ“ฆ
The versioning trap, learned the expensive way. We shipped a v2 of an agent bundle, rebuilt the package, uploaded it, verified the download was byte-identical, and repointed the affected customer's record at the new file. What we did not do was repoint the environment variable that sets the default for future buyers. Fixing one customer's row is not shipping the new version. When a product is a file behind a link, the "release" is the default pointer, and it is a separate step from the upload.

Bonus: Where Not to Put a Model

The short list, each learned expensively by someone:


Bonus: The AI Scaling Readiness Checklist


Bonus: Tools and Resources Library

Routing and gateways

Agents and orchestration

Evaluation

Observability and cost

Infrastructure


Start here

Deeper

Worth following


What's Next?

This is the last guide in the playbook. Guide 1 covers product strategy and discovery, Guide 2 the design system, Guide 3 production architecture including repository structure and app-store releases, Guide 4 security and compliance, Guide 5 testing, and Guide 6 go-to-market.

If you would rather have this installed than read about it, that is what we do.

Flagship · by application · 3 installations per quarter Scalewright Installation$15,000 Done-with-you. A six-week production build with 100% of the IP yours from day one, the four growth systems installed with it, and two working sessions a week inside your repo. We don't hand you a codebase and walk, we stay on it until you hit $10K MRR. Guaranteed. Book a consultation →
Claude Code · monthly The Skillsmith Club $47/mo · cancel in one click The 213 production skills behind this guide, plus a few new ones and one autonomous agent dropped every month. Ship $10,000 of agency-grade software by Sunday or we refund every dollar. Application-only Scalewright Circle™ Free · no card, ever The room where founders ship every week. Priority answers from our engineers, weekly office hours, blueprint pods, and vetted investor intros. Access worth $650+/mo.
Varritech

Seven guides in the playbook.
Product strategy, design systems, production engineering, security, testing, go-to-market, and AI scaling.