<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Roman Belov</title>
    <description>The latest articles on DEV Community by Roman Belov (@spyrae).</description>
    <link>https://dev.to/spyrae</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3814828%2F4f08754d-1c5b-45ed-9659-de1473e054df.jpeg</url>
      <title>DEV Community: Roman Belov</title>
      <link>https://dev.to/spyrae</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spyrae"/>
    <language>en</language>
    <item>
      <title>Context Engineering: How to Manage Context for AI Models and Agents</title>
      <dc:creator>Roman Belov</dc:creator>
      <pubDate>Thu, 09 Apr 2026 04:33:23 +0000</pubDate>
      <link>https://dev.to/spyrae/context-engineering-how-to-manage-context-for-ai-models-and-agents-1hej</link>
      <guid>https://dev.to/spyrae/context-engineering-how-to-manage-context-for-ai-models-and-agents-1hej</guid>
      <description>&lt;p&gt;Claude's context window holds 200,000 tokens. Gemini's stretches to two million. But response quality starts degrading long before the window fills up. Window size doesn't solve the context problem — it masks it.&lt;/p&gt;

&lt;p&gt;Prompt engineering teaches you &lt;em&gt;how to ask&lt;/em&gt;. Context engineering teaches you &lt;em&gt;what to feed&lt;/em&gt; the model before asking. And the second one shapes the answer more than the first.&lt;/p&gt;

&lt;p&gt;Andrej Karpathy &lt;a href="https://x.com/karpathy/status/1937902205765607626" rel="noopener noreferrer"&gt;put it this way&lt;/a&gt;: "Context engineering — the delicate art and science of filling the context window with just the right information for the next step." Tobi Lütke, CEO of Shopify, popularized the term itself, and Gartner declared in July 2025: "Context engineering is in, and prompt engineering is out."&lt;/p&gt;

&lt;p&gt;This piece covers concrete techniques, models, and patterns. Things that actually work when you're using AI agents in development every day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prompt vs Context: Where the Line Falls
&lt;/h2&gt;

&lt;p&gt;Here's an analogy that works: you're hiring an expert consultant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prompt&lt;/strong&gt; — your question: "What should I do?"&lt;br&gt;
&lt;strong&gt;Context&lt;/strong&gt; — the briefing you hand them before the question.&lt;/p&gt;

&lt;p&gt;You can phrase the question perfectly, but if the briefing contains 500 pages of irrelevant documents, even a strong expert will get lost. Flip it around: hand them exactly the 2 pages they need, and even a simple question yields a precise answer.&lt;/p&gt;

&lt;p&gt;Prompt engineering answers questions like: how to frame the task, what role to assign the model, what output format to request. Context engineering answers different ones: feed 100 reviews or pick 15 representative ones? The entire 500-line file or just lines 45–80? All the documentation or extract the facts?&lt;/p&gt;

&lt;p&gt;A more technical analogy drives it home. The LLM is a CPU. The context window is RAM. You're the operating system deciding what gets loaded into working memory. The goal: load exactly the data needed for the current operation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why More Context Is Worse
&lt;/h2&gt;

&lt;p&gt;This is counterintuitive, but backed by research.&lt;/p&gt;
&lt;h3&gt;
  
  
  Context Rot
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://research.trychroma.com/context-rot" rel="noopener noreferrer"&gt;Chroma's research (2025)&lt;/a&gt; showed that LLM accuracy drops as the token count in context grows — even when the window is far from full.&lt;/p&gt;

&lt;p&gt;The mechanism: attention is a fixed resource. Weights always sum to 1. More tokens means less attention per fragment. Think of a flashlight — the wider the beam, the dimmer the light at any point. And the harder the task, the steeper the drop.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lost in the Middle
&lt;/h3&gt;

&lt;p&gt;A &lt;a href="https://arxiv.org/abs/2307.03172" rel="noopener noreferrer"&gt;study&lt;/a&gt; found a specific pattern: LLM performance drops 30%+ when critical information sits in the middle of a long context. Beginning and end? Fine. The middle is a blind spot.&lt;/p&gt;

