<?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: Susheem Koul</title>
    <description>The latest articles on DEV Community by Susheem Koul (@susheem-k).</description>
    <link>https://dev.to/susheem-k</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3400154%2Fcbd57c42-b444-4478-965d-0243e3ea9e5a.jpg</url>
      <title>DEV Community: Susheem Koul</title>
      <link>https://dev.to/susheem-k</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/susheem-k"/>
    <language>en</language>
    <item>
      <title>I built an RPG that teaches Claude Code by making you actually use it</title>
      <dc:creator>Susheem Koul</dc:creator>
      <pubDate>Wed, 26 Aug 2026 15:14:07 +0000</pubDate>
      <link>https://dev.to/susheem-k/i-built-an-rpg-that-teaches-claude-code-by-making-you-actually-use-it-mlg</link>
      <guid>https://dev.to/susheem-k/i-built-an-rpg-that-teaches-claude-code-by-making-you-actually-use-it-mlg</guid>
      <description>&lt;p&gt;Most tool documentation teaches by just telling you things. You read a page about&lt;br&gt;
&lt;code&gt;/model&lt;/code&gt;, or hooks, or subagents, nod along, and forget it by the time you'd&lt;br&gt;
actually need it. I wanted something closer to how people actually learn a CLI,&lt;br&gt;
by using it, with something checking whether you did the thing right or not.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;claude-quest&lt;/strong&gt;, a text RPG that runs entirely inside a real&lt;br&gt;
&lt;code&gt;claude&lt;/code&gt; session and teaches the Claude Code CLI zero to hero.&lt;/p&gt;
&lt;h2&gt;
  
  
  the idea isn't new, I borrowed it
&lt;/h2&gt;

&lt;p&gt;This is basically &lt;a href="https://github.com/phyver/GameShell" rel="noopener noreferrer"&gt;GameShell&lt;/a&gt;'s philosophy&lt;br&gt;
applied to Claude Code. GameShell teaches Unix shell commands by dropping you&lt;br&gt;
into a real shell wrapped in a themed fake filesystem, and grading your&lt;br&gt;
progress by checking real shell/filesystem state instead of asking you to self&lt;br&gt;
report or answer a quiz question.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;claude-quest&lt;/code&gt; does the same thing, except the "filesystem" is a real Claude&lt;br&gt;
Code environment. missions live in real sandbox directories, and progress is&lt;br&gt;
checked by inspecting what you actually did, config files you wrote, hooks&lt;br&gt;
that fired, tool calls that happened.&lt;/p&gt;
&lt;h2&gt;
  
  
  what it actually looks like
&lt;/h2&gt;

&lt;p&gt;There's no separate app, no fancy terminal UI, none of that. You say "let's&lt;br&gt;
play claude quest" inside a normal &lt;code&gt;claude&lt;/code&gt; session, and Claude itself becomes&lt;br&gt;
the game master. It reads real output from the engine and narrates on top of&lt;br&gt;
it, something like this:&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="gt"&gt;&amp;gt; lets play claude quest&lt;/span&gt;

&lt;span class="gs"&gt;**The Gatehall**&lt;/span&gt;

You've just been let through the outer gate. The tower keeps no secrets
from those who bother to read the walls...

&lt;span class="gs"&gt;**Mission: First Contact**&lt;/span&gt; (Tier 1, Artifact)

Create a CLAUDE.md file in this sandbox recording how to run the
project's tests. Let me know when you're done and I'll check it.
&lt;span class="gt"&gt;
&amp;gt; done&lt;/span&gt;

CLAUDE.md records how to run the tests. Claude Code will know next time.
MISSION_STATUS: complete

&lt;span class="gs"&gt;**What you actually learned:**&lt;/span&gt; Claude Code reads a file named CLAUDE.md
in your project root automatically, at the start of every session...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that's it, that's the whole interface. it's just a chat, with real commands&lt;br&gt;
running underneath it and real files getting checked. nothing gets rendered,&lt;br&gt;
nothing gets animated, it's plain text the way &lt;code&gt;claude&lt;/code&gt; sessions already look.&lt;/p&gt;
&lt;h2&gt;
  
  
  missions are graded on real state, not vibes
&lt;/h2&gt;

