<?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: Patrick Hughes</title>
    <description>The latest articles on DEV Community by Patrick Hughes (@pat9000).</description>
    <link>https://dev.to/pat9000</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%2F3763138%2Fa7736e79-1b96-4f55-a9f7-9ddd8775eb09.jpg</url>
      <title>DEV Community: Patrick Hughes</title>
      <link>https://dev.to/pat9000</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pat9000"/>
    <language>en</language>
    <item>
      <title>Ollama num_batch: 256 Was My RTX 5090 Sweet Spot</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Mon, 20 Jul 2026 14:45:09 +0000</pubDate>
      <link>https://dev.to/pat9000/ollama-numbatch-256-was-my-rtx-5090-sweet-spot-158i</link>
      <guid>https://dev.to/pat9000/ollama-numbatch-256-was-my-rtx-5090-sweet-spot-158i</guid>
      <description>&lt;h1&gt;
  
  
  Ollama num_batch: 256 Was My RTX 5090 Sweet Spot
&lt;/h1&gt;

&lt;p&gt;I changed one Ollama setting and got 37.5 percent more generation speed from the same local model. Then I doubled it again, burned more power, and gained almost nothing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The short answer:&lt;/strong&gt; In my four-run &lt;code&gt;gemma4:26b&lt;/code&gt; workshop, moving &lt;code&gt;num_batch&lt;/code&gt; from 128 to 256 raised measured throughput from 156.9 to 215.7 tokens per second. Moving from 256 to 512 reached 218.5 tokens per second, only 1.3 percent faster, while average GPU power rose from 187.6 to 234.3 watts. For this RTX 5090 workload, 256 was the practical setting. Canonical URL: &lt;a href="https://bmdpat.com/blog/ollama-num-batch-rtx-5090-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/blog/ollama-num-batch-rtx-5090-2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1dtg29gtrsfi86mpk2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1dtg29gtrsfi86mpk2c.png" alt="Four Ollama batch and context settings compared by measured generation speed" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is num_batch in Ollama?
&lt;/h2&gt;

&lt;p&gt;Ollama exposes &lt;code&gt;num_batch&lt;/code&gt; inside the &lt;code&gt;options&lt;/code&gt; object on the generate API. The &lt;a href="https://github.com/ollama/ollama/blob/main/docs/api.md" rel="noopener noreferrer"&gt;official API reference&lt;/a&gt; lists it beside settings such as &lt;code&gt;num_ctx&lt;/code&gt;, &lt;code&gt;num_gpu&lt;/code&gt;, and &lt;code&gt;num_thread&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That makes it a runtime setting to measure, not a quality score. I did not assume a larger value would produce a better completed task. The useful value can change with the model, context, GPU, prompt shape, and runtime version.&lt;/p&gt;

&lt;p&gt;I wanted a measured setting for my own machine, not a copied default. The workshop changed one configuration at a time and recorded speed, average power when available, and a fixed coding check.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did the RTX 5090 workshop measure?
&lt;/h2&gt;

&lt;p&gt;The model was &lt;code&gt;gemma4:26b&lt;/code&gt; through Ollama. Each run used three short generation prompts capped at 200 output tokens plus four fixed coding tasks with deterministic checks. The first three runs held context at 2,048 and tested batch values of 128, 256, and 512.&lt;/p&gt;

&lt;p&gt;At batch 128, throughput measured 156.9 tokens per second. The coding checks scored zero percent on that run, so I do not treat its speed delta as a clean batch-only benchmark. It still exposed a bad configuration for the whole job.&lt;/p&gt;

&lt;p&gt;At batch 256, throughput reached 215.7 tokens per second and all four checks passed. Average GPU power measured 187.6 watts. At batch 512, throughput reached 218.5 tokens per second with the same passing checks, while average power measured 234.3 watts.&lt;/p&gt;

&lt;p&gt;These are workshop measurements from July 16 through July 18, 2026. They are not vendor claims and they do not predict another GPU.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did I keep 256 instead of 512?
&lt;/h2&gt;

&lt;p&gt;The extra 256 batch units bought 2.8 tokens per second. That is a 1.3 percent speed gain. Average power increased by 46.7 watts, about 24.9 percent.&lt;/p&gt;

&lt;p&gt;I will take a large speed gain when it removes real wait time. I will not pay a quarter more power for a change I cannot feel in the workflow. Batch 256 captured 98.7 percent of the measured batch-512 speed at the same context, while keeping the passing task result.&lt;/p&gt;

&lt;p&gt;This is why I tune for completed work instead of the largest allowed number. The setting with the highest throughput was technically 512. The setting I would deploy was 256.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happened when context doubled?
&lt;/h2&gt;

&lt;p&gt;The July 19 run kept batch at 512 and moved context from 2,048 to 4,096. Throughput fell from 218.5 to 183.6 tokens per second. The four coding checks still passed, and average power measured 212.4 watts.&lt;/p&gt;

&lt;p&gt;That run was discarded because the earlier 2,048-context setting was faster at the same quality score. It also reinforced a rule from my &lt;a href="https://bmdpat.com/blog/pin-num-ctx-local-llm-reload-tax-2026" rel="noopener noreferrer"&gt;Ollama context reload test&lt;/a&gt;: context belongs in the measured configuration. A batch result without its context value is incomplete.&lt;/p&gt;

&lt;p&gt;The prompt totals were small, so the larger context did not help the task. I would only pay for it when the input needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should you tune num_batch on your own GPU?
&lt;/h2&gt;

&lt;p&gt;Hold the model, quant, context, prompts, output cap, and runtime version steady. Test a small ladder such as 128, 256, and 512. Record throughput, loaded memory, average power, and a task-level pass or fail.&lt;/p&gt;

&lt;p&gt;Do not keep a setting because it wins one speed column. Reject any run that breaks the output contract. Then choose the smallest setting that captures nearly all of the useful speed with enough memory headroom for the real workload.&lt;/p&gt;

&lt;p&gt;The same rule applies to model choice. My &lt;a href="https://bmdpat.com/blog/ternary-27b-vs-gemma4-26b-local-ai-2026" rel="noopener noreferrer"&gt;Ternary Bonsai comparison&lt;/a&gt; kept the larger Gemma default because instruction compliance beat file size. Runtime tuning should use the same gate: fit, run, verify, then keep.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; It turns local Ollama benchmark rows into a measured &lt;code&gt;num_batch&lt;/code&gt; recommendation without inventing missing data.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a local LLM runtime tuning reviewer.

Context:
Paste benchmark rows for one model and GPU. Include model, quant,
runtime version, num_ctx, num_batch, tokens per second, power,
loaded memory, and task verifier result when available.

Task:
Compare the settings and reject any run that fails the task verifier.

Output:
- A compact comparison table.
- The smallest setting that captures nearly all useful speed.
- The exact measurement missing before deployment.

Constraints:
- Compare only runs with the same workload.
- Keep context attached to every batch result.
- Separate measured values from estimates.
- Do not invent missing power or memory readings.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;I publish measured local AI build notes in &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;The 5090 Reports&lt;/a&gt;. Join the email list for the next result.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=ollama-num-batch-rtx-5090-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=ollama-num-batch-rtx-5090-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/ollama-num-batch-rtx-5090-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=ollama-num-batch-rtx-5090-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=ollama-num-batch-rtx-5090-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localai</category>
      <category>ollama</category>
      <category>localllm</category>
      <category>rtx5090</category>
    </item>
    <item>
      <title>A 7 GB 27B Model Lost to My 17 GB Default</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Sun, 19 Jul 2026 14:45:08 +0000</pubDate>
      <link>https://dev.to/pat9000/a-7-gb-27b-model-lost-to-my-17-gb-default-26ej</link>
      <guid>https://dev.to/pat9000/a-7-gb-27b-model-lost-to-my-17-gb-default-26ej</guid>
      <description>&lt;h1&gt;
  
  
  A 7 GB 27B Model Lost to My 17 GB Default
&lt;/h1&gt;

&lt;p&gt;A new 27B model landed on my RTX 5090 in a 6.66 GiB GGUF file. It generated 123 tokens per second. It answered all three factual checks correctly. I still did not make it my default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The short answer:&lt;/strong&gt; Ternary Bonsai 27B proved that a large model can fit in a small memory budget, but fit did not decide the job. My local test favored &lt;code&gt;gemma4:26b&lt;/code&gt; because it generated faster and followed the requested output format. File size gets a model onto the machine. Task completion keeps it there. Canonical URL: &lt;a href="https://bmdpat.com/blog/ternary-27b-vs-gemma4-26b-local-ai-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/blog/ternary-27b-vs-gemma4-26b-local-ai-2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febw9uhmpq8cloaio1ive.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Febw9uhmpq8cloaio1ive.png" alt="Three measured results from a local Ternary Bonsai 27B and Gemma 4 26B comparison" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How did a 27B model fit in 6.66 GiB?
&lt;/h2&gt;

&lt;p&gt;I tested the official &lt;code&gt;Ternary-Bonsai-27B-Q2_0.gguf&lt;/code&gt; on July 16, 2026. &lt;code&gt;llama-bench&lt;/code&gt; reported a 6.66 GiB file and 26.90 billion parameters. The model ran with 99 GPU layers on an RTX 5090 at a 4,096-token context.&lt;/p&gt;

&lt;p&gt;The compact file comes from ternary weights. Instead of storing ordinary high-precision weights, the model uses values of negative one, zero, or positive one, plus shared scale factors. The &lt;a href="https://huggingface.co/prism-ml/Ternary-Bonsai-27B-gguf" rel="noopener noreferrer"&gt;official model card&lt;/a&gt; describes a roughly 7.2 GB deployed footprint for the language model. My downloaded file measured 7,165,121,600 bytes.&lt;/p&gt;

&lt;p&gt;That is the first win. A 27B-class model that fits under 8 GB opens options for laptops, smaller GPUs, and multi-model servers. It also makes model size a poor proxy for task quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was the smaller file fast on an RTX 5090?
&lt;/h2&gt;

&lt;p&gt;Yes, with a caveat. Bonsai generated 123.37 tokens per second in three &lt;code&gt;llama-bench&lt;/code&gt; repetitions. Prompt processing measured 3,885.47 tokens per second on the same run. Those are my local measurements, not vendor estimates.&lt;/p&gt;

