Interpretability
Why agents quit early
We ran Qwen3.5-9B, a nine-billion-parameter open model, as the agent in the opencode harness on three research tasks from our harness benchmark: find US importers of black tea, list biotech companies that filed a Form D for new money, and list every original Form D notice in a fortnight. Four runs in all. Three ended with the work undone. One asked the user whether to carry on, one wrote a recap of what it had found and stopped, and one announced its next step and never took it.
All three quits came right after the same event. When a run’s context fills, opencode asks the model to summarise the conversation, swaps the transcript for the summary, and sends the line below. We measured why the quit comes there, what it looks like inside the model, and whether an edit to the model or a change to the line can prevent it.
Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.
What opencode sends right after it compacts the transcript.
The quit
It only stops right after compaction
In opencode a turn with no tool call is the answer: the harness takes it and the run ends. A logging proxy in front of the model kept every request the harness sent. We sent each one again 16 times with the harness’s own sampling settings and counted the replies that carried no tool call, at 12 ordinary turns picked at random, at all 5 turns right after compaction, and at the 3 runs’ last turns.
Point at a dot for its run and call.
None of the 192 replies at ordinary turns stopped. After compaction the same model stops between 3 and 11 times in 16, about half on average. None of those runs had written its document yet, so each of those stops is premature.
Nor does the model stop more when the work is done. At the last turn of the one run that delivered, where stopping is right, it stops 8 times in 16, no more often than after compaction. The stop after compaction is a coin the harness’s line tosses, not a judgement about the work.
Inside the model
Two wells: one that goes on, one that stops
To see the choice inside the model we read its residual stream, the running sum every layer writes into, at the token where a reply either ends or opens a tool call. For each layer we took the replies after compaction, averaged those that stopped and those that went on, and called the difference the stop direction. Fitted on two runs and scored on the third, it tells the two apart with an AUROC of 0.99 from layer 7 on. Part of that is built in, since by that token the two kinds of reply have already written different text. What is not built in is where every other turn lands. We use layer 21, and each reply becomes one number: how far it sits along the direction.
Point at a reply. Each of 10 decision points was sampled 16 times.
The replies that went on after compaction average −24.3, and ordinary turns sit beside them at −20.7. The replies that stopped average +25.1, about 49 units away, and no ordinary turn comes near them. At the runs’ last turns the replies split the same way, those that went on in the go well and those that stopped spread from the ridge into the stop well, whether or not the work was done.
That is the shape of a bistable system: two attractors with a ridge between them. On an ordinary turn the state starts deep in the go well and never crosses. Compaction, followed by an offer to “stop and ask”, starts it at the ridge, which is what a stop rate of one half means, and sampling decides the side. The stop well is absorbing, because in opencode a reply that lands there ends the run.
Try it yourself
Would you have stopped here?
- Every decision point after compaction, with the harness's own line
- How often Qwen3.5-9B stopped there, out of 16 tries
- The start of a reply it wrote, and where it sits between the two wells
Recorded runs, free to look at. Nothing runs on your account.
Open the decision pointsIdea basins
Failing runs wander rather than stick
The wells say how a run ends. They do not say whether the run was already lost, so we also mapped how each run explored. Bespoke Labs drew a model’s ideas as a path over a map of basins, clusters of related ideas, and asked how often it left one. We did the same for tool calls. Every data call of every run on a task, such as trade search companies or trade company shipments, becomes a TF-IDF vector of its command and arguments. MDS lays the calls on a plane and k-means groups them, with the number of basins picked by silhouette. On the black-tea task the map keeps the order of 77% of random triplets of calls, against 50.5% for a map that only knows which run each call came from.
Qwen3.5-9B, live run 1
early quit, 37 calls, 3 basins
Qwen3.5-9B, live run 2
early quit, 39 calls, 3 basins
DeepSeek V4.1 Flash, run 1
early quit, 76 calls, 4 basins
DeepSeek V4.1 Flash, run 2
early quit, 67 calls, 4 basins
DeepSeek V4.1 Flash, run 3
timed out, 46 calls, 4 basins
GLM-5.3-Flash, run 1
timed out, 78 calls, 4 basins
GLM-5.3-Flash, run 2
delivered, 149 calls, 4 basins
GLM-5.3-Flash, run 3
timed out, 140 calls, 4 basins
Particle-1, run 1
early quit, 73 calls, 4 basins
Particle-1, run 2
timed out, 51 calls, 4 basins
Particle-1, run 3
timed out, 93 calls, 4 basins
Eleven runs worked the black-tea task: Qwen’s two and nine from DeepSeek V4.1 Flash, GLM-5.3-Flash and Particle-1 in our earlier benchmark. All of them use the same four basins: search for importers, read an importer’s shipments, and look up a supplier’s customers two ways. Ten failed, five by quitting early and five by running out of time. They did not fail by sticking in one basin, since every run visited at least three.
Qwen differs in degree. Its runs made 37 and 39 calls where the others made 46 to 149, moved to another basin on 16% and 25% of calls against 36% to 64%, and never reached the fourth basin. One run spent 77% of its calls searching for importers. Then compaction came, and it stopped.
| Model | Runs | Basins visited | Moved basin | Came back | In first basin | Delivered | Quit early | Timed out |
|---|---|---|---|---|---|---|---|---|
| Qwen3.5-9B | 4 | 3.8 | 33% | 73% | 24% | 1 of 4 | 3 of 4 | 0 of 4 |
| DeepSeek V4.1 Flash | 31 | 5.1 | 63% | 82% | 22% | 26 of 31 | 3 of 31 | 2 of 31 |
| GLM-5.3-Flash | 33 | 4.3 | 56% | 77% | 29% | 30 of 33 | 0 of 33 | 3 of 33 |
| Particle-1 | 29 | 5.0 | 57% | 80% | 20% | 22 of 29 | 3 of 29 | 3 of 29 |
Across all 17 tasks and 97 runs the pattern holds. Runs that failed spent less of themselves in the basin they began in (Spearman ρ −0.25, p = 0.01). How often a run moved basin shows no reliable link with failing (ρ −0.16, p = 0.12), and how long it stayed in its first basin has none with quitting early in particular (ρ −0.09, p = 0.36). Only 2 runs never left their first basin, and both delivered.
So the basins argue against the easy story that a model quits because it is stuck on one idea. Failing runs wander. Quitting is a separate event, and the harness sets the moment for it.
Editing the model
An edit removes the quit and adds a loop
If the stop is a well, an edit can try to keep the state out of it. Every edit below works at layer 21 along the stop direction, through a forward hook on vLLM that touches every token. We measured each at the same turns with 8 replies a turn. Replies that loop until the 3,072-token cap are counted apart from clean stops, because a loop is the fourth kind of pause.
| Model | Stops after compaction | Loops after compaction | Stops on ordinary turns | Loops on ordinary turns | Stops at the final turn |
|---|---|---|---|---|---|
| Uneditedthe same server in eager mode, 16 replies a point | 0.51 | 0.00 | 0.01 | 0.00 | 0.29 |
| Subtract dh − d on every token | 0.00 | 1.00 | 0.02 | 0.98 | 0.00 |
| Clamp at the go wellprojection on d capped at the went-on mean (−24.3) | 0.00 | 0.30 | 0.00 | 0.08 | 0.00 |
| Clamp at the ridgeprojection capped halfway between the wells (+0.4) | 0.55 | 0.00 | 0.00 | 0.00 | 0.25 |
| Clamp near the stop wellprojection capped three quarters of the way (+12.7) | 0.53 | 0.00 | 0.00 | 0.00 | 0.29 |
| Random directiona random vector with |d|, subtracted | 0.57 | 0.03 | 0.04 | 0.02 | 0.25 |
Subtracting the whole direction breaks the model. Every reply runs to the cap, repeating one word (“biotech biotech biotech”) or switching languages mid-sentence. A random vector of the same length changes nothing, which says the direction, not the size of the push, is what matters.
The clamp leaves a state alone unless it has moved past the bottom of the go well, and then pulls it back there. It removes the quit entirely: no clean stop in 40 replies after compaction. But 12 of those 40 now loop to the cap. The model also loses its correct stop, since at the delivered run’s last turn it no longer stops. Some replies show the conflict outright: the thinking reads “Let me present this clearly to the user”, and the action is a tool call.
A gentler clamp does nothing. Capping the projection at the ridge, or three quarters of the way to the stop well, leaves the quit at 0.55 and 0.53, with no loops. The stopped replies sit far beyond either cap, so if the direction were the switch, these clamps should have stopped them. It is a readout of the decision more than a lever on it. Only pinning every token to the bottom of the go well, a pull of up to 49 units, moves the behaviour, and a pull that large costs the model its correct stops and some of its coherence.
Rewording the harness
Changing one line halves the quit
The cheaper change is in the harness. We sent the same 5 post-compaction requests to the unedited model with only the last line replaced, 8 replies each.
| Line after compaction | Stops after compaction | Loops after compaction |
|---|---|---|
| The harness’s own lineQwen3.5-9B as released | 0.49 | 0.00 |
| “Continue with the next step of the task.” | 0.25 | 0.00 |
| “Continue working until the task is complete; the user is not available to answer questions.” | 0.28 | 0.00 |
Either line halves the quit, and neither produced a loop. Half the stops remain, so the offer to stop is not the whole cause. The other candidate is the summary itself. The summary opencode writes is a report of work done, and a report of work done reads like a final answer to a model choosing whether to give one.
Method and data
How we measured it
Qwen3.5-9B in bf16 served by vLLM on one GPU with a 64k-token window, behind a proxy that logged every request and reply. The four runs used opencode as the harness, on 13 November 2026. A turn counts as a stop when it carries no tool call. Resampling resent a logged request unchanged, with its own sampling settings, and read the stop from the reply. Residual states came from teacher-forcing each sampled reply through the same weights in Hugging Face Transformers, with thinking on, and reading every layer at the reply’s last token.
Edits ran with vLLM in eager mode. Under torch.compile the forward hook is silently skipped, and two different edits gave identical numbers until we noticed. The idea maps use the data calls of 97 runs on 17 tasks from our harness benchmark plus Qwen’s live runs, with MDS or t-SNE per task, whichever keeps more triplets in order.
- Idea maps after Bespoke Labs’ How models explore ideas.
- Basins of calls after Fork-and-Flush (arXiv 2610.07447).
- An earlier pass replayed 116 recorded harness runs into Qwen and seemed to show it stopping at 19% of mid-run turns. Every one of those turns was in fact a run’s real final answer, because recorded runs end with an empty extra turn. We dropped that pass and measured live runs instead.
- Four live runs and five post-compaction turns are a small sample. The stop rate at each turn rests on 16 replies, the edits on 8.
What it means
What this means
For a harness author: do not end a compaction with an offer to stop. A plain instruction to continue halves premature quits at no cost, and a summary written as a handover rather than a report of work done is the next thing to try.
For a model trainer: the stop is a bistable choice that barely depends on whether the work is done. The model stops as often at a finished run’s end as at an unfinished run’s compaction. An activation edit can push the state out of the stop well only by pinning it at the bottom of the other one. That removes the right stops too, and some of what it pushes lands in a loop. Training has to teach the choice what “done” means.
For anyone running a small model as an agent: a quit right after compaction is a coin that came up tails. Resuming the run gives it another toss.
Try it yourself
Would you have stopped here?
- Every decision point after compaction, with the harness's own line
- How often Qwen3.5-9B stopped there, out of 16 tries
- The start of a reply it wrote, and where it sits between the two wells
Recorded runs, free to look at. Nothing runs on your account.
Open the decision pointsMore head-to-head evals
| Measure | GLM-5.3 | DeepSeek V4.1 Flash |
|---|---|---|
| Right, of 75 | 75 | 71 |
| Seconds a question, median | 3.9 | 1.8 |
| Measure | First run | Best since |
|---|---|---|
| Landscape, seconds | 937 | 233 |
| Memo, seconds | 759 | 602 |
| Measure | Qwen3 235B | GLM-5.2 | Gemini 3.8 Flash | Claude Opus 5 |
|---|---|---|---|---|
| Seconds to the plan, median | 27 | 48 | 57 | 94 |
| Plans written, of three runs | 2 | 3 | 3 | 3 |
| Measure | SubQ | jev | Decider | Nimble |
|---|---|---|---|---|
| Found, mean of five columns at section length | 64% | 65% | 66% | 68% |
| Mechanism of action, found at section length | 57% | 51% | 61% | 54% |
| Measure | ask | Apollo | treg |
|---|---|---|---|
| Usable leads | 13 of 40 | 7 of 40 | 6 of 28 |
| Cost per usable lead | $0.037 | $0.27 | $0.23 |
| Measure | ask with jev | ask with Decider |
|---|---|---|
| Questions right, of 92 | 89 | 89 |
| Wrong answers | 1 | 2 |
| Measure | jev | ask |
|---|---|---|
| Our 370 clinical decisions, right | 94.6% | 93.0% |
| PubMedQA, right (best EdgeEvals scored: 62.2%) | 77.0% | 74.4% |
| Measure | ask | Claude Opus 5.5 |
|---|---|---|
| Questions right, of 95 | 59 | 63 |
| Small companies right, of 20 | 13 | 9 |
| Measure | realestate-us | Best of four assistants |
|---|---|---|
| Floor-plan rents right, of 26 | 26 | 23 |
| Amenities claimed the listing doesn't state | 12 | 129 |
| Measure | ask | jev |
|---|---|---|
| Right, of the questions answered | 98% | 79% |
| Wrong answers, of 92 | 2 | 19 |
| Measure | Trained localiser | Best of four frontier models |
|---|---|---|
| Mean overlap with the defect (IoU, 0 to 1) | 0.421 | 0.109 |
Particle-1, run 1