&lt;p&gt;Practical takeaway: put the important stuff at the beginning or end. System prompt up top. Few-shot examples at the bottom.&lt;/p&gt;
&lt;h3&gt;
  
  
  Economics
&lt;/h3&gt;

&lt;p&gt;Every token costs money, and the model rereads the entire context on every request (LLMs are stateless):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input: ~$3 per 1M tokens (Claude Sonnet)&lt;/li&gt;
&lt;li&gt;100K context × 100 requests/day = ~$30/day = &lt;strong&gt;$900/month&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Context engineering is budget engineering too.&lt;/p&gt;
&lt;h3&gt;
  
  
  Hallucinations from Overload
&lt;/h3&gt;

&lt;p&gt;With a bloated context, the model tries to "use everything" and starts inventing connections between unrelated parts. Data about Company A gets attributed to Company B. Functions that don't exist get "recalled" from similar code that drifted into the context twenty screens back.&lt;/p&gt;
&lt;h2&gt;
  
  
  Six Layers of Context
&lt;/h2&gt;

&lt;p&gt;Structure context like an onion — six layers, each with a specific job. This fights degradation by placing the most important information at the beginning and end, instead of spreading it across the middle.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│  1. SYSTEM — who you are &amp;amp; how to act   │  ← Permanent (beginning)
├─────────────────────────────────────────┤
│  2. PROJECT — project context           │  ← Semi-permanent
├─────────────────────────────────────────┤
│  3. TASK — the specific task            │  ← Per task
├─────────────────────────────────────────┤
│  4. DIFF / CODE — relevant fragments    │  ← Per task
├─────────────────────────────────────────┤
│  5. ACCEPTANCE CRITERIA — exit criteria │  ← Per task
├─────────────────────────────────────────┤
│  6. EXAMPLES (Few-shot) — samples       │  ← Optional (end)
└─────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  System: Role and Behavior
&lt;/h3&gt;

&lt;p&gt;Who the model is and how it should behave. Always at the very beginning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are an experienced backend developer working with Python and FastAPI.
Keep answers concise. Use type hints. Don't add dependencies without asking.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the role, response style, and constraints go. Task details do &lt;strong&gt;not&lt;/strong&gt; belong here — that's layer 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project: Project Context
&lt;/h3&gt;

&lt;p&gt;Tech stack, structure, architecture decisions, code conventions. This layer gets reused across tasks. In Claude Code, it lives in the &lt;code&gt;CLAUDE.md&lt;/code&gt; file — the agent reads it automatically on every launch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task: What to Do
&lt;/h3&gt;

&lt;p&gt;A clear description of what to do, why, and — this gets forgotten constantly — what &lt;strong&gt;not&lt;/strong&gt; to do.&lt;/p&gt;

&lt;p&gt;A good example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Task: Add rate limiting to /users.
Context: Endpoint is unprotected, bots are overloading it.
Requirements: 100 req/min per IP, Redis for counters, 429 on exceeded.
Out of scope: Changing endpoint logic, adding authorization.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A bad example: "Add rate limiting."&lt;/p&gt;

&lt;h3&gt;
  
  
  Diff/Code: Only What's Relevant
&lt;/h3&gt;

&lt;p&gt;Provide only the code fragments that relate to the task. Not the entire file. Specify path and lines: &lt;code&gt;app/api/users.py, lines 45–60&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Acceptance Criteria: When to Stop
&lt;/h3&gt;

&lt;p&gt;Clear, verifiable conditions. The model only knows when to stop if you tell it. Skip these and you'll get either a half-finished answer or something wildly overengineered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; [ ] Return 429 status when limit is exceeded
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Include Retry-After header in the response
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Unit tests cover edge cases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Examples (Few-shot): At the End
&lt;/h3&gt;

&lt;p&gt;For nonstandard output formats or a specific style. Place them at the end of the context — the model "sees" the finale better.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Hurts to Put in Context
&lt;/h3&gt;