&lt;p&gt;Every mission is one of four tiers, and the grading gets less mechanical the&lt;br&gt;
further you go:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Artifact&lt;/strong&gt;, write or edit a file (a &lt;code&gt;CLAUDE.md&lt;/code&gt;, a config) and the engine
checks the file itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Invocation&lt;/strong&gt;, actually run a &lt;code&gt;claude&lt;/code&gt; session and do the thing (switch
models, compact, check cost). the engine checks what landed afterward
(like &lt;code&gt;.claude/settings.json&lt;/code&gt;), never what you said in the session.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mastery&lt;/strong&gt;, fix something that's conceptually broken (a skill whose
description doesn't say what its for, a subagent that won't fire), then
the engine runs a held-out test battery against your own &lt;code&gt;claude&lt;/code&gt; CLI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Judgment&lt;/strong&gt;, write something graded on a rubric (a commit message, a
skill description) and an isolated judge call scores it per criteria.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of these ask you to type an answer into a prompt, they ask you to leave&lt;br&gt;
a trace and then the engine checks the trace.&lt;/p&gt;
&lt;h2&gt;
  
  
  try it
&lt;/h2&gt;

&lt;p&gt;Inside any &lt;code&gt;claude&lt;/code&gt; session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/plugin marketplace add susheem-k/claude-quest
/plugin &lt;span class="nb"&gt;install &lt;/span&gt;claude-quest@claude-quest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just say "let's play claude quest." Progress saves to &lt;code&gt;~/.claude-quest/&lt;/code&gt;,&lt;br&gt;
so it doesn't really matter which project your in when you pick it back up.&lt;/p&gt;

&lt;h2&gt;
  
  
  where it's at, not all the levels exist yet
&lt;/h2&gt;

&lt;p&gt;This is a playable alpha, not a finished game. The full loop already works&lt;br&gt;
(characters, saves, hints, grading for all four tiers) but the campaign&lt;br&gt;
doesn't cover everything Claude Code can do yet. Right now there's only a&lt;br&gt;
handful of example missions, one or two per tier, across five arcs. More&lt;br&gt;
missions are getting added.&lt;/p&gt;

&lt;p&gt;And since this is open source, that part doesn't have to be just me. If&lt;br&gt;
there's a Claude Code feature you wish more people knew how to use, a&lt;br&gt;
command, a hook, a workflow you had to learn the hard way, I'd genuinely like to turn it into a mission. The mission format is just a directory with a goal, a hint, and a &lt;code&gt;check.js&lt;/code&gt; (the &lt;a href="https://github.com/susheem-k/claude-quest/blob/main/docs/DESIGN.md" rel="noopener noreferrer"&gt;design doc&lt;/a&gt; has the exact file contract for it), so adding one doesn't require touching&lt;br&gt;
the engine at all.&lt;/p&gt;

&lt;p&gt;Open an &lt;a href="https://github.com/susheem-k/claude-quest/issues" rel="noopener noreferrer"&gt;issue&lt;/a&gt; with a&lt;br&gt;
mission idea, or just send a PR with one built already, both are welcome.&lt;/p&gt;

&lt;p&gt;if you try it and it teaches you something, a star on the repo genuinely&lt;br&gt;
helps, it's how other people find it.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/susheem-k/claude-quest" rel="noopener noreferrer"&gt;https://github.com/susheem-k/claude-quest&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>opensource</category>
      <category>node</category>
    </item>
    <item>
      <title>From Validating Code to Evaluating Behavior: Rethinking Testing for AI Agents</title>
      <dc:creator>Susheem Koul</dc:creator>
      <pubDate>Mon, 17 Aug 2026 17:25:57 +0000</pubDate>
      <link>https://dev.to/susheem-k/from-validating-code-to-evaluating-behavior-rethinking-testing-for-ai-agents-315g</link>
      <guid>https://dev.to/susheem-k/from-validating-code-to-evaluating-behavior-rethinking-testing-for-ai-agents-315g</guid>
      <description>&lt;p&gt;Traditional software testing assumes that system behavior is governed by &lt;strong&gt;deterministic code paths and configurations&lt;/strong&gt;. Once an LLM enters the execution loop, that assumption weakens. The challenge shifts from verifying that code followed the expected path to evaluating whether a system behaved appropriately and achieved the desired outcome.&lt;/p&gt;

&lt;p&gt;That distinction fundamentally changes what we test, how we write assertions, and even what &lt;strong&gt;"correctness"&lt;/strong&gt; means. We are moving from verifying deterministic code to evaluating probabilistic system behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traditional Code Testing and Where It Starts Breaking Down
&lt;/h2&gt;

&lt;p&gt;In traditional software systems, behavior is encapsulated into methods, APIs, configuration, and external dependencies. Even when a system becomes extremely complex, the behavior is still ultimately determined by code.&lt;/p&gt;

