<?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: Lynkr</title>
    <description>The latest articles on DEV Community by Lynkr (@lynkr).</description>
    <link>https://dev.to/lynkr</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%2F3645387%2F794ced23-25c9-41ed-863a-401839a48d59.png</url>
      <title>DEV Community: Lynkr</title>
      <link>https://dev.to/lynkr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lynkr"/>
    <language>en</language>
    <item>
      <title>The 5% Router Tax: What Hosted LLM Gateways Charge For (and How to Self-Host It)</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Sun, 05 Jul 2026 08:48:56 +0000</pubDate>
      <link>https://dev.to/lynkr/the-5-router-tax-what-hosted-llm-gateways-charge-for-and-how-to-self-host-it-513</link>
      <guid>https://dev.to/lynkr/the-5-router-tax-what-hosted-llm-gateways-charge-for-and-how-to-self-host-it-513</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I maintain &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;, the self-hosted gateway discussed in the second half. OpenRouter and Requesty are good products — this post is about understanding what you're paying for so you can decide whether you need to.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Hosted LLM routers had a huge 2026 — OpenRouter alone pushes 25 trillion tokens a week. The pitch is real: one API key, 400+ models, automatic failover. The price is a &lt;strong&gt;~5% fee on every token you route&lt;/strong&gt; (5.5% on OpenRouter credits, 5% on Requesty), plus a subtler cost: every prompt, every file your coding agent reads, every secret that leaks into a context window transits their infrastructure.&lt;/p&gt;

&lt;p&gt;For a hobby project, 5% of a small bill is nothing and the convenience wins. For an agentic coding workload — where teams routinely spend $500–$2,000 per engineer per month — 5% is real money, and the data-transit question stops being academic. So it's worth asking precisely: &lt;strong&gt;what does the hosted router actually do for that fee, and which parts can you self-host?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the fee buys
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unified API across providers&lt;/strong&gt; — one format in, translated per-provider out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failover&lt;/strong&gt; — a provider 500s, your request retries elsewhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model marketplace&lt;/strong&gt; — new models available the day they launch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consolidated billing&lt;/strong&gt; — one invoice instead of six provider accounts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;(Sometimes) smart routing&lt;/strong&gt; — OpenRouter's &lt;code&gt;auto&lt;/code&gt; router picks a model per-request.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Items 1, 2, and 5 are software. Items 3 and 4 are genuinely hard to self-host — if you want day-one access to every new model with zero account setup, the marketplace earns its fee. But most coding workloads use a handful of models, not four hundred.&lt;/p&gt;