&lt;p&gt;My existing &lt;code&gt;gemma4:26b&lt;/code&gt; default generated the same factual prompt at 179.95 tokens per second through Ollama. That comparison crosses two runtimes, so I treat it as a job-level spot check, not a clean model benchmark. It was still enough to answer the operator question: which model should keep the drafting slot on this machine?&lt;/p&gt;

&lt;p&gt;The answer stayed Gemma. Bonsai was compact and fast enough to serve. It was not faster for the task I needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did instruction following decide the winner?
&lt;/h2&gt;

&lt;p&gt;I asked both models three factual questions and required one exact &lt;code&gt;FINAL&lt;/code&gt; line. Both models found Canberra, Ursula K. Le Guin, and Python 3.7. Bonsai put the correct answers in its reasoning, then used the 384-token cap before it emitted the required line. Gemma returned the exact line.&lt;/p&gt;

&lt;p&gt;That difference matters in an agent loop. A correct answer in hidden reasoning is not the same as a parseable result. If the next step expects one line, the model that emits that line finishes the job. The model that explains past the cap creates a retry, a repair step, or a manual check.&lt;/p&gt;

&lt;p&gt;This is why I separate model intelligence from model usefulness. Benchmarks can tell me whether a model has capability. My verifier tells me whether it completed my task.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should a local model selection test measure?
&lt;/h2&gt;

&lt;p&gt;Start with fit, but do not stop there. Record the actual loaded footprint at the context you plan to use. Context and cache settings can change the memory total after the weights fit.&lt;/p&gt;

&lt;p&gt;Then measure the real output path. I care about generation speed, cold-load behavior, exact format compliance, and whether the result passes a deterministic check. My &lt;a href="https://bmdpat.com/blog/q4km-vs-q5km-q4-k-m-vs-q5-k-m-2026" rel="noopener noreferrer"&gt;Q4_K_M versus Q5_K_M comparison&lt;/a&gt; uses the same idea: the quant label is an input, not the verdict.&lt;/p&gt;

&lt;p&gt;Test the workload at its natural length too. My &lt;a href="https://bmdpat.com/blog/local-llm-long-form-model-selection-2026" rel="noopener noreferrer"&gt;8B long-form failure test&lt;/a&gt; showed that a quick answer can hide a length-control failure. A model that wins a short prompt may lose a full draft.&lt;/p&gt;

&lt;p&gt;For each candidate, I now want one row with five fields: loaded memory, warm generation speed, cold-load time, verifier result, and failure reason. The default slot goes to the model with the best completed-task result, not the smallest download.&lt;/p&gt;

&lt;h2&gt;
  
  
  When would I still choose Ternary Bonsai 27B?
&lt;/h2&gt;

&lt;p&gt;I would test it again on a memory-constrained machine or a server that needs several resident models. A 6.66 GiB file leaves much more room than my 17 GB Gemma default. That can matter more than raw speed.&lt;/p&gt;

&lt;p&gt;I would also run it as a persistent server. My captured Bonsai load took 68.99 seconds, and other launches from the Windows E: drive took longer. Paying that cost for every request would erase the value of fast generation.&lt;/p&gt;

&lt;p&gt;The model earned a place in the sizing data. It did not earn the default drafting job. That is a useful result. A good model test should be allowed to end with "fits, runs, does not replace."&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; It turns a local model comparison into a task-based keep, test, or reject decision.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a local LLM model-selection reviewer.

Context:
Paste the GPU, runtime, model files, context size, benchmark output,
task prompt, expected output format, and verifier result.

Task:
1. Compare loaded memory and cold-load time.
2. Compare warm generation speed on the same task.
3. Check exact output compliance and verifier results.

Output:
- A table with fit, speed, compliance, and failure reason.
- One decision: keep, test again, or reject for this job.

Constraints:
- Separate local measurements from vendor claims.
- Do not compare different runtimes as a clean model benchmark.
- Do not invent missing measurements.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;I publish measured local model decisions in &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;The 5090 Reports&lt;/a&gt;. Join the email list for the next result.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=ternary-27b-vs-gemma4-26b-local-ai-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=ternary-27b-vs-gemma4-26b-local-ai-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/ternary-27b-vs-gemma4-26b-local-ai-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=ternary-27b-vs-gemma4-26b-local-ai-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=ternary-27b-vs-gemma4-26b-local-ai-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localai</category>
      <category>localllm</category>
      <category>gguf</category>
      <category>modelselection</category>
    </item>
    <item>
      <title>My Agents Have to Prove What They Did</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Sat, 18 Jul 2026 20:48:25 +0000</pubDate>
      <link>https://dev.to/pat9000/my-agents-have-to-prove-what-they-did-1p1c</link>
      <guid>https://dev.to/pat9000/my-agents-have-to-prove-what-they-did-1p1c</guid>
      <description>&lt;p&gt;I stopped trusting "done."&lt;/p&gt;

&lt;p&gt;One of my agents reported three completed actions. Two were false. The model produced a convincing final answer. The repository did not match it.&lt;/p&gt;

&lt;p&gt;The tool trace looked busy. The summary sounded sure. Nothing in that chat proved the side effects landed.&lt;/p&gt;

&lt;p&gt;So I made a rule for the operation: every material completion needs a check that can fail.&lt;/p&gt;

&lt;p&gt;That layer is now open source as &lt;a href="https://github.com/bmdhodl/showwork" rel="noopener noreferrer"&gt;showwork&lt;/a&gt;. It is on PyPI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;showwork
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fney95pebe2dnywifxyrq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fney95pebe2dnywifxyrq.png" alt="The showwork loop: a falsifiable claim, a deterministic check, a verdict, and an append-only receipt" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does showwork verify?
&lt;/h2&gt;

&lt;p&gt;Observability answers, "What did the agent do?"&lt;/p&gt;

&lt;p&gt;showwork answers, "Is the outcome it claimed actually true?"&lt;/p&gt;

&lt;p&gt;The first question needs traces. The second needs a falsifiable assertion and a deterministic checker. No LLM judging an LLM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;showwork start &lt;span class="nt"&gt;--session&lt;/span&gt; fix-timeout &lt;span class="nt"&gt;--agent&lt;/span&gt; claude-code

showwork claim &lt;span class="nt"&gt;--session&lt;/span&gt; fix-timeout &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;--claim&lt;/span&gt; &lt;span class="s2"&gt;"bumped billing-sync API timeout to 30s"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;--type&lt;/span&gt; file_contains &lt;span class="nt"&gt;--path&lt;/span&gt; config/api.yaml &lt;span class="nt"&gt;--pattern&lt;/span&gt; &lt;span class="s2"&gt;"timeout: 30"&lt;/span&gt;

showwork finish &lt;span class="nt"&gt;--session&lt;/span&gt; fix-timeout &lt;span class="nt"&gt;--status&lt;/span&gt; ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a claim is RED, the clean close is refused. Exit code 2. Fix reality, retract the claim, or finish as blocked.&lt;/p&gt;

&lt;p&gt;The command checker has no shell. It only permits a Python script under the project root. It rejects shell metacharacters, path escape, and recursive verification. Other checks cover files, content, path moves, frontmatter, and file counts. Vacuous patterns (regex that match empty strings, always-true counts) are rejected, not blessed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is the ledger append-only?
&lt;/h2&gt;

&lt;p&gt;Agents will be wrong. Operators will also be wrong. Deleting a bad assertion makes the record look cleaner while destroying the most useful evidence.&lt;/p&gt;

&lt;p&gt;showwork appends a retraction that names the earlier claim and explains the correction. The original record stays. Failures become training material for the operation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does it gate the session?
&lt;/h2&gt;

&lt;p&gt;Yes, through the explicit finish command. Observation and gating stay separate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;showwork finish &lt;span class="nt"&gt;--session&lt;/span&gt; fix-timeout &lt;span class="nt"&gt;--status&lt;/span&gt; ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Claude Code Stop-hook adapter records a verdict when a session stops, but always exits 0. It observes. It does not block. The gate is the finish call your prompt contract requires.&lt;/p&gt;

&lt;h2&gt;
  
  
  What proof came before the package?
&lt;/h2&gt;

&lt;p&gt;I derived a sanitized snapshot from the private ledger that runs the operation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2,158 claims recorded&lt;/li&gt;
&lt;li&gt;2,152 backed by deterministic checks&lt;/li&gt;
&lt;li&gt;842 sessions represented&lt;/li&gt;
&lt;li&gt;152 append-only retractions&lt;/li&gt;
&lt;li&gt;One malformed ledger line surfaced&lt;/li&gt;
&lt;li&gt;Captured verdict: RED, 54 of 60 verified&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I kept the RED result. A proof system that only publishes green is not proof.&lt;/p&gt;

&lt;p&gt;The derivation publishes aggregates plus a source fingerprint. It does not copy private claim text, paths, strategy, or financial values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why publish a specification?
&lt;/h2&gt;

&lt;p&gt;The package can be copied. The record format can outlive it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bmdhodl/showwork/blob/main/SPEC.md" rel="noopener noreferrer"&gt;&lt;code&gt;spec-v0.1&lt;/code&gt;&lt;/a&gt; defines the JSONL schema, checker semantics, anti-vacuous rules, retractions, verdict algebra, session events, and exit-gate contract. Every normative requirement names a behavioral test.&lt;/p&gt;

&lt;p&gt;Another team can implement the same evidence format in Go or TypeScript. That is more useful than forcing every agent stack through one Python process.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the artifact?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Installable CLI and Python API: &lt;code&gt;pip install showwork&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Portable ledger specification&lt;/li&gt;
&lt;li&gt;Claude Code Stop-hook adapter&lt;/li&gt;
&lt;li&gt;Genesis receipt where the repository verified its own tests&lt;/li&gt;
&lt;li&gt;Sanitized case study and derivation script&lt;/li&gt;
&lt;li&gt;Marketing demo cut: agents say done, finish is REFUSED, then GREEN after reality matches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/bmdhodl/showwork" rel="noopener noreferrer"&gt;github.com/bmdhodl/showwork&lt;/a&gt; &lt;br&gt;
PyPI: &lt;a href="https://pypi.org/project/showwork/" rel="noopener noreferrer"&gt;pypi.org/project/showwork&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Where runtime limits fit
&lt;/h2&gt;