&lt;p&gt;A few anti-patterns that will reliably tank your results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The entire project codebase&lt;/strong&gt; — signal drowns in noise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contradictory instructions&lt;/strong&gt; — "use Redux" + "use Context API" = the model gets confused&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outdated examples&lt;/strong&gt; — code with deprecated APIs gets reproduced verbatim&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vague phrasing&lt;/strong&gt; — "make it better" gives the model no direction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Four Strategies for Managing Context
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.langchain.com/context-engineering-for-agents/" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt; and Anthropic propose a framework: all context work boils down to four actions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Strategy&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Persist externally&lt;/td&gt;
&lt;td&gt;Scratchpads, MEMORY.md, progress files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Select&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extract only what's relevant&lt;/td&gt;
&lt;td&gt;RAG, grep, code search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compress&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Compact&lt;/td&gt;
&lt;td&gt;Compaction, summarization, tool result cleanup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Isolate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Isolate tasks&lt;/td&gt;
&lt;td&gt;Subagents with clean context&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Everything described below is a specific case of one of these four.&lt;/p&gt;

&lt;h2&gt;
  
  
  Persistence: Bridging Sessions
&lt;/h2&gt;

&lt;p&gt;Every session with an AI agent starts from scratch. New context window, zero memory of previous work. &lt;a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents" rel="noopener noreferrer"&gt;Anthropic&lt;/a&gt; calls it the "shift engineer" problem: each new engineer coming on shift remembers nothing of the previous one's work. No notes left behind? Start over.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plain Files
&lt;/h3&gt;

&lt;p&gt;The most basic form of memory — markdown notes the agent writes for its future self. Claude Code uses &lt;code&gt;MEMORY.md&lt;/code&gt; for this: the agent automatically records project patterns, decisions, and architectural notes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git as Memory
&lt;/h3&gt;

&lt;p&gt;Commits with meaningful messages form a changelog and restore points. The agent can experiment freely, knowing it can always roll back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structured Notes
&lt;/h3&gt;

&lt;p&gt;Plain files evolve. Instead of a flat log, the agent maintains a structured knowledge base. The pattern: &lt;code&gt;write_to_notes(topic, content)&lt;/code&gt; + &lt;code&gt;read_from_notes(topic)&lt;/code&gt; — an external hard drive for memory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents" rel="noopener noreferrer"&gt;An example from Anthropic&lt;/a&gt;: an agent playing Pokemon recorded "trained Pikachu 1234 steps, 8 out of 10 levels." After a context reset, it read its own notes and picked up right where it left off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scratchpad
&lt;/h3&gt;

&lt;p&gt;Working memory within the current session. The agent "thinks out loud" — storing intermediate results, hypotheses, a plan. Scratchpad is RAM; files are disk.&lt;/p&gt;

&lt;p&gt;Simple thought, but it changes everything: stop making the model remember. Give it a notebook.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context Compaction
&lt;/h3&gt;

&lt;p&gt;When the context fills up, compress it. The model gets the full history and produces a summary. Old conversation gets tossed, compressed version goes at the start of the new context.&lt;/p&gt;

&lt;p&gt;Manual compaction at logical breakpoints (after finishing a feature) beats automatic. There's also a lighter variant: cleaning up tool results — strip the verbose command outputs from history, keep just the fact that they ran.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task Trackers
&lt;/h3&gt;

&lt;p&gt;For long-running projects, the "Initializer + Executor" pattern works well. The first agent doesn't write code — it creates a structured task list in JSON: description, status, dependencies. Each subsequent agent reads the list, picks a pending task, completes it, updates the status, and commits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subagents: Isolation as Strategy
&lt;/h2&gt;

&lt;p&gt;The main agent can delegate a subtask to a subagent — a separate process with its own clean context window. Like a manager asking a database specialist to optimize a query: hand them the schema and the slow query, not the entire month's email thread.&lt;/p&gt;