&lt;h2&gt;
  
  
  The parts a hosted router structurally can't give you
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local models as a tier.&lt;/strong&gt; No hosted router will route your easy requests to the Ollama instance on your own machine — free, private, zero latency to first byte on cached weights. For coding traffic, where (in my instrumented sessions) 70–90% of requests are simple enough for a good local model, this is the single biggest cost lever, and it's only available to something running on your side of the wire.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your data staying home.&lt;/strong&gt; Self-hosted means prompts, code, and keys never transit a third party. For anyone with a compliance requirement — or code they'd rather not ship to a router's logs — this isn't a preference, it's a prerequisite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token optimization before the bill.&lt;/strong&gt; A hosted router bills you for the tokens you send it — it has no incentive to shrink them. A self-hosted proxy can strip unusable tool schemas (measured: −53% on tool-heavy requests) and compress JSON tool results (measured: 3,458 → 427 tokens on a grep result) &lt;em&gt;before&lt;/em&gt; any provider bills you. That's not a routing saving; it stacks on top of routing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No availability dependency.&lt;/strong&gt; Hosted routers go down (OpenRouter's outages have their own HN threads) and offer no SLA at consumer tiers. A local proxy fails independently of anyone's status page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What self-hosting costs you
&lt;/h2&gt;

&lt;p&gt;Honesty cuts both ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You run a process.&lt;/strong&gt; &lt;code&gt;npm install -g lynkr &amp;amp;&amp;amp; lynkr init &amp;amp;&amp;amp; lynkr start&lt;/code&gt; — but it's yours now: updates, logs, the works.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You manage provider accounts.&lt;/strong&gt; Two or three API keys instead of one. The consolidated invoice is genuinely gone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model lag.&lt;/strong&gt; A new provider means waiting for support (or a PR) instead of it appearing in a dropdown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nobody to email.&lt;/strong&gt; Self-hosted support is a GitHub issue tracker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those trade-offs read as "fine," the math is straightforward: the 5% fee disappears, the local-tier routing removes the easy majority of requests from your bill entirely, and compression shrinks what's left.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hybrid that actually makes sense
&lt;/h2&gt;

&lt;p&gt;This isn't either/or. A pattern I see working:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Coding tool → self-hosted proxy (Lynkr)
                ├─ SIMPLE/MEDIUM  → local Ollama/llama.cpp   (free)
                ├─ COMPLEX        → direct provider API keys  (no fee)
                └─ exotic models  → OpenRouter               (5% on the long tail only)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep a hosted router as &lt;em&gt;one backend&lt;/em&gt; for the long tail of models you rarely need, route the bulk directly or locally, and let the proxy's classifier decide per-request. You get the marketplace when you want it without paying the tax on your entire volume.&lt;/p&gt;

&lt;p&gt;Lynkr is Apache-2.0, self-hosted, supports 13 providers including Ollama, llama.cpp, LM Studio, Bedrock, Azure, Databricks — and OpenRouter itself as a tier: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;github.com/Fast-Editor/Lynkr&lt;/a&gt;. Benchmarks with methodology are in the repo; run them on your own workload before believing anyone's percentages, including mine.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>selfhosted</category>
      <category>llm</category>
    </item>
    <item>
      <title>How a 13-Dimension Complexity Scorer Decides Which Model Gets Your Request</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Sun, 05 Jul 2026 08:48:40 +0000</pubDate>
      <link>https://dev.to/lynkr/how-a-13-dimension-complexity-scorer-decides-which-model-gets-your-request-e95</link>
      <guid>https://dev.to/lynkr/how-a-13-dimension-complexity-scorer-decides-which-model-gets-your-request-e95</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I'm the author of &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;, the open-source proxy whose internals this post walks through. All code shown is real and Apache-2.0 — &lt;a href="https://github.com/Fast-Editor/Lynkr/blob/main/src/routing/complexity-analyzer.js" rel="noopener noreferrer"&gt;read it here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The most expensive default in AI coding tools is that &lt;strong&gt;model choice is a setting, not a decision&lt;/strong&gt;. You pick a model once; every request — "what does git stash do?" and "refactor this auth module" alike — goes there. Routing each request to the cheapest model that can actually handle it is worth 50%+ of most bills, but it only works if the "can actually handle it" judgment is reliable. Get it wrong downward and a small model fumbles your file edits; get it wrong upward and you've saved nothing.&lt;/p&gt;

&lt;p&gt;Here's how Lynkr makes that judgment, in enough detail that you could reimplement it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just count tokens?
&lt;/h2&gt;

&lt;p&gt;The obvious heuristics fail in both directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"Long request → big model"&lt;/strong&gt; fails on a 60k-token context that's mostly grep output around a trivial question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Short request → small model"&lt;/strong&gt; fails catastrophically on "fix the auth bug in session.js" — eight words that unleash a tool-heavy agentic session a 7B model will faceplant on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Token count is &lt;em&gt;one&lt;/em&gt; signal. The failure cases all come from treating it as the only one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture: weighted dimensions, then overrides
&lt;/h2&gt;

&lt;p&gt;Every request gets a 0–100 score from 13 dimensions in four groups. The weights are configurable; these are the defaults:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DIMENSION_WEIGHTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Content Analysis (35%)&lt;/span&gt;
  &lt;span class="na"&gt;tokenCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;promptComplexity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// avg sentence length/structure&lt;/span&gt;
  &lt;span class="na"&gt;technicalDepth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// technical keyword density&lt;/span&gt;
  &lt;span class="na"&gt;domainSpecificity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// security/ML/distributed/db/frontend/devops&lt;/span&gt;
  &lt;span class="c1"&gt;// Tool Analysis (25%)&lt;/span&gt;
  &lt;span class="na"&gt;toolCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;toolComplexity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// which tools, not how many&lt;/span&gt;
  &lt;span class="na"&gt;toolChainPotential&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// "first...then", "step 2", sequencing language&lt;/span&gt;
  &lt;span class="c1"&gt;// Reasoning Requirements (25%)&lt;/span&gt;
  &lt;span class="na"&gt;multiStepReasoning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;codeGeneration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;analysisDepth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.07&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// trade-off/comparison markers&lt;/span&gt;
  &lt;span class="c1"&gt;// Context Factors (15%)&lt;/span&gt;
  &lt;span class="na"&gt;conversationDepth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;priorToolUsage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// tool_results already in the conversation&lt;/span&gt;
  &lt;span class="na"&gt;ambiguity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.05&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;A few design decisions worth stealing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not all tools are equal.&lt;/strong&gt; A request that can &lt;code&gt;Grep&lt;/code&gt; is not like a request that can &lt;code&gt;Bash&lt;/code&gt;. Each tool carries a hand-tuned risk weight — &lt;code&gt;Bash&lt;/code&gt; 0.9, &lt;code&gt;Write&lt;/code&gt; 0.8, &lt;code&gt;Edit&lt;/code&gt; 0.7, down to &lt;code&gt;Grep&lt;/code&gt; at 0.2. A request whose available toolset averages 0.8 is an agentic mutation session; one averaging 0.25 is read-only research. Same tool &lt;em&gt;count&lt;/em&gt;, completely different stakes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subtract the harness baseline.&lt;/strong&gt; Claude Code ships ~14 tool schemas with &lt;em&gt;every&lt;/em&gt; request, including "hello". If you count them naively, everything looks agentic and nothing routes local. The scorer subtracts the client's constant baseline and scores only the &lt;em&gt;effective&lt;/em&gt; tools the request could plausibly use — one of those fixes that sounds trivial and changed everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conversation history is a signal.&lt;/strong&gt; Three &lt;code&gt;tool_result&lt;/code&gt; blocks already in the conversation means you're mid-agentic-flow — this is not the moment to downgrade models and break the session's momentum. &lt;code&gt;priorToolUsage&lt;/code&gt; and &lt;code&gt;conversationDepth&lt;/code&gt; push mid-session requests up-tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ambiguity cuts the other way.&lt;/strong&gt; "file X, line 42, this error" is specific — a small model can act on it. "Something feels slow sometimes" needs interpretation before action. Specificity markers (paths, line numbers, error strings) &lt;em&gt;lower&lt;/em&gt; the score.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overrides: the classifier knows what it can't know
&lt;/h2&gt;

&lt;p&gt;Two pattern lists short-circuit the whole scoring pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Force-local:&lt;/strong&gt; greetings, acknowledgments, "what does X do" one-liners. Score 0, never leave the machine, no cloud tokens ever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Force-cloud:&lt;/strong&gt; security-critical analysis, architecture decisions, anything matching high-risk patterns. Straight to the top tier regardless of how cheap it looks. A JWT-vs-cookies security question is short and toolless — every naive heuristic routes it local. This is the wrong request to save $0.004 on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of the regex dimensions, an AST pass (tree-sitter) scores actual code structure in the payload — cyclomatic signals beat keyword counting when real code is present.&lt;/p&gt;

&lt;h2&gt;
  
  
  From score to model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;score &amp;lt; threshold        → SIMPLE   (e.g. ollama:qwen2.5:7b, free)
threshold..~65           → MEDIUM   (e.g. ollama:qwen2.5-coder, free)
above                    → COMPLEX  (your API key: Sonnet, GPT-4o...)
reasoning markers heavy  → REASONING (o3, DeepSeek R1...)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The threshold moves with a single mode switch — &lt;code&gt;aggressive&lt;/code&gt; (60) routes more local, &lt;code&gt;conservative&lt;/code&gt; (25) routes more to the cloud, default is 40. Multi-turn conversations score with a recency-weighted sliding window, so a short follow-up ("now add tests") inherits the complexity of the work it refers to instead of scoring as a trivial one-liner.&lt;/p&gt;

&lt;p&gt;Crucially, &lt;strong&gt;the classifier only chooses among models you listed&lt;/strong&gt;. It's not an autonomous agent picking providers — you define the tiers, it picks the tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does it work?
&lt;/h2&gt;

&lt;p&gt;In my instrumented sessions, 70–90% of requests score SIMPLE or MEDIUM and run free on local models, while tool-heavy and security-flagged requests reliably escalate. The failure mode everyone fears — cheap model breaking an agentic session — is exactly what the tool weights, baseline subtraction, and prior-tool-usage dimensions exist to prevent.&lt;/p&gt;

&lt;p&gt;Is 13 hand-weighted dimensions the optimal design? Almost certainly not — a learned router trained on outcome data would beat it eventually. But it's transparent (every routing decision logs its per-dimension breakdown), it's tunable, it runs in-process in microseconds, and it never sends your prompts to a third-party classifier API.&lt;/p&gt;

&lt;p&gt;The whole thing is readable in one sitting: &lt;a href="https://github.com/Fast-Editor/Lynkr/blob/main/src/routing/complexity-analyzer.js" rel="noopener noreferrer"&gt;src/routing/complexity-analyzer.js&lt;/a&gt;. Steal the design or use the proxy — either outcome means fewer frontier-model tokens spent on &lt;code&gt;git stash&lt;/code&gt; questions.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>node</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The 21,000-Token Typo: Where Agentic Coding Budgets Actually Die</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Sun, 05 Jul 2026 08:48:24 +0000</pubDate>
      <link>https://dev.to/lynkr/the-21000-token-typo-where-agentic-coding-budgets-actually-die-1pa4</link>
      <guid>https://dev.to/lynkr/the-21000-token-typo-where-agentic-coding-budgets-actually-die-1pa4</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I maintain &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;, an open-source proxy mentioned at the end. The first 80% of this post is tool-agnostic and the takeaways apply whether or not you ever use it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There's a &lt;a href="https://www.cyfrin.io/blog/expensive-and-slow-for-small-changes-why-ai-coding-agents-can-be-overkill" rel="noopener noreferrer"&gt;documented case&lt;/a&gt; of a coding agent burning &lt;strong&gt;21,000+ input tokens to fix a one-line README typo&lt;/strong&gt;. Not a bug. Not a runaway loop. That's the normal cost structure of agentic coding, and once you see why, you can't unsee it on your own bill.&lt;/p&gt;

&lt;p&gt;Stanford's Digital Economy Lab &lt;a href="https://digitaleconomy.stanford.edu/news/how-are-ai-agents-spending-your-tokens/" rel="noopener noreferrer"&gt;measured it&lt;/a&gt;: agentic tasks consume on the order of &lt;strong&gt;1000x the tokens of ordinary code chat&lt;/strong&gt;, and the &lt;em&gt;same task with the same agent&lt;/em&gt; can vary 30x in cost depending on how the session unfolds. Teams running heavy automation report $500–$2,000 per engineer per month. So where does it go?&lt;/p&gt;

&lt;h2&gt;
  
  
  The anatomy of one "small" agentic task
&lt;/h2&gt;

&lt;p&gt;Say you ask your agent to fix a typo. Here's what actually crosses the wire:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn 1:&lt;/strong&gt; Your one-line prompt... plus the system prompt, plus ~14 tool schemas (Write, Edit, Bash, Grep, Git — a couple thousand tokens before anyone thinks).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn 2:&lt;/strong&gt; The agent greps for the file. The result comes back as JSON — paths, line numbers, match context, metadata. A modest grep is easily 1,000–3,000 tokens. It's now in the context &lt;strong&gt;and gets re-sent on every subsequent turn&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn 3:&lt;/strong&gt; The agent reads the file. Add the full file contents to the context. Re-sent every turn from now on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn 4:&lt;/strong&gt; The edit itself — the cheapest part of the entire session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn 5:&lt;/strong&gt; Verification: re-read, maybe run a linter, another JSON blob of output.&lt;/p&gt;

&lt;p&gt;Five turns, and your one-line fix carried: 5x the tool schemas, 4x the grep results, 3x the file contents. Input tokens dominate output roughly &lt;strong&gt;25:1&lt;/strong&gt; in typical sessions. You're not paying for intelligence — you're paying for &lt;em&gt;cargo&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The three structural leaks
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Leak 1: Tool schemas on every request.&lt;/strong&gt; The agent might use two tools this session. You ship fourteen schemas every turn anyway, because the client doesn't know which ones matter. Measured on a realistic Claude Code request: schemas the request couldn't use accounted for &lt;strong&gt;53% of billed input tokens&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leak 2: Raw JSON in the context window.&lt;/strong&gt; JSON is the least token-efficient format your context will ever hold — keys repeated per element, quotes, braces, whitespace. A 60-match grep result: ~3,400 tokens raw, &lt;strong&gt;427 after conversion to a tabular token-oriented format&lt;/strong&gt; with redundant fields stripped. Nothing lost that the model needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leak 3: Frontier models on non-frontier requests.&lt;/strong&gt; "What does git stash do?" does not need the same model as "refactor this auth module." But your client sends both to the same place, because model choice is a config setting, not a per-request decision. In my instrumented sessions, &lt;strong&gt;70–90% of requests scored as simple or medium complexity&lt;/strong&gt; — they'd be fine (and free) on a local model.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do about it — tool-agnostic
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instrument before optimizing.&lt;/strong&gt; Log tokens per request by category (schemas / tool results / conversation). You cannot fix a leak you haven't sized. Most people find their intuition about their own spend is wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never let raw JSON accumulate in a context window.&lt;/strong&gt; Compact it, tabularize it, or summarize it. Tabular JSON is nearly free compression — same information, a fraction of the tokens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep sessions short and contexts clean.&lt;/strong&gt; Every tool result you leave in the context is a recurring charge, billed again on every turn until the session ends.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Match model to request, not to workflow.&lt;/strong&gt; Route the easy 80% somewhere cheap or local; reserve the frontier model for the requests that actually exercise it. Bring your own API keys and the routing is entirely within your control.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The plumbing version
&lt;/h2&gt;

&lt;p&gt;Everything above can be done manually. I got tired of doing it manually, so I built it into a proxy: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt; sits between your coding tool (Claude Code, Cursor, Codex CLI) and your providers, strips unusable tool schemas, compresses JSON tool results, caches semantically, and scores each request on 13 dimensions to route it to a tier you define — local Ollama for the easy stuff, your API keys for the hard stuff. Self-hosted, Apache-2.0, no markup, zero client changes.&lt;/p&gt;

&lt;p&gt;But the numbers above aren't about my tool. They're about a cost structure every agentic workflow shares. The 21,000-token typo isn't an outlier — it's the default. Measure yours.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>devtools</category>
      <category>llm</category>
    </item>
    <item>
      <title>Lynkr vs claude-code-router: Static Rules vs a Complexity Classifier</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Sun, 05 Jul 2026 08:48:08 +0000</pubDate>
      <link>https://dev.to/lynkr/lynkr-vs-claude-code-router-static-rules-vs-a-complexity-classifier-38nd</link>
      <guid>https://dev.to/lynkr/lynkr-vs-claude-code-router-static-rules-vs-a-complexity-classifier-38nd</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I'm the author of &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;. claude-code-router is a genuinely good project that pioneered this category — this is a technical comparison of two different approaches, not a takedown. Where CCR is the better choice, I say so.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to keep the Claude Code harness but route requests to other models, you have two main self-hosted options today: &lt;a href="https://github.com/musistudio/claude-code-router" rel="noopener noreferrer"&gt;claude-code-router&lt;/a&gt; (CCR, ~35k stars, the incumbent) and &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;. They solve the same problem with fundamentally different architectures, and which one fits you depends on how much you want to configure versus delegate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core difference in one paragraph
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CCR routes by scenario rules you write.&lt;/strong&gt; It has slots — &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;background&lt;/code&gt;, &lt;code&gt;think&lt;/code&gt;, &lt;code&gt;longContext&lt;/code&gt; (triggered above a token threshold), &lt;code&gt;webSearch&lt;/code&gt;, &lt;code&gt;image&lt;/code&gt; — and you assign a model to each. It's predictable, transparent, and entirely under your control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lynkr routes by scoring the request itself.&lt;/strong&gt; Every request gets a 0–100 complexity score computed from 13 weighted dimensions — token count, technical keyword density, tool complexity, multi-step reasoning markers, conversation depth, ambiguity, and so on — and lands in a tier (&lt;code&gt;SIMPLE&lt;/code&gt;/&lt;code&gt;MEDIUM&lt;/code&gt;/&lt;code&gt;COMPLEX&lt;/code&gt;/&lt;code&gt;REASONING&lt;/code&gt;) you've mapped to models. You configure the tiers once; the classifier decides per-request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where CCR wins
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maturity and ecosystem.&lt;/strong&gt; 35k stars, ~730k monthly npm downloads, 20+ provider transformers, custom JS plugins, a web UI, and in-session &lt;code&gt;/model&lt;/code&gt; switching. If you hit a weird provider quirk, someone has already hit it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictability.&lt;/strong&gt; A rule is a rule. If you want &lt;em&gt;"long contexts always go to Gemini"&lt;/em&gt;, CCR expresses that in one line and never surprises you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code specialization.&lt;/strong&gt; CCR does one client deeply. Lynkr supports Claude Code, Cursor, Codex CLI, Cline, and Continue — breadth costs some depth.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Where the rule-based approach breaks down
&lt;/h2&gt;

&lt;p&gt;Browse CCR's issue tracker (~1,000 open issues) and one complaint dominates: &lt;strong&gt;tool-calling breakage on downgraded models&lt;/strong&gt; — failed file edits, broken git operations, agents going in circles. The root cause usually isn't CCR's code. It's that static rules can't see &lt;em&gt;what the request needs&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A short prompt ("fix the auth bug in session.js") looks cheap by token count — but it's an agentic, tool-heavy task that a small local model will fumble.&lt;/li&gt;
&lt;li&gt;A long context triggers the &lt;code&gt;longContext&lt;/code&gt; rule — but if it's 60k tokens of grep output around a trivial question, an expensive long-context model is wasted money.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Token counts and scenario names are proxies. The thing you actually care about — &lt;em&gt;can a cheap model handle this without breaking the session?&lt;/em&gt; — requires looking at the request's structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Lynkr does differently
&lt;/h2&gt;

&lt;p&gt;Three things, all absent from CCR by design (it aims to be a lean router):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The complexity classifier.&lt;/strong&gt; Requests with agentic signals (write/edit/bash tool availability, prior tool results in the conversation, sequential-step language) score into higher tiers even when they're short. Trivia stays local even when the context is long. Force-patterns short-circuit both ways: greetings never hit the cloud; security-critical analysis never gets downgraded. The design goal is exactly the failure mode above — &lt;em&gt;route down only when the answer will still work&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Token optimization on the wire.&lt;/strong&gt; Lynkr strips tool schemas the request can't use (measured: &lt;strong&gt;53% fewer tokens&lt;/strong&gt; on a realistic 14-tool Claude Code request) and compresses large JSON tool results before they hit the model (measured: 3,458 → 427 tokens on a 60-match grep result). CCR forwards requests as-is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Semantic caching.&lt;/strong&gt; Paraphrased repeat questions are served from an embedding cache in ~171ms with zero tokens billed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest comparison table
&lt;/h2&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;claude-code-router&lt;/th&gt;
&lt;th&gt;Lynkr&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Routing logic&lt;/td&gt;
&lt;td&gt;Scenario rules + token threshold&lt;/td&gt;
&lt;td&gt;13-dimension complexity score → tiers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuration&lt;/td&gt;
&lt;td&gt;Per-scenario, per-provider (flexible, verbose)&lt;/td&gt;
&lt;td&gt;Pick 4 tier models via &lt;code&gt;lynkr init&lt;/code&gt; wizard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool-schema stripping&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (−53% measured)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON tool-result compression&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (TOON + field stripping)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic cache&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clients&lt;/td&gt;
&lt;td&gt;Claude Code (deep)&lt;/td&gt;
&lt;td&gt;Claude Code, Cursor, Codex CLI, Cline, Continue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Provider transformers/plugins&lt;/td&gt;
&lt;td&gt;20+, custom JS&lt;/td&gt;
&lt;td&gt;13 providers built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ecosystem maturity&lt;/td&gt;
&lt;td&gt;~35k stars, huge community&lt;/td&gt;
&lt;td&gt;Young (~500 stars), one maintainer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;In-session model switching&lt;/td&gt;
&lt;td&gt;Yes (&lt;code&gt;/model&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;No (automatic per-request)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;License&lt;/td&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;Apache-2.0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Which should you use?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You want explicit control and a battle-tested ecosystem&lt;/strong&gt; → CCR. It's the safe default and its community is unmatched.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're tired of tuning rules, or your cheap-model sessions keep breaking&lt;/strong&gt; → try Lynkr. The classifier exists precisely because static rules degrade on agentic workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your bill is dominated by tool output and repeated context&lt;/strong&gt; → Lynkr, regardless of routing preference; the compression and caching layers work even if you route everything to one model.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are self-hosted, free, and take five minutes to try. Run your own workload through each and compare the token logs — that's the only benchmark that matters. Mine are reproducible here: &lt;a href="https://github.com/Fast-Editor/Lynkr/blob/main/BENCHMARK_REPORT.md" rel="noopener noreferrer"&gt;github.com/Fast-Editor/Lynkr&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>claude</category>
    </item>
    <item>
      <title>Where Claude Code's Tokens Actually Go (and How I Cut My Bill in Half)</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Sun, 05 Jul 2026 08:21:25 +0000</pubDate>
      <link>https://dev.to/lynkr/where-claude-codes-tokens-actually-go-and-how-i-cut-my-bill-in-half-13g6</link>
      <guid>https://dev.to/lynkr/where-claude-codes-tokens-actually-go-and-how-i-cut-my-bill-in-half-13g6</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure up front: I'm the author of &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;, the open-source (Apache-2.0) proxy discussed below. All numbers come from a benchmark you can reproduce yourself — methodology linked at the end.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I spent a few weeks instrumenting my own Claude Code sessions to answer one question: &lt;strong&gt;where do the tokens actually go?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer surprised me. It wasn't my prompts. It wasn't even the model's responses. The bulk of my spend was overhead I never looked at:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tool schemas sent on every single request.&lt;/strong&gt; Claude Code ships ~14 tool definitions (Write, Edit, Bash, Git, Grep...) with &lt;em&gt;every&lt;/em&gt; message — even when you're asking a read-only question that can only ever use two of them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raw JSON tool results.&lt;/strong&gt; A single grep returning 60 matches came back as a ~3,400-token JSON array. File reads, test output, &lt;code&gt;ls&lt;/code&gt; results — all shipped verbatim into the context, on every turn, forever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paying full price for trivial requests.&lt;/strong&gt; "What does &lt;code&gt;git stash&lt;/code&gt; do?" was hitting the same expensive model as "refactor this auth module."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A famous example of this failure mode: an agent &lt;a href="https://www.cyfrin.io/blog/expensive-and-slow-for-small-changes-why-ai-coding-agents-can-be-overkill" rel="noopener noreferrer"&gt;burned 21,000+ input tokens fixing a one-line README typo&lt;/a&gt;. Stanford's Digital Economy Lab found agentic coding tasks consume &lt;a href="https://digitaleconomy.stanford.edu/news/how-are-ai-agents-spending-your-tokens/" rel="noopener noreferrer"&gt;~1000x the tokens of ordinary code chat&lt;/a&gt;. This is not a niche problem — it's the cost structure of every agentic coding tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: put intelligence between the agent and the model
&lt;/h2&gt;

&lt;p&gt;None of this requires changing your tools. Claude Code, Cursor, and Codex CLI all let you override the API base URL. So I built a proxy that sits in the middle and does four things:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Strip tools the request can't use
&lt;/h3&gt;

&lt;p&gt;Classify each request; a read-only question doesn't need Write/Edit/Bash schemas, so don't send them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measured result:&lt;/strong&gt; 959 tokens vs 2,085 for the identical request — &lt;strong&gt;53% fewer tokens, same model, same answer.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Compress JSON tool results
&lt;/h3&gt;

&lt;p&gt;Large JSON payloads (grep output, file listings, test results) get converted to &lt;a href="https://github.com/toon-format/toon" rel="noopener noreferrer"&gt;TOON&lt;/a&gt;, a token-oriented format, plus redundant-field stripping before they're forwarded to the model. Plain text passes through untouched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measured result:&lt;/strong&gt; that 60-match grep result went from 3,458 tokens to 427 — &lt;strong&gt;87.6% smaller&lt;/strong&gt;. (Honest caveat: TOON alone typically saves ~40%; the 87.6% is TOON &lt;em&gt;stacked with&lt;/em&gt; field-stripping on a tabular payload. Deeply nested data compresses less. Run the benchmark on your own workload.)&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Semantic caching
&lt;/h3&gt;

&lt;p&gt;If you ask "explain TCP vs UDP" and later "what's the difference between TCP and UDP?", that's the same question. Embedding similarity ≥ 0.85 → serve the cached response. &lt;strong&gt;171ms, zero tokens billed.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Route by complexity, not by config
&lt;/h3&gt;

&lt;p&gt;This is the part I haven't seen anywhere else done automatically. Each request is scored on 15 dimensions — token count, code complexity, reasoning markers, agentic signals, risk patterns — and routed to a tier you define:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;TIER_SIMPLE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama:qwen2.5:7b          &lt;span class="c"&gt;# free, local&lt;/span&gt;
&lt;span class="nv"&gt;TIER_MEDIUM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama:qwen2.5-coder:latest &lt;span class="c"&gt;# free, local&lt;/span&gt;
&lt;span class="nv"&gt;TIER_COMPLEX&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-cloud-provider        &lt;span class="c"&gt;# your API key&lt;/span&gt;
&lt;span class="nv"&gt;TIER_REASONING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your-cloud-provider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my sessions, &lt;strong&gt;70–90% of requests scored SIMPLE or MEDIUM&lt;/strong&gt; and never left my machine. Only genuinely hard problems — architecture, tricky refactors, security analysis — hit a paid backend.&lt;/p&gt;

&lt;p&gt;The routing is deliberately conservative in one direction: tool-heavy agentic requests don't get downgraded, because the #1 complaint with every static routing setup is cheap models fumbling tool calls (failed edits, broken git operations). Routing &lt;em&gt;down&lt;/em&gt; is only a saving if the answer still works.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like in practice
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; lynkr
lynkr init          &lt;span class="c"&gt;# interactive wizard: pick your tiers and providers&lt;/span&gt;
lynkr start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then point your tool at it — for Cursor it's Settings → Models → Override Base URL → &lt;code&gt;http://localhost:8081/v1&lt;/code&gt;; for Codex CLI it's two lines in &lt;code&gt;~/.codex/config.toml&lt;/code&gt;. No code changes, no plugins.&lt;/p&gt;

&lt;p&gt;Everything is self-hosted: your prompts and code never transit a third-party SaaS, there's no markup fee, and the whole thing is Apache-2.0 on &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers, side by side
&lt;/h2&gt;

&lt;p&gt;Benchmarked against LiteLLM v1.87.1 on identical workloads, same backend providers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Through Lynkr&lt;/th&gt;
&lt;th&gt;Baseline&lt;/th&gt;
&lt;th&gt;Delta&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tool-heavy request (14 schemas)&lt;/td&gt;
&lt;td&gt;959 tokens&lt;/td&gt;
&lt;td&gt;2,085 tokens&lt;/td&gt;
&lt;td&gt;−53%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;60-result grep (JSON tool output)&lt;/td&gt;
&lt;td&gt;427 tokens&lt;/td&gt;
&lt;td&gt;3,458 tokens&lt;/td&gt;
&lt;td&gt;−87.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repeated paraphrased query&lt;/td&gt;
&lt;td&gt;171ms, 0 tokens&lt;/td&gt;
&lt;td&gt;3,282ms, full price&lt;/td&gt;
&lt;td&gt;11x faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Complexity routing&lt;/td&gt;
&lt;td&gt;simple→local, hard→cloud&lt;/td&gt;
&lt;td&gt;cheapest-model-always&lt;/td&gt;
&lt;td&gt;correctness&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Projected over 100k requests/month on a tool-heavy workload: roughly &lt;strong&gt;half the bill, same backend, same models for the requests that matter&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways even if you never use my tool
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Audit your tool schemas.&lt;/strong&gt; They're the silent tax on every agentic request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never ship raw JSON into a context window.&lt;/strong&gt; Tabular JSON is the single most compressible thing in your token stream.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Most of your requests are simple.&lt;/strong&gt; You don't need a frontier model to explain &lt;code&gt;git stash&lt;/code&gt;. Bring your own API keys, keep the easy 80% local, and spend where it counts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you try Lynkr and the numbers don't hold on your workload, open an issue with your benchmark output — I want the counterexamples: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;github.com/Fast-Editor/Lynkr&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Built an LLM Gateway That Extends Claude Pro/Max Users with Azure AI Foundry, Amazon Bedrock, Local Models</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Tue, 30 Jun 2026 22:28:50 +0000</pubDate>
      <link>https://dev.to/lynkr/i-built-an-llm-gateway-that-extends-claude-promax-with-azure-ai-foundry-and-amazon-bedrock-1efb</link>
      <guid>https://dev.to/lynkr/i-built-an-llm-gateway-that-extends-claude-promax-with-azure-ai-foundry-and-amazon-bedrock-1efb</guid>
      <description>&lt;p&gt;AI coding tools have gotten very good.&lt;/p&gt;

&lt;p&gt;But the infrastructure behind them is still weirdly inefficient.&lt;/p&gt;

&lt;p&gt;Most tools assume one provider, one lane, one billing path.&lt;/p&gt;

&lt;p&gt;That means the same expensive model or subscription ends up handling everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reading files&lt;/li&gt;
&lt;li&gt;summarizing logs&lt;/li&gt;
&lt;li&gt;quick repo questions&lt;/li&gt;
&lt;li&gt;multi-file refactors&lt;/li&gt;
&lt;li&gt;architecture planning&lt;/li&gt;
&lt;li&gt;long debugging sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the wrong abstraction.&lt;/p&gt;

&lt;p&gt;A coding workflow is not one type of problem. So it should not be forced through one type of model path.&lt;/p&gt;

&lt;p&gt;That idea is what pushed me to build &lt;strong&gt;Lynkr&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lynkr is an open-source LLM gateway for AI coding tools&lt;/strong&gt; that lets me combine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max subscription access&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure AI Foundry-hosted models&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon Bedrock-hosted models&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;and local/free models like &lt;strong&gt;Ollama&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;behind one routing layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with single-lane AI coding
&lt;/h2&gt;

&lt;p&gt;If you use a premium coding assistant every day, you have probably seen this already.&lt;/p&gt;

&lt;p&gt;A lot of the workload is not actually premium reasoning work.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"open this file"&lt;/li&gt;
&lt;li&gt;"search for auth middleware"&lt;/li&gt;
&lt;li&gt;"summarize this module"&lt;/li&gt;
&lt;li&gt;"show me where this class is used"&lt;/li&gt;
&lt;li&gt;"read these test failures"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are useful requests, but they are not the same as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"refactor this subsystem"&lt;/li&gt;
&lt;li&gt;"design a safer auth flow"&lt;/li&gt;
&lt;li&gt;"debug this multi-step failure"&lt;/li&gt;
&lt;li&gt;"trace this agent loop bug"&lt;/li&gt;
&lt;li&gt;"rewrite this implementation across five files"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet most tools send both classes of work through the same expensive path.&lt;/p&gt;

&lt;p&gt;That creates three problems:&lt;/p&gt;

&lt;h3&gt;
  
  
  1) You waste premium capacity
&lt;/h3&gt;

&lt;p&gt;If a subscription-backed or premium model handles every tiny prompt, you burn good capacity on low-value tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) You stay locked into one provider
&lt;/h3&gt;