&lt;p&gt;The output of a request flowing through a service can be largely thought of as a combination of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Output ≈ Input × Configuration × Infrastructure × Dependencies × Code Version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting state space may be enormous, but it remains largely open to systematic testing against an enumerated set of cases. This is the foundation upon which software testing is built. Cover enough of the state space and you gain confidence that the system will behave correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Concrete Example
&lt;/h3&gt;

&lt;p&gt;Consider a workflow that reads configuration from a config store, calls a customer profile API, calls a pricing API, applies deterministic business rules, and produces a recommendation. Testing this system is relatively straightforward. We can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mock the APIs&lt;/li&gt;
&lt;li&gt;Control configuration state&lt;/li&gt;
&lt;li&gt;Enumerate edge cases&lt;/li&gt;
&lt;li&gt;Verify outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Distributed systems introduce their own challenges—network latency, node failures, and partial outages—but established testing techniques such as &lt;strong&gt;chaos engineering&lt;/strong&gt; can provide confidence that the system behaves correctly under those conditions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Things Change with LLMs
&lt;/h3&gt;

&lt;p&gt;Now replace the deterministic business rules with an &lt;strong&gt;LLM-driven planner&lt;/strong&gt;. The APIs, tools, and data remain unchanged, but the workflow must now decide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tools to call&lt;/li&gt;
&lt;li&gt;In what order&lt;/li&gt;
&lt;li&gt;Whether more information is needed&lt;/li&gt;
&lt;li&gt;How to handle ambiguity&lt;/li&gt;
&lt;li&gt;How to formulate the final response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The upside is obvious: the system becomes dramatically more flexible and can handle scenarios that were never explicitly programmed for.&lt;/p&gt;

&lt;p&gt;The downside is that &lt;strong&gt;the testing surface area grows significantly&lt;/strong&gt;. The behavior driver is no longer only code; it is now a probabilistic reasoning system operating inside the application itself. Even temperature-0 inference does not always guarantee perfectly reproducible outputs in many production LLM deployments due to model updates, infrastructure differences, and implementation details.&lt;/p&gt;

&lt;p&gt;The result is a system whose behavior is &lt;strong&gt;harder to predict, harder to bound, and therefore harder to test&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Testing Challenge Shifts
&lt;/h4&gt;

&lt;p&gt;From:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did the code execute exactly as expected?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did the system behave appropriately?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once we accept that agent behavior cannot always be validated through deterministic assertions, the next question becomes: what exactly are we evaluating?&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are We Actually Testing?
&lt;/h2&gt;

&lt;p&gt;Agent testing significantly expands what correctness means. Instead of asking whether a function returned the correct value, we ask whether the &lt;strong&gt;overall behavior was acceptable&lt;/strong&gt;. A response can be factually correct while being incomplete, violate instructions, or arrive at the right answer through an inefficient or risky sequence of actions.&lt;/p&gt;

&lt;p&gt;As a result, evaluating an agent often means evaluating it across &lt;strong&gt;multiple dimensions&lt;/strong&gt;:&lt;/p&gt;

&lt;h3&gt;
  
  
  Outcome Metrics
&lt;/h3&gt;

&lt;p&gt;These metrics focus on whether the agent successfully completed the task.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Response Completeness&lt;/strong&gt; — Did the agent fully complete the task, or only address part of the request?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response Correctness&lt;/strong&gt; — Is the answer factually accurate, grounded in the available context, and compliant with instructions?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Operational Metrics
&lt;/h3&gt;

&lt;p&gt;These metrics evaluate how efficiently the agent performed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runtime and Latency&lt;/strong&gt; — How quickly does the agent respond and complete its work?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost Efficiency&lt;/strong&gt; — How many tokens, model calls, and external resources were required to complete the task?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reliability Metrics
&lt;/h3&gt;

&lt;p&gt;These metrics measure how the system behaves when things do not go according to plan.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Failure Handling&lt;/strong&gt; — Does the agent recover gracefully from tool failures, timeouts, malformed inputs, and missing data?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Quality Metrics
&lt;/h3&gt;

&lt;p&gt;These metrics focus on the usefulness and presentation of the final output.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Response Quality&lt;/strong&gt; — Is the output clear, concise, well-structured, and appropriate for the audience?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Governance Metrics
&lt;/h3&gt;

&lt;p&gt;These metrics ensure the system operates within acceptable boundaries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security and Safety&lt;/strong&gt; — Is the agent resilient to prompt injection, jailbreaks, data exfiltration attempts, and other adversarial inputs?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Behavioral Metrics
&lt;/h3&gt;