&lt;p&gt;Three wins:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Context purity.&lt;/strong&gt; The subagent isn't polluted by the main agent's history. The main agent might have 85% of its window occupied — the subagent starts at 5%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specialization.&lt;/strong&gt; You can use different models or system prompts for different subagents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelization.&lt;/strong&gt; Multiple subagents can work simultaneously.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In Claude Code, subagents are launched via the Task tool. The main agent describes the task, the subagent receives it in a clean context, does the work, and returns a structured result. The main agent's context cost is minimal.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP and the Tool Tax
&lt;/h2&gt;

&lt;p&gt;MCP (&lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;Model Context Protocol&lt;/a&gt;) is an open standard defining how AI agents discover and call tools. Each MCP server adds its tool descriptions to the context. Every description costs tokens.&lt;/p&gt;

&lt;p&gt;You feel it the moment you start working for real: connect 5–10 MCP servers (GitHub, Slack, database, analytics, monitoring) and tens of thousands of tokens in tool descriptions land &lt;em&gt;in every request&lt;/em&gt;, even when none of them get called.&lt;/p&gt;

&lt;p&gt;The fix is lazy loading. Claude Code uses Tool Search: tool descriptions load on demand, only when the agent decides it might need one. Saves around 85% of tokens. Other agents have similar tricks: lazy-mcp, MetaMCP.&lt;/p&gt;

&lt;p&gt;Tool design principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Self-sufficiency:&lt;/strong&gt; the description contains everything needed for use. The model doesn't read your README.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unambiguity:&lt;/strong&gt; &lt;code&gt;user_email&lt;/code&gt; instead of &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;validate_payment&lt;/code&gt; instead of &lt;code&gt;process&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimalism:&lt;/strong&gt; one tool = one atomic operation. If the description exceeds 200 words, the tool does too much.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Memory Hierarchy
&lt;/h2&gt;

&lt;p&gt;Context in production tools isn't a single file — it's a multi-level system. &lt;a href="https://code.claude.com/docs/en/memory" rel="noopener noreferrer"&gt;Claude Code's docs&lt;/a&gt; lay out the hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;System prompt&lt;/strong&gt; — base instructions (always loaded)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settings&lt;/strong&gt; — user preferences&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLAUDE.md&lt;/strong&gt; — project instructions (loaded from the repository root)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rules&lt;/strong&gt; — modular instructions, can be path-specific (loaded only when working with certain files)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skills&lt;/strong&gt; — entire folders of instructions and scripts the agent loads at its own discretion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto Memory&lt;/strong&gt; — memory the agent forms for itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/articles/exploring-gen-ai/context-engineering-coding-agents.html" rel="noopener noreferrer"&gt;Martin Fowler&lt;/a&gt; proposes a useful distinction: &lt;strong&gt;Instructions&lt;/strong&gt; (orders — "write a test for this function") vs &lt;strong&gt;Guidance&lt;/strong&gt; (general rules — "all tests must be independent of each other"). CLAUDE.md and rules are mostly Guidance. Chat prompts are Instructions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with Large Documents
&lt;/h2&gt;

&lt;p&gt;You can't just dump a 50-page PDF into the model. You need a strategy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chunking
&lt;/h3&gt;

&lt;p&gt;Break it into pieces of 1,500–3,000 tokens with 10–20% overlap. Semantic chunking (by chapters and sections) works noticeably better than chopping at fixed lengths.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.anthropic.com/news/contextual-retrieval" rel="noopener noreferrer"&gt;Contextual Retrieval from Anthropic&lt;/a&gt; tackles the ripped-from-context problem: before indexing, each fragment gets a description of where it came from and what the section covers. Result: at least 35% fewer retrieval failures, up to 67% with reranking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fact Extraction
&lt;/h3&gt;

&lt;p&gt;Skip the full text. Pull a structured list of facts and figures from each chunk instead. Smaller footprint, better accuracy for analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Map-Reduce
&lt;/h3&gt;

&lt;p&gt;For very large documents: split into chunks, summarize each (MAP), assemble the mini-summaries into a final one (REDUCE). The MAP phase can be parallelized — speedup scales with the number of workers.&lt;/p&gt;

&lt;h3&gt;
  
  
  RAG vs Long Context