&lt;p&gt;Verification is one half of trusting an unattended agent. The other half is bounding what the agent can do before it does it.&lt;/p&gt;

&lt;p&gt;showwork proves what an agent did after the fact. It does not stop an agent from looping, over-calling a paid API, or draining a token budget on the way to a wrong answer. Those are runtime questions, and they need a runtime limit.&lt;/p&gt;

&lt;p&gt;That is the job of &lt;a href="https://bmdpat.com/tools/agentguard" rel="noopener noreferrer"&gt;AgentGuard&lt;/a&gt;: hard caps on tokens, cost, and call rate around an agent run, enforced while the agent is still running. AgentGuard bounds what an agent can spend. showwork proves what an agent actually produced. Run both and an unattended agent has a ceiling on the way in and a receipt on the way out.&lt;/p&gt;
&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bmdpat.com/blog/ai-agent-claims-done-verify-2026" rel="noopener noreferrer"&gt;Your AI Agent Says "Done." Make It Prove It.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bmdpat.com/blog/pin-num-ctx-local-llm-reload-tax-2026" rel="noopener noreferrer"&gt;Pin Your Context Window or Pay the Reload Tax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; turns an agent's vague "done" report into falsifiable claims with deterministic checks you can run yourself.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role: senior engineer auditing an AI agent's completion report.
Context: an agent reported finishing a task in my repository. I have the report and repo access.
Task:
1. Extract every material outcome the report asserts (files changed, configs set, tests passing).
2. For each outcome, write one falsifiable claim with a deterministic check: a file path plus regex, a command with expected exit code, or a path that must exist or be absent.
3. Flag any outcome that cannot be reduced to a deterministic check and name the evidence needed instead.
Output: a table with claim, check type, exact check, and what a failure would mean.
Constraints: no LLM-judged checks. Every check runs from the repo root and can fail.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;Get the artifact-backed local AI lab notes by email: &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;https://bmdpat.com/5090-reports&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=my-agents-have-to-prove-what-they-did-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=my-agents-have-to-prove-what-they-did-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/my-agents-have-to-prove-what-they-did-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=my-agents-have-to-prove-what-they-did-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=my-agents-have-to-prove-what-they-did-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>agentinfrastructure</category>
      <category>showwork</category>
      <category>localai</category>
    </item>
    <item>
      <title>Your Agent's Audit Trail Cannot Be Retrofitted</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Sat, 18 Jul 2026 20:48:17 +0000</pubDate>
      <link>https://dev.to/pat9000/your-agents-audit-trail-cannot-be-retrofitted-cdi</link>
      <guid>https://dev.to/pat9000/your-agents-audit-trail-cannot-be-retrofitted-cdi</guid>
      <description>&lt;p&gt;My agent said it completed three actions. Two had not happened.&lt;/p&gt;

&lt;p&gt;The chat transcript looked fine. The tool trace showed activity. The final answer sounded certain. None of that proved the files and state matched the answer.&lt;/p&gt;

&lt;p&gt;That failure led me to build a separate verification layer. Every material completion claim now needs a deterministic check. The session cannot close cleanly when a RED claim fails.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyvg7perb6yyqdgyiiv8v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyvg7perb6yyqdgyiiv8v.png" alt="Action logs show activity; outcome receipts prove the claim: the two columns compared" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Logs are not outcome proof
&lt;/h2&gt;

&lt;p&gt;An agent trace can show that a model called a file-writing tool. It cannot prove the write landed in the right repository, contained the required value, passed the relevant test, or survived another process changing the file.&lt;/p&gt;

&lt;p&gt;Those are outcome questions.&lt;/p&gt;

&lt;p&gt;I wanted each claim to be falsifiable. "Updated the configuration" became a file-content check. "Moved the queue task" became a source-absent and destination-present check. "Tests pass" became a locked command with an expected exit code.&lt;/p&gt;

&lt;p&gt;No model grades the model. The checker reads reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The record has three parts
&lt;/h2&gt;

&lt;p&gt;The first part is the claim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"session"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"deploy-fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"claim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"the API timeout is configured"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"severity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"artifact"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"config/api.yaml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"check"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"file_contains"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"config/api.yaml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="nl"&gt;"pattern"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"timeout: 30"&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second part is deterministic verification. The current checker set covers file existence, file content, path moves, frontmatter, glob counts, and locked Python commands. Vacuous checks fail. A regex that matches every file is not proof. A count of at least zero is not proof.&lt;/p&gt;

&lt;p&gt;The third part is an append-only receipt. Corrections become retraction records. The original assertion remains in history.&lt;/p&gt;

&lt;h2&gt;
  
  
  The exit gate changes agent behavior
&lt;/h2&gt;

&lt;p&gt;A normal stop hook runs after the agent has already stopped. It can record a verdict, but it cannot send the agent back to fix its work.&lt;/p&gt;

&lt;p&gt;The explicit finish command can.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;showwork finish &lt;span class="nt"&gt;--session&lt;/span&gt; deploy-fix &lt;span class="nt"&gt;--status&lt;/span&gt; ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a RED claim fails, the command exits with code 2 and refuses the clean close. The agent must fix the outcome, retract the claim truthfully, or report the session as blocked.&lt;/p&gt;

&lt;p&gt;The Stop-hook adapter still records the final verdict. It always exits zero because it observes rather than gates. Keeping those roles separate prevents a reporting hook from becoming an availability risk.&lt;/p&gt;

&lt;h2&gt;
  
  
  The production ledger is not perfectly green
&lt;/h2&gt;

&lt;p&gt;The ledger runs next to the agents themselves: my fleet operates on owned hardware, and the receipts live on the same machine as the work. The sanitized source ledger contains 2,158 claims from 842 sessions. Deterministic checks back 2,152 claims. It also contains 152 retraction records and one malformed line that the parser surfaced instead of dropping.&lt;/p&gt;

&lt;p&gt;The captured audit was RED at 54 of 60 verified.&lt;/p&gt;

&lt;p&gt;That is useful evidence. A verification system that converts its own gaps into a green launch number is not doing verification.&lt;/p&gt;

&lt;p&gt;The public case study contains aggregates only. It excludes claim text, private paths, strategy, financial values, and trading records. A SHA-256 fingerprint ties the aggregate to the exact source ledgers used for the derivation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Act makes evidence an engineering problem
&lt;/h2&gt;

&lt;p&gt;The European Commission says the AI Act becomes fully applicable on 2 August 2026, with named exceptions and longer transitions for some regulated-product systems. That does not make this package a compliance solution. I am not offering legal advice.&lt;/p&gt;

&lt;p&gt;It does make one engineering question harder to ignore: can you reproduce the evidence behind an agent's claimed outcome?&lt;/p&gt;

&lt;p&gt;Action logs are useful. Model traces are useful. Neither replaces a check that compares the assertion with the resulting state.&lt;/p&gt;

&lt;p&gt;The official application timeline is on the &lt;a href="https://digital-strategy.ec.europa.eu/en/policies/regulatory-framework-ai" rel="noopener noreferrer"&gt;European Commission's AI Act page&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The portable part is the specification
&lt;/h2&gt;

&lt;p&gt;The Python package is one implementation. The longer-lived artifact is &lt;a href="https://github.com/bmdhodl/showwork/blob/main/SPEC.md" rel="noopener noreferrer"&gt;&lt;code&gt;spec-v0.1&lt;/code&gt;&lt;/a&gt;, which defines the JSONL record, six check types, retractions, verdict rules, session events, and exit-gate behavior.&lt;/p&gt;

&lt;p&gt;Someone can implement the same format in Go or TypeScript without reading the Python source.&lt;/p&gt;

&lt;p&gt;The repository is &lt;a href="https://github.com/bmdhodl/showwork" rel="noopener noreferrer"&gt;bmdhodl/showwork&lt;/a&gt;. It includes the Stop-hook adapter, conformance tests, genesis receipt, and sanitized production case study.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bound the agent before you audit it
&lt;/h2&gt;

&lt;p&gt;A receipt proves what happened. It does not cap what an agent can spend on the way to a wrong outcome. Evidence and limits are two sides of one problem: trusting work no human watched in real time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://bmdpat.com/tools/agentguard" rel="noopener noreferrer"&gt;AgentGuard&lt;/a&gt; is the limit side. It puts hard ceilings on tokens, cost, and call rate around an agent run and enforces them while the run is live, so a looping agent hits a wall instead of your bill. showwork is the evidence side: the append-only receipt that proves the outcome after the fact. Bound what the agent can do, then prove what it did.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bmdpat.com/blog/my-agents-have-to-prove-what-they-did-2026" rel="noopener noreferrer"&gt;My Agents Have to Prove What They Did&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bmdpat.com/blog/pin-num-ctx-local-llm-reload-tax-2026" rel="noopener noreferrer"&gt;Pin Your Context Window or Pay the Reload Tax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; audits an existing agent workflow for outcome claims that today rest only on logs, and designs the receipt layer to close each gap.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role: platform engineer hardening an AI agent workflow.
Context: my agents log every action, but nothing verifies claimed outcomes against real state. The workflow description follows this prompt.
Task:
1. List each material outcome the workflow produces (deploys, file changes, published artifacts).
2. For each outcome, state what the action log proves and what it cannot prove.
3. Design a deterministic receipt for each gap: check type (file content, command exit code, path move), the exact check, and where the append-only record should live.
4. Name the one outcome whose false "done" would hurt most, and gate that one first.
Output: a gap table plus an ordered rollout plan for the receipt layer.
Constraints: checks must be deterministic and runnable today. No model-graded evidence.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;Get the artifact-backed local AI lab notes by email: &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;https://bmdpat.com/5090-reports&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=your-agent-audit-trail-cannot-be-retrofitted-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=your-agent-audit-trail-cannot-be-retrofitted-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/your-agent-audit-trail-cannot-be-retrofitted-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=your-agent-audit-trail-cannot-be-retrofitted-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=your-agent-audit-trail-cannot-be-retrofitted-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>agentverification</category>
      <category>showwork</category>
      <category>euaiact</category>
    </item>
    <item>
      <title>Ollama Raised $65M. What Builders Get</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Fri, 17 Jul 2026 14:45:09 +0000</pubDate>
      <link>https://dev.to/pat9000/ollama-raised-65m-what-builders-get-1mkk</link>
      <guid>https://dev.to/pat9000/ollama-raised-65m-what-builders-get-1mkk</guid>
      <description>&lt;h1&gt;
  
  
  Ollama Raised $65M. What Builders Get