&lt;p&gt;These metrics evaluate how the agent arrived at its answer, not just the answer itself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trajectory Quality&lt;/strong&gt; — Did the agent follow a sensible path to reach its answer, or waste effort on unnecessary reasoning and tool calls?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Paradigm Shift
&lt;/h3&gt;

&lt;p&gt;Taken together, these dimensions reveal an important shift:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are no longer evaluating whether a piece of code returned the expected value. We are evaluating whether an intelligent system behaved effectively across a range of often competing objectives.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  How Do We Measure These Metrics?
&lt;/h2&gt;

&lt;p&gt;Once we know what we want to evaluate, the next challenge is figuring out how to measure it.&lt;/p&gt;

&lt;p&gt;In traditional software testing, assertions are usually &lt;strong&gt;deterministic&lt;/strong&gt;. We know the expected output ahead of time and can compare actual behavior against it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;calculate_tax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Many agent evaluation dimensions do not naturally translate to this style of "hard" testing.&lt;/p&gt;

&lt;p&gt;How do we write deterministic assertions for questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Was the answer complete?&lt;/li&gt;
&lt;li&gt;Was the response faithful to the provided context?&lt;/li&gt;
&lt;li&gt;Did the agent use retrieved information appropriately?&lt;/li&gt;
&lt;li&gt;Was the tone professional?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;semantic questions&lt;/strong&gt; rather than computational ones.&lt;/p&gt;

&lt;p&gt;As a result, modern AI evaluation frameworks have largely converged on three broad approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Mathematical Metrics
&lt;/h3&gt;

&lt;p&gt;Some dimensions can be measured using statistical techniques.&lt;/p&gt;

&lt;p&gt;For example, here's an excerpt from the &lt;strong&gt;RAGAS metrics documentation&lt;/strong&gt; on Answer Relevancy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Answer Relevancy metric measures how relevant a response is to the user input. It ranges from 0 to 1, with higher scores indicating better alignment with the user input.&lt;/p&gt;

&lt;p&gt;An answer is considered relevant if it directly and appropriately addresses the original question. This metric focuses on how well the answer matches the intent of the question, without evaluating factual accuracy. It penalizes answers that are incomplete or include unnecessary details.&lt;/p&gt;

&lt;p&gt;This metric is calculated using the &lt;code&gt;user_input&lt;/code&gt; and the &lt;code&gt;response&lt;/code&gt; as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a set of artificial questions (default is 3) based on the response. These questions are designed to reflect the content of the response.&lt;/li&gt;
&lt;li&gt;Compute the cosine similarity between the embedding of the user input (E_u) and the embedding of each generated question (E_q).&lt;/li&gt;
&lt;li&gt;Take the average of these cosine similarity scores to get the Answer Relevancy.
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Answer Relevancy = (1/N) Σ cosine_similarity(E_q, E_u)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.ragas.io/en/latest/concepts/metrics/index.html" rel="noopener noreferrer"&gt;You can find the entire catalog of metrics provided by RAGAS here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Specialised Models
&lt;/h3&gt;

&lt;p&gt;Some evaluation dimensions are measured using dedicated machine learning models trained for specific tasks.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sentiment analysis&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PII detection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bias detection&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In these cases, the evaluator itself is a model that has been optimised for a particular classification or scoring task.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. LLM-as-a-Judge with Pre-defined Rubrics
&lt;/h3&gt;

&lt;p&gt;One of the increasingly common approaches is using &lt;strong&gt;another LLM to evaluate the output&lt;/strong&gt; of the system under test.&lt;/p&gt;

&lt;p&gt;Rather than comparing outputs against exact expected values, an evaluator model is asked to assess whether a response satisfies a particular rubric.&lt;/p&gt;

&lt;p&gt;Frameworks such as &lt;strong&gt;DeepEval&lt;/strong&gt; and &lt;strong&gt;RAGAS&lt;/strong&gt; package these techniques into reusable metrics that engineers can apply directly within their test suites.&lt;/p&gt;

&lt;p&gt;For example, rather than implementing faithfulness scoring from scratch, a framework may expose a pre-built metric:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;deepeval.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FaithfulnessMetric&lt;/span&gt;

&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FaithfulnessMetric&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result is that engineers can focus on &lt;strong&gt;defining what good behavior looks like for their application&lt;/strong&gt; rather than building evaluation logic from first principles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building Metrics on Top of These Approaches
&lt;/h3&gt;

&lt;p&gt;This is an important shift. In traditional software, we primarily wrote assertions against &lt;strong&gt;outputs&lt;/strong&gt;. In agent systems, we increasingly write assertions against &lt;strong&gt;behaviours&lt;/strong&gt;, and those behaviours are often quantified through metrics rather than exact expected values.&lt;/p&gt;