&lt;/h3&gt;

&lt;p&gt;With windows getting bigger (Gemini 2M), the question keeps coming up: do we still need RAG? &lt;a href="https://arxiv.org/abs/2501.01880" rel="noopener noreferrer"&gt;Research (arXiv:2501.01880)&lt;/a&gt; says it depends on the task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;RAG wins:&lt;/strong&gt; the corpus is huge (&amp;gt; 1M tokens), freshness matters, budget is limited.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Long context wins:&lt;/strong&gt; you need synthesis across sections, structural understanding, document &amp;lt; 200K.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hybrid (the way to go):&lt;/strong&gt; RAG for selection, long context for analysis. The cost gap is real: full 2M context on every request runs an order of magnitude more than RAG selection + 50K of relevant context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where This Doesn't Work
&lt;/h2&gt;

&lt;p&gt;Wouldn't be honest to stop at the upsides.&lt;/p&gt;

&lt;h3&gt;
  
  
  Context engineering won't fix a bad model
&lt;/h3&gt;

&lt;p&gt;If the model can't write Rust, no amount of context will help. Context engineering works within what the model can already do. If the task is too hard for the current generation, break it into subtasks or try a different angle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparation overhead
&lt;/h3&gt;

&lt;p&gt;Assembling a perfect six-layer context package for every request takes time. For quick questions ("how does this function work?") it's overkill. Context engineering pays off on repeatable tasks and with agents that chain dozens of operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compaction loses information
&lt;/h3&gt;

&lt;p&gt;Compression is a tradeoff. The model picks what to keep and what to toss. Sometimes it tosses what matters. Manual compaction at logical breakpoints is safer, but needs the operator paying attention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lost in the Middle works both ways
&lt;/h3&gt;

&lt;p&gt;You can get so focused on "important stuff at the beginning and end" that the middle turns into a junk drawer. Better to cut the context down than hope positioning saves you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subagents add latency
&lt;/h3&gt;

&lt;p&gt;Delegating to a subagent means a separate API call with its own context. On a complex task, one subagent fires dozens of requests. For anything real-time, that's too slow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy tool loading isn't free
&lt;/h3&gt;

&lt;p&gt;Tool Search saves context but adds a search step. If the agent hunts for a tool before every action, that's extra requests and wasted time. Balancing tools-in-context against search frequency takes tuning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common mistakes
&lt;/h3&gt;

&lt;p&gt;Three that come up more than anything else:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Copying an entire file instead of the relevant fragment.&lt;/strong&gt; The model gets 500 lines when it needed lines 45–60. The other 440 lines are pure noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not saying what NOT to do.&lt;/strong&gt; Without constraints, the model refactors the whole file when you asked it to fix one function.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping acceptance criteria.&lt;/strong&gt; The model doesn't know when to stop. You get either undercooked or overcomplicated output.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Checklist
&lt;/h2&gt;

&lt;p&gt;Run through this before every serious request to a model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before the request:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is there a source of truth (docs, code, data) in the context?&lt;/li&gt;
&lt;li&gt;Is the task clearly described?&lt;/li&gt;
&lt;li&gt;Is the output format specified?&lt;/li&gt;
&lt;li&gt;Is what NOT to do specified?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In the prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Answer only based on the provided context"&lt;/li&gt;
&lt;li&gt;"If you don't know — say you don't know"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After the response:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are the facts verified?&lt;/li&gt;
&lt;li&gt;Do the referenced functions and libraries actually exist?&lt;/li&gt;
&lt;li&gt;Were characteristics of one object attributed to another?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Five takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Less = better.&lt;/strong&gt; Quality and relevance of context matter more than quantity. The goal is the smallest set of tokens with the strongest signal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure it.&lt;/strong&gt; Six layers: System, Project, Task, Code, Criteria, Examples. Important stuff at the beginning and end.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persist it.&lt;/strong&gt; Persistence = bridge between sessions. State files, structured notes, git.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolate it.&lt;/strong&gt; Subagents with clean context for specialized tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compress it.&lt;/strong&gt; Compaction and tool result cleanup when the context grows.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start small: assemble a six-layer context package for one typical task and compare the result to what you get from pasting code into the chat. The difference tends to be obvious on the first try.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  At what token count does context rot become practically noticeable, and is there a threshold to monitor?
&lt;/h3&gt;

