How DeepSeek Harness Saves Tokens by Not Editing History
DeepSeek Harness never edits sent tokens. A still prefix cache stays warm, so the same agent input lands in the cheap column, up to 30× less.
Get the next article
Field-tested notes on AI tooling, TypeScript, SvelteKit, and full-stack systems engineering.

An agent is not a chat with a good memory. It is a loop that resends the entire transcript on every step.
The model does one thing. Text in, text out. When the call ends, it remembers nothing. Step 40 is not "continue from last time." Step 40 is step 1 plus 39 more chapters, shipped again. System prompt, tool schemas, every message, every tool result, the whole pile.
That is why a long coding session can feel cheap on the way out and surprisingly expensive on the way in. Output is the new work. Input is mostly you, re-reading yourself.
Providers will skip re-reading the front of that transcript. The trick is called prefix caching. It has one condition, and the condition is a little bit rude. The bytes at the front of this request must be word-for-word identical to last time.
Picture the model reading your conversation the way a person reads a book, page one forward, because what page 400 means depends on everything before it. There is no skipping to the good part. The order is the meaning. If the first 200 pages match, the provider restores a bookmark and starts there. Change one character on page 3 and every page after it means something slightly different. The bookmark is toast. The book gets read again, and you pay full price for the reread.
DeepSeek Harness is built around that condition. Once something has been sent to the model, it does not go back and change it. A wrong file path stays in the log. You append a line that says, yup, that path was wrong.
That sounds like bookkeeping. It is how you stop paying to re-read your own diary.
Two columns on one price list
DeepSeek publishes both rates, which is unusual and honestly pretty useful. These are V4-Pro numbers as of 17 August 2026, per million input tokens.
| Off-peak | Peak | |
|---|---|---|
| Cache hit | $0.022 | $0.044 |
| Cache miss | $0.66 | $1.32 |
That is 30×. Same model. Same text. Neighboring columns of one table. Peak hours (01:00–04:00 and 06:00–10:00 UTC) do not shrink the gap. They just make a busted prefix more expensive.
The harness shipped as an MIT developer preview on 13 August. Peak billing landed three days later. That is not a contradiction. A wrapper that keeps the prefix still is how the dearer miss column stays survivable.
The architecture does not send fewer tokens. An agent still resends the whole history every step. What it decides is which column those tokens land in.
A 100-step bill
This is a simplified model, not a benchmark. Recheck the pricing page before you budget from it.
Assume a 100-step coding session on V4-Pro, off-peak.
- 10,000-token header that never needs to change (system prompt + tool schemas)
- 2,000 new tokens per step (assistant + tool results)
- input at step k =
10_000 + 2_000 × (k − 1)
Step 1 sends 10k tokens. Step 100 sends 208k. Over the whole run the provider sees about 10.9 million input tokens. That number does not move. The architecture only moves which rate you pay.
If history stays still, append-only, each byte is a miss once and a hit forever after.
| Tokens | Off-peak | |
|---|---|---|
| Cache miss (new bytes only) | 208,000 | $0.14 |
| Cache hit (replayed prefix) | 10,692,000 | $0.24 |
| Input total | 10.9M processed | ~$0.37 |
Almost 98% of the input is billed at the hit rate. That is the fun part.
If history gets rewritten, or the prefix never matches, those same 10.9M tokens are all misses. About $7.19.
About 19× for the same work. The model did not get smarter. The wrapper just stopped editing page 3.
One edit is enough to feel it. By step 80 the prompt is ~168k tokens. A static step is roughly $0.005 (166k hit + 2k miss). Rewrite a tool result sitting in the middle of that prompt and the bookmark dies. That one step costs about $0.11, at the expensive end of the session. Keep trimming, refreshing, and summarizing in place, and you never get a stable prefix again. You are now the person who keeps moving the bookmark and wondering why the library is so slow.
Output is a different line on the bill (V4-Pro $1.98 / $3.96 per million, off-peak / peak). Static history does not touch it. Long agent runs are still input-dominated, because history is resent every step. The MIT license is not free inference. The local web UI is not a local model. The harness is what keeps you in the cheap column of a bill you still pay.
The sensible choices point the wrong way
Most harnesses cannot keep the bookmark, because agents edit history constantly.
- a summary replaces old turns when the context fills
- bulky tool output gets trimmed in place to make room
- a file is re-read and the fresh copy is swapped over the stale one
Every one of those is a reasonable thing to do. Every one reaches backward into the transcript. Every one throws the bookmark away at the moment the conversation is longest and re-reading it costs the most. Helpful, tidy, and accidentally expensive.
The real design question for a harness is not which tools to offer or how to word the prompt. Can you run a 200-step session without ever going back and editing what you already sent?
If the answer is "we summarize when it gets long," you have already answered no.
They made rewriting unexpressible
DeepSeek's 5 July 2026 reconstructable requests design note is delightfully blunt about the shape. A session is not a list of messages. It is an append-only log of typed events. A user message is an event. An assistant reply is an event. A tool result is an event. The log only grows at one end. No sneaking back to page 3 with a red pen.
The message history handed to the model is not stored. It is derived on every step by folding a pure function over the events. There is no message array to reach into, because there is no message array. You cannot edit what does not exist.
The principle fits on one line. Model-visible means durably referenced.
If something can reach the model, it must be reconstructable from the log (plus the immutable objects the log points at, plus a pinned code version). Byte for byte. Not equivalently. Identically.
Cache stability is corollary number one, not the headline. They did not set out to build a cache optimizer. They built a log you cannot edit and a projection that is a pure function of it. Prefix stability falls out the other side. In their words, stability is emergent, not managed.
When something has to change, you append. Trim a bulky tool result and that trim is itself a new log event, carrying the shorter value under the same call id. The correction goes on the end. The history in front of it is untouched.
They close the door in code, not in prose. Derived messages are deep-frozen. If a plugin reaches through a projection to mutate history, it does not corrupt the log. It throws. A request the log does not explain cannot be constructed by accident, not by the loop and not by a listener a third party plugs in later.
They even rejected the obvious safety net: compare consecutive requests and warn on divergence. A warning arrives after the bad request has shipped. A rule you can only check by reading the code decays the first week somebody is in a hurry. We have all been that somebody.
So they wrote a module whose job is to disbelieve the agent loop. On every request it builds a fresh session, replays the log from the beginning, derives the messages again, and compares that answer against what the loop is about to send, so the live cache cannot vouch for itself. On top of that, a paid test against the real API fails unless the second request in a conversation reports cache-read tokens.
The bill is the assertion. If the cheap column does not light up, the design is lying.
Compaction is where append-only gets hard
Sooner or later the conversation grows past what the model can hold. The harness has to summarize the old part so the work can continue. That means a second call to the model. This is the case that should break an append-only design, if anything does.
The obvious summarizer puts a fresh system prompt at the front ("you are a summarizer") plus the conversation to condense. That is reasonable, and close to the most expensive move available. The system prompt sits at token one, which is exactly where the cache starts keying. One differing first token invalidates the entire prefix. The summarizing call shares nothing with the warm request that just tripped the limit. You pay full miss price for the whole history twice, at the longest moment. Congratulations, you summarized your way into a bigger bill.
The fix reads like nothing and turns out to be the whole idea. Leave the cached prefix alone. Replay the previous request word for word, same system prompt, same tool definitions, same history, then hang the summarizer instruction off the end. The call is a strict extension of what the provider already cached. The bookmark survives. The provider reads a new instruction and nothing else. The summary lands in the log as a new event. The conversation continues on a prefix that was never disturbed.
They go further than "send the model what it needs." The summarizer will never call a tool. It has no use for the tool schemas. They send them anyway, because removing them would shorten the token sequence and knock every following token out of alignment with the cached copy. Waste a few tokens on purpose. Save the rest of the book.
The rule is not "send the model what it needs."
The rule is do not disturb the bytes that came before.
Append less, after you stop rewriting
Static history is the main saving. There is a second one, and it is almost as satisfying.
In a normal tool loop the model picks a function, round-trips, picks another. Every intermediate result lands back in the conversation whether it matters or not. The log grows. The static prefix gets heavier even when you never edit it. You stopped rewriting history and then invited every scratch note to live there forever.
DeepSeek's Code mode (programmatic tool calling) hands the model a generated TypeScript interface and one transport, run_code. The model writes a small program. The program loops, branches, filters, runs several reads. Only what it returns joins the log. The model curates its own context instead of drowning in it. Cloudflare made the same argument for Code Mode. Models have read millions of lines of real code and comparatively few canned tool-call traces, so ask them for the thing they have actually seen.
That second saving is append less, so the prefix you must keep still stays smaller. It is not a substitute for never rewriting what you already appended. First, stop editing page 3. Then stop adding pages you do not need.
Plugins cannot be allowed to touch the past
The README line is "everything is a plugin." The model adapter, the tools, the sandbox, the summarizer, the UI, even the agent loop, the thing most frameworks treat as the center of the universe, is a row in a configuration file.
That is only safe if unloading a component leaves nothing behind in the log. A plugin that rewrites a past tool result to "clean up" would bust the prefix for every step that follows. The same append-only rule that keeps the bill down is the rule that makes hot-swapping possible.
The kernel under that is Cordis, a plugin system where every registration is an effect, and every register function hands back the thing that undoes it. Nothing gets installed without a way to uninstall it. DeepSeek did not invent it. It grew out of the Koishi chatbot stack, and they vendored it rather than taking it as a floating dependency. The point for this article is smaller than the paper. A swap must not reach backward into history, or the cache dies.
The inspectable trajectory in the UI is the same log. You can see why a step went sideways because the bytes were never rewritten to make the story tidier. The design that keeps the bill down is the design that makes the incident readable. Cheap and honest. That is a rare combo.
The wrapper is the product
On the public Terminal-Bench 2.1 board, the same weights (Fable 5) score 83.8% under Claude Code and 80.4% under Terminus 2. Same model, same tasks, different wrapper. A few points decided by software with no weights in it at all. That is the gap between two harnesses that are both good. Between a good one and a careless one, the gap is the miss column.
DeepSeek does not have a row on that board yet. Treat launch-week scoreboards as the vendor's until somebody neutral reproduces them. The architecture is still the thing worth stealing.
If you need an agent that works this afternoon, this is not it. It is a v0.1 developer preview. The README promises compatibility-breaking changes. Pin a version. Use a disposable workspace. Do not wire production to it this week. Play with it. Do not marry it.
If you are building an agent loop on any model, read the reconstructable-requests note before you write another line that splices a summary into the middle of a message array. It is one file. It is written in plain English. It will change what you do with history.
The rule you want is not a cache flag.
Once a token has been sent to the model, do not go back and change it.
Thank You!
Thank you for taking the time to read my article and I hope you found it useful (or at the very least, mildly entertaining). For more great information about web dev, systems administration and cloud computing, please read the Designly Blog. Also, please leave your comments! I love to hear thoughts from my readers.
If you want to support me, please follow me on Spotify or SoundCloud!
Please also feel free to check out my Portfolio Site
Looking for a web developer? I'm available for hire! To inquire, please fill out a contact form.
Related posts

How to Automate Scheduled X Posts with Codex and xurl
A scheduled task researches and drafts each post, while a fixed-account skill handles secure publishing.

Filling the Memory Gap: Building MCPMem to Fix AI Assistant Forgetfulness
How I hacked together a semantic memory system for AI assistants with the Model Context Protocol

Building a Multi-Modal GPT Agent in TypeScript with OpenAI
Learn how to build powerful multi-modal GPT agents using OpenAI function calling--complete example project.
One practical engineering essay each week
Field-tested notes on AI tooling, TypeScript, SvelteKit, and full-stack systems engineering.
Comments (0)
Join the discussion and share your thoughts on this post.
No comments yet
Be the first to share your thoughts!