&lt;p&gt;Even if you already have access to Azure, AWS, or local models, your coding workflow is often tied to one vendor path.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) You lose resilience
&lt;/h3&gt;

&lt;p&gt;If one provider is rate-limited, degraded, or just not the best fit for a task, you have no routing layer to adjust.&lt;/p&gt;

&lt;h2&gt;
  
  
  The idea behind Lynkr
&lt;/h2&gt;

&lt;p&gt;Lynkr sits between AI coding tools and model providers.&lt;/p&gt;

&lt;p&gt;It works as an &lt;strong&gt;LLM gateway&lt;/strong&gt;, which means the coding tool talks to Lynkr, and Lynkr decides what to do next.&lt;/p&gt;

&lt;p&gt;That lets the gateway:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;route by complexity&lt;/li&gt;
&lt;li&gt;compress bulky tool outputs&lt;/li&gt;
&lt;li&gt;cache repeated requests&lt;/li&gt;
&lt;li&gt;switch providers without changing the client workflow&lt;/li&gt;
&lt;li&gt;use different backends for different classes of tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The part I am most excited about is hybrid routing across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Claude Pro/Max&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure AI Foundry&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Amazon Bedrock&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What "extending Claude Pro/Max" means
&lt;/h2&gt;

&lt;p&gt;The simplest version looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;simple tasks&lt;/strong&gt; → local/free model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hard coding tasks&lt;/strong&gt; → Claude Pro/Max subscription&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;enterprise workloads&lt;/strong&gt; → Azure AI Foundry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fallback or alternate routing&lt;/strong&gt; → Amazon Bedrock&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of replacing Claude, Azure, or Bedrock, the gateway combines them.&lt;/p&gt;

&lt;p&gt;This is the key idea: &lt;strong&gt;extend your Claude Pro/Max usage instead of burning it on everything&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example workflow
&lt;/h3&gt;

&lt;p&gt;Imagine a coding session that looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;"Read the auth middleware and summarize it."&lt;br&gt;&lt;br&gt;
Route to a cheap local model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Search all routes that call this helper."&lt;br&gt;&lt;br&gt;
Still cheap/local.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Refactor this auth flow to support tenant isolation."&lt;br&gt;&lt;br&gt;
Route to Claude Pro/Max.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Generate an enterprise-safe variant for our internal stack."&lt;br&gt;&lt;br&gt;
Route to Azure AI Foundry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"Azure is unavailable or rate-limited."&lt;br&gt;&lt;br&gt;
Fallback to Bedrock.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is a much more natural way to run coding agents than pretending every prompt deserves the same model path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Claude Pro/Max + Azure + Bedrock is interesting
&lt;/h2&gt;

&lt;p&gt;This combination matters because each lane solves a different problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Claude Pro/Max
&lt;/h3&gt;

&lt;p&gt;Great for high-quality coding and reasoning tasks where you already have subscription value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Azure AI Foundry
&lt;/h3&gt;

&lt;p&gt;Useful when a team wants enterprise-hosted models, internal approvals, or Azure-aligned infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amazon Bedrock
&lt;/h3&gt;

&lt;p&gt;Useful for AWS-native orgs, alternate model access, or fallback when you want another enterprise provider path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local models
&lt;/h3&gt;

&lt;p&gt;Useful for cheap, frequent, low-stakes tasks that should not consume premium capacity at all.&lt;/p&gt;

&lt;p&gt;Putting these together in one gateway gives you a better operational model than any one of them alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for coding agents specifically
&lt;/h2&gt;

&lt;p&gt;I think coding is one of the best use cases for an LLM gateway because coding workflows are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool-heavy&lt;/li&gt;
&lt;li&gt;repetitive&lt;/li&gt;
&lt;li&gt;multi-step&lt;/li&gt;
&lt;li&gt;full of structured outputs&lt;/li&gt;
&lt;li&gt;sensitive to token waste&lt;/li&gt;
&lt;li&gt;often spread across many turns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means a gateway can add value in several ways.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Complexity-based routing
&lt;/h3&gt;

&lt;p&gt;Not every prompt deserves the same model.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Cost control
&lt;/h3&gt;

&lt;p&gt;Cheap requests stay cheap.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Better use of subscriptions
&lt;/h3&gt;

&lt;p&gt;Premium capacity gets reserved for tasks that actually need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Enterprise compatibility
&lt;/h3&gt;

&lt;p&gt;Teams can use Azure AI Foundry or Bedrock where policy or procurement matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  5) Resilience
&lt;/h3&gt;

&lt;p&gt;If one provider path fails, the workflow can continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where MCP and agent workflows fit in
&lt;/h2&gt;

&lt;p&gt;Another reason this matters is MCP and agentic tooling.&lt;/p&gt;

&lt;p&gt;As coding tools become more agentic, they use more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool schemas&lt;/li&gt;
&lt;li&gt;file reads&lt;/li&gt;
&lt;li&gt;command outputs&lt;/li&gt;
&lt;li&gt;structured results&lt;/li&gt;
&lt;li&gt;long multi-turn sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That creates a lot of overhead and a lot of repeated context.&lt;/p&gt;

&lt;p&gt;A gateway is the right place to optimize that.&lt;/p&gt;

&lt;p&gt;That is also why I think the future is not just better models.&lt;/p&gt;

&lt;p&gt;It is better &lt;strong&gt;routing, caching, tool handling, and workload separation&lt;/strong&gt; around those models.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I wanted Lynkr to do
&lt;/h2&gt;

&lt;p&gt;I did not want just another OpenAI-compatible endpoint.&lt;/p&gt;

&lt;p&gt;I wanted a gateway that could actually help with real coding economics and workflow design.&lt;/p&gt;

&lt;p&gt;For me, that means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keeping the coding tool workflow the same&lt;/li&gt;
&lt;li&gt;preserving subscription value&lt;/li&gt;
&lt;li&gt;combining subscription + cloud + local lanes&lt;/li&gt;
&lt;li&gt;supporting enterprise backends&lt;/li&gt;
&lt;li&gt;reducing waste on easy tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Who this is for
&lt;/h2&gt;

&lt;p&gt;I think this is especially useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code users who want more mileage from Pro/Max&lt;/li&gt;
&lt;li&gt;teams using Azure AI Foundry for approved enterprise model access&lt;/li&gt;
&lt;li&gt;AWS teams already standardizing on Bedrock&lt;/li&gt;
&lt;li&gt;developers mixing local models with premium coding assistants&lt;/li&gt;
&lt;li&gt;MCP and agent workflow builders who need an LLM gateway&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;I do not think the next big improvement in AI coding comes only from stronger base models.&lt;/p&gt;

&lt;p&gt;A lot of value will come from better infrastructure around them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better routing&lt;/li&gt;
&lt;li&gt;better caching&lt;/li&gt;
&lt;li&gt;better cost control&lt;/li&gt;
&lt;li&gt;better tool handling&lt;/li&gt;
&lt;li&gt;better use of multiple model lanes in one workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the direction I am building toward with &lt;strong&gt;Lynkr&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr&lt;/a&gt;&lt;br&gt;
Ps:- This is fully following Anthropic TOS because lynkr wraps around your existing claude code &lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>claudecode</category>
      <category>aws</category>
    </item>
    <item>
      <title>How to Use T3 Code With Claude Code and an Open-Source LLM Gateway</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Thu, 25 Jun 2026 07:55:29 +0000</pubDate>
      <link>https://dev.to/lynkr/how-to-use-t3-code-with-claude-code-and-an-open-source-llm-gateway-2aek</link>
      <guid>https://dev.to/lynkr/how-to-use-t3-code-with-claude-code-and-an-open-source-llm-gateway-2aek</guid>
      <description>&lt;p&gt;If I were setting up &lt;strong&gt;T3 Code&lt;/strong&gt; for serious daily use, the stack I would want looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;T3 Code
   ↓
Claude Code
   ↓
Lynkr
   ↓
Anthropic / OpenAI / Ollama / OpenRouter / Bedrock / Azure / Databricks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That flow is interesting because each layer is doing a different job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T3 Code&lt;/strong&gt; is the workflow and interface layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; is the coding agent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lynkr&lt;/strong&gt; is the gateway layer under the agent&lt;/li&gt;
&lt;li&gt;the &lt;strong&gt;model providers&lt;/strong&gt; sit behind that gateway&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That separation is the whole point.&lt;/p&gt;