&lt;h2&gt;
  
  
  Traditional Testing Layers Still Matter
&lt;/h2&gt;

&lt;p&gt;Most traditional testing techniques remain just as important. The difference is that they now validate different parts of the system. An agent is still built on top of code, APIs, databases, configuration, authentication systems, and external dependencies. These deterministic components should continue to be tested using the same techniques that have worked for decades.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit tests&lt;/strong&gt; validate building blocks like API clients, parsers, and retry logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration tests&lt;/strong&gt; verify tool contracts and connections to databases or vector stores.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functional/E2E tests&lt;/strong&gt; validate outcomes, ensuring the agent achieves goal Z given input X and environment Y.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chaos and Performance tests&lt;/strong&gt; ensure the system remains performant and recovers gracefully from tool outages or timeouts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional testing therefore does not disappear in agent systems. It continues to provide confidence in the deterministic layers of the stack.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing Methodologies for AI Agents
&lt;/h2&gt;

&lt;p&gt;Understanding what to measure is only half the problem. The next challenge is designing tests that produce meaningful and repeatable signals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define the Test Unit
&lt;/h3&gt;

&lt;p&gt;The first step is deciding what a test actually represents. For agents, a test is usually centered around a &lt;strong&gt;scenario or behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A typical test contains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;strong&gt;scenario definition&lt;/strong&gt; describing the behavior being evaluated&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;input prompt&lt;/strong&gt; that triggers the scenario&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;controlled environment&lt;/strong&gt; consisting of tool responses, configuration, and datasets&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;set of assertions&lt;/strong&gt; used to evaluate the outcome&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Control the Environment
&lt;/h3&gt;

&lt;p&gt;One of the easiest ways to create flaky agent tests is to allow the environment to change between runs.&lt;/p&gt;

&lt;p&gt;Tool responses, configuration state, datasets, and external dependencies should be controlled wherever possible. This is no different from traditional testing, but &lt;strong&gt;becomes even more important because the LLM itself already introduces variability&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Without environmental control, it becomes difficult to determine whether a failure was caused by the agent or by a changing dependency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hard vs Soft Assertions
&lt;/h3&gt;

&lt;p&gt;Some behaviours are &lt;strong&gt;non-negotiable&lt;/strong&gt; and should fail immediately when violated. Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invalid schemas&lt;/li&gt;
&lt;li&gt;Incorrect computed values&lt;/li&gt;
&lt;li&gt;Required tool usage&lt;/li&gt;
&lt;li&gt;Missing mandatory fields&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;hard assertions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Other behaviours are &lt;strong&gt;inherently subjective&lt;/strong&gt; and are often better represented as scores or thresholds. Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Completeness&lt;/li&gt;
&lt;li&gt;Clarity&lt;/li&gt;
&lt;li&gt;Tone&lt;/li&gt;
&lt;li&gt;Faithfulness&lt;/li&gt;
&lt;li&gt;Trajectory quality&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are &lt;strong&gt;soft assertions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In practice, &lt;strong&gt;most agent tests combine both&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Account for Variability
&lt;/h3&gt;

&lt;p&gt;Because agent behavior is probabilistic, a &lt;strong&gt;single test execution is rarely sufficient&lt;/strong&gt;. Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Did the test pass?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We must ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How consistently does the agent pass?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Reliability is measured through success rates across multiple runs&lt;/strong&gt; rather than binary outcomes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Capabilities Across Agent Testing Frameworks
&lt;/h2&gt;

&lt;p&gt;After exploring several agent evaluation frameworks, I found that most of them converge on a similar set of capabilities.&lt;/p&gt;

&lt;p&gt;Whether you're looking at &lt;strong&gt;DeepEval&lt;/strong&gt;, &lt;strong&gt;RAGAS&lt;/strong&gt;, &lt;strong&gt;LangSmith&lt;/strong&gt;, &lt;strong&gt;Arize&lt;/strong&gt; or other emerging tools, the implementation details vary but the core ideas remain largely the same.&lt;/p&gt;

&lt;p&gt;Most frameworks focus on &lt;strong&gt;three major areas&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Capturing and understanding agent behavior&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evaluating that behavior using reusable metrics&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Persisting and re-running evaluations over time&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Tracing and Observability
&lt;/h3&gt;