&lt;/h1&gt;

&lt;p&gt;Ollama just turned local AI from a developer preference into a funded product category. The money matters less than what it will buy: better model access, more predictable runtimes, and a clearer path between a workstation and cloud capacity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The short answer:&lt;/strong&gt; TechCrunch reported a $65 million Series B, while &lt;a href="https://ollama.com/blog/all-aboard-open-models" rel="noopener noreferrer"&gt;Ollama says&lt;/a&gt; it has raised $88 million in total and serves 8.9 million developers. That does not prove every workload should move local. It does mean builders can expect the local model on-ramp to keep improving. Canonical URL: &lt;a href="https://bmdpat.com/blog/ollama-raises-65m-what-it-means-for-local-ai-builders-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/blog/ollama-raises-65m-what-it-means-for-local-ai-builders-2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xbjnpwslwv76k4pf6fj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1xbjnpwslwv76k4pf6fj.png" alt="Three decisions for builders after Ollama's $65M round" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What did Ollama's funding actually prove?
&lt;/h2&gt;

&lt;p&gt;The round proved that access to open models is now a business, not just a GitHub project. Ollama's official announcement centers on ownership, privacy, local execution, and an optional cloud path for models that do not fit on one machine. That is a practical product map.&lt;/p&gt;

&lt;p&gt;I read the signal this way: local inference no longer has to win every benchmark. It only has to own a useful class of work. Drafting, extraction, classification, private retrieval, and repeatable agent steps are good candidates. Hard reasoning and occasional long-context work can still go to a frontier API.&lt;/p&gt;

&lt;p&gt;That split is already how I use my RTX 5090. Ollama handles repeatable local work. A frontier model handles the final QA gate when the output will publish or change an important system. The local model buys capacity. The verifier buys trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does local inference remove token costs?
&lt;/h2&gt;

&lt;p&gt;No. It changes the bill.&lt;/p&gt;

&lt;p&gt;A local request does not create a provider token charge. The real costs are the GPU, electricity, model load time, cooling, maintenance, and the attention needed when the runtime fails. If the hardware already exists and the workload runs often, the marginal request cost can be small. If the workload is rare or needs the best available reasoning, an API may still be cheaper.&lt;/p&gt;

&lt;p&gt;This is why I avoid the phrase "free inference." Owned compute is prepaid compute. The useful comparison is workload by workload: requests per day, latency target, privacy boundary, model size, and how much operator time the local path consumes.&lt;/p&gt;

&lt;p&gt;My &lt;a href="https://bmdpat.com/blog/local-llm-inference-consumer-gpu-production-2026" rel="noopener noreferrer"&gt;consumer GPU production guide&lt;/a&gt; covers the operating side. The deciding question is not "local or cloud?" It is "which steps are stable enough to own?"&lt;/p&gt;

&lt;h2&gt;
  
  
  What should builders expect Ollama to improve?
&lt;/h2&gt;

&lt;p&gt;Ollama says its funding will support hybrid inference, faster access to new open models, and cloud access without giving up the local product. Those are useful priorities because model serving has three separate problems.&lt;/p&gt;

&lt;p&gt;First, the model must fit. Quantization, context size, and KV cache decide whether a run stays inside VRAM. Second, the runtime must stay loaded and answer consistently. Third, the surrounding agent must fail safely when the model stalls, repeats, or calls the wrong tool.&lt;/p&gt;

&lt;p&gt;The funding can improve the first two. Builders still own the third.&lt;/p&gt;

&lt;p&gt;For example, changing context size can force a full model reload. I documented that failure in my &lt;a href="https://bmdpat.com/blog/pin-num-ctx-local-llm-reload-tax-2026" rel="noopener noreferrer"&gt;Ollama context reload field note&lt;/a&gt;. A friendlier runtime does not remove the need to pin settings, measure reloads, and keep a bounded fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  How should a local agent fail safely?
&lt;/h2&gt;

&lt;p&gt;Treat the model server and the agent as separate systems. Ollama produces tokens. Your agent decides what those tokens are allowed to do.&lt;/p&gt;

&lt;p&gt;I put timeouts around generation, cap retries, log tool calls, and require a verifier before writes. If a task needs filesystem or network access, the runtime also needs explicit limits. A loop that costs no provider tokens can still burn an afternoon, corrupt files, or hold a GPU indefinitely.&lt;/p&gt;

&lt;p&gt;That is where &lt;a href="https://bmdpat.com/tools/agentguard" rel="noopener noreferrer"&gt;AgentGuard's runtime limits&lt;/a&gt; fit. The point is not to make Ollama safe by association. The point is to bound the code around any model, local or hosted, before it receives tools.&lt;/p&gt;

&lt;p&gt;The best local-first design is boring. Route repeatable work to the owned GPU. Measure it. Escalate the hard cases. Verify every consequential result.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes for builders now?
&lt;/h2&gt;

&lt;p&gt;The local path has stronger financial backing and a large developer base. That should improve the on-ramp. It does not change the engineering decision.&lt;/p&gt;

&lt;p&gt;Start with one bounded workload. Record model, quant, context, latency, failure mode, and verifier result. Compare that row with the same task on an API. Keep the route that wins on cost, privacy, availability, and operator time.&lt;/p&gt;

&lt;p&gt;Ollama's round is useful because it gives that experiment a longer runway. Your own measurements still decide where local inference belongs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; It turns one workload into a measured local-versus-cloud routing decision with explicit pass and fail rules.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a local AI workload evaluator.

Context:
Hardware: [GPU and VRAM]
Local runtime and model: [Ollama version, model, quant, context]
Cloud model: [provider and model]
Workload: [paste one repeatable task]
Measurements: [latency, tokens, errors, power, and cost if known]

Task:
1. Check whether the local model fits and completes the workload.
2. Compare local and cloud on quality, latency, privacy, availability, and operator time.
3. Choose local, cloud, or a verified hybrid route.

Output:
- A comparison table using only supplied measurements.
- A routing recommendation with one pass rule and one fallback trigger.
- The next measurement needed to reduce uncertainty.

Constraints:
- Keep it short.
- Use exact numbers and file paths when available.
- Do not invent missing measurements.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;I publish measured local runs, failure notes, and routing decisions in &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;The 5090 Reports&lt;/a&gt;. Join the email list to get the next field note.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=ollama-raises-65m-what-it-means-for-local-ai-builders-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=ollama-raises-65m-what-it-means-for-local-ai-builders-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/ollama-raises-65m-what-it-means-for-local-ai-builders-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=ollama-raises-65m-what-it-means-for-local-ai-builders-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=ollama-raises-65m-what-it-means-for-local-ai-builders-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localai</category>
      <category>localllm</category>
      <category>ollama</category>
      <category>ownedhardware</category>
    </item>
    <item>
      <title>Why production AI is moving to open weights</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Thu, 16 Jul 2026 14:45:12 +0000</pubDate>
      <link>https://dev.to/pat9000/why-production-ai-is-moving-to-open-weights-1gj9</link>
      <guid>https://dev.to/pat9000/why-production-ai-is-moving-to-open-weights-1gj9</guid>
      <description>&lt;h1&gt;
  
  
  Why production AI is moving to open weights
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; I do not need a frontier model to write every first draft. I need one where mistakes are expensive. On my RTX 5090, a local 26B model can do the high-volume writing pass. Deterministic checks and an independent frontier reviewer decide whether the draft is safe to publish.&lt;/p&gt;

&lt;p&gt;That is not a theory. I ran the split on this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F029zrrbayq1k15c0oivr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F029zrrbayq1k15c0oivr.png" alt="Local-first content pipeline from RTX 5090 draft through code gates and independent frontier QA" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gemma 4 26B wrote the draft through Ollama. The model was fully resident on the 5090. The accepted local generation took 6.2 seconds. Before the file entered review, code checked the metadata, post length, banned phrases, internal links, prompt block, CTA, and every percentage or dollar claim.&lt;/p&gt;

&lt;p&gt;Then a separate frontier model reviewed the result. It rejected the first draft.&lt;/p&gt;

&lt;p&gt;That rejection is the important part.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did the local model get wrong?
&lt;/h2&gt;

&lt;p&gt;The local draft had three real problems.&lt;/p&gt;

&lt;p&gt;First, it split the digits in the 41% figure. Second, it omitted the closing line required by the reusable prompt block. Third, the source card did not contain the primary links needed to support its Vercel numbers, even though those numbers were in the writer's verified source pack.&lt;/p&gt;

&lt;p&gt;The deterministic gate caught unsupported percentages in an earlier attempt. The frontier reviewer caught the corrupted number and the provenance gap in the accepted attempt. The repair script refused to make a subjective source decision and left the post blocked.&lt;/p&gt;

&lt;p&gt;That is the behavior I want. Local generation can be cheap and fast because every later stage is allowed to say no.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why move the writing pass to a 5090?
&lt;/h2&gt;

&lt;p&gt;The economics now support this split outside my machine too.&lt;/p&gt;

&lt;p&gt;Hugging Face reports that Chinese models accounted for 41% of model downloads on its platform. Vercel reports open-weight models handled 29% of AI Gateway tokens in June 2026 on under 4% of spend. Frontier labs still retained 95% of spend.&lt;/p&gt;

&lt;p&gt;Those numbers do not say frontier models are obsolete. They say production volume and premium judgment are separating.&lt;/p&gt;

&lt;p&gt;Writing a first draft is high-volume and reversible. Factual review is lower-volume and higher consequence. Running both steps on the most expensive model wastes the frontier budget on work my hardware can already do.&lt;/p&gt;

&lt;p&gt;The same logic applies to classification, extraction, summaries, support drafts, and log analysis. Start with tasks where a bad local result can be rejected before a customer sees it.&lt;/p&gt;