&lt;p&gt;T3 Code gives me the UX I want.&lt;br&gt;
Claude Code gives me the coding behavior I want.&lt;br&gt;
Lynkr gives me control over how model traffic actually gets handled.&lt;/p&gt;

&lt;p&gt;That is a much better stack than treating the model layer as an afterthought.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick demo
&lt;/h2&gt;

&lt;p&gt;I also recorded a short walkthrough of this setup in action:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;YouTube:&lt;/strong&gt; &lt;a href="https://www.youtube.com/watch?v=clqKXFnMyDw" rel="noopener noreferrer"&gt;How to use T3Code with any model @t3dotgg&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want the faster visual version before reading the rest, start there. The architecture is the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;T3 Code
   ↓
Claude Code
   ↓
Lynkr
   ↓
Your actual model/provider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why T3 Code is a useful surface
&lt;/h2&gt;

&lt;p&gt;T3 Code is interesting because it is not trying to become a new model or a new lab-specific harness.&lt;/p&gt;

&lt;p&gt;It is building a better way to &lt;em&gt;work with&lt;/em&gt; coding agents people already use.&lt;/p&gt;

&lt;p&gt;That is a smarter product decision than trying to replace everything at once.&lt;/p&gt;

&lt;p&gt;Its current support includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Codex&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Cursor&lt;/li&gt;
&lt;li&gt;OpenCode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means the value of T3 Code is not “one more coding assistant.”&lt;/p&gt;

&lt;p&gt;It is more like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one place to manage coding sessions&lt;/li&gt;
&lt;li&gt;one place to manage projects and threads&lt;/li&gt;
&lt;li&gt;one cleaner interface across multiple agent backends&lt;/li&gt;
&lt;li&gt;less context-switching between separate tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That makes a lot of sense.&lt;/p&gt;

&lt;p&gt;But once you pick &lt;strong&gt;Claude Code&lt;/strong&gt; as the coding agent inside that stack, the next problem becomes obvious:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the model layer under Claude Code matters just as much as the top-level UX.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because once the agent is doing real work, cost and reliability stop being invisible plumbing.&lt;/p&gt;

&lt;p&gt;They become part of the product experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Claude Code is the right example
&lt;/h2&gt;

&lt;p&gt;Claude Code is a good example because it exposes the problem very clearly.&lt;/p&gt;

&lt;p&gt;A real Claude Code session does not look like a single “generate code” call.&lt;/p&gt;

&lt;p&gt;It looks more like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;inspect the repo&lt;/li&gt;
&lt;li&gt;read a few files&lt;/li&gt;
&lt;li&gt;plan a fix&lt;/li&gt;
&lt;li&gt;call tools&lt;/li&gt;
&lt;li&gt;generate or edit code&lt;/li&gt;
&lt;li&gt;hit an issue&lt;/li&gt;
&lt;li&gt;retry with more context&lt;/li&gt;
&lt;li&gt;inspect another file&lt;/li&gt;
&lt;li&gt;summarize the result&lt;/li&gt;
&lt;li&gt;do another pass&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That creates a traffic pattern that is very different from plain chat:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repeated system instructions&lt;/li&gt;
&lt;li&gt;repeated repo context&lt;/li&gt;
&lt;li&gt;repeated tool schemas&lt;/li&gt;
&lt;li&gt;repeated state&lt;/li&gt;
&lt;li&gt;large tool outputs&lt;/li&gt;
&lt;li&gt;retries that quietly multiply tokens&lt;/li&gt;
&lt;li&gt;easy turns mixed with hard reasoning turns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly why coding-agent workflows need a stronger model layer than “just point it directly at one provider.”&lt;/p&gt;

&lt;p&gt;Once Claude Code is being used as an actual coding agent, the model path underneath it becomes infrastructure.&lt;/p&gt;

&lt;p&gt;And infrastructure decisions compound.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with wiring Claude Code directly forever
&lt;/h2&gt;

&lt;p&gt;Direct setup is fine for testing.&lt;/p&gt;

&lt;p&gt;But it gets worse as the workflow becomes more serious.&lt;/p&gt;

&lt;p&gt;If Claude Code is always wired straight to one provider path, you get a few problems:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Every turn gets treated like it needs the same model
&lt;/h3&gt;

&lt;p&gt;That is usually false.&lt;/p&gt;

&lt;p&gt;Some steps are lightweight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;summarize a file&lt;/li&gt;
&lt;li&gt;extract the likely cause of an error&lt;/li&gt;
&lt;li&gt;choose the next action&lt;/li&gt;
&lt;li&gt;interpret logs&lt;/li&gt;
&lt;li&gt;reformat an answer&lt;/li&gt;
&lt;li&gt;produce a short structured response&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some steps are genuinely expensive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;debug a multi-file integration break&lt;/li&gt;
&lt;li&gt;reason across a large codebase&lt;/li&gt;
&lt;li&gt;recover after several failed tool loops&lt;/li&gt;
&lt;li&gt;refactor something deep without breaking behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If those all hit the same expensive path, you overpay.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Retries become cost multipliers
&lt;/h3&gt;

&lt;p&gt;Coding agents retry all the time.&lt;/p&gt;

&lt;p&gt;That is not a bug. That is how they work.&lt;/p&gt;

&lt;p&gt;But retries mean the same or almost-the-same context gets resent over and over.&lt;/p&gt;

&lt;p&gt;Without a caching layer or routing control, you keep paying full price for repeated work.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tool-heavy traffic becomes the silent token killer
&lt;/h3&gt;

&lt;p&gt;The expensive part is often not the user’s prompt.&lt;/p&gt;

&lt;p&gt;It is everything around it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool definitions&lt;/li&gt;
&lt;li&gt;file reads&lt;/li&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;stack traces&lt;/li&gt;
&lt;li&gt;JSON blobs&lt;/li&gt;
&lt;li&gt;repeated state&lt;/li&gt;
&lt;li&gt;structured outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is where a lot of token waste hides.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Provider changes become annoying
&lt;/h3&gt;

&lt;p&gt;Maybe today you want Claude for everything.&lt;/p&gt;

&lt;p&gt;Later maybe you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local Ollama for cheap exploratory passes&lt;/li&gt;
&lt;li&gt;Anthropic for hard reasoning&lt;/li&gt;
&lt;li&gt;OpenRouter for overflow&lt;/li&gt;
&lt;li&gt;Bedrock or Azure for enterprise constraints&lt;/li&gt;
&lt;li&gt;a different mix for different teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the setup is too tightly wired, those changes become more painful than they should be.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Reliability problems leak into workflow
&lt;/h3&gt;

&lt;p&gt;Latency spikes, rate limits, auth weirdness, provider outages, degraded outputs — eventually you hit all of them.&lt;/p&gt;

&lt;p&gt;If there is no gateway layer, every one of those issues becomes a client-side problem.&lt;/p&gt;

&lt;p&gt;That is exactly the kind of thing I would rather solve once in the model layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The split I want
&lt;/h2&gt;

&lt;p&gt;This is the mental model that makes sense to me.&lt;/p&gt;

&lt;h3&gt;
  
  
  T3 Code handles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;threads&lt;/li&gt;
&lt;li&gt;projects&lt;/li&gt;
&lt;li&gt;top-level UX&lt;/li&gt;
&lt;li&gt;session management&lt;/li&gt;
&lt;li&gt;coding workflow surface&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Claude Code handles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;code reasoning&lt;/li&gt;
&lt;li&gt;edits&lt;/li&gt;
&lt;li&gt;tool usage&lt;/li&gt;
&lt;li&gt;the coding loop itself&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lynkr handles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;fallback&lt;/li&gt;
&lt;li&gt;token optimization&lt;/li&gt;
&lt;li&gt;local/cloud backend mix&lt;/li&gt;
&lt;li&gt;provider switching&lt;/li&gt;
&lt;li&gt;cost control under one stable endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a clean stack.&lt;/p&gt;

&lt;p&gt;The interface stays separate from the agent.&lt;br&gt;
The agent stays separate from the gateway.&lt;br&gt;
The gateway stays separate from the providers.&lt;/p&gt;

&lt;p&gt;That separation is valuable because it lets each layer evolve independently.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Lynkr fits under Claude Code
&lt;/h2&gt;

&lt;p&gt;Lynkr is an open-source &lt;strong&gt;LLM gateway&lt;/strong&gt; built for coding assistants, MCP-heavy workflows, and tool-heavy traffic.&lt;/p&gt;

&lt;p&gt;That last part matters.&lt;/p&gt;

&lt;p&gt;A lot of model-routing products talk about general-purpose requests. But coding traffic is different. It is noisier, more repetitive, and much more likely to carry large tool payloads.&lt;/p&gt;

&lt;p&gt;That is why the fit is real here.&lt;/p&gt;

&lt;p&gt;The role of Lynkr in this stack is not to replace Claude Code.&lt;/p&gt;

&lt;p&gt;It is to sit &lt;strong&gt;under Claude Code&lt;/strong&gt; and decide how model traffic should actually be handled.&lt;/p&gt;

&lt;p&gt;That gives you a few levers that matter a lot in coding workflows.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Tier routing changes the economics
&lt;/h2&gt;

&lt;p&gt;The biggest mistake people make with coding agents is asking the wrong question.&lt;/p&gt;

&lt;p&gt;They ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which is the best coding model?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more useful question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which parts of my coding workflow actually deserve the expensive model?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is what a gateway lets you answer.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;low-risk summarization can go to a cheaper/faster model&lt;/li&gt;
&lt;li&gt;repeated inspection steps can stay local&lt;/li&gt;
&lt;li&gt;simple classification or extraction steps do not need frontier pricing&lt;/li&gt;
&lt;li&gt;hard debugging or refactors can escalate to a stronger path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a much better economic model than treating every Claude Code turn as if it deserves maximum spend.&lt;/p&gt;

&lt;p&gt;And once that logic sits in the gateway, you do not need to keep rebuilding it at the app layer.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Caching matters more in coding than people think
&lt;/h2&gt;

&lt;p&gt;Coding agents repeat themselves constantly.&lt;/p&gt;

&lt;p&gt;The same instructions, the same repo background, similar prompts, similar recovery steps, similar tool outputs — they come up again and again.&lt;/p&gt;

&lt;p&gt;That means a caching layer is not a “nice optimization.”&lt;/p&gt;

&lt;p&gt;It is one of the biggest obvious wins in the stack.&lt;/p&gt;

&lt;p&gt;Lynkr’s current benchmark claims are the part that stand out here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;53% fewer tokens on tool-heavy requests&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;87.6% compression on large JSON tool results&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;171ms semantic cache hits&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly the kind of traffic Claude Code creates during real multi-step work.&lt;/p&gt;

&lt;p&gt;The point is not just lower cost.&lt;/p&gt;

&lt;p&gt;The point is lower cost &lt;em&gt;and&lt;/em&gt; lower latency on repeated work.&lt;/p&gt;

&lt;p&gt;That compounds very quickly.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Tool payload optimization is a real lever
&lt;/h2&gt;

&lt;p&gt;This is one of the most under-discussed parts of coding-agent economics.&lt;/p&gt;

&lt;p&gt;People spend a lot of time comparing model prices, but a huge amount of waste comes from the payload shape itself.&lt;/p&gt;

&lt;p&gt;In coding workflows, the model is often seeing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;large tool schemas&lt;/li&gt;
&lt;li&gt;verbose JSON results&lt;/li&gt;
&lt;li&gt;long command outputs&lt;/li&gt;
&lt;li&gt;repeated file excerpts&lt;/li&gt;
&lt;li&gt;repeated structured state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means reducing payload size is often just as important as picking the right provider.&lt;/p&gt;

&lt;p&gt;This is why gateway-level optimization makes sense.&lt;/p&gt;

&lt;p&gt;It is solving a real problem in the actual traffic pattern, not just shuffling providers around.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. T3 Code stays stable while the model layer evolves
&lt;/h2&gt;

&lt;p&gt;This is maybe the biggest architectural reason I like this stack.&lt;/p&gt;

&lt;p&gt;If T3 Code points to Claude Code, and Claude Code points to Lynkr, then the top-level workflow can remain stable while the backend policy changes underneath.&lt;/p&gt;

&lt;p&gt;That means I can change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;default providers&lt;/li&gt;
&lt;li&gt;local/cloud mix&lt;/li&gt;
&lt;li&gt;fallback policy&lt;/li&gt;
&lt;li&gt;cache behavior&lt;/li&gt;
&lt;li&gt;cost policy&lt;/li&gt;
&lt;li&gt;model tiers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…without having to rethink the interface and workflow every time.&lt;/p&gt;

&lt;p&gt;That is a better long-term design.&lt;/p&gt;

&lt;p&gt;The UI layer should not be where I want model policy to live.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Local-first and fallback become much easier
&lt;/h2&gt;

&lt;p&gt;There are plenty of steps in a coding workflow that can be handled locally or by a cheaper model path.&lt;/p&gt;

&lt;p&gt;There are also plenty of steps where I want a stronger cloud model.&lt;/p&gt;

&lt;p&gt;A gateway makes that hybrid model much easier.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;local model for lightweight repo inspection&lt;/li&gt;
&lt;li&gt;stronger provider for hard debugging&lt;/li&gt;
&lt;li&gt;cloud fallback when local output is not good enough&lt;/li&gt;
&lt;li&gt;alternate provider when the main path is slow or unavailable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That kind of setup is a lot harder to maintain cleanly when every client is wired directly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Example of the architecture in practice
&lt;/h2&gt;

&lt;p&gt;The point is not that T3 Code itself becomes the gateway.&lt;/p&gt;

&lt;p&gt;The point is that the stack stays layered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;T3 Code
   ↓
Claude Code
   ↓
Lynkr
   ↓
Anthropic / OpenAI / Ollama / OpenRouter / Bedrock / Azure / Databricks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a clean interface at the top&lt;/li&gt;
&lt;li&gt;a strong coding agent in the middle&lt;/li&gt;
&lt;li&gt;one stable gateway layer underneath&lt;/li&gt;
&lt;li&gt;swappable providers behind that&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the shape I would trust more over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for people using T3 Code seriously
&lt;/h2&gt;

&lt;p&gt;If you are trying T3 Code casually, none of this matters much.&lt;/p&gt;

&lt;p&gt;But if you are actually using it for repeated coding workflows, then it starts to matter fast.&lt;/p&gt;

&lt;p&gt;Because daily coding-agent usage means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lots of repeated calls&lt;/li&gt;
&lt;li&gt;lots of tool-heavy turns&lt;/li&gt;
&lt;li&gt;more retries than you expected&lt;/li&gt;
&lt;li&gt;more context repetition than you expected&lt;/li&gt;
&lt;li&gt;more need for backend flexibility than you expected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is when the gateway stops being optional architecture theory and starts becoming the practical layer that controls cost and reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final take
&lt;/h2&gt;