&lt;p&gt;Multiple benchmarks (including studies by Chroma and others) show measurable accuracy degradation starting around 20–30K tokens for complex reasoning tasks, with a steeper drop past 50K. For simpler extraction tasks the threshold is higher — around 80–100K. A practical monitoring rule: if your average context exceeds 40K tokens per request and you're seeing inconsistent output quality, context size is the first variable to investigate. The $900/month calculation in the article assumes 100K tokens — most production agents can cut that by 60–70% through selective RAG retrieval without measurable quality loss.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does lazy tool loading in Claude Code achieve 85% token savings, and what is the actual mechanism?
&lt;/h3&gt;

&lt;p&gt;Without lazy loading, every MCP server's full tool schema is injected into the system prompt on every request — 10 servers with 5 tools each at ~200 tokens per tool description equals 10,000 tokens of overhead per call, regardless of which tools actually get used. Tool Search defers schema injection: the agent first sends a semantic search query to find relevant tool names (~50 tokens), then loads only the matching tool descriptions (~400 tokens for 2 tools). The 85% savings comes from eliminating the full schema dump for 8–9 unused tools per typical request.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should you use manual context compaction versus automatic, and what information is typically lost?
&lt;/h3&gt;

&lt;p&gt;Manual compaction at logical breakpoints (end of a feature, after a passing test suite) is safer because you control what the summary captures. Automatic compaction triggers on window fill and summarizes whatever is current — which may include half-finished reasoning, temporary debugging state, or contradictory instructions from mid-session pivots. The most common loss is architectural decisions made conversationally: "let's not use Redux here because X" survives a manual summary but gets dropped by automatic compaction which treats it as transient chat rather than binding constraint.&lt;/p&gt;

</description>
      <category>contextengineering</category>
      <category>llm</category>
      <category>ai</category>
      <category>promptengineering</category>
    </item>
    <item>
      <title>I Built a Lie Detector for AI Coding Agents</title>
      <dc:creator>Roman Belov</dc:creator>
      <pubDate>Mon, 09 Mar 2026 13:59:51 +0000</pubDate>
      <link>https://dev.to/spyrae/i-built-a-lie-detector-for-ai-coding-agents-21l2</link>
      <guid>https://dev.to/spyrae/i-built-a-lie-detector-for-ai-coding-agents-21l2</guid>
      <description>&lt;h2&gt;
  
  
  The problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;AI coding agents lie. Not on purpose - they hallucinate.&lt;/p&gt;

&lt;p&gt;Claude Code tells you "All tests pass!" when tests were never executed. It says "I updated the file" when the content is byte-for-byte identical. It sneaks in &lt;code&gt;git commit --no-verify&lt;/code&gt; to skip the hooks that would catch its mistakes.&lt;/p&gt;

&lt;p&gt;This isn't rare. It's a &lt;a href="https://github.com/anthropics/claude-code/issues/1501" rel="noopener noreferrer"&gt;documented bug&lt;/a&gt; and it hits every serious Claude Code user. System prompts don't help - the agent just ignores them when it "decides" something is done.&lt;/p&gt;

&lt;p&gt;I spent a couple weeks building a fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't ask the agent to be honest - verify it
&lt;/h2&gt;

&lt;p&gt;That's the whole idea. Claude Code has a hooks API - before and after every tool call, it can run your scripts. Those scripts inspect what actually happened and &lt;strong&gt;block&lt;/strong&gt; the agent if the results don't match the claims.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent claims: "I updated utils.ts"
    |
[PostToolUse hook]
    |
Compare SHA256 before/after -&amp;gt; IDENTICAL
    |