&lt;p&gt;Most modern frameworks provide some form of &lt;strong&gt;tracing or instrumentation&lt;/strong&gt;. This enables understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The sequence of tool calls&lt;/li&gt;
&lt;li&gt;Retrieved documents&lt;/li&gt;
&lt;li&gt;Intermediate decisions&lt;/li&gt;
&lt;li&gt;Model interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These captured data points provide the &lt;strong&gt;raw signals&lt;/strong&gt; from which many evaluation metrics are derived.&lt;/p&gt;

&lt;p&gt;For example, DeepEval allows developers to instrument portions of an application and collect execution traces that can later be inspected or evaluated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;deepeval.tracing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;observe&lt;/span&gt;

&lt;span class="nd"&gt;@observe&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Metrics and Assertions
&lt;/h3&gt;

&lt;p&gt;Once behavior can be observed, the next challenge is evaluating it.&lt;/p&gt;

&lt;p&gt;Most frameworks provide a &lt;strong&gt;collection of reusable metrics&lt;/strong&gt; that abstract away the complexity of evaluation. Instead of building custom scoring logic for every use case, teams can &lt;strong&gt;compose existing metrics into test assertions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A typical evaluation for DeepEval, for example, may look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;deepeval.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FaithfulnessMetric&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;deepeval.test_case&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMTestCase&lt;/span&gt;

&lt;span class="n"&gt;metric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FaithfulnessMetric&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;test_case&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LLMTestCase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is Kubernetes?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;actual_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;retrieval_context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;test_case&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;metric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important idea here is not the specific metric itself, but the &lt;strong&gt;abstraction&lt;/strong&gt;. Engineers are no longer writing assertions directly against outputs. They are increasingly &lt;strong&gt;writing assertions against behavioural qualities&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Datasets and Regression Testing
&lt;/h3&gt;

&lt;p&gt;The final pillar is &lt;strong&gt;persistence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once tests have been defined, they need to be &lt;strong&gt;stored, versioned, and re-executed&lt;/strong&gt; as systems evolve.&lt;/p&gt;

&lt;p&gt;Prompt changes, model upgrades, workflow modifications, tool additions, and retrieval improvements can all introduce unexpected regressions. Without a persistent evaluation suite, it becomes difficult to determine whether changes are improving the system or silently degrading it.&lt;/p&gt;

&lt;p&gt;A test case becomes a &lt;strong&gt;reusable artifact&lt;/strong&gt; containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inputs&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Expected behavior&lt;/li&gt;
&lt;li&gt;Evaluation criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once persisted, these datasets become &lt;strong&gt;regression suites&lt;/strong&gt; that can be executed repeatedly throughout development and deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Observability and Self-Learning is the Next Frontier
&lt;/h2&gt;

&lt;p&gt;As I worked through these ideas, one thing became increasingly clear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even with comprehensive evaluation datasets, no test suite can realistically capture every scenario an autonomous agent will encounter in the real world.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is why modern evaluation frameworks place so much emphasis on &lt;strong&gt;tracing and metrics&lt;/strong&gt;. The &lt;strong&gt;same signals used to evaluate agents during testing can also be used to understand how they behave in production&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What I find particularly interesting is that these capabilities are &lt;strong&gt;not just useful for testing&lt;/strong&gt;. They are &lt;strong&gt;foundational building blocks for systems that can learn from their own behavior&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's a topic I'll explore in future articles, but it starts with a simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before a system can learn from its behavior, we first need to be able to measure it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Traditional software testing breaks down with LLM-driven agents due to probabilistic behavior&lt;/li&gt;
&lt;li&gt;Agent evaluation requires measuring across 6+ dimensions (outcome, operational, reliability, quality, governance, behavioral)&lt;/li&gt;
&lt;li&gt;Three primary measurement approaches: mathematical metrics, specialized models, and LLM-as-a-Judge&lt;/li&gt;
&lt;li&gt;Traditional testing remains critical for deterministic system layers&lt;/li&gt;
&lt;li&gt;Modern frameworks converge on tracing, metrics, and persistent test datasets&lt;/li&gt;
&lt;li&gt;The future lies in observability-driven development where testing metrics inform production behavior&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://susheemk.substack.com/p/from-validating-code-to-evaluating" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;The promise of AI agents is flexibility. They can solve problems we never anticipated. The challenge is control. Traditional testing can't capture every scenario an agent will encounter. That's why modern evaluation frameworks are moving toward observability: continuous measurement of agent behavior across outcome, reliability, cost, and safety dimensions.&lt;/p&gt;