&lt;p&gt;If I were using &lt;strong&gt;T3 Code with Claude Code&lt;/strong&gt;, I would not want Claude Code wired directly to one backend forever.&lt;/p&gt;

&lt;p&gt;I would want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T3 Code&lt;/strong&gt; for workflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; for coding behavior&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lynkr&lt;/strong&gt; for routing, caching, fallback, and cost control&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;multiple providers&lt;/strong&gt; behind that gateway&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That feels like the right stack for where coding tools are going.&lt;/p&gt;

&lt;p&gt;Better UX at the top.&lt;/p&gt;

&lt;p&gt;Better agent behavior in the middle.&lt;/p&gt;

&lt;p&gt;Better economics and control underneath.&lt;/p&gt;

&lt;p&gt;If you want to check the projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T3 Code:&lt;/strong&gt; &lt;a href="https://github.com/pingdotgg/t3code" rel="noopener noreferrer"&gt;https://github.com/pingdotgg/t3code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lynkr:&lt;/strong&gt; &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why I’d Use a LLM gateway with Goose</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Wed, 17 Jun 2026 07:15:15 +0000</pubDate>
      <link>https://dev.to/lynkr/why-id-put-lynkr-between-goose-and-my-model-stack-1jpi</link>
      <guid>https://dev.to/lynkr/why-id-put-lynkr-between-goose-and-my-model-stack-1jpi</guid>
      <description>&lt;p&gt;Open-source coding agents are getting a lot more useful, and &lt;strong&gt;Goose&lt;/strong&gt; is one of the clearest examples of that shift.&lt;/p&gt;

&lt;p&gt;Goose is an open-source AI agent that goes beyond autocomplete. It can inspect code, execute tasks, edit files, and work through real development loops that look much closer to &lt;em&gt;install → execute → edit → test&lt;/em&gt; than traditional code assistance.&lt;/p&gt;

&lt;p&gt;That also means Goose creates the exact kind of workload where the model layer starts to matter a lot.&lt;/p&gt;

&lt;p&gt;Once an agent is reading files, retrying commands, generating code, reasoning across context, and iterating through multi-step tasks, the cost and reliability of your model setup stops being a background detail. It becomes part of the product experience.&lt;/p&gt;

&lt;p&gt;That’s why I think the cleaner architecture is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goose
  ↓
Lynkr
  ↓
OpenAI / Anthropic / Ollama / OpenRouter / Bedrock / Azure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words: &lt;strong&gt;use Goose as the coding agent, and use Lynkr as the LLM gateway underneath it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Goose is
&lt;/h2&gt;

&lt;p&gt;If you haven’t looked at it yet, &lt;a href="https://github.com/aaif-goose/goose" rel="noopener noreferrer"&gt;Goose&lt;/a&gt; is an open-source, extensible AI agent built for more than just code suggestions. The project describes it as an agent that can &lt;em&gt;install, execute, edit, and test with any LLM&lt;/em&gt;, which is exactly why it’s interesting.&lt;/p&gt;

&lt;p&gt;That framing matters.&lt;/p&gt;

&lt;p&gt;A lot of developer AI tooling still assumes the model is mostly there to answer questions or generate snippets. Goose is part of the newer wave where the model is expected to participate in a real workflow. That means the token pattern changes too:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;more repeated context&lt;/li&gt;
&lt;li&gt;more tool-style back and forth&lt;/li&gt;
&lt;li&gt;more retries&lt;/li&gt;
&lt;li&gt;more multi-step reasoning&lt;/li&gt;
&lt;li&gt;more chances to waste expensive model calls on easy tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s where a gateway helps.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Lynkr does in this setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt; is an open-source &lt;strong&gt;LLM gateway&lt;/strong&gt;. Instead of wiring Goose directly to a single provider, you point Goose at Lynkr and let Lynkr handle the model layer underneath.&lt;/p&gt;

&lt;p&gt;That gives you one control point for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provider switching&lt;/li&gt;
&lt;li&gt;local + cloud model setups&lt;/li&gt;
&lt;li&gt;fallback handling&lt;/li&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;cleaner long-term infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Goose stays focused on the agent workflow. Lynkr stays focused on how requests should reach the right model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for coding agents specifically
&lt;/h2&gt;

&lt;p&gt;If you only make occasional direct API calls, model choice is simple.&lt;/p&gt;

&lt;p&gt;If you use an agent heavily, it isn’t.&lt;/p&gt;

&lt;p&gt;A Goose session can easily include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;reading repo context&lt;/li&gt;
&lt;li&gt;planning a change&lt;/li&gt;
&lt;li&gt;generating code&lt;/li&gt;
&lt;li&gt;fixing an error&lt;/li&gt;
&lt;li&gt;retrying with more context&lt;/li&gt;
&lt;li&gt;running another step&lt;/li&gt;
&lt;li&gt;revisiting earlier files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is not one request. It is a chain of requests with different complexity levels.&lt;/p&gt;

&lt;p&gt;Some of those steps can run on a cheaper or local model. Some need a stronger cloud model. Some repeat enough context that caching matters. Some need a fallback path because a provider slows down or fails mid-session.&lt;/p&gt;

&lt;p&gt;Without a gateway, that logic ends up scattered or simply ignored.&lt;/p&gt;

&lt;p&gt;With a gateway, you can manage it in one place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic idea: point Goose at Lynkr instead of a raw provider
&lt;/h2&gt;

&lt;p&gt;The exact Goose setup may vary depending on how you run it, but the architecture is straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goose talks to one model endpoint&lt;/li&gt;
&lt;li&gt;that endpoint is Lynkr&lt;/li&gt;
&lt;li&gt;Lynkr forwards to the real provider you want underneath&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical environment setup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:3000/v1
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dummy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run Goose normally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;goose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or for a direct task:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;goose run &lt;span class="s2"&gt;"Review this repo and suggest 3 refactors"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this flow, Goose thinks it’s talking to its configured LLM endpoint. Lynkr handles what happens next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example 1: Run Goose on a local model through Lynkr
&lt;/h2&gt;

&lt;p&gt;Let’s say you want Goose to use a local coding model first.&lt;/p&gt;

&lt;p&gt;A simple Lynkr config might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local-coder&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qwen2.5-coder:14b&lt;/span&gt;

&lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local-coder&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:3000/v1
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dummy

goose run &lt;span class="s2"&gt;"Explain this repository structure and identify dead code"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why do this instead of connecting Goose directly to Ollama?&lt;/p&gt;

&lt;p&gt;Because once Goose is pointed at Lynkr, you can change the backend later without changing the Goose-side integration.&lt;/p&gt;

&lt;p&gt;That means you can start local, then later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;switch to a better coding model&lt;/li&gt;
&lt;li&gt;add a cloud fallback&lt;/li&gt;
&lt;li&gt;route specific workloads differently&lt;/li&gt;
&lt;li&gt;keep the same stable endpoint for Goose&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example 2: Local-first, cloud fallback
&lt;/h2&gt;

&lt;p&gt;A more realistic setup is usually local-first with a stronger cloud fallback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local-fast&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qwen2.5-coder:14b&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cloud-strong&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropic&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-sonnet-4&lt;/span&gt;

&lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local-fast&lt;/span&gt;
  &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cloud-strong&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configure Goose to talk to Lynkr:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:3000
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dummy

goose run &lt;span class="s2"&gt;"Debug why the integration tests are failing and propose a patch"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you a much nicer operating model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cheap/local by default&lt;/li&gt;
&lt;li&gt;stronger cloud help when needed&lt;/li&gt;
&lt;li&gt;Goose workflow stays the same&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example 3: One Goose workflow, multiple providers behind it
&lt;/h2&gt;

&lt;p&gt;One of the biggest advantages of putting a gateway under a coding agent is that your model preferences change all the time.&lt;/p&gt;

&lt;p&gt;Sometimes you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a fast model for lighter steps&lt;/li&gt;
&lt;li&gt;a stronger model for code generation&lt;/li&gt;
&lt;li&gt;a local model for private work&lt;/li&gt;
&lt;li&gt;a backup provider when your main one rate-limits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Lynkr, you don’t need to keep reworking Goose every time you change that strategy.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openrouter&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openai/gpt-4o-mini&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coder&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;anthropic&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;claude-sonnet-4&lt;/span&gt;

  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;qwen2.5-coder:14b&lt;/span&gt;

&lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;coder&lt;/span&gt;
  &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fast&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Goose still uses the same top-level environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_BASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:3000/v1
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dummy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s the part I like most about the gateway pattern: &lt;strong&gt;the agent stays stable while the model layer evolves underneath it.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Lynkr becomes especially useful
&lt;/h2&gt;

&lt;p&gt;There are a few situations where this setup becomes much more valuable than direct provider wiring.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. You want to avoid vendor lock-in
&lt;/h3&gt;

&lt;p&gt;If Goose is wired straight to one provider, every change becomes a reconfiguration problem.&lt;/p&gt;

&lt;p&gt;If Goose is wired to Lynkr, provider changes happen underneath the same gateway layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. You want local + cloud flexibility
&lt;/h3&gt;

&lt;p&gt;A lot of developers want a local-first workflow but still need access to stronger cloud models when tasks get harder.&lt;/p&gt;

&lt;p&gt;That’s much cleaner when Goose talks to one gateway instead of multiple provider-specific setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. You want better cost control
&lt;/h3&gt;

&lt;p&gt;Agent workflows can burn tokens in places that don’t need premium models.&lt;/p&gt;

&lt;p&gt;A gateway gives you a place to route easier work more cheaply.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. You want a more future-proof stack
&lt;/h3&gt;

&lt;p&gt;Coding agents are changing fast. Model providers are changing fast too.&lt;/p&gt;

&lt;p&gt;A stable gateway layer gives you a cleaner architecture than coupling every tool directly to every provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical mental model
&lt;/h2&gt;

&lt;p&gt;The easiest way to think about this is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Goose = behavior layer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lynkr = model control layer&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Goose decides &lt;em&gt;what work to do&lt;/em&gt;.&lt;br&gt;
Lynkr decides &lt;em&gt;where that work should go&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That separation gets more useful as your workflows get more agentic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Goose is part of a bigger shift in developer tools. We’re moving from AI assistants that mostly answer questions to coding agents that can actually work through tasks.&lt;/p&gt;

&lt;p&gt;As that shift happens, the model layer matters more.&lt;/p&gt;

&lt;p&gt;If you connect Goose directly to a provider, it works.&lt;/p&gt;

&lt;p&gt;If you connect Goose to &lt;strong&gt;Lynkr&lt;/strong&gt;, you get a cleaner long-term setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one stable gateway&lt;/li&gt;
&lt;li&gt;easier provider switching&lt;/li&gt;
&lt;li&gt;local/cloud flexibility&lt;/li&gt;
&lt;li&gt;fallback support&lt;/li&gt;
&lt;li&gt;better control over how your coding agent uses models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why I’d rather put Goose on top of an LLM gateway than wire it straight to a raw provider.&lt;/p&gt;

&lt;p&gt;If you’re already experimenting with Goose, this is one of the simplest ways to make the setup more flexible without changing the agent workflow itself.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goose: &lt;a href="https://github.com/aaif-goose/goose" rel="noopener noreferrer"&gt;https://github.com/aaif-goose/goose&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lynkr: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Configure LibreChat with Lynkr Using a Custom OpenAI-Compatible Endpoint</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Tue, 16 Jun 2026 05:02:25 +0000</pubDate>
      <link>https://dev.to/lynkr/how-to-configure-librechat-with-lynkr-using-a-custom-openai-compatible-endpoint-3423</link>
      <guid>https://dev.to/lynkr/how-to-configure-librechat-with-lynkr-using-a-custom-openai-compatible-endpoint-3423</guid>
      <description>&lt;p&gt;LibreChat is one of the best open-source AI chat and agent surfaces for teams that want self-hosting, MCP support, flexible model backends, and a real product surface instead of a demo UI.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt; is an open-source &lt;strong&gt;LLM gateway&lt;/strong&gt; built for coding assistants, agents, and MCP-heavy workflows. It gives you one OpenAI-compatible endpoint in front of multiple providers, with routing, caching, and cleaner model infrastructure behind it.&lt;/p&gt;

&lt;p&gt;Put together, they make a clean split:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LibreChat&lt;/strong&gt; handles the app layer: chat UI, agents, files, MCP, user workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lynkr&lt;/strong&gt; handles the gateway layer: routing, provider switching, fallback, caching, and model control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why this pairing works so well. LibreChat already supports custom OpenAI-compatible endpoints, and Lynkr is a strong fit for the kind of multi-provider, tool-using, agentic traffic LibreChat users actually generate.&lt;/p&gt;

&lt;p&gt;This article is the practical follow-up to the architecture case: the goal here is to get LibreChat talking to Lynkr with a minimal working setup.&lt;/p&gt;

&lt;p&gt;I built Lynkr, so founder disclosure applies. I’m keeping this grounded to what LibreChat and Lynkr support today.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Lynkr fits LibreChat especially well
&lt;/h2&gt;

&lt;p&gt;There are plenty of tools that can sit between an app and a model provider, but Lynkr is a particularly strong fit for LibreChat for a few reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI-compatible endpoint&lt;/strong&gt;: LibreChat already has a clean seam for custom OpenAI-compatible APIs, which makes Lynkr easy to drop in underneath it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for agentic traffic&lt;/strong&gt;: LibreChat is not just plain chat. It supports agents, MCP, tools, and more complex request patterns. Lynkr is designed for those heavier workflows, not just one-shot completions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing + caching in one place&lt;/strong&gt;: if you want LibreChat to stay clean at the product layer while the backend evolves, Lynkr gives you a better home for that logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider portability&lt;/strong&gt;: you can keep LibreChat stable while moving between Ollama, OpenRouter, Bedrock, OpenAI, and others behind the gateway&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good fit for MCP and coding workflows&lt;/strong&gt;: Lynkr was built around the kind of traffic these users actually generate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means this setup is not just “put any proxy in front of LibreChat.” It is specifically about using a gateway that matches the workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you need
&lt;/h2&gt;

&lt;p&gt;Before starting, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a running &lt;strong&gt;LibreChat&lt;/strong&gt; instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js 20+&lt;/strong&gt; for Lynkr&lt;/li&gt;
&lt;li&gt;at least one backend provider configured in Lynkr&lt;/li&gt;
&lt;li&gt;one LibreChat endpoint that points to Lynkr instead of directly to a provider&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repo references:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LibreChat:&lt;/strong&gt; &lt;a href="https://github.com/danny-avila/LibreChat" rel="noopener noreferrer"&gt;github.com/danny-avila/LibreChat&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lynkr:&lt;/strong&gt; &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;github.com/Fast-Editor/Lynkr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two details matter here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;LibreChat explicitly supports &lt;strong&gt;custom OpenAI-compatible APIs&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Lynkr exposes an &lt;strong&gt;OpenAI-compatible &lt;code&gt;/v1&lt;/code&gt; endpoint&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s the seam we’re using.&lt;/p&gt;




