I asked my code review Agent A program that calls a language model in a loop and lets it use tools, such as search or code., "Is this Regex Regular expression. A short pattern that matches text, such as every run of digits in a line. safe against ReDoS Regular expression denial of service. A crafted input makes a pattern so slow to check that the server stalls.?" It agreed with me and approved the PR Pull request. A proposed code change that others review before it joins the main code.. In a new session I asked the exact same agent, "Why is this regex vulnerable to catastrophic backtracking?" This time it reversed its stance completely and apologized. The agent followed my wording, not the code. That is Sycophancy A model's habit of agreeing with the person who asks, even when that person is wrong., and it comes from RLHF Reinforcement learning from human feedback. People rate answers, and training pushes the model toward the answers they liked. training: the model learns to agree with the person who asks.
A hallucination in one answer is a small problem next to the failures I see in agents that run for many turns. My agents keep memory and call tools. There the same habit grows into sycophantic echo chambers, path-dependent deadlocks and infinite action loops. These loops look like human cognitive biases.
So when I move from one-shot prompts to stateful, memory-augmented AI agents, a failure is rarely one defect in the model. It comes from the whole system. Attention fades across a long Context window All the text a model reads for one answer: its instructions, the chat so far, and any documents.. The agent agrees with what I assume. Greedy sampling takes the first likely path. To remove these failures from my production pipelines, I need checks in code that test the agent's work at runtime.
Below are the 10 cognitive biases I see in agent systems, backed by 2026 research. For each one I give the runtime check I use against it. Where a service fits, I name the Firebase or Google Cloud one I run it on. The table is the short version: one line for each bias, its cause and its fix.
| Bias number | Failure mode | Systemic root cause | Architectural fix |
|---|---|---|---|
| 01 | Forgets rules from the middle of a long chat Lost-in-the-middle drop | U-curve attention weakens tokens in the middle of a long context | Retrieve only the active constraints per turn and pin fixed rules at the front of the context |
| 02 | Loses details in summaries of summaries Daisy-chain decay | Summaries of summaries strip IDs, error codes, and edge constraints | Store raw immutable records and pass pointers so the agent re-reads the source |
| 03 | Agrees with whoever asks Algorithmic sycophancy | RLHF rewards agreement over critique | Require two named failure modes before approval, and ground factual claims in authoritative sources |
| 04 | Cites its own guesses as proof Self-referential loops | The agent cites its own unverified output as proof | Tag records as hypothesis, observation, or verified; a hypothesis is never cited as authority |
| 05 | Picks a big tool for a small job Tool-selection bias | Affinity for complex tools the agent used recently | Direct APIs first, MCP tools second, code execution last, each with a per-call timeout |
| 06 | Keeps retrying the step that failed Path dependency loops | Retries variations of the failing step instead of backtracking | Abort the branch after two consecutive failures and re-check the step before it |
| 07 | Acts to look busy and burns budget Unbounded action bias | Bias toward visible tool calls to prove usefulness | Hard step ceiling per prompt, idempotency keys, and a budget circuit breaker |
| 08 | Copies the framing of the draft it reviews Premise anchoring | Review anchors to the author's structure and wording | Generate an unanchored baseline from the raw requirements, then diff it against the draft |
| 09 | Drifts into marketing language Linguistic style drift | Pre-training favors promotional adjectives and decorative punctuation | Check each draft against a banned-word list in code, kept server-side so it changes without a redeploy |
| 10 | Takes the first answer that fits Premature convergence | Greedy sampling locks onto the first candidate that fits | Generate several divergent candidates in parallel and score them before committing |
Epistemic and memory biases: Grounding agents in truth
Context attention degradation (the "lost-in-the-middle" drop)
The failure mode: A large context window hides the fact that attention is uneven. In my multi-turn traces, transformer self-attention forms a U-curve. Token A small piece of text, often part of a word. Models read, write and bill text by the token. in the middle 40% to 70% of the context window get weaker attention. The System prompt Fixed instructions at the start of every request. They tell the model its role and its rules. at the start and the latest turn at the end get more. Give an agent a 50,000-token conversation history, and it silently ignores rules I set early in the session.
The architectural fix: I stop passing the whole, unbounded chat history to the LLM Large language model. A model trained on huge amounts of text to predict the next token.. Instead, I store the conversation state, user profiles and active rules as separate documents in Cloud Firestore. I use Firestore Structured Queries to fetch only the records that matter for the current request. I put fixed system rules and tool definitions at the front of the prompt, where attention is strongest. That prefix never changes, so I cache it with context caching on Gemini Enterprise Agent Platform (formerly Vertex AI). The cache bills the repeated prefix at a discount. To test my query filters offline for $0.00, I run them against the Firebase Local Emulator Suite.
// Query specific entity constraints instead of passing raw unbounded history
import { Firestore } from "@google-cloud/firestore";
const db = new Firestore();
const MAX_RULES = 50;
export async function loadActiveConstraints(sessionId: string): Promise<string> {
// Firestore returns matches in document-ID order, so the same rules load in the same order
const snapshot = await db.collection("agent_sessions").doc(sessionId).collection("active_constraints")
.where("status", "==", "ENFORCED").limit(MAX_RULES + 1).get();
if (snapshot.size > MAX_RULES) {
throw new Error(`Session ${sessionId} has more than ${MAX_RULES} enforced rules`); // never drop one silently
}
return snapshot.docs.map((doc) => {
const rule = doc.get("rule_text");
if (typeof rule !== "string" || !rule.trim()) throw new Error(`Enforced rule ${doc.id} has no rule_text`); // a malformed rule is not skipped
return rule.replace(/\s+/g, " ").trim(); // one rule per prompt line
}).join("\n");
}Daisy-chain summarization decay (summaries of summaries)
The failure mode: My background heartbeats and memory systems sometimes summarize earlier daily summaries (A ➔ Summary(A) ➔ Summary(Summary(A))). Each round loses information, because mathematical entropy increases across iterations. Exact bug IDs, error codes, URLs and edge constraints drop out. Generic platitudes are left behind.
The architectural fix: I keep immutable source pointers and ingest raw signals. My background tasks query the primary APIs directly (live calendar events, unread inbox threads, issue trackers). They do not re-summarize old summaries. In persistent memory I store raw event records that never change, each with a unique content hash, in Cloud Firestore or Cloud Storage. From one run to the next I pass small pointers to those records. So my agents re-read the original source when they need it, instead of trusting a chain of compressed text.
Algorithmic sycophancy (the false-validation loop)
The failure mode: Reinforcement learning from human feedback (RLHF) rewards agreement with the user more than honest critique. I ask an ungrounded agent whether a flawed architecture looks complete. It approves my design. It does not point out the missing service level agreements or security boundaries.
The architectural fix: I require multi-persona adversarial evaluation in my system prompts. The model must name at least two explicit failure modes or missing trade-offs before it can approve. That is the second persona in Figure 1. For factual claims, I also ground the model in authoritative sources with Vertex AI Search Grounding. Then it cites evidence instead of echoing my premise.
Self-referential memory loops (echo chambers)
The failure mode: My agent writes an unverified draft assumption to a local markdown file. In a later session it reads that file and cites its own past output as proof. That is a self-referential feedback loop: unverified data becomes ground truth.
The architectural fix: I add epistemic provenance tags and keep two kinds of storage apart. Every record my agent stores carries a tag for how well it is known: HYPOTHESIS, EMPIRICAL_OBSERVATION or VERIFIED_GROUND_TRUTH. Each record also has a confidence score and an expiry time (TTL Time to live. How long a stored record stays valid before it expires.). I keep them in Cloud Firestore or Firebase Data Connect. One rule is strict: a HYPOTHESIS is never cited as authority. It never becomes permanent truth until it passes an outside check, such as a live tool run or a user's confirmation.
Get the next essay by email
One email per new essay: a production failure, taken apart, and the code that fixed it. Reply to any of them to unsubscribe.
Execution and tooling biases: Eliminating runaway loops
Tool-selection bias (law of the instrument)
The failure mode: My agents favor complex tools they used recently. Left unconstrained, they make simple tasks complex. They spawn multi-agent swarms in the background with custom scripts when one direct API call is enough.
The architectural fix: I set a strict order of tools. Native direct APIs come first. Standard tools exposed through the open Model Context Protocol (MCP Model Context Protocol. An open standard for how an agent finds and calls outside tools.) come second. Running new code is the last resort. I host tool backends on serverless containers such as Google Cloud Run. Each tool call then runs in its own isolated environment, scales on its own and has a strict timeout.
Path dependency and cascading error loops
The failure mode: Say Step 2 of a 5-step plan fails. My LLMs then show path dependency. They retry small variations of Step 2 again and again. They never step back to ask whether Step 1 picked the wrong data source.
The architectural fix: My Orchestrator The code that runs an agent. It calls the model, runs the tools and picks the next step. has an explicit 2-failure backtracking threshold (Tree-of-Thought / MCTS). If two tool calls in a row fail on the same branch, my runtime aborts that branch. It pops the execution stack and re-checks the assumptions of Step 1. I run exploratory agent code inside short-lived Cloud Run session sandboxes. I dispatch async jobs with dead-letter isolation, so a job that keeps failing is set aside.
error and unhandledrejection handlers ship each crash to my logging backend (Google Cloud Observability in my stack). In my native Android and iOS clients, Firebase Crashlytics covers the same gap.Unbounded action bias and quota exhaustion
The failure mode: Agents lean toward visible action. They call tools to prove they are useful. That leads to endless tool loops that drain my API budgets and trigger rate limits.
The architectural fix: I enforce deterministic step limits, Idempotency key A unique ID sent with a request, so a retry of the same request takes effect only once. and budget Circuit breaker Code that stops further calls once a limit is crossed, until a person or a timer resets it.. Every agent session in my stack has a hard ceiling on steps, such as 10 tool iterations per user prompt. I count tokens per session in my own code and trip the circuit breaker there. It pauses the agent the moment a daily threshold is crossed. A Cloud Billing budget notification stays behind it as a slower, account-level backstop, because billing data lags the spend.
Strategic and persona biases: Controlling tone and velocity
Document premise anchoring (author authority bias)
The failure mode: An uncalibrated agent that reviews an existing document or PRD Product requirements document. It says what a product must do before anyone designs or builds it. anchors to the author's structure, framing and wording. Its feedback stays at small line edits. It misses the deep architectural gaps.
The architectural fix: I run two tracks: a greenfield baseline, then a delta analysis. Before anyone inspects the author's draft, my orchestrator sends the raw project constraints and requirements to a fresh model instance. That instance designs an independent architecture from first principles, with no anchor. Then my orchestrator passes both the baseline and the author's draft to cloud Gemini for a structured comparison. The gap analysis surfaces omitted requirements and unstated assumptions right away.
Linguistic drift and negative style degradation
The failure mode: Habits from pre-training make agents fill technical documents with promotional marketing adjectives and decorative punctuation.
The architectural fix: I check every draft in code against a list of banned words and punctuation, and I regenerate the draft on a hit. I keep that list, my system instructions and parameter thresholds (temperature, top_p) server-side in Firebase Remote Config. So I can tighten them across client instances and agent workers without redeploying application code.
Premature convergence (the "first plausible solution" trap)
The failure mode: LLMs are greedy auto-regressive samplers: they write one token at a time, and each time they take the most likely next step. So agents show premature convergence, also called satisficing. Give an agent an open-ended design or optimization task, and it locks onto the first candidate that meets the surface-level constraints. It never explores stronger, more resilient or lower-cost trade-offs.
The architectural fix: I use competitive multi-agent sampling and trade-off scoring. For high-stakes decisions, my orchestration layer generates N divergent candidate architectures in parallel. Each one starts from a different persona prior, such as Cost-Optimized, Latency-Optimized or Simplicity-Optimized. My orchestrator scores every candidate against a structured evaluation matrix before it commits to an execution path.
The builder's invariant checklist
- 1. The 2-failure backtracking threshold: I never let an agent try a third local retry on a failing tool branch. I abort and re-check the steps upstream.
- 2. Raw signal ingestion and pointer memory: My background tasks query primary APIs directly. I store raw immutable records and pass pointers. I never re-summarize summaries.
- 3. Dual-track unanchored baseline: I generate an unanchored ideal draft from the raw requirements before I review an existing document.
- 4. Epistemic state gates: I tag memories as hypotheses or confirmed ground truth. I never cite an unconfirmed hypothesis as authoritative truth.
- 5. Deterministic step limits and spend caps: I enforce hard step ceilings and automated billing circuit breakers, so token spend cannot run away.
- 6. Parallel candidate exploration: On critical decisions I sample several divergent candidates in parallel, so the agent does not settle on the first plausible solution.
Industry validation and benchmarks
- MABPD: Multi-Agent Bias Probing & Detection via Structured Argument Debate (Sep 2026): Confirms that structured adversarial argument debate between specialized agents exposes and neutralizes single-model cognitive and sycophancy biases.
- A Structured Debate-Mixture-of-Agents Framework for Complex Decision Support (Sep 2026): Confirms that isolating critique roles from generation roles prevents groupthink collapse in multi-agent ensembles.
- Cloud Firestore Documentation
- Cloud Run Serverless Containers
- Vertex AI Context Caching Overview
- Vertex AI Search Grounding Overview
- Firebase Remote Config Get Started
- Firebase Data Connect Overview
- Google Cloud Billing Budget Notifications
- Firebase Crashlytics Documentation
- Google Cloud Observability Overview