Darkwood · Symfony · Flow · context

Nolife Tokens

Shrinking LLM context
without destroying recoverability

Symfony + Flow experiment

@matyo91

The problem

Tool
↓
50 KB stdout
↓
LLM context
logs
JSON telemetry
git diffs
repo trees
compiler output
test output

Large context windows make it possible to send everything.
They do not make it wise.

01 | problem @matyo91

Hypothesis

Do more deterministic work
before the LLM.

Before

Tool
→ raw output
→ LLM

After

Tool
→ deterministic reducer
→ useful context
→ LLM

PHP handles

deduplication · classification · filtering · hashing · recovery

These tasks do not require a model.

02 | hypothesis @matyo91

content/nolife-tokens

A laboratory, not a framework

PHP 8.5
Symfony 8.1
Console
darkwood/flow

Not used

No embeddings
No vector DB
No MCP
No Redis
No LangChain

Pipeline

Load → Classify
→ Measure → Optimize
→ Measure → Evaluate
03 | experiment @matyo91

Content is not all the same

Different noise. Different limits.

Logs

[INFO] started
[INFO] started
[INFO] started
[ERROR] Payment failed

↓

[INFO] started ×3
[ERROR] Payment failed

JSON

id
status
error
telemetry…

↓

id
status
error

Git diff

- security check
+ …

Changed lines are
often already
the signal.

Natural compression limits differ by type.

04 | content-types @matyo91

TOKEN_PIPELINE_POC · measured

Volume vs signal

log · −75.4%

raw
4839
opt
1190

diff · −24.0%

raw
3186
opt
2421

JSON · −99.0%

raw
6780
opt
67
CaseRaw*Opt*SavedSignal
log4,8391,19075.4%PASS
diff3,1862,42124.0%PASS
JSON6,7806799.0%PASS

* estimated tokens = bytes / 4 — not provider-billed

Token reduction without signal retention is vanity.

05 | first-benchmark @matyo91

The gap

REMOVE FROM CONTEXT
≠
DESTROY INFORMATION

Bad

raw
→ compress
→ information gone

Better

raw
       ↘ stored omission
compress
   ↓
visible context

Next milestone: REVERSIBLE_CONTEXT_POC

06 | reversible-idea @matyo91

Reversible references

Structure stays. Bulk leaves.

Original

{
  "id": 42,
  "status": "failed",
  "error": "…",
  "telemetry": { "…6000 tok…" }
}

Optimized

{
  "id": 42,
  "status": "failed",
  "error": "…",
  "telemetry": "#ref:ctx_31154f"
}
#ref:ctx_31154f
→
var/context/…json
→
exact bytes

Marker cost ≈ 4 estimated tokens

07 | refs @matyo91

Flow pipeline

Two invariants

1Load
2Classify
3MeasureRaw
4Optimize + store refs
5MeasureVisible
6Signal check
7Recovery check
SIGNAL = PASS
RECOVERY = PASS
bin/console tokens:show-ref ctx_31154f
08 | flow @matyo91

REVERSIBLE_CONTEXT_POC · measured

Out of context ≠ gone

Case Raw* Visible* Referenced* Saved Refs
log coarse4,8391,2043,67175.1%1
log fine4,8391,2023,67075.2%3
JSON6,7801466,19197.8%9
diff3,1862,43474923.6%1

* estimated (bytes / 4) · SIGNAL PASS · RECOVERY PASS on all rows

6,191 estimated JSON tokens moved out of active context.
Not destroyed. Recoverable.

09 | reversible-benchmark @matyo91

Granularity experiment · logs

Granularity has a cost

Coarse

1 ref
4 marker tokens
1,204 visible

Fine

3 refs
12 marker tokens
1,202 visible

3× more references for ~2 estimated tokens saved.
For this workload: coarse > fine

Workload-dependent — structured JSON can benefit from finer, positional refs.

10 | granularity @matyo91

For coding agents

Better context. Same agents.

Tool output → PHP reducer
↓
Useful context → LLM
↓ needs more?
#ref expansion → raw source
git diff
logs
tests / JSON / trees

Not another agent interface — better context for the ones we already use.
Next: progressive disclosure (L0 overview → expand #ref → raw).

What is the minimum context the model needs
to make the correct decision?

11 | agents · @matyo91 @matyo91