Can models pass working state without writing it down?

Independent Research — Waylon Zabriskie · August–October 2026

When two AI models work together, they exchange text. I wanted to know whether they have to. Could one model pass information directly through its internal representations, and would that keep more information or cost less than writing it down?

Strongest finding
A small map, trained only to reproduce how the receiving model internally represents a record, let a different model answer kinds of questions the map never saw. It scored as well as the receiver does with its own representation of the record: 0.90–0.92 on a held-out equality task and 0.78 on a held-out mapping task, across three independently trained maps. Substituting another record's state changed the answers to match that record.
Main limitation
What crossed between the models was a synthetic record of about 15 bits. Plain JSON did the same job with equal accuracy, in 77 bytes instead of 80,640. On real agent sessions, the memory approach did not beat simple text matching.
Open questions
Does the map work on field values it never saw in training? Does latent memory beat a good written summary when the question does not give away its own answer? (Section 6)

Results in brief

By internal state I mean the numbers a model computes while it reads, as opposed to the text it writes. All models studied were open-weight models run locally. In the cross-model experiment both models stayed frozen; only the small map between them was trained.

  1. It works, in a narrow sense. A small learned map moved a seven-field record from one model's internals into a different model's internals. The second model then answered kinds of questions the map had never been trained on: 0.90–0.92 on a held-out equality task and 0.78 on a held-out mapping task. Those scores match what the second model achieves with its own representation of the real record.
  2. It was not better than text. On the same kind of record, JSON produced the same decision accuracy (1.000 on 300 unseen cases) in 77 bytes. The internal route used 80,640 bytes and about a second of extra compute. I stopped that line of work.
  3. Memory across a context reset worked on synthetic data, and did not work on my real coding-agent sessions. When I audited my own evaluation, I found that the real-session benchmark could be solved perfectly by exact string matching. The learned memory scored well below that.

What came out of this is a clearer picture of when passing internal state is worth trying and when it isn't, plus a set of evaluation checks. Those checks overturned several of my own conclusions along the way.

1. Why I looked at this

A lot of practical work with language-model agents is context engineering: deciding what an agent sees, what it remembers when its context window fills, and what it hands to the next agent. Most practical agent handoffs today exchange text, such as summaries or structured messages. A model that has read a long session has some internal representation of it. To pass that on, it writes a summary, and the next model rebuilds its own representation from that summary. Summaries drop details nobody thought to write down, and rebuilding context costs tokens and time.

So the question was simple to state. Could a model hand over its internal representation directly, to a different model or to a fresh copy of itself after a reset? I started with three hypotheses, and I want to keep them separate from what was actually shown:

2. Moving a record from one model to another

The experiment in one picture Model A reads a short private record. Instead of writing it as text, A's internal numbers for the record pass through a small learned map into model B, which never sees the record. B then answers a question about the record, including kinds of question the map was never trained on. The usual route, writing the record as JSON, is shown underneath for comparison. Model A reads a private record F1=B F2=D F3=A F4=C N1=3 N2=5 N3=1 synthetic example Small learned map converts A's internal numbers into B's internal format never sees a question or answer Model B a different model never sees the record as text answers a new question: "Is F2 equal to F4?" held-out kind of question internal state usual route: write it as text (JSON, 77 bytes) Check: swap in a different record's state, same question → B's answer should change to match it.

Figure 1. The experiment in one picture. Both models stay frozen; only the small map is trained.

Model A reads a short record. Instead of writing it out, A's internal numbers for that record pass through a small learned map into Model B, a different model that never sees the record as text. B is then asked questions about the record. The map was trained only to imitate how B itself represents a record, and never saw a question. Two kinds of question were held out entirely, so the test is whether B can use the transferred state for questions nobody trained it on.

Technical setup: models, dimensions, training and injection point
How the cross-model state transfer experiment works Model A reads a private record. Usually it would write the record as text for model B. In this experiment, seven hidden-state vectors from model A pass through a small learned map and are written into model B's internal state at layer 4, where B's own prompt only contains placeholders. B then answers a question about the record. Controls swap in another record's state, use zeros, or use an untrained map. Model A (frozen) Qwen2.5-3B-Instruct private record (synthetic) F1=B F2=D F3=A F4=C N1=3 N2=5 N3=1 A reads the record. Its final-layer hidden state is taken at each of the 7 values. 7 vectors × 2,048 numbers Learned map small transformer, trained on 1,500 records to reproduce B's own layer-4 representation of the same record. Never sees a question or an answer. Output: 7 vectors × 2,880 numbers Model B (frozen) gpt-oss-20b, 24 layers B's prompt: placeholder record F1=_ F2=_ … N3=_ + a question it was given only now, e.g. "Is F2 equal to F4?" map output added to the 7 value rows after layer 4; layers 6–24 run (layer 5 skipped) → B answers Usual route: A writes the record as text {"F1":"B","F2":"D",…} · 77 bytes How I checked that B used A's state Swap: give B another record's state, same question → B's answer should follow the other record. Zero state, random state, and an untrained map should all fall to chance. Ceiling: insert B's own layer-4 rows for the real record.