&lt;p&gt;For the machine details, read my &lt;a href="https://bmdpat.com/blog/local-llm-inference-consumer-gpu-production-2026" rel="noopener noreferrer"&gt;5090 local inference guide&lt;/a&gt;. For the budget side, see &lt;a href="https://bmdpat.com/blog/ai-agent-cost-control-agentguard-python" rel="noopener noreferrer"&gt;AI agent cost control&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where should frontier models stay in the loop?
&lt;/h2&gt;

&lt;p&gt;I am keeping frontier models on four jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claim verification against primary sources.&lt;/li&gt;
&lt;li&gt;Voice review for public writing.&lt;/li&gt;
&lt;li&gt;Decisions where a false positive can publish, charge money, or change production state.&lt;/li&gt;
&lt;li&gt;Recovery when the local model fails the deterministic contract repeatedly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I am moving routine drafting to the 5090. The local writer cannot approve its own work. It cannot publish. Its only output is a draft in a queue.&lt;/p&gt;

&lt;p&gt;This boundary matters more than the model name. A local model with direct publish access is a bad design. A frontier model with direct publish access can still be a bad design. The controls need to live in code, not in a prompt asking the model to be careful.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes the pipeline permanent?
&lt;/h2&gt;

&lt;p&gt;The old pipeline started at QA. If the morning digest created a content task but no draft, QA saw an empty folder and reported success. The publisher also saw an empty folder and reported success. Every process was green while the actual outcome was red.&lt;/p&gt;

&lt;p&gt;The new chain starts earlier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The digest routes a source-backed content task.&lt;/li&gt;
&lt;li&gt;At 7:45 CT, Gemma 4 26B converts one eligible task into a draft.&lt;/li&gt;
&lt;li&gt;Code rejects malformed metadata, weak structure, unsafe language, and unsupported numeric claims.&lt;/li&gt;
&lt;li&gt;At 8:30 CT, an independent frontier provider reviews the surviving draft.&lt;/li&gt;
&lt;li&gt;The repair and publisher stages keep their existing gates.&lt;/li&gt;
&lt;li&gt;At 9:35 CT, the healer reruns the full chain and checks the live site.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Provider limits are scoped too. If the Claude subscription is exhausted, Claude is removed from the QA chain. That no longer disables Codex, Grok, or Gemini. Known Codex quota failures are skipped instead of consuming the whole review window.&lt;/p&gt;

&lt;p&gt;The target is not zero frontier use. It is spending frontier attention where it changes the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; This prompt helps you design a two-tier workflow where a local model generates content and a frontier model audits it for accuracy.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are an AI Workflow Architect specializing in hybrid local-frontier pipelines.

Context:
I am running high-volume text generation on a local RTX 5090 setup using Ollama. I use frontier models (like Claude or GPT) only for final quality audits to keep costs low.

Task:
1. Analyze the provided raw text generated by my local model.
2. Identify any factual hallucinations or logical inconsistencies.
3. Check if the tone meets my brand guidelines.
4. Provide a "Pass" or "Fail" grade for each section.

Output:
- Error Log: List specific errors found.
- Audit Score: A score from 1 to 10.
- Corrected Version: The final text ready for publication.

Constraints:
- Do not rewrite the entire text if it is already correct.
- Focus only on factual accuracy and risk mitigation.
- Keep the feedback concise.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;Weekly measured local runs: &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;https://bmdpat.com/5090-reports&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=why-production-ai-is-moving-to-open-weights-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=why-production-ai-is-moving-to-open-weights-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/why-production-ai-is-moving-to-open-weights-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=why-production-ai-is-moving-to-open-weights-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=why-production-ai-is-moving-to-open-weights-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>openmodels</category>
      <category>rtx5090</category>
      <category>aiinfrastructure</category>
    </item>
    <item>
      <title>Devlog 2026-07-13: local drive git corruption stalls the q</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Thu, 16 Jul 2026 14:45:08 +0000</pubDate>
      <link>https://dev.to/pat9000/devlog-2026-07-13-local-drive-git-corruption-stalls-the-q-31i0</link>
      <guid>https://dev.to/pat9000/devlog-2026-07-13-local-drive-git-corruption-stalls-the-q-31i0</guid>
      <description>&lt;h1&gt;
  
  
  Devlog 2026-07-13: local drive git corruption stalls the q
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;p&gt;The nightly queue sweep aborted for the fourth straight night. The root cause is a critical failure in the vault health check. I discovered a private path worktree corruption affecting agent47, agent47-dashboard, and bmdpat.&lt;/p&gt;

&lt;p&gt;This corruption prevents sandbox provisioning because the metadata is missing or corrupt. The 04:45 retry task failed to fire as expected today. I am also dealing with an open Request from 2026-07-07 that has left the bmdpat main branch stuck on a stash-pop conflict.&lt;/p&gt;

&lt;h2&gt;
  
  
  What shipped
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Closed the blog infographic quality backlog in config/visuals/todo.md (P2-2 through P2-4 cancelled).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Added several blog infographics for different layouts via bmdpat commits 06145c02, 1a1be6a4f, 4af87a05, a5ef3eee, 040bc94a, and 8117da61.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replaced the rebuild-vector-index infographic with an aligned card layout via bmdpat commit ef861315.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Corrected embedding rebuild infographic provenance via bmdpat commit 1f772ad6.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fixed blog dates to America/Chicago and removed UTC next-day labels via bmdpat commits bd55734f, a6b22c02, 357d067e, and aba807e4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logged Kraken manager flat reconciliation at 18:16 CT via autotrader commit 6c4248d.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logged Kraken manager flat reconciliation at 17:16 CT via autotrader commit a7a319.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logged Kraken manager flat reconciliation at 16:16 CT via autotrader commit 6c139ec.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logged Kraken manager flat reconciliation at 15:16 CT via autotrader commit a19f212.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logged Kraken position manager flat reconciliation at 14:15 CT via autotrader commit 9d01475.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set kraken-entry-scout to stand down on macro blackout for multiple timestamps via autotrader commits 6645d32, 0efcdd4, e62ae5b, 7eb9ac5, 6c139ec, 9adfce6, 64ddb70, a19f212, and b88315d.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set kraken-position-manager to FLAT with 0 closes via autotrader commits e0fb1ca and 165e97b.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cannon state
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CC debt is not pulled today.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Autotrader equity is a private amount with a +0.45% P&amp;amp;L.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SPY alpha is -6.72.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;BTC alpha is -4.37.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the machine did overnight
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The nightly queue sweep aborted because sandbox repo provisioning failed for three repositories.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vault-health and security-analyst both fired today after yesterday's scheduler drop.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SecurityAnalyst returned a YELLOW verdict with 0 P0, 15 P1, and 80 P2 issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gitleaks scanned 5/5 repos and found 1 unique leak.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brain worker drained the queue from 6 to 2 tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prompt-evolver logged 5 patterns but zero prompt-shaped candidates.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I thought about
&lt;/h2&gt;

&lt;p&gt;The infrastructure is breaking under its own weight. The local drive drive corruption is a blocker that prevents the entire automated pipeline from progressing. I cannot move forward with the queue until these git trees are repaired.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tomorrow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Repair the corrupt local drive git work trees for agent47, agent47-dashboard, and bmdpat.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run queue-sweep once the sandbox can provision.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Related
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bmdpat.com/blog/local-llm-inference-consumer-gpu-production-2026" rel="noopener noreferrer"&gt;local LLM on consumer GPUs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bmdpat.com/blog/ai-agent-cost-control-agentguard-python" rel="noopener noreferrer"&gt;agent cost control&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Get the artifact-backed local AI lab notes by email: &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;https://bmdpat.com/5090-reports&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; Explains how this public daily log is produced from the private vault devlog with deterministic redaction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Take today's private BMD HODL devlog. Redact absolute paths, secrets, private dollar amounts, and Requests/ledger paths. Keep first-person builder voice. Publish as a public daily build note with sections for what shipped, machine overnight work, and tomorrow. Link 5090 Reports.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=bmd-hodl-devlog-2026-07-13" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=bmd-hodl-devlog-2026-07-13&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/bmd-hodl-devlog-2026-07-13?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=bmd-hodl-devlog-2026-07-13&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=bmd-hodl-devlog-2026-07-13&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devlog</category>
      <category>daily</category>
      <category>bmdhodl</category>
    </item>
    <item>
      <title>My 8B Model Failed a 400-Word Task</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Wed, 15 Jul 2026 14:45:23 +0000</pubDate>
      <link>https://dev.to/pat9000/my-8b-model-failed-a-400-word-task-23lf</link>
      <guid>https://dev.to/pat9000/my-8b-model-failed-a-400-word-task-23lf</guid>
      <description>&lt;p&gt;I gave Llama 3.1 8B a simple job: turn a set of verified daily artifacts into a 400-to-700-word devlog. It returned 208 to 299 words across three live runs. A retry collapsed the required structure before the post reached the floor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The short version:&lt;/strong&gt; Small local models are good when the task is bounded and the output has a hard verifier. Three failed 8B devlog trials gave me the evidence to keep that model on short scoring work. I assigned long-form synthesis to Gemma 4 26B and gate both task classes with code.&lt;/p&gt;

&lt;p&gt;Canonical URL: &lt;a href="https://bmdpat.com/blog/local-llm-long-form-model-selection-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/blog/local-llm-long-form-model-selection-2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsgjv57ap24tiykyywvwa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsgjv57ap24tiykyywvwa.png" alt="A verifier-driven route from Llama 3.1 8B to Gemma 4 26B for long-form local model work" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What failed in the three 8B runs?
&lt;/h2&gt;

&lt;p&gt;The prompt asked for six required sections and a 400-word minimum. Llama 3.1 8B produced 208 to 299 words across three runs on my RTX 5090. It could identify the source facts. It could not keep the full long-form shape intact.&lt;/p&gt;

&lt;p&gt;That distinction matters. The result did not make the model useless. The July 10 handoff records the same 8B model as a fit for research triage and scoring, where the answer is short, structured, and easy to check.&lt;/p&gt;

&lt;p&gt;The measured numbers in this post come from my July 10 local-inference handoff report. That report records the three 8B attempts, the passing 26B result, and the runtime settings that changed the outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did another retry not solve the problem?
&lt;/h2&gt;

