<?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: lizer yang</title>
    <description>The latest articles on DEV Community by lizer yang (@lizer_yang_ea7d0520b1bb05).</description>
    <link>https://dev.to/lizer_yang_ea7d0520b1bb05</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%2F2452898%2Fe79de90a-d9ee-4cc7-b674-6620869d1801.png</url>
      <title>DEV Community: lizer yang</title>
      <link>https://dev.to/lizer_yang_ea7d0520b1bb05</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lizer_yang_ea7d0520b1bb05"/>
    <language>en</language>
    <item>
      <title>Build a Low-Cost AI Backend Architecture: Count, Cache, Meter</title>
      <dc:creator>lizer yang</dc:creator>
      <pubDate>Tue, 22 Sep 2026 09:39:12 +0000</pubDate>
      <link>https://dev.to/lizer_yang_ea7d0520b1bb05/build-a-low-cost-ai-backend-architecture-count-cache-meter-1o7m</link>
      <guid>https://dev.to/lizer_yang_ea7d0520b1bb05/build-a-low-cost-ai-backend-architecture-count-cache-meter-1o7m</guid>
      <description>&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; a low-cost AI backend is not a cheaper model list. It is four decisions taken in&lt;br&gt;
one order: price the call before you shop, with a cost series built from the route you actually&lt;br&gt;
used; cache and batch the work that repeats, because a repeated prompt prefix and an offline batch&lt;br&gt;
are the two cheapest tokens you will ever buy; route each call to the cheapest model that passes&lt;br&gt;
its own quality gate; and self-host only past a break-even computed from your own utilisation.&lt;br&gt;
Metering is the substrate underneath all three - and the guardrails that cap work get there first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Price the call, not the model.&lt;/strong&gt; A table of prices per million tokens cannot tell you what your
traffic costs. The mix of input to output, and the savings your own request path produced, can.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache and batch what repeats.&lt;/strong&gt; Providers bill a cache read at a fraction of fresh input, and
an asynchronous batch endpoint well below the interactive rate. Both prices reward moving work
off the interactive path.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route on cost per successful task.&lt;/strong&gt; A route that is cheap per token but fails and gets retried
costs more than the model you were avoiding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-host break-even is arithmetic, and utilisation decides the answer.&lt;/strong&gt; The same rented GPU
is a bargain at 40% utilisation and an expensive lesson at 4%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guardrails are the caps that arrive before the invoice.&lt;/strong&gt; An output limit, an iteration limit
and a monthly budget per team are cheaper than the incident they prevent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meter where you enforce.&lt;/strong&gt; A number you cannot read per call cannot be routed, cached or
defended later.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  A cheap LLM API is a price list; your bill is a series
&lt;/h2&gt;

&lt;p&gt;Every hunt for a cheap LLM API starts as a table of prices per million tokens, and that table&lt;br&gt;
answers a question nobody asked. Your bill is the sum, over calls, of input tokens at the route's&lt;br&gt;
input price plus output tokens at the route's output price, minus whatever your own request path&lt;br&gt;
avoided before anything was sent. Two of those terms belong to the model; two belong to your&lt;br&gt;
traffic and your pipeline. Until all four sit in one series, "cheap" is a headline rather than a&lt;br&gt;
measurement.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dashboard&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;reports&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;trend&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="mi"&gt;124&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="mi"&gt;127&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buildTokenCostSeries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildTokenCostSeries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;dailyTokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReportsTrendDataSlice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dailyTokens&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;costSavings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReportsTrendDataSlice&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;costSavings&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;dashboard&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;reports&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;trend&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;metrics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="mi"&gt;147&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="mi"&gt;163&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buildTokenCostSeries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;costSavings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;byDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compress&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compress&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;byDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;compress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;compress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;search&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;search&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;byDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()].&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Read the function as those four terms meeting on one axis. Token totals and savings are joined on&lt;br&gt;
the same date key, so a single chart shows spend and the savings that offset it. A date present in&lt;br&gt;
only one of the two inputs is still emitted, because a day with compression savings and no model&lt;br&gt;
spend is a real day. And the result comes back sorted, so no consumer has to sort it again.&lt;/p&gt;