Figure 2. The same experiment in detail.

Models and task. Model A (Qwen2.5-3B-Instruct) reads a private record of seven fields: four letters (A–D) and three digits (1–5), which allows 32,000 possible records. Model B (gpt-oss-20b) never sees the record as text. Its prompt contains the same seven field names with placeholder values, followed by a question that A never sees. I chose gpt-oss-20b as the receiver after testing seven local models. It was the only one that answered at least six of eight kinds of questions about a record correctly at least 95% of the time when given the record as plain text. Without that, a failure later would have been uninterpretable.

What the map is trained to do. For each of the seven values, I take A's final-layer hidden state at that value's position (7 vectors of 2,048 numbers). A small transformer with one attention layer maps them to 7 vectors of 2,880 numbers. It is trained on 1,500 records to reproduce one thing: how B itself represents the same record, measured after B's fourth layer, at the seven value positions, relative to the placeholder record. The map never sees a question, an answer, or which task will be asked. A zero-in, zero-out constraint stops it from adding a constant offset that would bias B regardless of the record.

At test time. B processes its placeholder prompt. After B's first four layers, the map's output is added at the seven value positions. The evaluation then continues from layer 6 and B answers. It skips B's fifth layer in every condition, including the baselines and the ceiling, so B runs 23 of its 24 layers. All conditions used the same execution path, which supports comparisons within this implementation; the effect of the skipped layer has not been independently established.

Why layer 4. Before training anything, I copied B's own internal rows for a real record into a placeholder prompt at different depths. At layers 0–4 that was enough to make B answer as if it had read the record (0.88–0.94 correct). From layer 8 on it degraded, and by layer 20 it had no effect. Past the early layers, the record's information has spread across the rest of the prompt. That probe used only 32 questions, so it chose the layer and proves nothing on its own.

What was held out

Six kinds of question were used:

Results

Cross-model state transfer: accuracy by operationGrouped bars for six operations showing correct-record accuracy, swapped-record follow rate, zero-state accuracy, and the real-record ceiling.Correct recordSwapped in another record (follow rate)No state (zeros)Real record rows (ceiling)0.000.250.500.751.00Accuracy / follow rateRetrieve a fieldchance 0.25Compare two numberschance 0.5Set membershipchance 0.5Count matcheschance 0.2Equality (held out)chance 0.5Mapping (final holdout)chance 0.25Bars: mean of 3 independently trained maps; whiskers: min–max. Dashed: chance. Shaded: operations never used to train or select the map.n = 60 questions per operation (80 for mapping). Mapping ceiling is 0.80 even with the record as text (answer-format limit).

Figure 3. Accuracy of B on six kinds of question when its record comes only through the map. "Swapped record" bars show how often B's answer followed a different record's state that was substituted on purpose.

On the two held-out question types, B scored 0.90–0.92 (equality) and 0.775–0.787 (mapping) across three independently trained maps. With its own internal rows for the real record inserted directly, B scored 0.90 and 0.775. Given the mapping record as plain text, B scored 0.80, because that question type is limited by how the answer is read out. So the map recovered essentially everything B could do with the record, on questions it had never seen.

The swap test is the main evidence that B used A's state rather than guessing. Keep the question fixed and substitute the state from a different record whose answer differs. B's answer then follows the substituted record at 0.92–1.00 on the development tasks, 0.77–0.78 on equality, and 0.80–0.83 on mapping. With all-zero state, or a map that was never trained, accuracy falls to the level B reaches with no record at all (an untrained map scored 0.15–0.30 against 0.775–1.00 for the trained one on a 40-question check).

What this does not show

What failed before this worked

The design above came after five earlier designs. Earlier versions did one of three things:

The change that worked was the training target: B's own early representation of the record, rather than anything tied to a task.

Chaining

The same kind of maps can be chained. In a five-step exchange (A to B to A to B to A to B), each model does a small private operation and passes the result on. B's final answer followed the transported value 0.975–1.000 of the time across five independently trained maps. My audit found the catch: several of these maps have rank three. Each step can only express a weighted choice among four fixed vectors, one per letter. So the chain shows that very small messages compose reliably. It does not show rich state moving back and forth. Each step was also a fresh prompt with no accumulated conversation.

3. Against plain JSON

A transfer that works is only useful if it beats the obvious alternative. In early October I built the most favorable comparison I could:

Cost of the hidden-state route versus JSONLog-scale bars: 80,640 bytes for the hidden-state message versus 77 bytes for JSON, at equal accuracy.1101001,00010,000100,0001,000,000Message size per state, bytes (log scale)Hidden-state route80,640 bytesJSON77 bytesBoth routes: decision accuracy 1.000 on the same 300 unseen states (no communication: 0.763). Read time: ~1,007 ms vs ≈ 0 ms.Same 7-field record; a fixed rule turns the recovered fields into an action. Latency excludes model loading.

Figure 4. At equal decision accuracy, the hidden-state message was about 1,000 times larger than the JSON message and took about a second to read back. Log scale.

Both routes chose the right action every time (1.000; with no communication at all the rule gets 0.763). The internal route also recovered all seven fields exactly in only 93% of cases. The extra errors happened to fall in fields the rule didn't use. JSON carries every field exactly, by construction.

I then tried the case where text is supposed to struggle: a context too long to summarize cheaply. There, B's native representation of the context was about 10.5 MB, and extracting A's state took 539 ms. That was longer than simply re-reading the raw context, which took 138 ms. On October 5 I stopped the practical line and wrote down a rule for when to use what:

4. Memory across a context reset

I then turned to a narrower version of the original problem. When an agent's context is reset, can a fresh copy of the same model continue from a compact internal memory of what came before? This part has two halves that must not be read together. In a controlled synthetic setup, memory transfer was promising. On real sessions, the evaluation exposed a weakness in the benchmark itself.

4a. Synthetic memory: it improves with training data

The setup:

Synthetic memory: accuracy grows with training contextsLine chart: accuracy on unseen fact combinations rises from 0.611 to 1.000 as training contexts grow from 48 to 384, while control memories stay near 0.20.0.00.20.40.60.81.04896192384Training contexts (log scale)Accuracy on unseen fact combinations0.6110.8610.9961.000Correct memoryZero memoryRandom memoryAnother context's memory- - chance (5 answers) = 0.203 replicate seeds at 192Each point: 64 unseen test contexts × 8 questions = 512 answers. Synthetic records; same 3B model with a small LoRA.