&lt;h2&gt;
  
  
  The target architecture
&lt;/h2&gt;

&lt;p&gt;The setup we want looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
  ↓
LibreChat
  ↓
Lynkr (OpenAI-compatible endpoint)
  ↓
OpenAI / Bedrock / OpenRouter / Ollama / Anthropic-compatible backends / others
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LibreChat owns the chat UI, agents, MCP, files, and workflows&lt;/li&gt;
&lt;li&gt;Lynkr owns routing, caching, and model-side control&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Install and start Lynkr
&lt;/h2&gt;

&lt;p&gt;Install Lynkr globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; lynkr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create a minimal &lt;code&gt;.env&lt;/code&gt; for Lynkr.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example A: local testing with Ollama
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MODEL_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama
&lt;span class="nv"&gt;OLLAMA_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:11434
&lt;span class="nv"&gt;OLLAMA_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;qwen2.5-coder:latest
&lt;span class="nv"&gt;FALLBACK_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
&lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8081
&lt;span class="nv"&gt;PROMPT_CACHE_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;&lt;span class="nv"&gt;SEMANTIC_CACHE_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start Lynkr:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lynkr start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example B: cloud setup with OpenRouter
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;MODEL_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;openrouter
&lt;span class="nv"&gt;OPENROUTER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_openrouter_key
&lt;span class="nv"&gt;FALLBACK_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false
&lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8081
&lt;span class="nv"&gt;PROMPT_CACHE_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;&lt;span class="nv"&gt;SEMANTIC_CACHE_ENABLED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lynkr start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optional direct smoke test against Lynkr
&lt;/h3&gt;

&lt;p&gt;Before touching LibreChat, you can test Lynkr directly with a simple OpenAI-compatible request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8081/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer dummy-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Say hello in one sentence."}]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If that succeeds, the gateway path is working before LibreChat is added on top.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick health check
&lt;/h3&gt;

&lt;p&gt;Once Lynkr is running, verify the endpoint responds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8081/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get a JSON response showing the service is running.&lt;/p&gt;

&lt;p&gt;At this point, Lynkr should expose an OpenAI-compatible base URL at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8081/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the URL LibreChat should talk to.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Decide how LibreChat should see Lynkr
&lt;/h2&gt;

&lt;p&gt;LibreChat supports custom endpoints and also lets users provide a custom &lt;code&gt;baseURL&lt;/code&gt; for supported endpoint flows.&lt;/p&gt;

&lt;p&gt;For this setup, the important part is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LibreChat should send requests to &lt;strong&gt;Lynkr’s &lt;code&gt;/v1&lt;/code&gt; base URL&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;LibreChat should use a model name that Lynkr will accept and route&lt;/li&gt;
&lt;li&gt;LibreChat should not need to know which upstream provider you finally use behind Lynkr&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the mental model is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LibreChat config → one base URL → Lynkr
Lynkr config → actual providers, routing, fallback, cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That separation is the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Add Lynkr as the LibreChat custom endpoint
&lt;/h2&gt;

&lt;p&gt;The exact UI path can differ depending on how you run LibreChat and how you expose custom endpoints, but the working shape is the same.&lt;/p&gt;

&lt;p&gt;In LibreChat, configure a custom OpenAI-compatible endpoint with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base URL:&lt;/strong&gt; &lt;code&gt;http://localhost:8081/v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API key:&lt;/strong&gt; any value Lynkr accepts for your setup, or the key your deployment expects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; a model string that Lynkr can map or forward&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Minimal example values
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Endpoint Type: Custom OpenAI-compatible endpoint
Base URL: http://localhost:8081/v1
API Key: dummy-key
Model: gpt-4o-mini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your LibreChat instance and Lynkr instance run on different hosts, replace &lt;code&gt;localhost&lt;/code&gt; with the actual reachable host:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://lynkr.internal:8081/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://lynkr.yourdomain.com/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are running LibreChat in Docker and Lynkr on the host machine, you may need to use a host-reachable name rather than &lt;code&gt;localhost&lt;/code&gt;, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://host.docker.internal:8081/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s one of the most common gotchas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Pick a model name strategy
&lt;/h2&gt;

&lt;p&gt;This part trips people up more than it should.&lt;/p&gt;

&lt;p&gt;LibreChat wants a model name. Lynkr also needs to know what to do with that model name.&lt;/p&gt;

&lt;p&gt;There are two clean ways to handle this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: pass through a real model name
&lt;/h3&gt;

&lt;p&gt;Use a model name that corresponds to the backend you want Lynkr to use.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gpt-4o-mini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;claude-3-5-sonnet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the simplest starting point if Lynkr is forwarding traffic in a straightforward way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: use stable logical model names in LibreChat
&lt;/h3&gt;

&lt;p&gt;A better long-term pattern is to let LibreChat use a stable name like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chat-fast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chat-quality
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then map those choices in the gateway layer.&lt;/p&gt;

&lt;p&gt;That way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LibreChat users keep the same model choices&lt;/li&gt;
&lt;li&gt;Lynkr can change the real backend later&lt;/li&gt;
&lt;li&gt;you can move from OpenRouter to Bedrock or from cloud to local without rewriting the app-side model menu&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you do not formalize that on day one, this is the direction I’d recommend.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Run a smoke test from LibreChat
&lt;/h2&gt;

&lt;p&gt;Once the endpoint is configured, test a simple chat request first.&lt;/p&gt;

&lt;p&gt;Use something cheap and easy to inspect, like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Write a Python function that reverses a string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If that works, test a second request that makes backend behavior easier to reason about, like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Summarize the difference between Redis and PostgreSQL in 5 bullets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What you’re looking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LibreChat sends successfully to Lynkr&lt;/li&gt;
&lt;li&gt;Lynkr forwards successfully to the configured provider&lt;/li&gt;
&lt;li&gt;the response comes back normally in LibreChat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this works, the base integration is done.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Add one routing policy behind Lynkr
&lt;/h2&gt;

&lt;p&gt;This is where the setup becomes more useful than direct provider wiring.&lt;/p&gt;

&lt;p&gt;A good first pattern is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;route lightweight general chat to a cheaper model&lt;/li&gt;
&lt;li&gt;route harder reasoning or code-heavy work to a stronger model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conceptually, the setup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LibreChat user chooses: chat-fast
  → Lynkr routes to cheaper tier

LibreChat user chooses: chat-quality
  → Lynkr routes to stronger tier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even without exposing every provider in LibreChat, you still get flexibility behind the gateway.&lt;/p&gt;

&lt;p&gt;That’s cleaner than giving end users six raw vendor choices and expecting them to know when each one is appropriate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: Add fallback once the happy path works
&lt;/h2&gt;

&lt;p&gt;Do not start with fallback complexity on the first try. Get one provider working first.&lt;/p&gt;

&lt;p&gt;After that, the next useful improvement is fallback.&lt;/p&gt;

&lt;p&gt;Example pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;primary backend: OpenRouter&lt;/li&gt;
&lt;li&gt;fallback backend: Bedrock&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;primary backend: local Ollama model&lt;/li&gt;
&lt;li&gt;fallback backend: stronger cloud model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This gives you a much better operational story than “LibreChat is hardwired to one provider and breaks when that provider has a bad day.”&lt;/p&gt;

&lt;p&gt;That’s one of the clearest reasons to keep failover logic below the app layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  A concrete request flow example
&lt;/h2&gt;

&lt;p&gt;Here’s what this looks like in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Without Lynkr
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LibreChat → OpenAI directly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to change providers, add fallback, or introduce routing, those concerns start leaking into the app layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  With Lynkr
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LibreChat → Lynkr → OpenRouter
                    ↘ Bedrock fallback
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LibreChat stays pointed at one endpoint.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;less config churn in the app&lt;/li&gt;
&lt;li&gt;easier backend changes&lt;/li&gt;
&lt;li&gt;cleaner rollout of new models&lt;/li&gt;
&lt;li&gt;a better place to add caching and routing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common gotchas
&lt;/h2&gt;

&lt;p&gt;Here are the ones most likely to waste your time.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Wrong base URL
&lt;/h2&gt;

&lt;p&gt;If you point LibreChat at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8081
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8081/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you may hit endpoint mismatches depending on how the OpenAI-compatible client path is built.&lt;/p&gt;

&lt;p&gt;Use the &lt;code&gt;/v1&lt;/code&gt; base URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Docker networking confusion
&lt;/h2&gt;

&lt;p&gt;If LibreChat runs in Docker, &lt;code&gt;localhost&lt;/code&gt; usually means &lt;strong&gt;the container itself&lt;/strong&gt;, not your host machine.&lt;/p&gt;

&lt;p&gt;Use a network-reachable host such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://host.docker.internal:8081/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or a proper internal hostname.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Model name mismatch
&lt;/h2&gt;

&lt;p&gt;If LibreChat sends a model string Lynkr does not recognize or route correctly, requests will fail even though the endpoint is reachable.&lt;/p&gt;

&lt;p&gt;When debugging, simplify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pick one known model string&lt;/li&gt;
&lt;li&gt;use one provider&lt;/li&gt;
&lt;li&gt;get one request working&lt;/li&gt;
&lt;li&gt;only then layer routing or aliases on top&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Starting with too much complexity
&lt;/h2&gt;

&lt;p&gt;Don’t try to validate all of these at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;custom endpoint&lt;/li&gt;
&lt;li&gt;multiple providers&lt;/li&gt;
&lt;li&gt;fallback&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;agents&lt;/li&gt;
&lt;li&gt;MCP tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get the base chat completion path working first.&lt;/p&gt;

&lt;p&gt;Then expand.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Treating LibreChat like the provider control plane
&lt;/h2&gt;

&lt;p&gt;LibreChat is excellent at the user/product layer.&lt;/p&gt;

&lt;p&gt;But if you keep using the app layer to own provider switching, cost control, and failover, you lose the main architectural benefit of using a gateway underneath it.&lt;/p&gt;

&lt;p&gt;Keep the responsibilities split.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this setup is worth it
&lt;/h2&gt;

&lt;p&gt;Even the minimal version gives you a better foundation than direct provider wiring.&lt;/p&gt;

&lt;p&gt;You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;one stable endpoint&lt;/strong&gt; in LibreChat&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;provider portability&lt;/strong&gt; behind the scenes&lt;/li&gt;
&lt;li&gt;a better place for &lt;strong&gt;routing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a better place for &lt;strong&gt;fallback&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a better place for &lt;strong&gt;caching&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a cleaner path from simple chat UI to broader agent infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And as your setup grows, that separation only gets more valuable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Minimal checklist
&lt;/h2&gt;

&lt;p&gt;If you just want the shortest possible version, this is it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install Lynkr&lt;/li&gt;
&lt;li&gt;Start Lynkr on port &lt;code&gt;8081&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Verify &lt;code&gt;http://localhost:8081/v1&lt;/code&gt; is reachable&lt;/li&gt;
&lt;li&gt;In LibreChat, add a custom OpenAI-compatible endpoint&lt;/li&gt;
&lt;li&gt;Set the base URL to &lt;code&gt;http://localhost:8081/v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use a model string Lynkr can route&lt;/li&gt;
&lt;li&gt;Run one smoke-test prompt&lt;/li&gt;
&lt;li&gt;Only after that, add routing and fallback&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Final take
&lt;/h2&gt;

&lt;p&gt;LibreChat already gives you the hard part: a good open-source surface for chat, agents, MCP, and self-hosting.&lt;/p&gt;

&lt;p&gt;Lynkr gives you the missing infrastructure layer under it.&lt;/p&gt;

&lt;p&gt;That combination is stronger than pushing all model concerns into the app itself.&lt;/p&gt;

&lt;p&gt;If you’re building a self-hosted AI stack that needs to survive provider churn, model changes, and growing workflow complexity, this is the shape I’d use.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LibreChat:&lt;/strong&gt; &lt;a href="https://github.com/danny-avila/LibreChat" rel="noopener noreferrer"&gt;github.com/danny-avila/LibreChat&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lynkr:&lt;/strong&gt; &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;github.com/Fast-Editor/Lynkr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this article was useful, star the repos and let me know if you want the next one to go deeper on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LibreChat + Lynkr with Docker Compose&lt;/li&gt;
&lt;li&gt;model aliases and routing strategy&lt;/li&gt;
&lt;li&gt;using LibreChat agents on top of a Lynkr-backed stack&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Cut Microsoft Agent Framework Costs With a Gateway Layer</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Sun, 14 Jun 2026 09:19:54 +0000</pubDate>
      <link>https://dev.to/lynkr/how-to-cut-microsoft-agent-framework-costs-with-a-gateway-layer-5gke</link>
      <guid>https://dev.to/lynkr/how-to-cut-microsoft-agent-framework-costs-with-a-gateway-layer-5gke</guid>
      <description>&lt;p&gt;Microsoft Agent Framework is built for production multi-agent systems, which is exactly why its LLM bill can grow faster than expected. If you are running workflows with retries, handoffs, tools, and checkpoints, the easiest savings do not come from prompting harder — they come from adding a gateway layer under the framework.&lt;/p&gt;

&lt;p&gt;I built Lynkr, so obvious founder disclosure: this article uses Lynkr as the gateway example. I’ll keep it practical and focus on where the cost actually shows up in Microsoft Agent Framework workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is a real Microsoft Agent Framework problem
&lt;/h2&gt;

&lt;p&gt;The current Microsoft Agent Framework README positions it as a production-grade framework for Python and .NET, with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multi-agent workflows&lt;/li&gt;
&lt;li&gt;sequential, concurrent, handoff, and group collaboration patterns&lt;/li&gt;
&lt;li&gt;middleware&lt;/li&gt;
&lt;li&gt;observability&lt;/li&gt;
&lt;li&gt;provider flexibility&lt;/li&gt;
&lt;li&gt;checkpointing and human-in-the-loop flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly the kind of stack where token usage grows quietly.&lt;/p&gt;

&lt;p&gt;A single prompt-response app is easy to reason about. A production workflow is not. Once you add routing, retries, multiple agents, MCP tools, and long-lived execution state, the same context starts getting resent over and over.&lt;/p&gt;

&lt;p&gt;That creates four predictable cost leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the spend comes from in Microsoft Agent Framework workloads
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Repeated shared context across agents
&lt;/h3&gt;