&lt;p&gt;We're building &lt;a href="https://theagentplane.github.io" rel="noopener noreferrer"&gt;Agentplane&lt;/a&gt; to provide the infrastructure layer for this shift. &lt;a href="https://github.com/theagentplane/tokenops" rel="noopener noreferrer"&gt;TokenOps&lt;/a&gt; is our FinOps control plane that enforces token budgets and governance policies across agent delegation trees, giving you real-time cost attribution and risk enforcement. &lt;a href="https://github.com/theagentplane/chronicle" rel="noopener noreferrer"&gt;Chronicle&lt;/a&gt; captures execution traces and behavioral signals from every agent run, turning observability data into actionable insights for improvement and compliance.&lt;/p&gt;

&lt;p&gt;Together, they close the gap between testing and production: measure your agents during development, enforce policies at runtime, and learn from real-world behavior.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>agents</category>
      <category>software</category>
    </item>
    <item>
      <title>How coding agents like Cursor quietly cut input costs by reusing KV states across turns — and what actually breaks the cache</title>
      <dc:creator>Susheem Koul</dc:creator>
      <pubDate>Thu, 30 Jul 2026 19:11:26 +0000</pubDate>
      <link>https://dev.to/susheem-k/how-coding-agents-like-cursor-quietly-cut-input-costs-by-reusing-kv-states-across-turns-and-what-49fe</link>
      <guid>https://dev.to/susheem-k/how-coding-agents-like-cursor-quietly-cut-input-costs-by-reusing-kv-states-across-turns-and-what-49fe</guid>
      <description>&lt;h2&gt;
  
  
  Why my Cursor bill looked weird
&lt;/h2&gt;

&lt;p&gt;I was poking around my usage dashboard in Cursor and noticed a metric I'd never paid attention to before: &lt;strong&gt;Cache Read&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Date            Type       Model    Tokens
May 2, 06:50 PM  Included   auto     898K   → Cache Read
May 2, 06:49 PM  Included   auto     1.4M   → Cache Write
May 2, 06:47 PM  Included   auto     346.8K → Input / Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Almost 99% of my input tokens for that session were served from cache. That sent me down a rabbit hole on what prompt caching actually &lt;em&gt;is&lt;/em&gt;, and why it matters so much for agentic coding tools specifically. Here's what I found.&lt;/p&gt;

&lt;h2&gt;
  
  
  What prompt caching actually is
&lt;/h2&gt;

&lt;p&gt;Agentic coding tools ship a &lt;em&gt;lot&lt;/em&gt; of context on every single call — system instructions, workspace rules, file contents, conversation history, the works. LLMs are stateless by default, so naively, all of that gets reprocessed from scratch on every request.&lt;/p&gt;

&lt;p&gt;Prompt caching short-circuits this. It saves the intermediate computation from the transformer's prefill stage — specifically the Key/Value states — so that when a later request shares the same leading sequence of tokens, the model reuses those states instead of recomputing them.&lt;/p&gt;

&lt;p&gt;One important caveat: &lt;strong&gt;this only applies to input tokens.&lt;/strong&gt; Output generation is still sequential, token-by-token, and gets no speedup from caching.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the payload is actually built
&lt;/h2&gt;

&lt;p&gt;Coding agents don't just fire your question at the model. They assemble a large composite prompt, and — critically — they structure it with the most static content first and the most volatile content last:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;system_instructions&amp;gt;&lt;/span&gt; You are an expert coding assistant... &lt;span class="nt"&gt;&amp;lt;/system_instructions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;project_rules&amp;gt;&lt;/span&gt; Use functional React components... &lt;span class="nt"&gt;&amp;lt;/project_rules&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;file_context_1&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/file_context_1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;file_context_2&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/file_context_2&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;conversation_history&amp;gt;&lt;/span&gt; ... &lt;span class="nt"&gt;&amp;lt;/conversation_history&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;user_input&amp;gt;&lt;/span&gt; Refactor this function to handle edge cases. &lt;span class="nt"&gt;&amp;lt;/user_input&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once that sequence hits the model, the transformer tokenizes it and starts computing attention. For every token, it derives a Key (K) and a Value (V) — essentially a map of how that token relates to every other token before it. This is the expensive part: attention computation scales quadratically with sequence length, so a big context window (lots of files, long history) gets disproportionately costly to prefill.&lt;/p&gt;

&lt;p&gt;The model doesn't refer back to your raw text when generating a response — it refers to these computed KV matrices. That's the artifact caching actually preserves.&lt;/p&gt;

&lt;p&gt;Providers typically charge less for input tokens than output tokens, but agentic coding tools push such enormous input payloads that shaving cost off the input side is still very much worth doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn 1 vs. every turn after
&lt;/h2&gt;

