Paritok-4B: Intent-Conditioned Context Compression for Coding Agents
Organizations: Paritok
Abstract
Coding agents re-send large file reads and tool outputs to a frontier LLM every turn, and this context dominates their token bill. General-purpose prompt compressors are trained on prose and suit code poorly: they paraphrase identifiers and drop the exact spans an agent needs to edit. We present Paritok-4B, a 4B LoRA compressor for coding-agent trajectories built on two commitments. It is extractive: it selects spans rather than rewriting them, and 96.0% of the identifiers, paths, and numbers it emits already appear in its input, holding at 96.2% on held-out SWE-bench Lite output. It is intent-conditioned: told the agent's current task, it acts chiefly inside a retained segment, selecting which lines survive (retained lines are +0.067 more intent-relevant than removed ones, paired 95% CI [+0.056, +0.078]) rather than changing how much is retained. We distil a gpt-4.1-mini teacher over 67,074 real OpenHands trajectories into 40,606 validated examples and fine-tune Qwen3-4B. On all 300 SWE-bench Lite instances, Paritok-4B compresses agent context to 25.7% of its size, 2.0x harder than a gpt-4.1-mini compressor (50.2%) and 2.4x harder than gpt-5 (61.9%), while retaining 86.5% of uncompressed single-shot solve quality. Fed the cat -n line-numbered input real agents produce, it compresses slightly less (27.8%) and retains more (89.3%); there the paired test is informative, with 30 instances solved only uncompressed and 17 only compressed, an exact McNemar p=0.079, so at this sample size compressing context to roughly a quarter of its size does not significantly reduce the solve rate. The model is a 264 MB adapter that self-hosts on one 24 GB GPU with no per-token compressor fee, which at list prices decides the economics: gpt-5 as a compressor is net-negative, costing more than the downstream tokens it saves. Weights, data, and evaluation scripts are open (Apache 2.0).
Figures & tables
| Marker | Replaces |
|---|---|
| [file: basename.py] | the cat -n framing of a file read |
| [body: N lines] | an elided function or class body |
| [lines L1-L2: fnA / fnB -- note] | a run of collapsed adjacent functions |
| [imports: A, B, C] | a collapsed import block |
| [N more matches in <file>] | truncated grep output |
| [<line> × N] | a log line repeated times |
| Kind | Line verbatim | Marker | Line novel | Token copy |
|---|---|---|---|---|
| file_read | 88.6% | 5.1% | 6.3% | 97.9% |
| log_output | 94.6% | 1.0% | 4.4% | 99.3% |
| file_operation | 55.4% | 0.0% | 44.6% | 98.0% |
| directory_listing | 93.4% | 4.2% | 2.4% | 95.8% |
| tool_result | 90.7% | 1.2% | 8.1% | 99.1% |
| bash_command | 46.5% | 0.0% | 53.5% | 98.1% |
| Stage | Script | Unit | Scale |
| Source trajectories (OpenHands) | 01_download | trajectory | |
| Turn-level samples (segmented) | 02_parse | turn | |
| Filtered (compressible, real action) | 03_filter | turn | |
| Labeled (levels + must-keep) | 04_label | turn | L0–L3 + spans |
| Finalized pool (traj-level split) | 05_finalize | turn | 80K train / 4K val |
| Per-segment distillation pool | 06_distill | segment | 45,000 |
| Level | Intended | Median realized | Drop rate | vs. next level | |
|---|---|---|---|---|---|
| L0 | 0.379 | 15.5% | 1,500 | ||
| L1 | 0.408 | 13.2% | 4,665 | ||
| L2 | 0.198 | 38.3% | 4,913 | ||
| L3 | 0.133 | 41.2% | 3,048 | — |
| Base model | Qwen3-4B-Instruct-2507 |
|---|---|
| Adapter | LoRA , , dropout , bias none |
| Target modules | q,k,v,o,gate,up,down_proj |
| Precision | bf16 (base not quantized) |
| Optimizer | 8-bit AdamW, wd |
| Learning rate | , linear decay, warmup |
| Batch | (effective 32) |
| Step | 10 | 100 | 250 | 500 | 750 | 1,250 | 1,750 | 2,000 |
|---|---|---|---|---|---|---|---|---|
| Loss | 0.487 | 0.216 | 0.090 | 0.080 | 0.073 | 0.072 | 0.051 | 0.086 |
| Tok. acc. | 0.928 | 0.951 | 0.967 | 0.964 | 0.968 | 0.976 | 0.978 | 0.975 |
| Backbone | Family | Per-device batch | Outcome |
|---|---|---|---|
| Qwen2.5-Coder-3B-Instruct | code-pretrained | 2 (grad-accum 16) | not shipped |
| Qwen3-4B-Instruct-2507 | general instruct | 2 (grad-accum 16) | shipped as v1 |
| Qwen2.5-Coder-7B-Instruct | code-pretrained | 8 (grad-accum 4) | not shipped |
| Checkpoint | Fmt | DropAcc | Drop-P | Drop-R | CR | chrF | IdentR |
|---|---|---|---|---|---|---|---|
| 1,800 | 0.99 | 0.47 | 0.33 | 0.29 | 0.233 | 30.1 | 0.399 |
| 2,000 | 1.00 | 0.49 | 0.33 | 0.24 | 0.236 | 34.2 | 0.383 |
| 2,200 | 1.00 | 0.50 | 0.37 | 0.32 | 0.221 | 33.2 | 0.393 |
| 2,400 | 1.00 | 0.49 | 0.33 | 0.24 | 0.231 | 34.4 | 0.380 |
| final (2,538) | 1.00 | 0.50 | 0.32 | 0.20 | 0.250 | 34.8 | 0.382 |
| Compressor | Compression rate | Quality retained |
|---|---|---|
| Uncompressed baseline | 100.0% | 100.0% |
| gpt-5 (compressor) | 61.9% | 93.6% |
| gpt-4.1-mini (compressor) | 50.2% | 85.6% |
| Paritok-4B , raw source | 25.7% | 86.5% |
| Paritok-4B , line-numbered | 27.8% | 89.3% |
| Compressor | Rate | Compressor in | Compressor out | Upstream | Total | vs. $3.00 |
| None | 1.000 | — | — | $3.00 | $3.00 | — |
| gpt-5 | 0.619 | $1.25 | $6.19 | $1.86 | $9.30 | +$6.30 |
| gpt-4.1-mini | 0.502 | $0.40 | $0.80 | $1.51 | $2.71 | $0.29 |
| Paritok-4B | 0.257 | no per-token fee | $0.77 | \mathbf{\0.77+C_{\text{self}}}$ | \mathbf{C_{\text{self}}-\2.23}$ | |