&lt;p&gt;Multi-agent systems reuse a lot of the same context:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;task instructions&lt;/li&gt;
&lt;li&gt;tool definitions&lt;/li&gt;
&lt;li&gt;previous messages&lt;/li&gt;
&lt;li&gt;workflow state&lt;/li&gt;
&lt;li&gt;grounding context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even when the framework orchestrates cleanly, the model provider still sees repeated input tokens.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tool-heavy steps explode prompt size
&lt;/h3&gt;

&lt;p&gt;Once agents start using tools, responses stop looking like simple chat. You get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search results&lt;/li&gt;
&lt;li&gt;file reads&lt;/li&gt;
&lt;li&gt;JSON blobs&lt;/li&gt;
&lt;li&gt;browser outputs&lt;/li&gt;
&lt;li&gt;execution traces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those payloads are often much larger than the user’s actual request.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Every task does not need the same model
&lt;/h3&gt;

&lt;p&gt;A workflow step that says “classify this,” “summarize these logs,” or “extract the next action” does not need the same model as “resolve a hard bug across four files.”&lt;/p&gt;

&lt;p&gt;Without a routing layer, teams overpay by sending too much easy work to premium models.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Retries and loops multiply waste
&lt;/h3&gt;

&lt;p&gt;Production agent systems do retries, fallbacks, approvals, and re-runs. That is good engineering. It is also how token bills get weird at the end of the month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gateway pattern that fits Microsoft Agent Framework
&lt;/h2&gt;

&lt;p&gt;The cleanest setup is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Microsoft Agent Framework app
        ↓
     Lynkr gateway
        ↓
OpenAI / Azure OpenAI / Bedrock / OpenRouter / Ollama / Databricks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The framework keeps doing orchestration. The gateway handles cost control under it.&lt;/p&gt;

&lt;p&gt;That split matters because you do &lt;strong&gt;not&lt;/strong&gt; want cost logic duplicated across every agent, every workflow node, and every environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Lynkr changes underneath the framework
&lt;/h2&gt;

&lt;p&gt;Lynkr is a self-hosted LLM gateway for Claude Code, Cursor, Codex, and general OpenAI-compatible workloads. In the current README and benchmark report, the grounded claims I can safely use here are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;version &lt;code&gt;9.5.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;13+ providers&lt;/li&gt;
&lt;li&gt;zero code changes at the app layer once the base URL points at the gateway&lt;/li&gt;
&lt;li&gt;benchmarked token reductions from smart tool selection and JSON compression&lt;/li&gt;
&lt;li&gt;semantic cache hits around 171ms in the published benchmark report&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The part that makes it useful for Microsoft Agent Framework is not “one more abstraction layer.” It is that the framework keeps its orchestration role while the gateway centralizes the three cost levers that matter most.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Prompt and semantic caching
&lt;/h3&gt;

&lt;p&gt;Agent workflows repeat themselves more than most teams realize.&lt;/p&gt;

&lt;p&gt;A classification step comes back with the same shape.&lt;br&gt;
A retry asks nearly the same thing again.&lt;br&gt;
A second agent gets almost the same upstream context.&lt;br&gt;
A human-in-the-loop resume often replays the same state plus one decision.&lt;/p&gt;

&lt;p&gt;Caching is how you stop paying full price for near-duplicate work.&lt;/p&gt;

&lt;p&gt;In Lynkr’s published benchmark report, semantic cache hits returned in &lt;strong&gt;171ms&lt;/strong&gt;. That speed matters in production workflows because lower latency compounds with lower spend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tool payload compression
&lt;/h3&gt;

&lt;p&gt;This is the least talked-about savings lever, and one of the most useful.&lt;/p&gt;

&lt;p&gt;Microsoft Agent Framework makes it easier to build workflows that use tools. But once tools start returning structured output, your bottleneck becomes payload size, not just model choice.&lt;/p&gt;

&lt;p&gt;Lynkr’s benchmark report shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;53% fewer tokens&lt;/strong&gt; on tool-heavy requests through smart tool selection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;87.6% compression&lt;/strong&gt; on large JSON tool results in the benchmarked scenario&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That maps well to framework workloads that push around logs, traces, extracted documents, or structured tool responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tier routing
&lt;/h3&gt;

&lt;p&gt;Not every orchestration step should hit the same model.&lt;/p&gt;

&lt;p&gt;A practical tiering setup looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;simple extraction or classification → cheaper fast model&lt;/li&gt;
&lt;li&gt;normal agent work → balanced model&lt;/li&gt;
&lt;li&gt;deep reasoning or hard refactors → premium model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the difference between “we support multiple providers” and “we actively spend less.”&lt;/p&gt;

&lt;p&gt;Microsoft Agent Framework already gives you the orchestration surface. A gateway adds the policy layer under it.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete use case: customer support triage agents
&lt;/h2&gt;

&lt;p&gt;This is the use case I think is under-covered and a very good fit for Lynkr.&lt;/p&gt;

&lt;p&gt;Imagine a support workflow built with Microsoft Agent Framework:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ingest a new ticket&lt;/li&gt;
&lt;li&gt;classify product area and urgency&lt;/li&gt;
&lt;li&gt;summarize the issue&lt;/li&gt;
&lt;li&gt;search internal docs or run retrieval&lt;/li&gt;
&lt;li&gt;draft a response&lt;/li&gt;
&lt;li&gt;escalate only ambiguous or risky cases to a stronger model or a human&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most of those steps are &lt;strong&gt;not&lt;/strong&gt; equally hard.&lt;/p&gt;

&lt;p&gt;If every one of them uses the same premium model, you pay premium price for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classification&lt;/li&gt;
&lt;li&gt;deduplication&lt;/li&gt;
&lt;li&gt;templated summaries&lt;/li&gt;
&lt;li&gt;known-answer lookups&lt;/li&gt;
&lt;li&gt;low-risk drafts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly where a gateway helps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this works especially well
&lt;/h3&gt;

&lt;p&gt;Support triage has all three patterns a gateway can optimize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repeated ticket shapes → cacheable&lt;/li&gt;
&lt;li&gt;structured tool results from retrieval/search → compressible&lt;/li&gt;
&lt;li&gt;mixed difficulty across workflow steps → routable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of baking cost logic into each agent, you let the framework orchestrate and let the gateway decide how expensive each turn should be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example architecture
&lt;/h2&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;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dummy&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:8081/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Your Microsoft Agent Framework components can keep using an OpenAI-compatible endpoint
# while Lynkr handles routing, caching, and payload optimization underneath.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is not this exact snippet. The point is the boundary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your agents keep their workflow logic&lt;/li&gt;
&lt;li&gt;your framework keeps orchestration&lt;/li&gt;
&lt;li&gt;your gateway handles provider choice, caching, and token reduction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I would route differently in this workload
&lt;/h2&gt;

&lt;p&gt;If I were wiring Microsoft Agent Framework for support triage, I would usually do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ticket classification&lt;/strong&gt; → cheap fast model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAQ / known-issue matching&lt;/strong&gt; → cheap fast model plus cache&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;retrieval-grounded answer draft&lt;/strong&gt; → mid-tier model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;escalation for ambiguous, legal, or high-risk cases&lt;/strong&gt; → strongest model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;repeat follow-up questions on the same issue&lt;/strong&gt; → let cache catch them where possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a much stronger operating model than “default everything to the best model and hope prompt engineering saves us later.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Where competitors can still win
&lt;/h2&gt;

&lt;p&gt;Fairness note: if your top priority is enterprise dashboards, centralized governance, or deeper out-of-the-box observability, other gateway products can be stronger on those axes.&lt;/p&gt;

&lt;p&gt;But for Microsoft Agent Framework teams trying to reduce the cost of agentic workloads without rewriting the app, the combination I care about is simpler:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep the framework for orchestration&lt;/li&gt;
&lt;li&gt;insert a gateway once&lt;/li&gt;
&lt;li&gt;let caching, compression, and tier routing do the cost work globally&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The practical takeaway
&lt;/h2&gt;

&lt;p&gt;Microsoft Agent Framework makes it easier to build serious agent systems. That also means it makes it easier to accidentally overpay for them.&lt;/p&gt;

&lt;p&gt;The underused pattern is not “choose a cheaper model.” It is putting a gateway layer under the framework so repeated context, oversized tool payloads, and easy workflow steps stop being billed like hard reasoning.&lt;/p&gt;

&lt;p&gt;That is the real use case for Lynkr here: &lt;strong&gt;production multi-agent workflows where the waste comes from orchestration overhead, not just model price.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want, I can write a follow-up with a full Microsoft Agent Framework example using a support triage workflow and a concrete Lynkr routing setup.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LiteLLM vs Lynkr for AI Coding Workflows: Where the Token Savings Actually Come From</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Wed, 10 Jun 2026 20:58:28 +0000</pubDate>
      <link>https://dev.to/lynkr/litellm-vs-lynkr-for-ai-coding-workflows-where-the-token-savings-actually-come-from-1482</link>
      <guid>https://dev.to/lynkr/litellm-vs-lynkr-for-ai-coding-workflows-where-the-token-savings-actually-come-from-1482</guid>
      <description>&lt;p&gt;Most LLM gateways promise the same thing: one endpoint, many providers. That part is useful, but it is not where the real savings come from in AI coding workflows.&lt;/p&gt;

&lt;p&gt;The expensive part is what happens inside repeated coding sessions: oversized tool schemas, large JSON tool results, repeated context, and using expensive models for turns that do not need them.&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;, so take this as a founder comparison. I’ll keep it honest: LiteLLM is a solid provider abstraction layer. But if your goal is specifically to reduce spend in Claude Code, Cursor, or Codex-style workflows, the difference is not “which gateway supports more providers.” The difference is whether the gateway cuts tokens &lt;em&gt;before they reach the model&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with most “gateway savings” claims
&lt;/h2&gt;

&lt;p&gt;There are a few common ways gateways claim to save money:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;route to cheaper models&lt;/li&gt;
&lt;li&gt;add fallbacks&lt;/li&gt;
&lt;li&gt;centralize traffic&lt;/li&gt;
&lt;li&gt;track budgets&lt;/li&gt;
&lt;li&gt;cache exact repeated prompts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of that helps.&lt;/p&gt;

&lt;p&gt;But coding workflows have a different cost shape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the same repo context is sent over and over&lt;/li&gt;
&lt;li&gt;tool definitions balloon every request&lt;/li&gt;
&lt;li&gt;tool outputs can be huge&lt;/li&gt;
&lt;li&gt;not every turn deserves the strongest model&lt;/li&gt;
&lt;li&gt;agent loops magnify small inefficiencies into large bills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why “multi-provider support” is not enough. You need token reduction at the gateway layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I benchmarked
&lt;/h2&gt;

&lt;p&gt;I recently ran a benchmark comparing Lynkr and LiteLLM on the &lt;strong&gt;same backend providers&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ollama local&lt;/li&gt;
&lt;li&gt;Moonshot&lt;/li&gt;
&lt;li&gt;Azure OpenAI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The benchmark covered 9 scenarios across 4 feature categories, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tool-heavy requests&lt;/li&gt;
&lt;li&gt;large JSON tool outputs&lt;/li&gt;
&lt;li&gt;paraphrased cache hits&lt;/li&gt;
&lt;li&gt;simple vs complex routing decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full report:&lt;br&gt;
&lt;a href="https://github.com/Fast-Editor/Lynkr/blob/main/BENCHMARK_REPORT.md" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr/blob/main/BENCHMARK_REPORT.md&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Smart tool selection: 53% fewer tokens
&lt;/h2&gt;

&lt;p&gt;One of the easiest ways to waste tokens is forwarding every possible tool definition on every request.&lt;/p&gt;

&lt;p&gt;A read-only question does not need write, edit, bash, or git tools. But that still happens in a lot of setups.&lt;/p&gt;

&lt;p&gt;Lynkr classifies the request and strips irrelevant tool schemas before forwarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark result
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proxy&lt;/th&gt;
&lt;th&gt;Tokens billed&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lynkr&lt;/td&gt;
&lt;td&gt;959&lt;/td&gt;
&lt;td&gt;$0.0044&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiteLLM&lt;/td&gt;
&lt;td&gt;2,085&lt;/td&gt;
&lt;td&gt;$0.0091&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Result: 53% fewer tokens, 52% cheaper on the same model and prompt.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That matters because coding sessions are not one-shot prompts. If every turn is carrying unnecessary tool baggage, your costs quietly double.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Large JSON tool results: 87.6% fewer tokens
&lt;/h2&gt;

&lt;p&gt;Another hidden cost is tool output.&lt;/p&gt;

&lt;p&gt;If a bash command, grep, file read, or agent step returns a large structured JSON payload, that payload gets forwarded to the model. And that gets expensive fast.&lt;/p&gt;

&lt;p&gt;Lynkr uses &lt;strong&gt;TOON compression&lt;/strong&gt; for large JSON tool results before sending them upstream.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark result
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proxy&lt;/th&gt;
&lt;th&gt;Tokens billed&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;Latency&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lynkr&lt;/td&gt;
&lt;td&gt;427&lt;/td&gt;
&lt;td&gt;$0.009&lt;/td&gt;
&lt;td&gt;12s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LiteLLM&lt;/td&gt;
&lt;td&gt;3,458&lt;/td&gt;
&lt;td&gt;$0.018&lt;/td&gt;
&lt;td&gt;12s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Result: 87.6% compression and 50% cheaper, with the same latency in this benchmark.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the kind of optimization that matters in real agent workflows, because those systems often generate verbose intermediate outputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Semantic cache: 171ms responses, 0 billed tokens on cache hit
&lt;/h2&gt;

&lt;p&gt;Exact-match caching is useful, but coding workflows often produce near-duplicate prompts rather than byte-for-byte repeats.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Explain TCP vs UDP”&lt;/li&gt;
&lt;li&gt;“What is the difference between TCP and UDP?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lynkr uses semantic caching, so paraphrased prompts can hit cache too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark result
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Tokens billed&lt;/th&gt;
&lt;th&gt;Response time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First call (cold)&lt;/td&gt;
&lt;td&gt;2,857&lt;/td&gt;
&lt;td&gt;1,891ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Second call (paraphrased cache hit)&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;171ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Result: 171ms response time and 0 billed tokens on cache hit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is the kind of win that changes the economics of repeated team usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Tier routing: not every prompt deserves the same model
&lt;/h2&gt;