&lt;p&gt;Here's the flow, roughly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn 1 (cold start):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the prompt: system instructions + project rules + file context + your first message.&lt;/li&gt;
&lt;li&gt;No cache exists yet → full prefill. The model computes KV states for &lt;em&gt;every&lt;/em&gt; token (the expensive O(n²) pass).&lt;/li&gt;
&lt;li&gt;Those KV states get written to cache storage.&lt;/li&gt;
&lt;li&gt;Generation proceeds normally.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Turn 2...N (warm):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the new prompt: same system instructions + same files + prior conversation + your new message.&lt;/li&gt;
&lt;li&gt;Check for a prefix cache hit against system + context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hit:&lt;/strong&gt; read the cached KV states for the unchanged prefix, and only compute &lt;em&gt;new&lt;/em&gt; KV states for the incremental conversation turn + your latest input.&lt;/li&gt;
&lt;li&gt;Concatenate cached + new KV states, then generate.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So instead of re-running the full O(n²) prefill on every message, only the marginal new tokens get freshly processed. That's the whole trick, and it's why long coding sessions don't get proportionally slower and more expensive turn after turn.&lt;/p&gt;

&lt;p&gt;Most major providers now do this optimization implicitly under the hood. Google's Vertex AI docs on &lt;a href="https://docs.cloud.google.com/vertex-ai/generativeai/docs/context-cache/context-cache-overview" rel="noopener noreferrer"&gt;context caching&lt;/a&gt; are a good primary-source reference if you want to see how one provider exposes this explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What breaks the cache
&lt;/h2&gt;

&lt;p&gt;Caching depends entirely on &lt;strong&gt;prefix stability&lt;/strong&gt;. The moment a token diverges from what's cached, everything downstream of that point has to be recomputed. In practice, here's what kills your hit rate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic injections&lt;/strong&gt; — a timestamp or other changing value stuffed near the top of the prompt invalidates the prefix on every single request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context reordering&lt;/strong&gt; — shuffling the order in which files or context blocks get loaded prevents prefix matching entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upstream file edits&lt;/strong&gt; — editing a file that sits early in the prompt structure invalidates the cache for that file &lt;em&gt;and everything that comes after it&lt;/em&gt; in the sequence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most systems rely on exact token-prefix matches, though some providers (Google's docs linked above, for instance) expose more explicit cache handles or partial-reuse mechanisms.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part that confused me: why appending doesn't break the cache
&lt;/h2&gt;

&lt;p&gt;This is the part that seemed contradictory at first. If attention connects every token to every other token, shouldn't adding a new message at the &lt;em&gt;end&lt;/em&gt; of the prompt ripple backward and change how the &lt;em&gt;earlier&lt;/em&gt; tokens (system instructions, file context) get attended to?&lt;/p&gt;

&lt;p&gt;It would — if the model attended in both directions. But modern generative LLMs are &lt;strong&gt;decoder-only&lt;/strong&gt; and use &lt;strong&gt;causal (masked) self-attention&lt;/strong&gt;: a token can only attend to tokens that came &lt;em&gt;before&lt;/em&gt; it, never after.&lt;/p&gt;

&lt;p&gt;That one architectural detail is what makes caching possible at all. We're not caching a fragile, bidirectional global attention matrix — we're caching the &lt;strong&gt;KV tensors of the prefix&lt;/strong&gt;. Those K and V states for the early context are computed once and never change, no matter what you append afterward. New tokens just generate their own Queries and attend against the already-cached Keys of everything before them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this goes next
&lt;/h2&gt;

&lt;p&gt;Prompt caching solves the "don't recompute what hasn't changed" problem. It doesn't solve the separate problem of &lt;em&gt;what to put in the context window in the first place&lt;/em&gt;. Instead of stuffing every file into the prompt and hoping for a cache hit, coding agents increasingly rely on retrieval — RAG-style embeddings over the codebase — to selectively pull in only the relevant slices of code.&lt;/p&gt;

&lt;p&gt;That's next on my list to dig into: how coding tools build queryable views of a codebase with embeddings, and what that does to the cost equation.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you want the deeper transformer-architecture background behind KV caching and attention, &lt;a href="https://www.3blue1brown.com" rel="noopener noreferrer"&gt;3Blue1Brown's "Large Language Models explained briefly"&lt;/a&gt; is a genuinely excellent, low-jargon primer.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on &lt;a href="https://susheemk.substack.com/p/prompt-caching-and-context-optimization" rel="noopener noreferrer"&gt;Susheem's Jottings&lt;/a&gt; — cross-posting here for the dev.to crowd.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