BLOCKED: "File was not actually modified. Checksum unchanged."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can't argue with a checksum. This isn't a prompt the agent can ignore. It's a gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  Six hooks, zero fluff
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Hook&lt;/th&gt;
&lt;th&gt;What it catches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dangerous command blocker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;--no-verify&lt;/code&gt;, &lt;code&gt;--force push&lt;/code&gt;; warns on &lt;code&gt;reset --hard&lt;/code&gt;, &lt;code&gt;clean -f&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pre-commit test runner&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auto-detects your framework, runs tests before every commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;File checksum recorder&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Saves SHA256 before file edit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Exit code verifier&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Command failed (exit 1) but agent claims success&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Phantom edit detector&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;File unchanged after a claimed "edit"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Commit verification reminder&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Makes the agent prove the fix works before claiming "done"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Two days of real use
&lt;/h2&gt;

&lt;p&gt;I ran TruthGuard on a production Flutter project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;5 commits blocked&lt;/strong&gt; - agent kept trying to commit with failing tests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 dangerous commands caught&lt;/strong&gt; - 2x &lt;code&gt;git push --force&lt;/code&gt;, 1x &lt;code&gt;git commit --no-verify&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;0 false positives&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pre-commit test hook alone stopped me from shipping broken code five times in two days. Five times.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-commit testing is the killer feature
&lt;/h2&gt;

&lt;p&gt;When Claude runs &lt;code&gt;git commit&lt;/code&gt;, TruthGuard intercepts it. Detects your project type, runs the right test command, and blocks the commit if tests fail. Simple as that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Auto-detection:&lt;/span&gt;
&lt;span class="c"&gt;# pubspec.yaml     -&amp;gt; flutter test&lt;/span&gt;
&lt;span class="c"&gt;# package.json     -&amp;gt; npm test&lt;/span&gt;
&lt;span class="c"&gt;# Cargo.toml       -&amp;gt; cargo test&lt;/span&gt;
&lt;span class="c"&gt;# go.mod           -&amp;gt; go test ./...&lt;/span&gt;
&lt;span class="c"&gt;# pyproject.toml   -&amp;gt; python -m pytest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Override if you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .truthguard.yml&lt;/span&gt;
&lt;span class="na"&gt;test_command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;npm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test:unit"&lt;/span&gt;
&lt;span class="na"&gt;skip_on_no_tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The subtler problem: wrong fixes
&lt;/h2&gt;

&lt;p&gt;After building the basic hooks, I ran into something trickier. Claude makes real changes, tests pass, but the fix doesn't actually solve the original problem. It genuinely thinks it's done.&lt;/p&gt;

&lt;p&gt;So I added a post-commit reminder. After every successful commit:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"You just committed code. STOP and verify: did you actually confirm the fix works?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A nudge, basically. But it makes the agent pause instead of rushing to "Done."&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx truthguard &lt;span class="nb"&gt;install
cd &lt;/span&gt;your-project
npx truthguard init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copies scripts to &lt;code&gt;~/.truthguard/&lt;/code&gt;, adds hooks to &lt;code&gt;.claude/settings.json&lt;/code&gt;. Restart Claude Code and that's it.&lt;/p&gt;

&lt;p&gt;Homebrew works too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap spyrae/truthguard &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;truthguard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Agent-agnostic
&lt;/h2&gt;

&lt;p&gt;Scripts read JSON from stdin, write JSON to stdout. Same scripts power both Claude Code and Gemini CLI. Supporting another agent means writing a config file, not rewriting hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;This is the free local-only version. No backend, no telemetry, everything on your machine.&lt;/p&gt;

&lt;p&gt;Some ideas I'm thinking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A second LLM that checks whether the diff actually solves the described problem&lt;/li&gt;
&lt;li&gt;Team dashboard with honesty stats&lt;/li&gt;
&lt;li&gt;VS Code extension for Cursor and Copilot users&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/spyrae/truthguard" rel="noopener noreferrer"&gt;github.com/spyrae/truthguard&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/truthguard" rel="noopener noreferrer"&gt;npmjs.com/package/truthguard&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your agent lies in ways I haven't covered - open an issue and I'll write a hook for it.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