&lt;p&gt;Retries help when failure is noisy. They help less when the model repeats the same limit.&lt;/p&gt;

&lt;p&gt;The July 10 handoff records a structure collapse on retry. It does not prove why the model collapsed, so I do not guess. The useful fact is simpler: three attempts stayed below the contract or lost the required shape.&lt;/p&gt;

&lt;p&gt;This is where a verifier earns its keep. I did not ask the model whether its draft was complete. Code checked the required sections, word range, forbidden terms, and output status. The task assignment changed because the artifact failed, not because the prose felt weak.&lt;/p&gt;

&lt;p&gt;The same principle applies to generation after retrieval. I &lt;a href="https://bmdpat.com/blog/preview-retrieval-before-local-llm-runs-2026" rel="noopener noreferrer"&gt;preview the files before local inference&lt;/a&gt;, then verify the generated artifact after inference. Both gates isolate the failed stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed when I routed the task to Gemma 4 26B?
&lt;/h2&gt;

&lt;p&gt;The first larger-model attempts exposed a different failure. Gemma 4 26B is a thinking model in Ollama 0.31. With its thinking mode left on, it consumed the output budget internally and returned an empty response.&lt;/p&gt;

&lt;p&gt;Setting &lt;code&gt;think&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt; fixed that boundary. Increasing &lt;code&gt;num_predict&lt;/code&gt; to 2600 kept path-heavy sections from being cut off. The configured model produced a 485-word devlog with all six required sections and passed the deterministic gate.&lt;/p&gt;

&lt;p&gt;The lesson was not "use the biggest model." The lesson was "route to the smallest model that can pass the artifact contract, then configure that model for the job." Model size, context, thinking mode, and output budget are one runtime shape.&lt;/p&gt;

&lt;p&gt;That runtime shape must stay stable. My &lt;a href="https://bmdpat.com/blog/pin-local-llm-context-size-before-routing-2026" rel="noopener noreferrer"&gt;RTX 5090 context-size sweep&lt;/a&gt; showed that changing &lt;code&gt;num_ctx&lt;/code&gt; can force a full reload. A good route includes those settings instead of treating the model name as the whole key.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not send every task to the 26B model?
&lt;/h2&gt;

&lt;p&gt;The 8B model is still my choice for bounded work. In a separate July 9 sweep, it peaked at 7,826 MiB of VRAM while the 26B model peaked at 20,233 MiB. A classifier that returns a score and one reason does not need the larger memory footprint of my long-form model.&lt;/p&gt;

&lt;p&gt;I separate tasks by output shape. Short extraction, scoring, tagging, and command selection go to the 8B route. Multi-source narrative work with six sections goes to the 26B route. The verifier decides whether either result may advance.&lt;/p&gt;

&lt;p&gt;The task classes are assigned before inference. Triage and scoring use the 8B route. The six-section devlog uses the 26B route. Each output carries its own verifier result, so the system does not silently swap models and call both outcomes equivalent.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should the verifier check before a route advances?
&lt;/h2&gt;

&lt;p&gt;Start with rules that code can judge. Check required sections, minimum and maximum length, forbidden phrases, empty output, truncated output, and whether cited paths came from the approved source manifest. Record the model, quant, context size, thinking mode, output budget, and verifier result with the artifact.&lt;/p&gt;

&lt;p&gt;Do not turn the verifier into another model unless the rule truly needs judgment. Word counts and section names belong in code. A human or separate model can review tone later. The first gate should be fast, exact, and repeatable.&lt;/p&gt;

&lt;p&gt;The resulting policy is boring: test each task shape, keep the smallest model that passes, pin that assignment, and run the same gate on every output. That is enough to stop a weak result from shipping and a larger model from handling every task by default.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; This prompt turns local-model run records into a verifier-driven routing rule for short and long-form tasks.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a local LLM routing engineer.

Context:
Paste the task, model settings, output artifact, and verifier result for each local run.

Task:
1. Group runs by task shape and required output.
2. Identify the smallest model that passed every deterministic rule.
3. Name the exact failure that justifies each larger-model route.

Output:
- A routing table with task shape, model, runtime settings, and pass rules.
- One default route and any justified escalation routes.
- A list of checks that should run in code before human review.

Constraints:
- Keep it short.
- Use exact numbers and file paths when available.
- Do not invent missing measurements.
- Do not recommend a larger model without a recorded verifier failure.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;I publish the measured local-model runs, failures, and fixes in &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;The 5090 Reports&lt;/a&gt;. Join the list to get the next artifact.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=local-llm-long-form-model-selection-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=local-llm-long-form-model-selection-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/local-llm-long-form-model-selection-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=local-llm-long-form-model-selection-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=local-llm-long-form-model-selection-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>modelselection</category>
      <category>ollama</category>
      <category>rtx5090</category>
    </item>
    <item>
      <title>Q4km vs Q5km: Q4_K_M vs Q5_K_M</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Wed, 15 Jul 2026 14:45:19 +0000</pubDate>
      <link>https://dev.to/pat9000/q4km-vs-q5km-q4km-vs-q5km-5dk2</link>
      <guid>https://dev.to/pat9000/q4km-vs-q5km-q4km-vs-q5km-5dk2</guid>
      <description>&lt;h1&gt;
  
  
  Q4km vs Q5km: Q4_K_M vs Q5_K_M
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Short answer:&lt;/strong&gt; &lt;code&gt;q4km&lt;/code&gt; and &lt;code&gt;q5km&lt;/code&gt; are informal spellings of GGUF quants &lt;code&gt;Q4_K_M&lt;/code&gt; and &lt;code&gt;Q5_K_M&lt;/code&gt;. For most local LLM loads on a single consumer GPU, start with Q4_K_M. Move to Q5_K_M only when you still have VRAM after weights plus KV cache.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do people mean by q4km vs q5km?
&lt;/h2&gt;

&lt;p&gt;Search and chat often drop the underscores: q4km, q5km, q8. In llama.cpp and Ollama file names the real tags are &lt;code&gt;Q4_K_M&lt;/code&gt;, &lt;code&gt;Q5_K_M&lt;/code&gt;, and &lt;code&gt;Q8_0&lt;/code&gt; (or close cousins like &lt;code&gt;Q5_K_S&lt;/code&gt;). Same decision: size vs quality vs speed under a fixed VRAM budget.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you pick Q4_K_M?
&lt;/h2&gt;

&lt;p&gt;Pick Q4_K_M when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You want the model to load fully without CPU fallback.&lt;/li&gt;
&lt;li&gt;You still need context headroom for the KV cache.&lt;/li&gt;
&lt;li&gt;You care more about tokens/sec than the last few quality points.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Q4_K_M is the default local quant for a reason: it is usually the best balance of file size and usable quality on 8-24 GB cards.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you pick Q5_K_M?
&lt;/h2&gt;

&lt;p&gt;Pick Q5_K_M when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Q4_K_M already fits with clear headroom.&lt;/li&gt;
&lt;li&gt;You see quality issues on coding or long-form tasks at Q4.&lt;/li&gt;
&lt;li&gt;You measured that Q5 still keeps full GPU offload at your context length.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If Q5 forces layers back to CPU, you often lose more quality (and speed) than you gain from the higher quant.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you decide in five minutes?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Note GPU VRAM and target context length.&lt;/li&gt;
&lt;li&gt;Open &lt;a href="https://bmdpat.com/tools/quant-compare" rel="noopener noreferrer"&gt;quant compare&lt;/a&gt; and &lt;a href="https://bmdpat.com/tools/vram-calculator" rel="noopener noreferrer"&gt;VRAM calculator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Check weight size for Q4_K_M and Q5_K_M against free VRAM after OS and cache.&lt;/li&gt;
&lt;li&gt;Prefer the smaller quant that stays fully on GPU.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the full matrix (Q4/Q5/Q6/Q8, K_S vs K_M, and edge cases), read the long guide: &lt;a href="https://bmdpat.com/blog/gguf-quantization-q4-q5-q8-explained-2026" rel="noopener noreferrer"&gt;GGUF Q4_K_M vs Q5_K_M vs Q8&lt;/a&gt;. For offload flags once the file fits, see &lt;a href="https://bmdpat.com/blog/llama-cpp-n-gpu-layers-explained-2026" rel="noopener noreferrer"&gt;llama.cpp --n-gpu-layers&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; It turns your GPU VRAM, context length, and two GGUF file sizes into a Q4_K_M vs Q5_K_M pick with a hard pass/fail.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a local LLM quant picker.

Context:
GPU VRAM (GB): [ ]
Target context length: [ ]
Model: [ ]
Q4_K_M file size (GB): [ ]
Q5_K_M file size (GB): [ ]
Need full GPU offload: yes/no

Task:
1. Estimate free VRAM after OS and KV cache.
2. Say whether Q4_K_M and Q5_K_M fit fully on GPU.
3. Pick one quant and one fallback if load fails.
4. List the single next measurement to run.

Output:
- Pick: Q4_K_M or Q5_K_M
- Fit: full GPU / mixed / no
- Fallback plan
- Next command or check

Constraints:
- Prefer full GPU offload over a higher quant with CPU fallback.
- Do not invent sizes I did not provide.
- Keep the answer under 12 lines.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;Weekly measured local runs: &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;https://bmdpat.com/5090-reports&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=q4km-vs-q5km-q4-k-m-vs-q5-k-m-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=q4km-vs-q5km-q4-k-m-vs-q5-k-m-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/q4km-vs-q5km-q4-k-m-vs-q5-k-m-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=q4km-vs-q5km-q4-k-m-vs-q5-k-m-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=q4km-vs-q5km-q4-k-m-vs-q5-k-m-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>gguf</category>
      <category>quantization</category>
      <category>llamacpp</category>
    </item>
    <item>
      <title>I Rebuilt 5,383 Embeddings After a Dimension Change</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:45:22 +0000</pubDate>
      <link>https://dev.to/pat9000/i-rebuilt-5383-embeddings-after-a-dimension-change-1ln5</link>
      <guid>https://dev.to/pat9000/i-rebuilt-5383-embeddings-after-a-dimension-change-1ln5</guid>
      <description>&lt;p&gt;I changed one embedding model and had to rebuild the whole vector index.&lt;/p&gt;

