PTENES
Beginning / Track 3 / Module 3.5
🧠
MODULE 3.5 Track 3 — Advanced

🧠 Distillation: recover the brain

This is the story that gives the course its soul. A good model appeared for a few days—and then it was gone. You will never have the weights of it. But there are the logs: every conversation recorded, turn by turn. And the logs contain enough behavior to reconstruct the disposition — the way of working — without the mind. This module distills the “Fable brain” back out: from raw JSONL files to a reusable behavior guide.

📋6 topics
⏱~50 min
🎯Advanced
⭐Key module
the DISTILLATION PIPELINE — from raw log to reusable method ① the LOGS *.jsonl (raw) noise · cheap to keep ② PYTHON script extracts 5 fields timestamp project · session model ←key user_msg assistant_msg filter model == fable ③ the PROFILE 429 measured turns reasoning before the 1st action reassesses disposition, in numbers ④ the GUIDE the decision loop GROUND REASON ACT OBSERVE RE-EVALUATE VERIFY · NARRATE reusable method ⑤ session NEW another model pointed to the guide inherits the method ⛔ you don’t have the weights …but the observed behavior is enough to reconstruct the disposition. We lost Fable; we recovered the method. the brain, back again disposition ≠ weights

Detailed content

1

The premise: without the weights, but with the logs

For a few days, an exceptional model was available. Those who used it felt the difference—not in what it knew, but in how worked: it reasoned before acting, read before changing anything, and checked what changed. Then it stepped aside. You will never have the weights that made it work. But there’s a better question than “how do I recover the weights?” how do I regain the willingness without them?

🧠 The idea in one sentence

You don’t have the model’s weights—but you do have the logs. Every Claude Code session records a file JSONL with, per turn: timestamp, the user's prompt, the model's response, the tool calls, the results and — the detail that unlocks everything — the model ID per turn. There's enough behavior there to reconstruct the disposition from the agent.

The module’s big distinction: weights ≠ disposition. The weights are the mind, closed off and unrecoverable. The disposition is the way of working — and the way of working leaves an observable trace. Traces can be read.

What it is

Behavioral distillation: the process of turning an agent's real sessions into a reusable disposition guide. You observe the recorded behavior, name the pattern, and turn it into an instruction. You don’t copy the mind— you extract the method. It works for any agent whose log you have, not just Fable.

Why learn

Because it’s the method for creating the method. The rest of the course teaches you to read lab prompts from the outside. This topic turns the camera inward: you generate your own data every time you talk with an agent, and you’re throwing that gold away. Anyone who masters distillation doesn’t depend on a model staying available — they save its behavior in a text file and point the next session to it.

✗ What is lost with the model

  • ✗The weights — the mind, closed and unrecoverable
  • ✗The model's intrinsic reasoning density
  • ✗Direct access ("god mode") to that cadence

✓ What is kept from the logs

  • ✓A disposition — the order in which it does things
  • ✓O decision loop explicit, in reusable text
  • ✓Measured numbers that become goals for your session
💡

The log is already being generated

You don’t need to start to collect data. The collection has been running for weeks, quietly, on your disk. Every good conversation you’ve had with an agent is an archived sample of its behavior. Distillation isn’t an experiment you build from scratch — it’s reading a record that already exists and that almost no one looks at.

2

Find the JSONL files — where the record lives

Before analyzing anything, you need to locate the source. The logs aren’t on a distant server or locked away—they’re on your machine, in a predictable directory. Every project you’ve worked on with Claude Code has its own session folder, and each session is a file .jsonl with one line per event.