&lt;p&gt;Routing to the cheapest available model is not the same thing as routing &lt;em&gt;correctly&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If someone asks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“What does git stash do?” → local/free model is fine&lt;/li&gt;
&lt;li&gt;“Design a secure JWT vs cookie architecture for banking auth” → that should escalate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lynkr scores requests across &lt;strong&gt;15 dimensions&lt;/strong&gt; including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;token count&lt;/li&gt;
&lt;li&gt;code complexity&lt;/li&gt;
&lt;li&gt;reasoning markers&lt;/li&gt;
&lt;li&gt;risk patterns&lt;/li&gt;
&lt;li&gt;agentic signals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it routes automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benchmark result
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Request&lt;/th&gt;
&lt;th&gt;Lynkr&lt;/th&gt;
&lt;th&gt;LiteLLM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;“What does git stash do?”&lt;/td&gt;
&lt;td&gt;local/free tier&lt;/td&gt;
&lt;td&gt;local/free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JWT vs cookies security analysis&lt;/td&gt;
&lt;td&gt;cloud model&lt;/td&gt;
&lt;td&gt;cheapest local model&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That difference matters. Cheap routing is only good when it is still the right call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monthly cost projection
&lt;/h2&gt;

&lt;p&gt;The benchmark includes a simple cost projection for &lt;strong&gt;100,000 requests/month&lt;/strong&gt; using a tool-heavy agentic workload:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Proxy&lt;/th&gt;
&lt;th&gt;Monthly cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LiteLLM&lt;/td&gt;
&lt;td&gt;~$818&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lynkr&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$409&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;That is roughly 50% cheaper on the same backend.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the key point: if you compare gateways fairly on equal footing, the savings do not come from magic. They come from removing waste before tokens ever hit the provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where LiteLLM is still strong
&lt;/h2&gt;

&lt;p&gt;LiteLLM is still a strong product if your main need is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provider abstraction&lt;/li&gt;
&lt;li&gt;budget controls&lt;/li&gt;
&lt;li&gt;standard proxy behavior&lt;/li&gt;
&lt;li&gt;existing Python-heavy infra&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want a broad proxy layer and do not care much about coding-workflow-specific token optimization, LiteLLM is a reasonable choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Lynkr is different
&lt;/h2&gt;

&lt;p&gt;Lynkr is built around AI coding and agent workflows specifically.&lt;/p&gt;

&lt;p&gt;That means it focuses on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;smart tool selection&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TOON compression for large JSON outputs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;semantic cache&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;automatic complexity-based tier routing&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MCP integration&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code Mode&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;long-term memory&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;drop-in compatibility for Claude Code, Cursor, and Codex&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;13+ providers supported&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Mode&lt;/strong&gt; reduces MCP tool-definition overhead by &lt;strong&gt;~96%&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0 code changes required&lt;/strong&gt; for drop-in integration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The real takeaway
&lt;/h2&gt;

&lt;p&gt;If all you want is “many providers behind one API,” a gateway like LiteLLM covers that.&lt;/p&gt;

&lt;p&gt;But if your actual goal is to make AI coding infrastructure materially cheaper, the important question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the gateway reduce tokens before they reach the model?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That is where the biggest savings come from.&lt;/p&gt;

&lt;p&gt;For AI coding workflows, the biggest cost levers are usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;removing irrelevant tools&lt;/li&gt;
&lt;li&gt;compressing tool output&lt;/li&gt;
&lt;li&gt;caching semantically similar turns&lt;/li&gt;
&lt;li&gt;routing simple requests to cheap models and escalating only when needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the layer I built Lynkr around.&lt;/p&gt;

&lt;p&gt;If you want to look at the benchmark or try it yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Benchmark report: &lt;a href="https://github.com/Fast-Editor/Lynkr/blob/main/BENCHMARK_REPORT.md" rel="noopener noreferrer"&gt;https://github.com/Fast-Editor/Lynkr/blob/main/BENCHMARK_REPORT.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are building around Claude Code, Cursor, Codex, or MCP workflows, I’d be curious what your biggest source of token waste has been.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How Efficient Model Routing can save upto 80% in AI costs without compromising the quality of the output</title>
      <dc:creator>Lynkr</dc:creator>
      <pubDate>Wed, 10 Jun 2026 04:01:33 +0000</pubDate>
      <link>https://dev.to/lynkr/explainable-llm-routing-is-the-missing-layer-in-agentic-systems-and-why-it-matters-for-lynkr-12ph</link>
      <guid>https://dev.to/lynkr/explainable-llm-routing-is-the-missing-layer-in-agentic-systems-and-why-it-matters-for-lynkr-12ph</guid>
      <description>&lt;p&gt;Why did this workflow get cheaper last week?&lt;/p&gt;

&lt;p&gt;Why did support quality drop after a routing change?&lt;/p&gt;

&lt;p&gt;Was the failure caused by the model, the router, or the task decomposition?&lt;/p&gt;

&lt;p&gt;Most multi-model systems can route for cost. Very few can explain why a task was sent to a specific model, what tradeoff was made, and whether the cheaper path was actually justified.&lt;/p&gt;

&lt;p&gt;That is not just a research gap. It is an operational one.&lt;/p&gt;

&lt;p&gt;Once an agent stack starts making economic decisions on every turn, developers need routing decisions they can inspect, replay, and override. In production, the only layer positioned to provide that is the gateway.&lt;/p&gt;

&lt;p&gt;I went through the paper &lt;em&gt;Explainable Model Routing for Agentic Workflows&lt;/em&gt; (&lt;a href="https://arxiv.org/abs/2604.03527v1" rel="noopener noreferrer"&gt;arXiv:2604.03527&lt;/a&gt;). It introduces &lt;strong&gt;Topaz&lt;/strong&gt;, a routing framework built around a useful idea: model routing should be interpretable by humans, not just optimized in the background.&lt;/p&gt;

&lt;p&gt;That matters because explainable routing is only valuable if it is attached to the layer that actually sees the real levers in production: cost, quality sensitivity, cache behavior, fallback paths, provider performance, and per-step policy decisions.&lt;/p&gt;

&lt;p&gt;That layer is the gateway.&lt;/p&gt;

&lt;h2&gt;
  
  
  Topaz in one minute
&lt;/h2&gt;

&lt;p&gt;Topaz keeps the core routing loop simple and interpretable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skill-based model profiles&lt;/strong&gt;: models are represented through capabilities like logic, code generation, tool use, factual knowledge, writing quality, instruction following, and summarization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit cost-quality optimization&lt;/strong&gt;: routing decisions are made through visible optimization logic instead of opaque heuristics alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer-facing explanations&lt;/strong&gt;: the system turns those decisions into plain-language reasoning a human can audit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the right direction. A routed system is only trustworthy if a developer can tell the difference between intelligent specialization and silent quality regression.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real production takeaway
&lt;/h2&gt;

&lt;p&gt;The paper is framed as a routing contribution, but the more important implication is where explainability has to live in practice.&lt;/p&gt;

&lt;p&gt;A router can score tasks. A gateway can explain the system.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;The gateway is the only layer with enough visibility to answer the questions teams actually ask after launch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which provider and model handled each step?&lt;/li&gt;
&lt;li&gt;did the system downgrade because the task was low risk or because the budget threshold fired?&lt;/li&gt;
&lt;li&gt;was there a cache hit or miss?&lt;/li&gt;
&lt;li&gt;did the request escalate because of tool complexity?&lt;/li&gt;
&lt;li&gt;did a fallback trigger because of timeout, rate limit, or policy?&lt;/li&gt;
&lt;li&gt;which step is safe to replay under a different routing policy?&lt;/li&gt;
&lt;li&gt;which user-visible step should be pinned to a stronger model no matter what?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If explainability stops at “the router chose model B because skill-match was 0.81,” it is not enough.&lt;/p&gt;

&lt;p&gt;In production, teams need a trace they can debug.&lt;/p&gt;

&lt;p&gt;They need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what happened&lt;/li&gt;
&lt;li&gt;why it happened&lt;/li&gt;
&lt;li&gt;what it cost&lt;/li&gt;
&lt;li&gt;what would have happened under a different policy&lt;/li&gt;
&lt;li&gt;what should be overridden next time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is gateway territory.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete example
&lt;/h2&gt;

&lt;p&gt;Take a simple support workflow with four steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Classify the incoming issue&lt;/strong&gt; → cheap model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate a fix plan&lt;/strong&gt; → strong reasoning model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execute tool-heavy actions&lt;/strong&gt; → model optimized for tool use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the final customer-facing response&lt;/strong&gt; → premium model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A production-grade explanation layer should not just say “the system routed efficiently.” It should explain each step in operational terms.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue classification&lt;/strong&gt;: routed to a cheaper model because quality sensitivity was low and the task profile was narrow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix planning&lt;/strong&gt;: escalated because the task required stronger reasoning and a downgrade increased regression risk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool-heavy execution&lt;/strong&gt;: assigned to a tool-optimized model because the step depended on multiple tool calls and fallback risk was higher on weaker models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final response&lt;/strong&gt;: pinned to a premium model because it was user-visible and policy disallowed aggressive downgrades&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fallback event&lt;/strong&gt;: rerouted after timeout or rate-limit threshold was hit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost note&lt;/strong&gt;: cache miss on shared context increased input cost for this run&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the kind of explanation developers can work with.&lt;/p&gt;

&lt;p&gt;It tells them whether the system behaved correctly, where cost increased, where quality was protected, and what policy they may want to change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Routing alone is not enough
&lt;/h2&gt;

&lt;p&gt;Routing is only one part of the cost stack.&lt;/p&gt;

&lt;p&gt;For real agent and coding workflows, the bigger savings usually come from three levers working together at the gateway layer.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Prompt caching
&lt;/h3&gt;

&lt;p&gt;A lot of agent loops resend the same long context: repo maps, attached files, prior tool traces, or repeated instructions.&lt;/p&gt;

&lt;p&gt;If the gateway can preserve or inject provider-side caching correctly, it cuts repeated input cost before routing even starts.&lt;/p&gt;

&lt;p&gt;Without gateway visibility, teams cannot explain whether a run was cheaper because the router made a better choice or because the system got a cache hit.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tier routing
&lt;/h3&gt;

&lt;p&gt;Not every step deserves the expensive model.&lt;/p&gt;

&lt;p&gt;Low-risk classification, formatting, and shallow transformations can route down. Hard reasoning, recovery paths, and user-visible outputs should stay higher.&lt;/p&gt;

&lt;p&gt;But those choices need replay and override. A team has to be able to inspect a downgrade decision and say: this was safe, this was too aggressive, this customer-facing step should never go below tier X.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Tool-flow compression
&lt;/h3&gt;

&lt;p&gt;In agent systems, the tool loop itself becomes expensive. Every extra round trip can resend context, increase latency, and amplify token waste.&lt;/p&gt;

&lt;p&gt;That is why patterns like MCP Code Mode matter. Compressing tool-heavy work into fewer round trips changes the economics of the whole system.&lt;/p&gt;

&lt;p&gt;Again, the gateway is where that becomes observable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;round-trip count&lt;/li&gt;
&lt;li&gt;tool-heavy vs plain completion flow&lt;/li&gt;
&lt;li&gt;token growth across steps&lt;/li&gt;
&lt;li&gt;fallback behavior during execution&lt;/li&gt;
&lt;li&gt;total cost deltas after policy changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why explainable routing belongs next to gateway observability, not as a thin layer on top of a black-box router.&lt;/p&gt;

&lt;h2&gt;
  
  
  The skepticism this space needs
&lt;/h2&gt;

&lt;p&gt;There is a real failure mode here: “explainable routing” can turn into theater.&lt;/p&gt;

&lt;p&gt;A few reasons to be skeptical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;skill taxonomies drift&lt;/strong&gt;: the categories used to profile models can stop matching real workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;explanations can become post-hoc&lt;/strong&gt;: a clean trace is useless if it is not faithful to the actual decision path&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;quality sensitivity is hard to label&lt;/strong&gt;: teams often underestimate which steps are truly user-visible or regression-sensitive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pretty traces are not enough&lt;/strong&gt;: developers need replay, policy override, and audit logs, not just a narrative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why the standard should be higher.&lt;/p&gt;

&lt;p&gt;An explanation system should be judged on whether it helps a team debug regressions, justify cost changes, and safely tighten routing policy over time.&lt;/p&gt;

&lt;p&gt;If it cannot support replay and override, it is not operationally complete.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for Lynkr
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;Lynkr&lt;/a&gt;, so the obvious disclosure is that I read Topaz through the lens of what an LLM gateway should expose in production.&lt;/p&gt;

&lt;p&gt;The core idea is straightforward: the gateway is where cost, quality, fallback, caching, and provider behavior meet. That makes it the natural home for explainable routing.&lt;/p&gt;

&lt;p&gt;For Lynkr specifically, that means explainability should connect to the things that actually drive outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;provider/model selection&lt;/li&gt;
&lt;li&gt;prompt caching behavior&lt;/li&gt;
&lt;li&gt;tier routing policy&lt;/li&gt;
&lt;li&gt;tool-heavy vs standard completion paths&lt;/li&gt;
&lt;li&gt;fallback events&lt;/li&gt;
&lt;li&gt;cache hit/miss impact&lt;/li&gt;
&lt;li&gt;downgrade risk on user-visible steps&lt;/li&gt;
&lt;li&gt;replay and override of routing decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is also why routing by itself is not enough.&lt;/p&gt;

&lt;p&gt;The real win is stacking levers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prompt caching to cut repeated input cost&lt;/li&gt;
&lt;li&gt;tier routing to reserve premium models for the steps that justify them&lt;/li&gt;
&lt;li&gt;tool-flow compression to reduce waste across agent loops&lt;/li&gt;
&lt;li&gt;observability strong enough to explain where savings came from and where quality risk entered the system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the difference between “we routed to a cheaper model” and “we know exactly why this workflow cost less, where the risk moved, and which policy we want to change next.”&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual shift
&lt;/h2&gt;

&lt;p&gt;The shift is not just from single-model apps to multi-model systems.&lt;/p&gt;

&lt;p&gt;It is from &lt;strong&gt;opaque orchestration&lt;/strong&gt; to &lt;strong&gt;auditable orchestration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Topaz is useful because it pushes routing toward human-interpretable decisions. The stronger takeaway is that explainability belongs at the gateway layer, because that is the only place with enough visibility to audit cost, quality, fallback, caching, and provider behavior across the whole system.&lt;/p&gt;

&lt;p&gt;That is where production routing gets real.&lt;/p&gt;

&lt;p&gt;If you are building multi-model or agentic systems, this is the right question to ask next:&lt;/p&gt;

&lt;p&gt;not just &lt;em&gt;can the system route?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;but &lt;em&gt;can the system explain, replay, and override the route when something breaks?&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paper: &lt;a href="https://arxiv.org/abs/2604.03527v1" rel="noopener noreferrer"&gt;Explainable Model Routing for Agentic Workflows&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Lynkr: &lt;a href="https://github.com/Fast-Editor/Lynkr" rel="noopener noreferrer"&gt;github.com/Fast-Editor/Lynkr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want, I can next turn this into a stronger LinkedIn post or write the follow-up piece on what explainable routing looks like for coding agents specifically.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