&lt;p&gt;Three consequences an engineer can act on. Count with the encoder the model family actually uses -&lt;br&gt;
&lt;code&gt;tiktoken&lt;/code&gt; for OpenAI-family encodings - or the series and the invoice will disagree at the edges.&lt;br&gt;
Keep the price table versioned, because a per-token price quoted from one version does not&lt;br&gt;
reproduce under another, and a savings number without its price version is a claim rather than a&lt;br&gt;
measurement. And check your input-to-output ratio before you shop: chat and agent workloads are&lt;br&gt;
output-heavy, so a cheap-looking model whose output price matches the expensive one is not cheaper&lt;br&gt;
for you at all.&lt;/p&gt;
&lt;h2&gt;
  
  
  What an IBM RAG and agentic AI professional certificate leaves out
&lt;/h2&gt;

&lt;p&gt;An IBM RAG and agentic AI professional certificate track teaches the parts that demo well:&lt;br&gt;
chunking, embeddings, a vector store, an agent loop over tools. Nothing in the syllabus bills you&lt;br&gt;
for them, and the distance between a capstone notebook and a production backend is almost entirely&lt;br&gt;
a cost question. Four things change on the way. Every chunk is embedded once and re-embedded&lt;br&gt;
whenever the source document changes. A vector index carries a monthly bill and a memory ceiling.&lt;br&gt;
Retrieval adds tokens to every prompt it feeds. And each extra agent step re-reads a context that&lt;br&gt;
has grown since the previous step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;smartgate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buildTraceView&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;requestId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;traceKind&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;totalDurationMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total_duration_ms&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;totalTokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total_tokens&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;spanCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;num&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;span_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;spansRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;summaryRaw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trace summary is the bridge between the course and the invoice, and it carries the numbers a&lt;br&gt;
cost model needs with nothing decorative attached: total tokens and total duration for the run,&lt;br&gt;
span count for how many model calls the run took, the route that served it, and the agent platform&lt;br&gt;
that asked. Two habits follow from that shape. Record the route and the platform on the trace&lt;br&gt;
itself rather than only in configuration, so a change in spend can be traced back to a change in&lt;br&gt;
routing. And attribute cost per trace rather than per HTTP request: a single agent run can be a&lt;br&gt;
dozen billable calls, and a per-request average buries the run that costs forty times its&lt;br&gt;
neighbours.&lt;/p&gt;
&lt;h2&gt;
  
  
  LLM guardrails that cap spend, not just output
&lt;/h2&gt;

&lt;p&gt;LLM guardrails are usually discussed as output policy - moderation, injection defence, PII&lt;br&gt;
filtering. The guardrails that decide your infrastructure bill are the ones that cap work before&lt;br&gt;
it is purchased, and every one of them is cheap to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A maximum output token count per request.&lt;/strong&gt; Output is the expensive half of almost every price
table, and it is the half a model chooses for itself when nobody caps it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A ceiling per request.&lt;/strong&gt; One pasted document should not be able to spend a team's day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An iteration cap on agent loops.&lt;/strong&gt; A loop with no ceiling is not an architecture, it is a
spend event with a status endpoint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A monthly budget per team, with headroom.&lt;/strong&gt; Refuse when the remainder crosses a threshold
rather than at zero, so the caller gets a warning instead of an outage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A retry budget.&lt;/strong&gt; Two retries of a 4,000-token prompt cost more than the model upgrade you
postponed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two asymmetries decide the implementation. The read that informs - how much is left - should fail&lt;br&gt;
open, so a monitoring outage never takes serving down with it. The counter that enforces must have&lt;br&gt;
one writer, or you will eventually discover that the number you bill is the sum of three&lt;br&gt;
optimistic paths. And the quota belongs in the same store as the counter, so the figure on the&lt;br&gt;
dashboard and the figure the gate applies cannot drift apart. The per-plan mechanics - explicit&lt;br&gt;
limit, plan default, unlimited escape hatch - are in&lt;br&gt;
&lt;a href="https://smartgate.network/industry/how-to-enforce-token-quota-per-team" rel="noopener noreferrer"&gt;per-team token quotas&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  MCP prompts are cache keys: reuse the template, not the round trip
&lt;/h2&gt;