&lt;p&gt;The old path used OpenAI &lt;code&gt;text-embedding-3-small&lt;/code&gt; at 1,536 dimensions. The new path uses &lt;code&gt;nomic-embed-text&lt;/code&gt; through Ollama at 768 dimensions on my RTX 5090. The model swap was easy. The data migration was the real job.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The short version:&lt;/strong&gt; An embedding dimension change is a schema change, not a model setting. I changed the vector column, cleared the old rows, rebuilt the HNSW index, re-embedded 5,383 chunks from 1,605 notes, and checked retrieval with three known queries after the rebuild.&lt;/p&gt;

&lt;p&gt;Canonical URL: &lt;a href="https://bmdpat.com/blog/rebuild-vector-index-embedding-dimensions-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/blog/rebuild-vector-index-embedding-dimensions-2026&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F26n5zm4aja1h6qy50bs6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F26n5zm4aja1h6qy50bs6.png" alt="A four-step vector index rebuild from 1,536 dimensions to 768 dimensions on an RTX 5090" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why can I not mix 1,536 and 768 dimension vectors?
&lt;/h2&gt;

&lt;p&gt;My Supabase table stored each embedding in a &lt;code&gt;vector(1536)&lt;/code&gt; column. The local model returned 768 values. Those are different data shapes.&lt;/p&gt;

&lt;p&gt;Changing only the application code would leave the database contract behind. Keeping the old rows would also leave corpus vectors and query vectors produced by different models. Even if I copied them into a looser storage format, the similarity scores would not represent one shared vector space.&lt;/p&gt;

&lt;p&gt;I treated the change like a database migration. The new column became &lt;code&gt;vector(768)&lt;/code&gt;. The search function accepted a 768-value query. The HNSW index was rebuilt for the new column. Old embeddings did not survive the cutover.&lt;/p&gt;

&lt;h2&gt;
  
  
  What did the rebuild include?
&lt;/h2&gt;

&lt;p&gt;The July 10, 2026 handoff report records the full pass: 5,383 chunks from 1,605 notes. One background run on the RTX 5090 generated every replacement vector with &lt;code&gt;nomic-embed-text&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I kept the corpus and query paths on the same model. &lt;code&gt;config/brain/embed_vault.py&lt;/code&gt; embeds notes. The vault search server embeds each query. Both now call the same Ollama model and expect 768 dimensions.&lt;/p&gt;

&lt;p&gt;That symmetry matters more than the model name. A corpus built by one embedding model and queried by another can return numbers, but those numbers do not prove useful retrieval. I want one encoder, one dimension, and one migration boundary.&lt;/p&gt;

&lt;p&gt;The process was simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Apply the 768-dimension schema and search function.&lt;/li&gt;
&lt;li&gt;Clear the old corpus rows.&lt;/li&gt;
&lt;li&gt;Rebuild every chunk with the local embedding model.&lt;/li&gt;
&lt;li&gt;Run known queries and inspect the top results.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How did I test retrieval after the migration?
&lt;/h2&gt;

&lt;p&gt;I used three queries with obvious expected answers. The AgentGuard query returned its entity note first at 0.694 cosine similarity. The Raspberry Pi researcher query returned its deployment README first at 0.676. The workflow audit query returned &lt;code&gt;Offer.md&lt;/code&gt; first at 0.637.&lt;/p&gt;

&lt;p&gt;Those scores are not universal quality targets. They are results from this corpus and this model. The useful test was whether each known query returned the expected source at the top after the rebuild.&lt;/p&gt;

&lt;p&gt;This is the same reason I &lt;a href="https://bmdpat.com/blog/preview-retrieval-before-local-llm-runs-2026" rel="noopener noreferrer"&gt;preview retrieval before a local LLM runs&lt;/a&gt;. Retrieval should produce an inspectable artifact before generation begins. A model cannot repair a missing source it never received.&lt;/p&gt;

&lt;p&gt;I also keep durable facts in files before they enter semantic search. That design is covered in &lt;a href="https://bmdpat.com/blog/ai-agent-memory-write-to-files-2026" rel="noopener noreferrer"&gt;why I write agent memory to files&lt;/a&gt;. The vector index makes those files easier to find. It is not the source of truth.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should fail closed during an embedding migration?
&lt;/h2&gt;

&lt;p&gt;The embedding helper now checks that the local response has exactly 768 values. A wrong-length vector stops the run. The database schema provides a second boundary. The query path uses the same expected dimension.&lt;/p&gt;

&lt;p&gt;I would also stop the cutover if the corpus count was far below the source count, if the embed service returned empty vectors, or if the known-query checks missed their expected files. A completed migration is not a successful migration unless retrieval still works.&lt;/p&gt;

&lt;p&gt;The safest rollout is a full rebuild with a small parity suite. Keep the old index available until the new one passes. Then switch the query path once. Do not let two embedding models write into the same active corpus.&lt;/p&gt;

&lt;h2&gt;
  
  
  When is a full rebuild worth it?
&lt;/h2&gt;

&lt;p&gt;I rebuilt because the change removed a paid API dependency from a daily vault search path. It also let me re-embed the corpus on hardware I own whenever the source files change.&lt;/p&gt;

&lt;p&gt;That benefit justified one clean migration. It would not justify swapping models every week. Each embedding model change creates a new corpus version, a new query contract, and another parity run.&lt;/p&gt;

&lt;p&gt;My rule is now explicit: pin the embedding model and dimension together. If either changes, version the index and rebuild the corpus. The application should never discover that contract drift during a live query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; This prompt turns an embedding-model change into a fail-closed vector-index migration plan with retrieval checks.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a vector search migration reviewer.

Context:
Paste the current embedding model, new model, dimensions, table schema, corpus counts, and three known queries with expected results.

Task:
1. Identify every schema, index, corpus, and query-path change.
2. Define the order for rebuilding vectors without mixing models.
3. Write parity checks that must pass before the query path switches.

Output:
- A numbered migration plan with rollback points.
- A pass/fail table for vector length, corpus count, and known-query results.
- The exact evidence to record after the rebuild.

Constraints:
- Keep it short.
- Use exact numbers and file paths when available.
- Do not invent missing measurements.
- Treat a model or dimension change as a new corpus version.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;I publish measured local-model migrations, failures, and fixes in &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;The 5090 Reports&lt;/a&gt;. Join the list to get the next artifact.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=rebuild-vector-index-embedding-dimensions-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=rebuild-vector-index-embedding-dimensions-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/rebuild-vector-index-embedding-dimensions-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=rebuild-vector-index-embedding-dimensions-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=rebuild-vector-index-embedding-dimensions-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>embeddings</category>
      <category>vectorsearch</category>
      <category>ollama</category>
    </item>
    <item>
      <title>I Raised the QA Bar on Blog Infographics</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Tue, 14 Jul 2026 14:45:17 +0000</pubDate>
      <link>https://dev.to/pat9000/i-raised-the-qa-bar-on-blog-infographics-4c93</link>
      <guid>https://dev.to/pat9000/i-raised-the-qa-bar-on-blog-infographics-4c93</guid>
      <description>&lt;p&gt;I ship measured local-model posts with charts. Generative image tools garble numbers. So the fleet uses one matplotlib renderer under &lt;code&gt;config/visuals/&lt;/code&gt;. Exact text. Fixed brand colors.&lt;/p&gt;

&lt;p&gt;That still was not enough. A chart could pass "it rendered" and still look sloppy: numbers in corners, tiny labels, digits that never appear in the post. I raised the bar.&lt;/p&gt;

&lt;h2&gt;
  
  
  What failed before
&lt;/h2&gt;

&lt;p&gt;The first defect class was layout. Step numbers sat in the top-left of a card while the label sat in the center. Peer cards did not share baselines. Long labels shrank below a readable floor.&lt;/p&gt;

&lt;p&gt;The second class was honesty. A graphic could invent a comparison that no metrics file contained. Vision QA only checked whether the image looked clean, not whether the numbers were true.&lt;/p&gt;

&lt;p&gt;The third class was publish mechanics. Committing a PNG from a feature branch worktree was easy to get wrong. Agents need a path that always targets &lt;code&gt;main&lt;/code&gt; for the one asset file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gates
&lt;/h2&gt;

&lt;p&gt;Every blog infographic now hits the same chain before an embed line is printed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Char budget.&lt;/strong&gt; Budgets scale with step count. A short chain (n≤3) gets wider cards and longer labels. A four-step row stays tight (18/22). Five or more steps use a two-row grid so cards do not crush.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layout then claims.&lt;/strong&gt; Numbers, labels, and subs share peer baselines. Step indexes sit in orange pills with clearance so they never paint over the words. Digits in the graphic require &lt;code&gt;--claims &amp;lt;post or metrics&amp;gt;&lt;/code&gt; or publish exits 8.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vision log.&lt;/strong&gt; The vision gate still fail-closes. Full stdout and stderr land under &lt;code&gt;Reports/Visuals/&lt;/code&gt; so a timeout is not a mystery.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Footer text stays at the same readable floor as body labels (7pt minimum). Titles sit on a dark header scrim so ambient textures cannot wash them out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwbz4irww2fl8pe3s6fyl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwbz4irww2fl8pe3s6fyl.png" alt="Three gates before a blog PNG ships: char budget, layout and claims, vision log" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;The unit suite under &lt;code&gt;config/visuals/&lt;/code&gt; is at 29 tests as of 2026-07-13. Selftest renders every file in &lt;code&gt;examples/&lt;/code&gt; and &lt;code&gt;specs/&lt;/code&gt; (13 specs after this post). Geometry QA checks containment, min size, peer baselines, and peer line counts. Char lint runs before draw.&lt;/p&gt;

&lt;p&gt;I also re-rendered the live vector-migration post asset earlier the same day after the first stack fix. New posts get the full gate set automatically when they use &lt;code&gt;publish_blog_asset.py&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I will not do
&lt;/h2&gt;

&lt;p&gt;I will not put labels inside a diffusion model. Charts need crisp, correct English. Ambient textures stay under the diagram. Text stays on the matplotlib layer.&lt;/p&gt;

&lt;p&gt;I will not ship a PNG that fails any gate. Fail closed means ship text-only or fix the spec. That is intentional.&lt;/p&gt;