Figure 5. Accuracy on unseen combinations of facts as the number of training contexts grows. Control memories (zero, random, or another context's) stay at chance.

The first run used 48 training contexts. It scored 0.625 on its test set of 32 unseen contexts. The pass bar of 0.70 had been committed to the record two days before the result, so the run was recorded as a failure.

After that failure, a follow-up varied only the number of training contexts and used a new, larger test set (Figure 5). Its plan was committed together with its results, so the record cannot show that its criteria came first. Accuracy was:

In this synthetic setup, more training data closed the gap. That does not show the same approach would scale to richer memory. A port to the 7B model scored 0.990 on a test set opened once, but that was a single run.

I also built automatic selection, deciding which events in a long generated history are worth keeping, and it reached 1.000 in that setup. My audit qualifies this. In those generated histories, an event counted as important exactly when a later event referred to it, and the selector could see those reference counts. The result confirms the pipeline works end to end, not that the system discovered what matters. The "128K-token" scaling test was 3,200 short events encoded one at a time, not one long context.

4b. Real sessions: no evidence that it works

Data. I used my own coding-agent session logs: about 1,670 sessions across three private repositories, of which 509 met a fixed rule for substantial work (enough tool calls, files, commands and at least one error). Only counts and hashes were stored. No transcript text is in any result.

Task. Cut a session at 70%. For an event after the cut, pick which earlier events concern the same file or command, using only a memory of 64 compressed event vectors.

How the settings were chosen. I chose the memory size (64 events) on development data, after memories of 16 and 32 events fell short. I set the pass bar for the sealed test (0.80 of the best achievable gain over no memory) alongside that development result, and fixed both before opening the sealed test. The sealed test used unseen sessions from the same repositories as training.

What worked. Compressing each stored event from 2,048 to 64 numbers (16 KiB for 64 events) lost nothing measurable, including on a sealed test.

What did not. Two separate evaluations, each with its own random baseline:

Real-session memory task versus simple baselinesBars: exact text match 1.000, word overlap 0.999, random 0.601, learned memory reader 0.51 to 0.56.0.000.250.500.751.00Exact match on the event's argument1.000Word overlap0.999Pick a candidate at random0.601Learned memory reader, seed 1010.532Learned memory reader, seed 2020.513Learned memory reader, seed 3030.559Top-1 hit rate: does the first pick concern the same file or command?Held-out repository, 263 tasks for the reader; baselines recomputed on the 261 tasks still reconstructable (2 sessions shrank).Even if exact match failed both missing tasks, it would score ≥ 0.992. Random is high because most tasks have several correct answers.

Figure 6. The cross-repository test, a separate evaluation from the sealed test above. The learned reader scores below random choice on this set, and exact string matching solves every task.

What the audit found. On October 29 I audited the benchmark itself. Each event is a tool name followed by its argument, such as a file path. The correct answers are earlier events with the same argument. So the question already contains the key to its own answer. Exact string matching scores 1.000 and word overlap 0.999. None of this needs memory.

I found two further problems in the later runs:

The honest conclusion is that this benchmark cannot show whether latent session memory works. Before any more modeling, it needs to be replaced by tasks where the needed information is not already in the question, with a strong text summary as a baseline.

4c. Not built

A shared, project-level memory, one memory object that several agents read and update over time, was planned as a later stage. It was never implemented.

5. How I ran the work

I built and ran the experiments with AI coding agents as my development tools, and used a separate agent pass to audit the record twice, in early and late October.

A few rules carried most of the weight:

Those rules changed several of my own conclusions. The most instructive corrections:

Full timeline of results and corrections
  1. retractionAn earlier solver's 0.975 headline was traced to answers leaking into its own checks. Corrected to 0.90.
  2. resultCross-model transfer (Section 2) passes its sealed mapping test and is frozen.
  3. processWorking files for three frozen results were lost from temporary storage. I rebuilt all three from code before doing anything else, and changed how results are stored.
  4. measurementMy standard way of reading B's answer turned out to repeat a line of the prompt instead of computing. I rewrote the measurement rules and rechecked earlier conclusions against them.
  5. auditFirst full audit of the record. Several "continuous" maps were rank three. One test set reported as a pass contained the same 32 inputs as its training set. Some sample sizes were overstated.
  6. stopJSON matched accuracy at about 1/1,000 of the size. I stopped the practical line.
  7. bugA scoring bug, which read letters where the answers were digits, invalidated every early memory number. All were rerun.
  8. reproducibilityA 0.977 memory result was a lucky initialization; reruns gave 0.73–0.81. It was reclassified.
  9. sealed testReal-session memory fails its sealed test (Section 4b).
  10. auditSecond audit. The real-session benchmark is solvable by string matching.

The October 2 audit findings have not yet been folded back into the project's own summary table. This article uses the corrected readings.

6. What I take from it

What I would test next

  1. Does the cross-model map work on field values it never saw during training? That would separate real translation between representations from a learned lookup table. It is cheap to run and has not been run.
  2. Does compact latent memory beat a good written summary on a real-session task where the question does not contain its own answer? That is the test the real-session benchmark should have been.

Both are small, well-defined experiments. The first says whether what I built is translation or lookup. The second says whether latent memory has any advantage once the benchmark stops giving away the answer.

Limitations

Related work

This study sits next to published work that I did not originate and do not claim:

What may be specific to this study:

Methods note

ItemDetail
ModelsQwen2.5-3B-Instruct (4-bit) and Qwen2.5-7B-Instruct; gpt-oss-20b (MXFP4). All frozen except where a LoRA is stated.
Transfer mapInput: 7 × 2,048 final-layer hidden states at value tokens. Output: 7 × 2,880 additions after receiver layer 4. Training: 1,500 records; validation: 400; state-matching loss only.
Receiver pathLayers 1–4, then the addition, then layers 6–24. As implemented, layer 5 is skipped in every condition, including the zero, random, ceiling and plain-text baselines. I found this while preparing the release and kept the recorded behavior rather than changing it after the fact.
Evaluation60 questions per type (80 for mapping). Three map trainings. Swap, zero and random controls. Untrained-map check. Ceiling from the receiver's own rows.
JSON comparison300 unseen records. Fixed decision rule. Bytes and read time per record.
Synthetic memory24 facts × 5 values. 96-number memory inserted at layers 4/10/16/22. Rank-8 LoRA on attention. 48–384 training contexts. 64 unseen test contexts × 8 questions.
Real-session memory509 qualifying sessions from three private repositories. Cut at 70%. 64 stored events × 64 numbers. Separate repositories for training and evaluation in the cross-repository test.
Rebuilt mapDownloadable rebuilt map and evaluation code (Hugging Face). The original three checkpoints were lost in September 2026. This map was retrained with the same recipe afterwards. It is not one of the three maps behind the results above. On the study's question sets it scores 0.917 on equality and 0.787 on mapping. Built with Qwen; the weights are for research and evaluation use only.
ComputeAll studied models were loaded from downloaded open weights. They were run and trained locally with the MLX framework. The experiment code makes no calls to hosted model APIs. Code was developed and run with AI coding agents (hosted services) as tools. The session logs used in Section 4b were produced by hosted coding agents during my ordinary work.

Every number in the figures is read from a recorded result file or a committed result document by a script that checks each value before drawing it. Where a figure combines sources, the caption says so. The October 29 baselines were recomputed from the same task construction used in the original run, with no model involved.