&lt;p&gt;MCP prompts are the protocol's reusable unit: a server publishes a template, a client lists what&lt;br&gt;
is available and pulls it, and the same text reaches many calls. Reuse is where cost is decided,&lt;br&gt;
because the part of a prompt that never changes is the part a provider can cache. Prompt caching&lt;br&gt;
prices a cache read at a fraction of fresh input - on the Claude API a cache write costs 1.25 times&lt;br&gt;
base input and a read about 0.1 times base, with a five-minute default TTL - which turns prompt&lt;br&gt;
layout into a budget decision: stable instructions first, variable data last, never interleaved. A&lt;br&gt;
single reordered word inside the cached prefix invalidates it and the next call pays full price for&lt;br&gt;
the whole prefix, which is a cost bug that looks like nothing in a diff.&lt;/p&gt;

&lt;p&gt;Reuse also needs a monthly reading to prove it paid off, and that reading has to come from counters&lt;br&gt;
you already trust rather than from a second pipeline written for the report.&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="c1"&gt;# dashboard-calibration/dashboard_calibration/verify_redis.py — source lines 22–41 (build_monthly_u_from_seed_stats)
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_monthly_u_from_seed_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed_stats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;monthly&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seed_stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;monthly_u&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;monthly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

    &lt;span class="n"&gt;by_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seed_stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;daily_u_by_date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;by_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;by_date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;day_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;by_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;month&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;day_key&lt;/span&gt;&lt;span class="p"&gt;)[:&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;

    &lt;span class="c1"&gt;# Legacy: entire window treated as current month only.
&lt;/span&gt;    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;seed_stats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;u_month_total&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;today&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%Y-%m&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function is the boring half of that reading, and the boring half is where the accounting bugs&lt;br&gt;
live. An explicit monthly map wins when one exists; otherwise day keys are grouped by their first&lt;br&gt;
seven characters, which is the &lt;code&gt;YYYY-MM&lt;/code&gt; prefix; and a legacy total is treated as the current&lt;br&gt;
month. Two invariants keep it honest: derive the month from the key prefix so a period rollover&lt;br&gt;
needs no cleanup job, and make the fold idempotent - re-running it must overwrite, never&lt;br&gt;
accumulate. The same discipline is what makes an avoided-token claim auditable: counts per call,&lt;br&gt;
aggregated by day, folded into the month your invoice already uses.&lt;br&gt;
&lt;a href="https://smartgate.network/industry/mcp-resources-prompts-sampling" rel="noopener noreferrer"&gt;MCP resources, prompts and sampling&lt;/a&gt; are the three&lt;br&gt;
server-side primitives a client can reach; only prompts repeat on a schedule.&lt;/p&gt;
&lt;h2&gt;
  
  
  What agentic RAG costs when the loop runs more than once
&lt;/h2&gt;

&lt;p&gt;Plain RAG spends a predictable amount per answer: one retrieval, one prompt, one generation.&lt;br&gt;
Agentic RAG hands the number of steps to the model, and the bill becomes a function of the loop.&lt;br&gt;
The arithmetic is short. Cost is the sum over steps of context tokens at that step times the input&lt;br&gt;
price, plus output tokens at that step times the output price. Because every appended observation&lt;br&gt;
grows the transcript, step n costs more than step one, and the total grows faster than the step&lt;br&gt;
count. The transcript is the multiplier, not the question.&lt;/p&gt;

&lt;p&gt;That shape decides which levers are worth pulling, and none of them is "pick a cheaper model".&lt;br&gt;
Retrieve once into a deduplicated context instead of retrieving before every step. Summarise the&lt;br&gt;
scratchpad instead of appending to it. Put the static instructions at the front where a cache can&lt;br&gt;
hold them. Give planning and routing to the smallest model that can make the decision, and reserve&lt;br&gt;
the largest for the final answer. Cap the iterations, because three passes that solve the task beat&lt;br&gt;
ten that also solve it. If you want the mechanics before you optimise them, start from&lt;br&gt;
&lt;a href="https://smartgate.network/industry/what-is-agentic-rag" rel="noopener noreferrer"&gt;what agentic RAG is&lt;/a&gt; and then count the steps your own traces show.&lt;/p&gt;
&lt;h2&gt;
  
  
  An agentic RAG survey read as a cost catalogue
&lt;/h2&gt;

&lt;p&gt;The agentic RAG survey literature reads as a catalogue of ways to spend more per answer. The&lt;br&gt;
reference taxonomy - &lt;a href="https://arxiv.org/abs/2501.09136" rel="noopener noreferrer"&gt;Agentic Retrieval-Augmented Generation: A Survey on Agentic&lt;br&gt;
RAG&lt;/a&gt; is the version the others cite - sorts the systems by how&lt;br&gt;
much autonomy they take: a single agent that plans and reflects, a router that chooses among&lt;br&gt;
retrievers, and multi-agent pipelines that delegate to specialists. Every axis buys accuracy with&lt;br&gt;
model calls, and the families differ mainly in how many. Read from the cost side, the useful&lt;br&gt;
question is not which pattern is best but which pattern's extra call saves more than it costs. A&lt;br&gt;
corrective pass that prevents a wrong answer the user would otherwise re-ask is worth its tokens;&lt;br&gt;
a second planner that restates the first planner's output is not.&lt;/p&gt;

&lt;p&gt;Three practices make that comparison possible on your own traffic. Put the pattern name on the&lt;br&gt;
trace, in the &lt;code&gt;agent_platform&lt;/code&gt; and &lt;code&gt;route&lt;/code&gt; fields above, so cost per resolved task can be compared&lt;br&gt;
between patterns instead of argued about. Send a canary share of traffic down the cheaper pattern&lt;br&gt;
and compare success rather than latency. And measure the whole answer, retries included, because a&lt;br&gt;
pattern's failure rate is part of its price. A survey maps the design space; only your traces say&lt;br&gt;
which corner of it you can afford.&lt;/p&gt;
&lt;h2&gt;
  
  
  MCP router and model router: route per call, not per team
&lt;/h2&gt;

&lt;p&gt;An MCP router and a model router sound like one product and are two decisions. An MCP router&lt;br&gt;
decides which server a tool call lands on. A model router decides which model answers a given&lt;br&gt;
prompt. Both are routing decisions, both are reversible, and both are only auditable if the choice&lt;br&gt;
is written down at the moment of the call - which is what this summary line is for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;smartgate&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;audit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="mi"&gt;72&lt;/span&gt;&lt;span class="err"&gt;–&lt;/span&gt;&lt;span class="mi"&gt;93&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buildSummary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;auditTool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;tokenUsed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`route=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;…`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`q=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokenUsed&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;tokenUsed&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tokenUsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt; tokens`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;auditTool&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;audit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; · &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The audit line above is that record: the route, a trimmed URL or query, the token count when one is&lt;br&gt;
known, and a failure marker. It is the minimum needed to answer the two questions routing creates -&lt;br&gt;
which route served the traffic, and which route produced the failures - and it is the per-call&lt;br&gt;
input to the cost series from the first section. Two rules keep routing honest. Route on cost per&lt;br&gt;
successful task rather than cost per token, because a model five times cheaper that fails a third&lt;br&gt;
of calls and gets retried is the more expensive one. And make the decision in the gateway, which is&lt;br&gt;
the only component that sees every call whatever client made it: an&lt;br&gt;
&lt;a href="https://smartgate.network/industry/mcp-gateway" rel="noopener noreferrer"&gt;MCP gateway&lt;/a&gt; is where one route table serves every host, and where a route&lt;br&gt;
your plan does not cover can be refused instead of billed.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP sampling: who pays for the tokens the server asks for
&lt;/h2&gt;

&lt;p&gt;MCP sampling inverts the direction of the call: instead of a client asking a server to do&lt;br&gt;
something, the server asks the client's model for a completion. Architecturally that is elegant - a&lt;br&gt;
server can use language reasoning without holding model credentials. Financially it hands the bill&lt;br&gt;
to someone else, because the tokens a sampled completion produces are paid by whoever owns the&lt;br&gt;
client's model. So the design question is not whether to allow sampling; it is which side of the&lt;br&gt;
boundary should own the spend.&lt;/p&gt;

&lt;p&gt;The same three habits bound the request from either side. Ask for the smallest completion that&lt;br&gt;
does the job, and set an explicit maximum token count on every sampling request so a retry loop&lt;br&gt;
cannot escalate the bill. Prefer deterministic local steps - parsing, filtering, arithmetic - over&lt;br&gt;
asking a model for something a function can decide. And log sampling calls next to the calls you&lt;br&gt;
started, so one trace tells the whole story. On the client or gateway side those habits mirror:&lt;br&gt;
cap tokens per sampling request, cap requests per server, and refuse rather than queue when a team&lt;br&gt;
is out of budget.&lt;/p&gt;

&lt;p&gt;When the same tokens can be billed to two parties, the meter stops being bookkeeping and becomes&lt;br&gt;
the contract. That is why skip reasons and idempotency keys belong in the charge path rather than&lt;br&gt;
in a report, the same discipline a queue-and-webhook billing chain needs -&lt;br&gt;
&lt;a href="https://smartgate.network/integration/ai-automation-for-saas-operations" rel="noopener noreferrer"&gt;AI Automation for SaaS Operations&lt;/a&gt; covers that&lt;br&gt;
half.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the money goes: four levers and what each one costs you
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lever&lt;/th&gt;
&lt;th&gt;What it changes&lt;/th&gt;
&lt;th&gt;What you give up&lt;/th&gt;
&lt;th&gt;When it breaks even&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompt and prefix caching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;bills the repeated part of a prompt at a fraction of the fresh-input price&lt;/td&gt;
&lt;td&gt;prompt layout discipline; any edit inside the cached prefix invalidates it&lt;/td&gt;
&lt;td&gt;the second call that repeats a prefix, which for an assistant with a system prompt is usually the first afternoon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Batching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;an asynchronous batch endpoint prices work well below the interactive rate&lt;/td&gt;
&lt;td&gt;turnaround measured in hours rather than seconds&lt;/td&gt;
&lt;td&gt;any job nobody is waiting for: embeddings, backfills, evaluations, nightly summaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model routing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;output tokens land on the cheapest route that clears a quality gate&lt;/td&gt;
&lt;td&gt;an evaluation harness, a fallback chain and a canary share of traffic&lt;/td&gt;
&lt;td&gt;when the cheaper route passes your own evals; a route that fails a third of calls is not cheaper&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-hosting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;a fixed hourly cost for a GPU replaces a price per token&lt;/td&gt;
&lt;td&gt;operations, upgrades, idle capacity&lt;/td&gt;
&lt;td&gt;only above the break-even rate computed from your own utilisation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Self-host break-even is arithmetic, and utilisation is what the arithmetic is unforgiving about.&lt;br&gt;
Assume a rented GPU at $2 per hour, a server that sustains 1,200 output tokens per second, and 40%&lt;br&gt;
utilisation: it produces 1,200 x 3,600 x 0.4 = 1.728M output tokens per hour, so those two dollars&lt;br&gt;
buy 1.728M output tokens - about $1.16 per million output tokens, before operations and on-call&lt;br&gt;
enter the picture. If your routed API price for comparable quality sits below that figure,&lt;br&gt;
self-hosting is a hobby. Push utilisation to the other extreme, 4% on an idle box waiting for a&lt;br&gt;
nightly job, and the same formula returns $11.60 per million: the version of the calculation most&lt;br&gt;
teams meet after the hardware arrives. Compare per output token, because output is the half of the&lt;br&gt;
bill that scales with generation and the half a self-hosted server actually produces - and treat&lt;br&gt;
the result as a floor, since it prices the GPU and not the model upgrade, the outage or the&lt;br&gt;
engineer who keeps it running.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Record the route and the token count on every call.&lt;/strong&gt; One audit line per call carrying the
route that served it, the token count when one is known, and a failure marker. A week of that
data beats any benchmark you can download.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build the cost series before changing any model.&lt;/strong&gt; Spend and savings on one date axis, split
by route, so "cheap" becomes a comparison you can read rather than a claim you can argue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache the stable part of every prompt, and batch what can wait.&lt;/strong&gt; Stable prefix first,
variable tail last; embedding backfills, evaluations and summaries belong on the asynchronous
endpoint rather than inside a user's request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route per call behind a quality gate.&lt;/strong&gt; Cheapest route that passes, one defined fallback, and
a canary share kept on the old route until the new one proves itself on success rate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cap before you optimise.&lt;/strong&gt; A maximum output count per request, an iteration limit on loops,
and a monthly budget per team with enough headroom to warn before it refuses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Then run the break-even with your own numbers.&lt;/strong&gt; Your utilisation, your route prices, your
quality bar - &lt;a href="https://smartgate.network/integration/optimize-ai-agent-execution-cost" rel="noopener noreferrer"&gt;Optimize AI Agent Execution Cost&lt;/a&gt;
is the attribution discipline this rests on, and the
&lt;a href="https://smartgate.network/docs" rel="noopener noreferrer"&gt;gateway primitives documentation&lt;/a&gt; lists the count, cap and meter primitives that make
steps three to five configuration rather than a project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The free tier exposes the count, the cap and the meter as gateway primitives (2M tokens a month,&lt;br&gt;
the &lt;code&gt;smart_*&lt;/code&gt; tool surface including &lt;code&gt;smart_budget_guard&lt;/code&gt;, no card): &lt;strong&gt;&lt;a href="https://smartgate.network/login?from=/dashboard" rel="noopener noreferrer"&gt;start&lt;br&gt;
free&lt;/a&gt;&lt;/strong&gt;. The &lt;strong&gt;&lt;a href="https://smartgate.network/pricing" rel="noopener noreferrer"&gt;pricing&lt;br&gt;
page&lt;/a&gt;&lt;/strong&gt; and the versioned table behind it are what the series&lt;br&gt;
above should be reconciled against, and &lt;strong&gt;&lt;a href="https://smartgate.network/contact" rel="noopener noreferrer"&gt;talk to sales&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
covers contract token pools and HMAC-based team budgets on Enterprise.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Is a cheap LLM API just the one with the lowest price per token?&lt;/strong&gt;&lt;br&gt;
No, because your bill is a mix. Output tokens usually dominate a chat or agent workload, so the&lt;br&gt;
model with the lowest input price can be the expensive one. The comparison that settles it is your&lt;br&gt;
own series: cost per day split by route, with the savings your pipeline produced counted against&lt;br&gt;
it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does prompt caching matter if my prompts change on every call?&lt;/strong&gt;&lt;br&gt;
The stable part of a prompt is usually bigger than people assume: system instructions, tool&lt;br&gt;
definitions, retrieved policy text, few-shot examples. Cache those and keep the variable tail last.&lt;br&gt;
A cache read is priced at a fraction of fresh input, and the TTL is short - five minutes on the&lt;br&gt;
Claude API - so the win lands on traffic that repeats inside the window, not on traffic that is&lt;br&gt;
unique.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I compute self-host break-even?&lt;/strong&gt;&lt;br&gt;
Divide the hourly cost of the server by the output tokens it serves in an hour: hourly cost divided&lt;br&gt;
by (tokens per second x 3,600 x utilisation) is cost per token, and multiplying by a million gives&lt;br&gt;
the figure you can compare with an API price. Then subtract operations and see whether the routed&lt;br&gt;
price is above or below it. Utilisation, not capability, is the number that decides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where does money leak in an agentic RAG pipeline?&lt;/strong&gt;&lt;br&gt;
Three places, in order of size: loop iterations that re-read a growing transcript, retrieval that&lt;br&gt;
adds context to every step instead of once, and re-embedding documents that did not change. All&lt;br&gt;
three are visible in a trace that carries span count and token count, and none of them is visible&lt;br&gt;
in a per-request average.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is batching always worth the discount?&lt;/strong&gt;&lt;br&gt;
Only for work nobody is waiting for. Asynchronous batch endpoints are priced well below the&lt;br&gt;
interactive rate and return results on a turnaround measured in hours, so embeddings, backfills,&lt;br&gt;
evaluations and nightly summaries fit; an interactive chat turn does not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What should I meter first if I only have a week?&lt;/strong&gt;&lt;br&gt;
Route and token count per call. Those two fields make every other decision measurable - which model&lt;br&gt;
actually served the traffic, what a resolved task costs, and whether the cheaper route is still&lt;br&gt;
cheaper after retries. Everything else in this article is arithmetic on top of that pair.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations and what this does not do
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;This is a cost architecture, not an optimiser.&lt;/strong&gt; Nothing here compresses a prompt or picks a
model for you; it makes those decisions measurable and reversible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching depends on a prefix that stays identical.&lt;/strong&gt; Any edit inside the cached region - a
reordered sentence, a timestamp, a per-user name - turns a cache read back into a full-price
write, silently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch discounts trade turnaround for price.&lt;/strong&gt; A job with a deadline belongs on the interactive
endpoint, whatever the discount says.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing needs an evaluation harness.&lt;/strong&gt; Without one, "cheap" is a guess that fails in production
rather than in a spreadsheet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break-even arithmetic is a floor, not a decision.&lt;/strong&gt; It prices the GPU and ignores operations,
model upgrades, on-call, and the cost of running three model generations behind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The lever you cannot meter is the one that keeps surprising you.&lt;/strong&gt; A per-call record is what
separates cost engineering from a monthly argument; reconstructing the numbers later from logs
is the reporting-only variant of the same discipline, which is where a
&lt;a href="https://smartgate.network/solutions/finops-lead" rel="noopener noreferrer"&gt;FinOps&lt;/a&gt; practice starts rather than ends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prices move.&lt;/strong&gt; Every figure here is mechanics rather than a quote: a number is only
reproducible next to the version of the price table that produced it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;tiktoken - the tokeniser used by OpenAI-family models: &lt;a href="https://github.com/openai/tiktoken" rel="noopener noreferrer"&gt;https://github.com/openai/tiktoken&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Anthropic - prompt caching, cache write and read pricing, default TTL: &lt;a href="https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching" rel="noopener noreferrer"&gt;https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI - the Batch API and its discount against the interactive endpoints: &lt;a href="https://developers.openai.com/api/docs/guides/batch" rel="noopener noreferrer"&gt;https://developers.openai.com/api/docs/guides/batch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Model Context Protocol - prompts, the reusable server-side template: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/server/prompts" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2026-07-28/server/prompts&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Model Context Protocol - sampling, where the server asks the client's model: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/client/sampling" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2026-07-28/client/sampling&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Model Context Protocol - tool definitions and descriptions: &lt;a href="https://modelcontextprotocol.io/specification/2026-07-28/server/tools" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2026-07-28/server/tools&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;arXiv - Agentic Retrieval-Augmented Generation: A Survey on Agentic RAG (2501.09136): &lt;a href="https://arxiv.org/abs/2501.09136" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2501.09136&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;IBM RAG and Agentic AI Professional Certificate (Coursera): &lt;a href="https://www.coursera.org/professional-certificates/ibm-rag-and-agentic-ai" rel="noopener noreferrer"&gt;https://www.coursera.org/professional-certificates/ibm-rag-and-agentic-ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Redis - INCRBY, the atomic counter primitive: &lt;a href="https://redis.io/docs/latest/commands/incrby/" rel="noopener noreferrer"&gt;https://redis.io/docs/latest/commands/incrby/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Redis - EXPIRE, used to keep counters self-cleaning: &lt;a href="https://redis.io/docs/latest/commands/expire/" rel="noopener noreferrer"&gt;https://redis.io/docs/latest/commands/expire/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;vLLM - continuous batching and serving throughput for self-hosted models: &lt;a href="https://docs.vllm.ai/en/latest" rel="noopener noreferrer"&gt;https://docs.vllm.ai/en/latest&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SmartGate - documentation, pricing and sales contact: &lt;a href="https://smartgate.network/docs" rel="noopener noreferrer"&gt;https://smartgate.network/docs&lt;/a&gt; · &lt;a href="https://smartgate.network/pricing" rel="noopener noreferrer"&gt;https://smartgate.network/pricing&lt;/a&gt; · &lt;a href="https://smartgate.network/contact" rel="noopener noreferrer"&gt;https://smartgate.network/contact&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Method note
&lt;/h2&gt;

&lt;p&gt;The prose was rewritten against a fresh measured keyword plan for this page: eight sections, every&lt;br&gt;
one of them drawn from the project's own demand evidence rather than from a code symbol. Four&lt;br&gt;
sections quote a code block; the other four are written from external sources, because the symbol&lt;br&gt;
matcher's verdict for those sections was abstain or no-slice - the honest outcome of a whole-name&lt;br&gt;
rule, and the reason no code sits under them. Every fenced block was cut directly out of the slice&lt;br&gt;
body returned by the SmartGate slice API and re-asserted byte-for-byte as a substring of that body&lt;br&gt;
before publication; the first line inside each fence records the file and the exact source lines.&lt;br&gt;
Two of the four blocks are quoted as line windows rather than whole bodies, and the provenance&lt;br&gt;
table below records every range.&lt;/p&gt;

&lt;h3&gt;
  
  
  Slice provenance
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;SERP keyword&lt;/th&gt;
&lt;th&gt;Symbol&lt;/th&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Source lines&lt;/th&gt;
&lt;th&gt;How it was pinned&lt;/th&gt;
&lt;th&gt;sha256(12)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;cheap llm api&lt;/td&gt;
&lt;td&gt;&lt;code&gt;buildTokenCostSeries&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lib/dashboard/reports-trend-metrics.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;124–127, 147–163&lt;/td&gt;
&lt;td&gt;rule A L2 → slot-proof&lt;/td&gt;
&lt;td&gt;&lt;code&gt;d265de9f668c&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;ibm rag and agentic ai professional certificate&lt;/td&gt;
&lt;td&gt;&lt;code&gt;buildTraceView&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lib/smartgate/trace.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;80–87&lt;/td&gt;
&lt;td&gt;rule A L2 → slot-proof&lt;/td&gt;
&lt;td&gt;&lt;code&gt;49028130dba9&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;mcp prompts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;build_monthly_u_from_seed_stats&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dashboard-calibration/dashboard_calibration/verify_redis.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;22–41&lt;/td&gt;
&lt;td&gt;rule A L2 → slot-proof&lt;/td&gt;
&lt;td&gt;&lt;code&gt;9b4fecef236f&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;mcp router&lt;/td&gt;
&lt;td&gt;&lt;code&gt;buildSummary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lib/smartgate/audit-logs.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;72–93&lt;/td&gt;
&lt;td&gt;rule A L2 → slot-proof&lt;/td&gt;
&lt;td&gt;&lt;code&gt;009eace0bd53&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every fenced block above was cut from the slice body and re-asserted against it byte-for-byte before&lt;br&gt;
publication. 4 of 8 sections pinned, 1 abstentions, 3 misses.&lt;/p&gt;

</description>
      <category>cheap</category>
      <category>ibm</category>
      <category>llm</category>
      <category>mcp</category>
    </item>
  </channel>
</rss>
