Most agent codebases already contain a confidence check. Few contain one that ever fires. It usually looks like a line of system prompt: "If you are not confident in your answer, escalate to a human." The model reads it, the model agrees with it, and the model then proceeds to be confident about everything, because nothing in that sentence defines confident, measures it, or routes anything anywhere when the measurement comes up short.
On November 11, 2026, Google published a blunt opinion about where that check should live instead: outside the generating model entirely. The Gemini Decisions API is a separate, priced product that answers bounded questions and attaches a calibrated 0-to-1 confidence score to each answer. You do not have to buy it (we will get to self-hosted alternatives), and you should read it as an architecture document either way. A vendor that sells generation by the token just told its customers that judgment is a different workload, with different latency, different pricing, and an explicit instruction in its own launch post: use the score to route uncertain cases "to a fallback or human reviewer."
Below, one concrete agent decision gets wired both ways. Same task, same policy question, two architectures: the judgment inlined into the generation prompt, and the judgment as a separate decision layer with thresholds, fallback routes, and an audit log. The differences are mechanical rather than philosophical, which is the nicest kind of difference to argue about.
The task we will wire up
A support agent drafts refund responses. Policy, written by a human, says: refunds under $50 for damaged items can go out automatically; anything ambiguous waits for the support lead; anything over $200 or smelling of fraud always gets a person. The agent's job is to draft the reply and decide which bucket this case falls into.
That second half is the judgment. The same wiring applies unchanged to outbound email, listing updates, or ticket closures; refunds just make the error costs easy to picture. Here is what it looks like when it lives inside the generation prompt.
Architecture A: the self-grading prompt
SYSTEM = """You are a support agent. Draft a refund decision. Policy: auto-approve damaged-item refunds under $50. If the request is ambiguous, or you are not confident, do not decide; output ESCALATE instead. Also rate your confidence 0-100 at the end.""" def handle(ticket: str) -> str: draft = llm.generate(SYSTEM + "\n\nTicket:\n" + ticket) if "ESCALATE" in draft: return queue_for_human(ticket, draft) return send(draft) Everyone has shipped a version of this, including us. It works in the demo and it fails in four specific places.
**The score is decorative. **That trailing "confidence 0-100" is a token sequence the model produces because you asked for one. It is a plausible-sounding number, generated by the same next-token machinery as the prose around it. Public evaluations have repeatedly found self-reported confidence from general chat models to be poorly calibrated; a model that says 90 is at best weakly related to an outcome that happens 90% of the time. Nothing in the pipeline above checks the number against reality, stores it, or trends it. It is theater that compiles. (The one place a self-assessment helps: as a cheap pre-filter ahead of a real check, where a model flagging its own doubt can only add recall. The failure mode is treating it as the check.)
The judge and the defendant share a brain. The same forward pass that produced the draft evaluates the draft. When the generation goes wrong because the model misread the ticket, the self-evaluation misreads it the same way. Correlated errors are the whole reason code review exists and the whole reason auditors do not report to the CFO they audit.
The policy is unversioned. Your threshold lives in English, inside a prompt, probably inside a string literal, possibly inside three string literals that have drifted apart. When someone asks "what was the escalation rule on October 3rd," the honest answer is a git archaeology expedition. When compliance asks "who changed it," the answer is worse.
**There is no ledger. **send(draft) fires and the decision evaporates. No record of what the score was, which rule version was live, or why this particular ticket sailed through. The first time you need that record is the first time something goes wrong, which is exactly when you do not have it.
Architecture B: a separate decision layer
The alternative moves the judgment into its own call, against its own model, returning a score your code can act on. With Google's new product, the request is a bounded question over the same context. The shape below follows the launch post's description (yes/no with probability, multiple choice over 2–255 options, rubric scoring; one multimodal input up to 256K tokens; up to 1,000 questions in a single pass). Field names here are illustrative pseudocode; the exact schema is whatever the official docs say.
# Decision request (shape per Google's launch post, 2026-11-11; # field names illustrative, consult official docs) decision = decisions_api.ask( context = ticket_text, questions = [ {"id": "policy_ok", "type": "yes_no", "text": "Does this request qualify for auto-approval " "under the damaged-item policy pasted below?"}, {"id": "fraud_risk", "type": "yes_no", "text": "Does this request show signs of refund abuse?"}, {"id": "amount_tier", "type": "choice", "options": ["under_50", "50_to_200", "over_200"]}, ], policy_text = POLICY_V7, ) # -> each answer arrives with a probability and a 0-1 confidence The generating model still drafts the reply. It just no longer grades its own homework. Around that call, three short pieces of code do what the prompt sentence only gestured at.
The threshold, as config. A policy object, versioned like any other config, reviewed like any other config:
THRESHOLDS = { # policy v7, owner: support-lead "auto_approve": {"policy_ok": 0.95, "fraud_risk_max": 0.10, "amount": "under_50"}, "queue": {"policy_ok": 0.70}, # below auto, above floor # below 0.70, or over_200, or fraud signals: always human } The fallback route. Low confidence is not an error; it is the third output. The launch post's own framing, routing uncertain cases to "a fallback or human reviewer," is a switch statement:
def route(decision, draft): a = decision["policy_ok"] if a.confidence >= 0.95 and passes_hard_rules(decision): return send(draft) if a.confidence >= 0.70: return queue(draft, reason="ambiguous", score=a.confidence) return queue(draft, reason="low_confidence", score=a.confidence) The ledger. One append per routed decision, written before anything sends:
ledger.append({ "ts": now(), "ticket": ticket_id, "question": "policy_ok", "answer": a.value, "confidence": a.confidence, "threshold_version": "v7", "route": route_taken, "reviewer": None, # filled when a human acts "reviewer_verdict": None, }) That is the whole architecture. No machine-learning team appears in it. The hard part, deciding the numbers in THRESHOLDS, is an organizational exercise (the method: tier actions by blast radius, price both error types, run two weeks in shadow mode, grant automation downward from the most conservative setting). We wrote that method up separately; wiring is the part a codebase can enforce, so wiring is what gets the code blocks.
Phrasing the questions is half the engineering
The decision call is only as good as the questions, and bounded questions have their own craft. Three rules cover most of it.
One judgment per question. "Does this qualify under the policy and show no fraud signals?" is two questions wearing one question mark, and a single probability over a conjunction is uninterpretable: a 0.55 could mean confident-yes on policy with doubts on fraud, or the reverse. Split them, as the example does, and each score means one thing.
Put the policy in the context, never in the question. A question that paraphrases the policy drifts from the policy; the prompt above pastes POLICY_V7 verbatim and asks whether the request qualifies under the pasted text. When the policy changes, the decision input changes with it, and the ledger's threshold_version row tells you which policy every past judgment was made against.
Prefer choices to free rubrics where you can. A 2-to-255-option choice with normalized probabilities ("under_50 / 50_to_200 / over_200") gives you a distribution you can threshold; an open scale invites the model to cluster around flattering middles. Save rubric scoring for things that are rubrics in real life, like severity grades a human team already uses.
The two architectures, item by item
Two rows there deserve a paragraph each, because they carry most of the argument.
The cost row: judgment is now the cheapest thing in your stack
At $0.10 per million input tokens with output tokens free (Google's published price, 2026-11-11), a policy check over a 2,000-token ticket costs $0.0002, assuming no retries. For comparison, a single generation task under our standard accounting (4,000 tokens in, 800 out, 10% retry, 70% cache hit; InventiveHQ pricing survey, modified 2026-10-19) runs $0.00086 to $0.0603 depending on model tier. The check costs a fraction of the work it checks, at every tier.
That kills the old excuse for Architecture A. Inlining judgment into the prompt was always partly a cost decision: a second model call per action felt extravagant. It is now a rounding error, and Google's own usage makes the point. The launch post describes the same API routing everyday internal requests between model tiers, with latency in those routed scenarios dropping by up to 40% (Google's own figure, about its own systems, 2026-11-11); the mechanics of that pattern are what multi-model routing is for.
The cheapness cuts the other way too, and it is worth saying plainly: when every check costs $0.0002, nothing in the invoice stops you from letting checks replace checkers everywhere. Which action tiers still end at a person is a policy decision now. The bill will never again make it for you.
The calibration row: a score you can audit vs. a vibe you cannot
A dedicated decision model computes its probability over a closed answer set; that number can be checked. Pull your last 500 human-decided cases, run them through the layer, bucket by reported score, compare each bucket with the known outcomes. If the 0.90 bucket is right about 90% of the time, calibration holds on your traffic. If it is right 72% of the time, you learned that before wiring it to anything irreversible.
Run the same loop monthly and you get drift detection almost for free, because the ledger already holds score and outcome side by side. This is the quiet, compounding advantage of Architecture B: every routed decision deposits a data point, and the pile of data points is the answer to next quarter's question, "is the automation actually as good as its scores say." Architecture A deposits nothing.
When the judge is down
A decision layer is a dependency, and dependencies fail: timeouts, rate limits, a 5xx on the one call that gates everything else. What your code does in that moment is a safety decision you are making right now, at design time, whether you notice or not.
Fail open (treat an unanswered question as confident) silently removes the gate during exactly the windows when a vendor is having an incident, which correlate with the windows when everyone else's retries are flooding the same API. Fail closed (route to the queue) degrades to more human work and no silent sends. For any action tier worth gating, closed is the only defensible default:
def judged(ticket, draft): try: d = decisions_api.ask(..., timeout_ms=800) except (Timeout, ApiError) as e: ledger.append({"ticket": ticket.id, "route": "queue", "reason": f"judge_unavailable:{e.code}"}) return queue(draft, reason="judge_unavailable") return route(d, draft) Two refinements earn their keep. A judge outage can flood the queue past what reviewers absorb, and a flooded queue rubber-stamps; pair the fallback with a circuit breaker that pauses non-urgent action classes outright when the queue depth crosses its cap. And write the outage into the ledger as shown, because a gap in the score column is itself a drift signal: a week of "judge_unavailable" entries explains a weird calibration bucket better than any post-hoc guesswork.
What the inline sentence is still good for
None of this makes the prompt-level instruction useless. It makes it a different tool.
As a pre-filter, self-assessment is free recall: a generator that flags its own doubt can only add cases to the review pile, never remove them, so wiring "output ESCALATE if unsure" in addition to the decision layer is pure upside. As an annotation, it is context the number cannot carry: a decision layer returns 0.63, and the generator's own note ("flagging: the order number in this ticket does not appear in the account history") is what lets the human clear the queue item in thirty seconds instead of five minutes. And in tiers where the blast radius is zero, internal drafts, suggestions a human always edits, Architecture A alone is proportionate; adding a priced check in front of a throwaway draft is ceremony.
The rule that falls out: let the generator talk about its doubts, let the decision layer measure them, and let only the measurement touch the routing. Trust the commentary as color, never as a gate.
A migration path that is not a rewrite
Nobody green-lights "pause the agent while we rebuild its judgment." The rewiring above installs incrementally, and each step pays for itself before the next one starts.
Week zero: add the ledger alone. Wrap existing sends with an append that records action, input pointer, and outcome when known. No scores yet, no behavior change, and you already gain the record you currently lack when something goes wrong.
Weeks one and two: add the decision call in shadow. Every action gets scored and logged; humans keep deciding everything; latency cost is one parallel call. The shadow data yields the two curves every threshold argument needs, the score distribution and the human-disagreement rate per band, measured on your traffic rather than a vendor benchmark.
Week three: automate one band of one action class, the highest-scoring slice of the cheapest, most reversible tier. Everything else keeps flowing to people. The ledger now accumulates measured error rates for the automated slice.
Week four onward: loosen one band at a time, each loosening justified by the measured error rate of the last, never by the backlog. Re-run calibration monthly on the most recent 500 human-decided cases. Review THRESHOLDS like a firewall rule: named owner, dated changes, reasons in the log. Incident-time changes move in one direction only, toward more review; relaxation waits for the postmortem.
A team that stops halfway through this list, ledger plus shadow scores and no automation at all, has still replaced "are we comfortable with the agent deciding" with a measured disagreement curve. That is most of the value, available before the first automated send.
What the decision layer does not fix
Named limits, so nobody files this under silver bullets.
Calibration drift survives the rewiring. A layer calibrated on last quarter's tickets walks off true when the product, the customers, or the input language changes. The ledger makes drift visible; it does not make it impossible. Google's calibration claims for gemini-decision-1 are measured on Google's benchmarks (vendor figures, 2026-11-11), never on your refund queue.
The accountability gap survives it too. Routing a case to a human puts a human in the loop; it does not make them awake, informed, or responsible. A queue that dumps forty items an hour on someone with a day job degrades into rubber-stamping within weeks. Cap queue volume, track the disagreement rate, and treat a reviewer who never overrules the model as a broken alarm.
Vendor dependency gets worse, by one API. A bought decision layer is an external dependency at the most sensitive point in your stack, the component that decides what your agent may do. The self-hosted version (an open-weight model with a constrained output head, or a small fine-tuned classifier) starts with worse scores and costs you the maintenance, and in exchange nobody can reprice, deprecate, or silently revise your judgment layer. Our rule of thumb: buy judgment for low-stakes tiers, keep the high-stakes gate on infrastructure whoever answers for the money controls. Teams writing this into contracts can lift the questions from a procurement standard.
And one whole class of decisions stays off the table at any score. The same week Google priced judgment, United Airlines confirmed it will not let third-party AI agents complete ticket purchases (The Verge, 2026-11-11): agents can search flights, and the transaction ends at a person, partly because federal rules require the passenger to personally attest to declarations like the no-explosives question. No threshold crosses that line, because the meaning of an attestation is that a specific person made it. Signature-class actions belong above every threshold, routed to a person every time, at confidence 1.0 as much as at 0.3.
Where this lands in an agent stack
Agents raise the stakes on all of the above because the output of the judgment is an action: send, purchase, delete, publish. One of the six criteria for a sovereign AI avatar is that actions are judged outside the model, by rules the owner sets. Architecture B is that criterion, written in code: the generating model proposes, a separate layer scores, versioned config decides, a ledger remembers.
Our own product, KarmaBox, is a platform and network for running your own AI avatars, and it ships this wiring as configuration rather than as a weekend project. Per-action policies (send, publish, spend, delete each get their own rules) are the THRESHOLDS object with an owner attached; approval cards are the queue() branch, pushing the ambiguous case to the person who answers for it; the action ledger is the append, kept in the owner's records rather than a vendor console. Where the judgment itself runs is a deployment choice: sensitive review flows can sit on machines you control, public-facing tasks can ride cloud avatars. The decision method, the tiers and the numbers, stays the team's own homework either way.
If you wire up exactly one piece of this on Monday, make it the ledger. Thresholds you can argue about forever; the ledger is twenty lines, and it is the only component that turns this quarter's automation into next quarter's evidence. The second-best Monday candidate is shadow scoring, for the same reason: both produce evidence while changing nothing a customer sees.
What is the one action your agent takes today that you could not reconstruct the reasoning for, six weeks later, if a customer asked?
Sources
Google, Introducing the Gemini Decisions API, 2026-11-11
The Verge, United won't let your AI agent book your flight, 2026-11-11