&lt;h2&gt;
  
  
  When a graphic is worth it
&lt;/h2&gt;

&lt;p&gt;Use a chart when the post has a process, a comparison, or a set of numbers. Write the short labels first. Point &lt;code&gt;--claims&lt;/code&gt; at the draft. If the story needs long phrases, use fewer steps or a stats/flow template. Do not fight the 4-up width with paragraphs inside cards.&lt;/p&gt;

&lt;p&gt;The contract lives in &lt;code&gt;Prompts/Includes/blog-publish.md&lt;/code&gt; and &lt;code&gt;config/visuals/README.md&lt;/code&gt;. Agents read it before inventing a one-off plot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; This prompt turns a draft post into a fail-closed infographic publish checklist with char budgets and claims.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role:
You are a blog infographic publisher for exact-text charts.

Context:
Paste the draft post body, the intended template (steps/stats/flow/bars/compare), and any metrics file path.

Task:
1. Write a JSON spec that fits char budgets (4-up steps: label &amp;lt;=18, sub &amp;lt;=22).
2. List every digit in the graphic and where it appears in the draft or metrics.
3. Run publish with --claims and report geometry/vision outcomes.

Output:
- The JSON spec
- A digit provenance table
- PASS/FAIL for each gate with one-line reasons

Constraints:
- No generative text-in-image for labels
- Fail closed on missing claims when digits exist
- Keep labels short; do not invent metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;I publish measured local-model work and the systems around it in &lt;a href="https://bmdpat.com/5090-reports" rel="noopener noreferrer"&gt;The 5090 Reports&lt;/a&gt;. Join the list for the next artifact.&lt;/p&gt;

&lt;p&gt;For related layout and local-model posts, see &lt;a href="https://bmdpat.com/blog/rebuild-vector-index-embedding-dimensions-2026" rel="noopener noreferrer"&gt;I rebuilt 5,383 embeddings after a dimension change&lt;/a&gt; and &lt;a href="https://bmdpat.com/blog/pin-num-ctx-local-llm-reload-tax-2026" rel="noopener noreferrer"&gt;the num_ctx reload tax&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=blog-infographic-layout-qa-gate-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=blog-infographic-layout-qa-gate-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/blog-infographic-layout-qa-gate-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog-infographic-layout-qa-gate-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=blog-infographic-layout-qa-gate-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>5090reports</category>
      <category>blog</category>
      <category>matplotlib</category>
    </item>
    <item>
      <title>Pin Your Context Window or Pay the Reload Tax</title>
      <dc:creator>Patrick Hughes</dc:creator>
      <pubDate>Sun, 12 Jul 2026 14:45:19 +0000</pubDate>
      <link>https://dev.to/pat9000/pin-your-context-window-or-pay-the-reload-tax-3nfo</link>
      <guid>https://dev.to/pat9000/pin-your-context-window-or-pay-the-reload-tax-3nfo</guid>
      <description>&lt;p&gt;I changed one setting on a local agent and it went silent for 140 seconds.&lt;/p&gt;

&lt;p&gt;No output. No error. Just a fan spinning up while a 17 GB model reloaded from disk. The actual answer, once the model was back, took under two seconds to generate. I had paid a two-minute tax for a two-second task.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The short version:&lt;/strong&gt; Ollama reloads the entire model when you change num_ctx, the context window size. On my RTX 5090, gemma4:26b took about 140 seconds to reload every time num_ctx changed. Generation itself ran near 200 tokens per second. Pin num_ctx once and the tax goes away.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv6klsibtb27vkpvrdvbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv6klsibtb27vkpvrdvbh.png" alt="Three stats: 140 second reload per num_ctx change, 17 GB model reloaded from disk, and about 200 tokens per second generation once loaded" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did my local model freeze for 140 seconds?
&lt;/h2&gt;

&lt;p&gt;I was benchmarking two models on one card: an RTX 5090 running Ollama 0.31.1. The sweep sent three workloads to each model, and one of them used a longer context, so my script bumped num_ctx from 4096 up to 8192 and back down again.&lt;/p&gt;

&lt;p&gt;Every one of those changes forced a full model reload. gemma4:26b is a 17 GB file at Q4_K_M. Each reload took between 138 and 142 seconds. Same model, same GPU, already warm. The only thing that changed was the context number, and that was enough to send the whole thing back to disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually triggers the reload?
&lt;/h2&gt;

&lt;p&gt;The context window is not a runtime knob you can turn for free. Ollama allocates the KV cache when it loads the model, and the cache size depends on num_ctx. Change num_ctx and the previous allocation no longer fits, so the runtime tears the model down and loads it again from scratch.&lt;/p&gt;

&lt;p&gt;This is easy to trigger by accident. An agent that sets context per request, a script that summarizes long documents then answers short questions, a chat loop that grows its window as the conversation runs. Each of those can flip num_ctx without anyone deciding to, and each flip is a fresh reload.&lt;/p&gt;

&lt;h2&gt;
  
  
  How much does the reload cost?
&lt;/h2&gt;

&lt;p&gt;The numbers from that run are blunt. gemma4:26b generated at about 198 to 207 tokens per second once it was loaded. A 256-token answer is done in under two seconds. The reload before it took about 140 seconds.&lt;/p&gt;

&lt;p&gt;So the model spent roughly 98 percent of that request loading and 2 percent working. There is a second, smaller tax hiding in the same place. The first prompt evaluation right after a load is a cold-start artifact: gemma's first reading measured 15 tokens per second, and the very next request hit 6,179. If you reload constantly, you also eat that cold start every single time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I stop paying the tax?
&lt;/h2&gt;

&lt;p&gt;Pick one context size and pin it. Decide the largest window your workload actually needs, set num_ctx to that value once, and never change it mid-session. A fixed 8192 that loads one time beats a "smart" window that reloads on every other request.&lt;/p&gt;

&lt;p&gt;In practice that means setting num_ctx at model load and leaving it. If different jobs genuinely need different windows, keep a separate warm model per window instead of retuning one. The reload is the expensive part. Paying it once at startup is fine. Paying it every few requests is the whole problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does this mean for a local coding agent?
&lt;/h2&gt;

&lt;p&gt;This is the trap for anyone running an agent loop on a local model. Agent stacks love to adjust context. They pad the window for a big file, shrink it for a quick tool call, grow it as history accumulates. On a small 8B model the reload is quick enough to ignore. On a 17 GB model it is a 140-second stall in the middle of your loop, and the agent has no idea it is waiting on I/O instead of thinking.&lt;/p&gt;

&lt;p&gt;June 12 I had this exact failure and did not understand it. A gemma4:26b run timed out at a 5-second limit. A 5-second timeout can never survive a 140-second load. The fix was not a faster GPU. It was pinning the context so the model stopped reloading.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you cap after you pin the context?
&lt;/h2&gt;

&lt;p&gt;Pinning num_ctx removes one hidden cost. It does not remove the other one: an agent looping on that model with no ceiling. A local agent that retries in a tight loop burns GPU time and wall-clock the same way a stray reload does, except it can run until you notice.&lt;/p&gt;

&lt;p&gt;So I put a hard limit around the loop. Before a local agent runs, I give it a budget, a token cap, and a rate limit, so one bad loop stops itself. That is what &lt;a href="https://bmdpat.com/tools/agentguard" rel="noopener noreferrer"&gt;AgentGuard&lt;/a&gt; does: runtime budget, token, and rate limits for AI agents, in one pip install. Pin the context so the model stops reloading. Cap the loop so the agent stops running. Two different meters, same discipline: find the hidden cost, then put a hard limit on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accompanying prompt
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What the prompt does:&lt;/strong&gt; It reviews how your local agent or script sets the context window and flags any place that would force Ollama to reload the model mid-run.&lt;/p&gt;

&lt;p&gt;Copy/paste this prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Role: You are a local LLM performance reviewer.

Context: I run models locally through Ollama on a single GPU. Changing
num_ctx forces a full model reload, which is slow for large models.

Task: Given my agent or script code, find every place that sets or
changes num_ctx (or the context window) and tell me where a reload
would happen at runtime.

Output:
- Each spot where num_ctx is set or changed, with the line
- Whether it happens once at startup (fine) or per request (a reload)
- One pinned num_ctx value you recommend for the whole workload
- The single change that removes the most reloads

Constraints: Assume a reload costs 100+ seconds for a large model.
Prefer one fixed context size over a dynamic one. Be specific about
lines. No general advice about prompt engineering.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the block above.&lt;/p&gt;

&lt;p&gt;Two minutes of pinning beats 140 seconds of dead air on every context change. Cap the reload by pinning num_ctx, then cap the agent with &lt;a href="https://bmdpat.com/tools/agentguard" rel="noopener noreferrer"&gt;AgentGuard&lt;/a&gt;. Predict the hidden cost, then put a hard limit on it. That is the whole habit.&lt;/p&gt;




&lt;p&gt;Get the local AI lab notes (benchmark rows, VRAM fit, quant choices, what runs on consumer GPUs), M-F only when there is something worth sending: &lt;a href="https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=pin-num-ctx-local-llm-reload-tax-2026" rel="noopener noreferrer"&gt;https://bmdpat.com/newsletter?utm_source=blog_md&amp;amp;utm_medium=aeo&amp;amp;utm_campaign=pin-num-ctx-local-llm-reload-tax-2026&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://bmdpat.com/blog/pin-num-ctx-local-llm-reload-tax-2026?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=pin-num-ctx-local-llm-reload-tax-2026&amp;amp;utm_content=footer_original" rel="noopener noreferrer"&gt;bmdpat.com&lt;/a&gt;. I run a one-person AI agent company and write about what actually works.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want these in your inbox? &lt;a href="https://bmdpat.com/newsletter?utm_source=devto&amp;amp;utm_medium=syndication&amp;amp;utm_campaign=pin-num-ctx-local-llm-reload-tax-2026&amp;amp;utm_content=footer_newsletter" rel="noopener noreferrer"&gt;Subscribe to the newsletter&lt;/a&gt; - no spam, unsubscribe anytime.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>localllm</category>
      <category>ollama</category>
      <category>numctx</category>
      <category>localaiagents</category>
    </item>
  </channel>
</rss>