Where the logs live
~/.claude/projects/<projeto>/*.jsonl

One folder per project; one file per session. Each line in the file is a JSON event — and inside the blob from the metadata is where the gold is: what you typed, what the model responded, the tools it called, and the model ID per turn.

🗂️ What each turn records

timestamp
when the turn happened — gives order and a time window
user prompt
what you asked for—the stimulus in each turn
assistant response
the response, with reasoning blocks and tool calls
model ID (per turn!)
which model responded to each turn — the key to everything

O model ID per turn is what makes distillation possible. Without it, you’d have a jumble of mixed conversations. With it, you can track exactly which turns came from the agent you want to study — and separate Fable from everything that isn’t Fable.

✓ The signal you want

  • ✓Sequence of tools per turn (start with Bash? grep?)
  • ✓Presence of reasoning blocks before the 1st action
  • ✓If you ran a check after editing
  • ✓The model ID, to filter for the target agent

✗ The noise you filter out

  • ✗UUIDs, internal hashes, transport fields
  • ✗Lists of MCP servers and skills repeated every turn
  • ✗Huge tool output (logs inside the log)
  • ✗Everything it doesn't say how the agent decided
🔎

Confirm the state before processing

True to the very method you’re distilling: ground yourself in reality first. List the directory, count the files, see which projects have sessions before asking for any script. You don't want to discover halfway through the analysis that you were pointing to the wrong folder. Ground, then reason — start here.

3

Reduce the noise — the script, not the context

Here’s the technical decision that determines whether distillation is feasible or an expensive waste. The raw JSONL is huge and full of useless metadata. A beginner’s temptation is to paste the entire file into the context and ask “analyze this.” Don’t do this. You bloat the window, waste tokens, and drown out the signal with noise. The right move is to process externally: ask Claude Code itself to write a Python script that extracts only the useful fields.

🐍 The rule: code processes; context receives the summary

The elegant move is the goal: ask the agent to write the extractor. It wasn't the person who opened the JSONL and copied fields by hand—it was Claude Code that generated a Python file to do that. The script reads the raw files, strips out the noise, and returns something lean: five fields per turn, still a bit of a "blob," but readable and inexpensive.

General principle, valid far beyond this task: don’t dump large raw data into the context. Have the code reduce it first. Context is precious; spend it on the distilled signal, not the raw dump.

What the Python script extracts — from each JSONL line, only these fields
# for each turn in ~/.claude/projects/<projeto>/*.jsonl
record = {
  "timestamp":  turn["timestamp"],
  "project":    turn["cwd"],
  "session":    turn["sessionId"],
  "model":      turn["message"]["model"],  # ← the filter key
  "user_msg":   extract_user_text(turn),
  "assistant_msg": extract_assistant_text(turn),
}
# discards: UUIDs, hashes, MCP/skills list, result blobs

Five fields. That’s enough to profile behavior without drowning the context. The output file still looks like a blob, but now each entry fits in your head — and the whole set fits within the budget.

✗ Put raw JSONL in the context

  • ✗Fills the window with useless metadata
  • ✗Costs a lot and degrades the model's attention
  • ✗The signal gets lost in the noise
  • ✗Doesn’t scale to dozens of sessions

✓ Let the script process it externally

  • ✓The code reads the raw data; the context gets the streamlined version
  • ✓5 fields per turn, cheap to carry
  • ✓Scale to all projects at once
  • ✓The agent writes the extractor—you just ask
💡

The meta-lesson

Notice the poetic detail: you're using the Fable successor to rebuild Fable. The current model writes the script, runs the analysis, puts together the guide—and then becomes guided based on the predecessor's behavior. The distillation tool and the distilled object coexist in the same session. It's reflective, and that's what makes the technique accessible: you don't need infrastructure, just ask the right way.

4

Filter by target agent

The reduced logs contain conversations from several mixed models — Opus 4.8, 4.6, 4.5, and Fable. To profile Fable, you need a set that is Fable only. This is where the per-turn model ID earns its keep: you filter the records, keeping only the turns where model == fable, and discards everything else.

The filter — isolate the agent you want to distill
turnos_fable = [
  r for r in records
  if "fable" in r["model"]
]
# from dozens of sessions and thousands of turns…
# …exactly the 429 Fable turns remain

Changing the filter criterion changes the distillation target. "fable" today; tomorrow it could be the next model you want to study. The pipeline is the same — only the string changes.

📚

Everything mixed together

Dozens of sessions over a four-day window, with responses of all the models used during the period. A rich, but heterogeneous set — you can’t conclude anything about a specific agent from this.

🧲

Filter model == fable

One line of code separates the wheat from the chaff. Note the practical intention: using Fable was front-loaded on purpose—those who knew the model was powerful focused the heavy work on it, generating a dense sample of exactly the agent that matters.

🎯

429 pure turns remain

A clean, homogeneous, measurable corpus—Fable only. It’s the foundation on which the behavioral profile in the next topic will be built. No is one session; it’s the set of model responses, counted turn by turn.

🧬

The sample is only as good as the filter

If the filter is loose (accidentally including turns from another model), the profile mixes behaviors and the conclusion is tainted. Confirm what's left before profiling: count the turns, check that all model IDs match the target. An impure corpus produces a guide that describes an agent that never existed.

5

Profile the behavior — the numbers

With the raw corpus in hand, you ask for a quantitative analysis e qualitative. The result is the Fable 5's behavioral profile over the 429 turns — a disciplined, reasoning-first, autonomous agent with broad dynamic range. A typical turn is compact, but when authorized, it can sustain enormous autonomous builds in a single turn. And best of all, all of this becomes number, comparable to the baseline.

📊 The profile in numbers—Fable 5, 429 real turns

Four-day window, compared over the same window against the baseline the model is supposed to improve on.

Habit Fable (source) Baseline Reading
turns containing reasoning 97% 80% reasons on almost every turn
reasons before the 1st action 84% 73% the plan comes before the action
reassesses after a result 87% 80% the observe → decide loop
read the file before the 1st edit 48% 52% both are weak → aim for ~100%
runs real check after editing 23% 19% the common blind spot → fix it
tool error rate 3,3% 3,0% low; recovery is methodical
abandons a turn after an error almost never almost never diagnoses, doesn’t give up
The analysis also profiles the qualitative: how it opens a task (the first remove reveals Bash → ToolSearch), its tool-use patterns, verification discipline, error handling, autonomy/delegation, and communication style.

🧭 The numbers aren't trophies—they're targets

The first three lines (reasoning, plan first, reassessment) are where Fable shines and far exceeds the baseline — it's the heart of the disposition. The next two (read-before-edit and check-after-edit) are where it fails — and the baseline too. This isn’t a minor detail: it’s the module’s most important instruction.

You’re not copying a perfect hero. You’re inheriting the strengths e explicitly aiming beyond the weak points. The guide you synthesize in the next section should say: "reason like it" e "verify better than it does".

💡

Measuring makes the willingness auditable

"Fable reasoned well" is an impression. "97% of turns contained reasoning, versus 80% for the baseline" is a verifiable fact and a actionable goal. Turning the vague into the measurable is what separates praising a model from rebuild a model. The number is the bridge between admiration and method.

6

Synthesize the guide—the decision loop, pointed

The final step closes the loop: you ask the agent to compare the profile with your current model (Opus 4.8) and produce a disposition guide — a playbook that distills the behavior into a decision loop explicit. Then, you points the new session to this guide. The successor starts operating with the predecessor's method in mind. We lost Fable; we kept the loop.

The distilled decision loop— the heart of the guide, run every turn
GROUND      establish the actual state (git, grep, read, run-state)
   │
REASON      state the objective + hypothesis + plan before acting
   │
ACT         take the next step; group what's independent
   │
OBSERVE     really read what came back
   │
RE-EVALUATE update the plan based on the result, not the other way around
   │        (repeat ACT..RE-EVALUATE until the goal is reached)
VERIFY      run the real check in what you changed
   │
NARRATE     report what happened honestly

The tight inner cycle is ACT → OBSERVE → RE-EVALUATE. Skipping OBSERVE is how good plans produce bad results. Note the last two steps in cyan: VERIFY e NARRATE are exactly where the source is weak — and where your guide should require more that Fable did.

✗ Vanilla session (without the guide)

  • ✗Each turn starts from scratch, with no fixed cadence
  • ✗Acts before establishing a foundation; skips observe
  • ✗Doesn’t inherit what the successor has already proven works

✓ Session pointed to the guide

  • ✓Adopts the decision loop as a permanent instruction
  • ✓Understands, reasons, reassesses — turn after turn
  • ✓Works "much better than expected" in practice

⚠️ Two honest caveats—don't promise what you don't deliver

①

Reasoning density is partly intrinsic

Those 97% of reasoning aren’t 100% reproducible through instructions alone — some of the cadence belongs to the source model. Pair the guide with a larger reasoning budget (in Opus 4.8: effortLevel in xhigh/max, e alwaysThinkingEnabled on) instead of waiting for the prose to close the gap. Disposition is the soft layer; effort is the hard guarantee.

②

The verification is weak at the source — do better than it

A real check after editing is weak in Fable (23%) and the baseline (19%). This is the clearest place for you to be better than the model it imitates, not just the same. Don’t distill the blind spot along with the virtue: copy Fable’s reasoning and fix its verification. A hook PostToolUse in Edit|Write forces the test that intent forgets.

🌉 The guide is the disposition layer — not the only layer

The distilled guide shapes the disposition, and placement is best-effort by nature. That’s why it fits well in a CLAUDE.md (loads every session) — and no in auto-memory, whose recall is relevance-gated and may not trigger the rule at the right turn. But the guide alone isn't enough: pair it with the hard guarantees that the harness actually enforces — effortLevel for density, hooks PostToolUse for verification. It's the exact cue for the next module.

🗂️
Logs
JSONL per turn
🐍
Script
reduces out of context
📊
Profile
429 measured turns
🧭
Guide
the decision loop

📝 Module Summary

  • ✓The premise: without the weights, but with the logs — the recorded behavior is enough to reconstruct the disposition
  • ✓Find the JSONL files: ~/.claude/projects/<projeto>/*.jsonl — with model ID per turn
  • ✓Reduce the noise: ask for a Python script that extracts 5 fields — never dump the raw JSONL into the context
  • ✓Filter the target: only the turns model == fable → 429 pure turns remain
  • ✓Profile: 97% reasoning · 84% before the 1st action · 87% re-evaluates · 23% real check
  • ✓Synthesize: the decision loop in a guide, aimed at the new session — and be better at verification

➡️ Next Module

3.6 — ⚙️ Disposition × hard guarantee. You distilled the disposition into a guide—but disposition is best-effort. Now let’s lock in the guarantees that the harness factual strength: effortLevel for reasoning density, hooks PostToolUse for verification, and where each rule really belongs.