qwen3.5-9b-drctx-mix-mk2-nc20-bs20-os2-sft-e2
SFT of
hamishivi/Qwen3.5-9B for
self / dynamic context management in long-horizon agents. The model decides
when and
how to compact its own context (via an
edit_context tool) while
solving long-context agentic tasks.
This is the
mk2 iteration. It differs from the previous
2-domain model
in two ways:
- Three domains instead of two — terminal/coding (CLI-Gym, TMax) plus
long-horizon web research (OpenResearcher), so compaction is learned on
research logs as well as terminal transcripts.
- A thinking-capped teacher. Rollouts were distilled from
bottlecapai/ThinkingCap-Qwen3.6-27B
rather than Qwen/Qwen3.6-27B. The mk1 evaluation found that generation
verbosity, not compaction, dominated inference cost — generation is the one
term neither prefix caching nor compaction can discount — so mk2 targets the
length of the distilled THOUGHT block. Measured on the built datasets, this cut
teacher THOUGHT tokens per turn by −25% (OpenResearcher), −37% (TMax)
and −11% (CLI-Gym) versus mk1.
Training data
Segmented self-compaction trajectories generated with a Codex/Claude-Code-style
harness and split at compaction boundaries into independent SFT sequences. The
model is trained on one
pre-balanced mixture,
osieosie/drctx-mix-mk2-nc20-bs20-os2
(17,595 rows), built from the three per-domain archives:
The mixture is balanced by compaction form (nc20-bs20-os2 = 20%
non-compaction, 20% of compactions from the forced backstop, scarce self-initiated
forms oversampled 2×) so the model sees non-compaction turns and rarer edit types,
not just the dominant summarization behavior:
| form | rows | share |
|---|
self:summarization | 10,181 | 57.9% |
| non-compaction | 3,519 | 20.0% |
backstop:full_compaction | 2,815 | 16.0% |
self:offload | 668 | 3.8% |
self:full_compaction | 320 | 1.8% |
self:deletion | 92 | 0.5% |
Each per-domain archive ships normal / medium / high compaction-effort splits
(generated at n1000 × k4 per domain per effort).
Recipe
- Base model:
hamishivi/Qwen3.5-9B (gated-delta hybrid)
- Objective: assistant-only loss with prompt-length-gated masking (carried-over
context is masked; only newly generated tokens after each compaction boundary
are trained)
- Max sequence length: 32,768 (matches the 32K generation budget)
- Epochs: 2 · global batch: 128 · LR: 2e-5 (linear, warmup 0.03) · bf16
- Parallelism: DeepSpeed ZeRO-3 (no offload) + Ulysses sequence parallelism
- Trainer: vendored open-instruct fork
Evaluation
Same unified (compaction) harness for every policy: strict 32K cap,
max_steps=64, max_tokens=16384, temp=0.7, top_p=0.95, k=1, single seed.
base = hamishivi/Qwen3.5-9B; mk1 = same recipe with the un-capped
Qwen3.6-27B teacher.
OpenResearcher (rl split, n=250, LLM-graded F1) — mk2 restores base-level
answer quality while keeping the compaction benefit:
| metric | base | mk1 | mk2 |
|---|
| mean F1 | 0.449 | 0.429 | 0.448 |
| empty-answer rate | 28.8% | 40.4% | 32.8% |
| fully correct | 0.380 | 0.375 | 0.388 |
| generation tokens / rollout | 5,587 | 10,293 | 6,029 |
| KV-cache-aware FLOPs / rollout | 8.51e15 | 1.65e15 | 1.53e15 (−82% vs base) |
Terminal-Bench 2 (89 tasks) — task success is flat within noise
(SE ≈ 0.039 at n≈88, k=1), and compute remains above base:
| metric | base | mk1 | mk2 |
|---|
| resolved rate | 0.182 | 0.161 | 0.148 |
| generation tokens / rollout | 31,597 | 58,485 | 58,257 |
| KV-cache-aware FLOPs / rollout | 3.96e15 | 4.52e15 | 4.42e15 (+11% vs base) |
Compaction behavior. edit_context anchor apply-success is 97%
(OpenResearcher) / 92% (TB2), and 73% / 64% of edits span multiple turns, so the
model compacts across whole sub-threads rather than only the last observation.
mk2 reaches mk1's context control with roughly half the edits (OR 1,032 → 528;
TB2 428 → 128) at equal-or-tighter peak context — and since every edit breaks the
prefix cache, fewer-but-equally-effective edits is the cheaper behavior.
Known limitations
- Form collapse toward summarization. Despite the mixture oversampling them,
offload and deletion are almost never chosen at inference (≈0% on
OpenResearcher; 2 offload events on TB2, neither read back). If you need those
behaviors, prompt for them explicitly.
- Terminal-domain cost is unimproved. The terser teacher shortened thinking on
both domains, but on TB2 the savings were reallocated into larger
bash payloads
(heredocs writing whole source files), leaving total generation flat. Terminal
output is ~40% code payload, which a thinking-length lever does not reach.
- Trained and evaluated at a 32K context budget; behavior at much larger budgets
is untested.
Usage
1from transformers import AutoModelForCausalLM, AutoTokenizer
2
3repo = "osieosie/qwen3.5-9b-drctx-mix-mk2-nc20-bs20-os2-sft-e2"
4tok = AutoTokenizer.from_pretrained(repo)
5model = AutoModelForCausalLM.from_pretrained(repo, torch_dtype="bfloat16", device_map="auto")
Serving with vLLM: the checkpoint ships open-instruct's flattened
qwen3_5_text config (Qwen3_5ForCausalLM), which older vLLM builds do not
recognize as a top-level architecture. If vllm serve rejects it, serve the base
model's wrapper config.json (model_type: qwen3_5) over these weights with
--language-model-only; the weight keys match the wrapper's language tower.
The model expects the harness system prompt that documents the edit_context
tool and stamps [[B<n>]] block markers on context messages — it anchors its
edits on those markers, which is why anchor apply-success is >90%.