Chapter 19 of 60

Inspect the Actual Model Input

Concepts

CHAPTER 19 β€” INSPECT THE ACTUAL MODEL INPUT

PART IV β€” Debugging Models

PURPOSE

Opens the convicted pipeline from Ch18 at its largest element on the missing-4.2 case (prompt file cites the exception, rendered bundle contains general policy twice and 4.2 nowhere — rank 9 cut at top-5 plus a v3-vs-v2 template duplication): the source→template→retrieval/assembly→ids byte pipeline with per-segment accounting and independent round-trip decode.

CENTRAL QUESTION

What did the model actually receive β€” byte for byte, id for id β€” and where did your intended input diverge from it?

UNIQUE CLAIM

Prompt debugging without the rendered artifact is alibi debugging: the file is intent, the render is fact β€” so fidelity is debugged downstream-first like Ch4 layers (tokenizer round-trip before retrieval blame, because a broken id mapping poisons every upstream conclusion) via capture-render β†’ capture-ids β†’ per-segment table (chars/tokens/rank/present/flags per system/instruction/doc/history/turn) β†’ round-trip verify β†’ single-segment repair (β‰₯5 trials); and the same table doubles as the indirect-prompt-injection audit (“did anything assembled tell the model to do this?”), while a matching round-trip still leaves content distortion open (glitch/under-trained tokens need their own scan) since tokenization is a lossy version-dependent transform (up to 15x length spread across languages).

DEBUGGING OBJECT

Evidence as rendered bytes + token ids — template name/version + tokenizer id + render/ids hashes, segment rows (4.2 absent rank-9/top-5; system duplicated into user turn), detokenize(ids)==render check; H1 retrieval-miss (absent at source) vs H2 assembly-loss (present→dropped/duplicated in transit) vs H3 template/tokenizer distortion (words present, structure relocated).

CONCEPTS INTRODUCED

Input-fidelity byte pipeline with per-leg contracts; legs-ruled-downstream-first ordering; structural-vs-content tokenizer distortion split (round-trip vs glitch-token scan); per-segment accounting as security control; rankless-logging prohibition (text without ranks/scores/cutoffs collapses H1/H2 into a shrug); four-part artifact pinning (render hash + template version + tokenizer id + ids hash into every future bundle).

CONCEPTS DEVELOPED / REUSED

Layer ordering from Ch4 (downstream-first leg rule); first-divergence checkpoints from Ch2 (ordered arrows, first break wins); H1/H2/H3 artifact FORECASTs from Ch17–18 (absent-in-retrieval vs present-in-retrieval-absent-in-render vs present-in-render-altered-in-ids); segment table as the Ch17 bundle’s render extension (accretion step 1).

PREREQUISITES

Ch18 (pipeline conviction), Ch17 (bundles, FORECASTs), Ch4 (layer order), Ch2 (ordered checkpoints).

LOCAL INVARIANTS

Capture post-template post-retrieval bytes + versions (never the source file); capture the id array + tokenizer id; table every segment before re-running anything; round-trip before retrieval investigation; repair exactly one segment with pre-written leg FORECASTs; pin all four artifact hashes.

FAILURE MODES

Source-as-evidence (“prompt says 4.2, model saw 4.2”); unlogged injections (provider/framework text never captured β†’ UNKNOWN, endpoint docs read, never trusted from this book); rank blindness / rankless logging; template drift (unpinned library upgrades reassigning roles); tokenizer assumption (equal strings β‡’ equal ids across versions); one-leg audits (render certified, ids unexamined).

DIAGNOSTIC METHOD

  1. Render + meta capture. 2. Ids capture. 3. Segment table. 4. Round-trip decode (mismatch = tokenizer leg immediately). 5. Single-segment repair Γ—5 against leg FORECASTs; pin artifact.

RESEARCH-DERIVED IDEAS

Petrov et al. NeurIPS 2023 (same text across languages β†’ token counts differing up to 15x even multilingual; ids a lossy version-dependent function β€” extreme-pair bounded); Land & Bartolo EMNLP 2024 Magikarp (automatic under-trained/glitch-token detection; valid ids mishandled β€” model-specific prevalence; round-trip necessary, not sufficient); Greshake et al. AISec 2023 indirect prompt injection (retrieved planted text acts as instruction / exfiltrates β€” PoC-bounded; segment table = injection audit); Chang/Jun/Lee ICLR 2026 ChatInject (user text reproducing the chat template’s role markers forges an extra assistant/system turn; several-fold higher injection success on AgentDojo/InjecAgent β€” the segment table must include the literal role-marker boundaries); chat-template mismatch (a model fed a format other than its fine-tuning format drops accuracy silently β€” pointer-level framework knowledge, template identity = a dependency to pin/diff).

EXPERIMENT / LAB

Lab 19 (PROPOSED): failing bundle (or injected top-k cap below decisive rank / template-version swap), render + template + tokenizer + ids frozen, H1/H2/H3 artifact FORECASTs pre-written, three-leg table + round-trip + single-segment repair Γ—5. H-structure: independent var = inspection point per leg (retrieval vs render vs ids), then one repaired segment; controls = revision/params/seed. Success = segment table + round-trip + repair row matching one pattern + four-part pin; corrected-prompt-without-table is not completion.

COMPANION TOOL

Prompt/Context Inspector β€” accepts: intended sources + render/version/tokenizer/ids + segment table + single-segment repair series. Can-establish: what the model received (bytes + ids) + which leg diverged, under this template/tokenizer only. Cannot-establish: causation alone (needs Ch18 swap outcome), cross-template/tokenizer generality, unseen provider injections (UNKNOWN β†’ endpoint logging docs); never prompt-file/paraphrase/self-report as input evidence.

PREVENTION ARTIFACT

Four-part artifact pin (render hash + template version + tokenizer id + ids hash) in the regression bundle + rank-cutoff/template-pin/segment-logging fixes (prompt text itself untouched in the illustration).

READER OUTCOME

Reader can certify the exact bytes-and-ids input and name the diverging leg β€” testable via Lab 19’s segment-table audit.

DEPENDENCIES

Ch18, Ch17, Ch4.

FORWARD BRIDGE

Ch20 “Context Windows and Truncation” β€” inherits the length remainder: complete certified bytes can still fail when the window silently cuts them between render and generation.

EVIDENCE / RESEARCH REQUIREMENTS

Missing-4.2 illustration constructed; Petrov 15x extreme-pair; glitch prevalence model-specific; Greshake PoC; provider behavior changeable (attribute endpoint docs, don’t assert).

ANTI-CLAIMS / LIMITS

One audit certifies one bundle under one template/tokenizer/retrieval revision; proves no causation alone, generalizes across no endpoint, rots on any version bump; UNKNOWN wherever any leg unlogged.

Explain this chapter with AI

Copy this prompt into ChatGPT, Claude, Gemini, a local model, or another AI.

Apply this chapter with AI

Copy this prompt into ChatGPT, Claude, Gemini, a local model, or another AI.

Part IV β€” Debugging Models

What you sent is not what it got

Chapter 18 convicted the pipeline for the split-shipment refund failure. The engineer now opens her prompt file β€” clean, correct, citing policy 4.2 β€” and concludes the context was fine. It was not. What she wrote never travels alone: a system prompt prepends it, a chat template wraps it in role markers, retrieval inserts (or fails to insert) documents, and a tokenizer re-cuts every word into ids the model actually reads. Memory of the prompt is not evidence of the input.

Concrete failure. The fixture log shows the engineer’s prompt asking for “the split-shipment exception,” yet the frozen bundle’s rendered input contains the general-policy section twice and section 4.2 nowhere β€” retrieval returned it ranked ninth, the assembler took top five, and a template duplicated the system instruction into the user turn. Three transforms, zero of them visible in the prompt file.

OBSERVATION: rendered input bytes (MEASUREMENT, hashed bundle) contain zero occurrences of “4.2-exception”; token-id decode confirms the absence is in ids, not rendering. HYPOTHESIS H1 (retrieval miss): the retriever never returned 4.2 in top-k β€” the bytes were absent at the source. HYPOTHESIS H2 (assembly loss): retrieval returned 4.2 but the assembler dropped or duplicated segments β€” the bytes died in transit. HYPOTHESIS H3 (template/tokenizer distortion): the bytes are present but role markers or token splits relocated their force β€” the model received the words without the structure. INFERENCE: none yet β€” only the rendered artifact with per-segment accounting separates source miss from transit loss from distortion.

This chapter’s question: what did the model actually receive β€” byte for byte, id for id β€” and where did your intended input diverge from it?

Why re-reading the prompt fails first

The obvious move β€” re-reading the prompt source and declaring it correct β€” fails because the source is one ingredient, not the meal. Four silent transforms stand between the file and the ids:

  1. System and developer prompts prepend invisibly. Library defaults, hosted-endpoint instructions, safety preambles β€” some stacks inject text the caller never wrote and never logs. Attribution here is UNKNOWN until the assembled bytes are captured; provider behavior here is changeable and must be read from current documentation for the reader’s own endpoint, not trusted from this book.
  2. Chat templates re-mark roles. user, assistant, system become control tokens or marker strings whose exact form is template-version-specific. A swapped template silently reassigns who said what β€” and a chat model fed a format different from the one it was fine-tuned on typically suffers a large, silent accuracy drop, because the role markers it learned to condition on are simply absent or wrong. Template identity is a dependency; pin it and diff it like one.
  3. Retrieval and assembly edit the middle. Ranking, dedup, rerank, top-k cutoffs, citation rewrites β€” each drops, duplicates, or reorders segments under a configuration nobody re-checked after the demo.
  4. Tokenization re-cuts the text. Splits, merges, and special-token handling mean “same string” can be different ids across tokenizer versions β€” and ids are what the model reads. The disparity is not small: Petrov and colleagues found the same text translated across languages tokenizes to lengths differing by up to 15x, even with multilingual tokenizers (Petrov et al., 2023). And some individual ids are themselves defective β€” under-trained or “glitch” tokens that the model handles erratically because they barely appeared in training (Land & Bartolo, 2024).
  5. History and tool outputs append silently. Prior turns, tool results, and framework-added context join the assembly under size rules nobody re-checked. The “same question” asked at turn 1 and turn 12 arrives as two different inputs.

OPINION: prompt debugging without the rendered artifact is alibi debugging β€” you verify what the suspect claims to have done instead of what arrived at the scene. Capture the bytes first and the theories get shorter by half.

The mental model: input fidelity as a byte pipeline. Source prompt β†’ template render β†’ retrieval insert β†’ assembly β†’ token ids. Each arrow states a contract (exact text in, exact text out); the first divergence between intended and rendered is the defect’s address. Debug it like Chapter 2 state: ordered checkpoints, first break wins.

The method: render, decode, account

  1. Capture the rendered prompt. Log the exact string (or message list) handed to the model call β€” after template application, after retrieval insertion β€” plus template name/version and tokenizer identifier. Hash it into the bundle.
  2. Decode the token ids back. Convert the id array to text independently of the render path; diff render vs. decode. A mismatch convicts the tokenizer leg; a match moves suspicion upstream.
  3. Account per segment. Table every segment (system, instruction, each retrieved doc with rank, history, user turn): characters, tokens, present/absent, rank, truncation flag. The missing 4.2 appears here as a row, not a theory.
  4. Replay the discriminating intervention. Re-render with the single repaired segment (inject 4.2 at rank 1; or pin the template version; or strip the duplicate) and re-run β‰₯5 trials. Prediction decides H1/H2/H3; anything else is UNKNOWN.
    flowchart LR
    SRC["intended prompt sources"] --> TPL["template render: role markers, system prepend"]
    TPL --> RA["retrieval + assembly: rank, dedup, top-k cutoff"]
    RA --> IDS["token ids β€” the actual model input"]
    IDS --> RT{"detokenize(ids) equals the render?"}
    RT -->|"mismatch"| H3["H3 convicted: tokenizer leg β€” pin the version, stop (it poisons upstream claims)"]
    RT -->|"match"| SEG["per-segment table: chars, tokens, rank, present / absent"]
    SEG --> Q{"where did intended diverge from rendered?"}
    Q -->|"absent from the retrieval output"| H1["H1: retrieval miss β€” fix ranking / cutoff"]
    Q -->|"in retrieval, absent from the render"| H2["H2: assembly loss β€” pin the template / assembler"]
  
# input-fidelity inspection (bytes before theories)
rendered, meta = render_full_prompt(system, user, docs, template="chat-v3", tokenizer="tok-2026-08")
print("template:", meta.template_version, "tokenizer:", meta.tokenizer_id)
print("segments:", account(rendered))  # per-segment chars/tokens/rank/absent flags
ids = tokenize(rendered, meta.tokenizer_id)
assert detokenize(ids, meta.tokenizer_id) == rendered  # H3 probe: tokenizer round-trip
# H1/H2 probe: same model, same params, re-rendered input with section 4.2 pinned at rank 1
print("repaired-render:", run(rendered.with_doc("4.2-exception", rank=1), trials=5))
# FORECAST: H1/H2 flip to >=10/12 only when 4.2 rows read PRESENT; H3 flips only on template/tokenizer change.

OBSERVATION (constructed illustration, not a measured run): segment table shows 4.2 absent (rank 9, top-k 5); system instruction duplicated into user turn (template v3 vs. v2 diff); round-trip decode matches render (H3 exonerated for this bundle). UPDATED BELIEF: H1+H2 jointly supported β€” retrieval ranked the decisive section out, and the template duplicated noise over the gap. The prompt file was innocent; the pipeline around it was not. INFERENCE: fix rank cutoff + template pin + per-segment logging; the prompt text itself needs no edit.

Note the ordering: the artifact table came before the repair run, and the round-trip check came before either. Had the decode mismatched the render, the retrieval investigation would have waited β€” a tokenizer-leg defect poisons every upstream conclusion, because no segment claim survives a broken id mapping. Legs are ruled out downstream-first, exactly like Chapter 4 layers: cheapest and most mechanical first.

Research lineage: the render is also the attack surface

The tokenizer leg carries real, measurable distortion. Petrov and colleagues’ 15x cross-language token-count spread is the extreme case of a general fact: the id sequence is a lossy, version-dependent function of the string, and the model’s behavior is defined on the ids (Petrov et al., 2023). Land and Bartolo’s automatic detection of under-trained tokens shows that a round-trip that matches is not fully sufficient β€” the ids can be valid and still be ones the model mishandles (Land & Bartolo, 2024). The round-trip check convicts the tokenizer leg for structural distortion; a glitch-token check is a separate probe for content distortion.

Per-segment accounting is a security control, not just a debugging one. Greshake and colleagues showed that retrieval-augmented systems blur the line between data and instructions: text planted in a document, email, or web page that the assembler later inserts can act as an instruction to the model, redirecting it or exfiltrating data (Greshake et al., 2023). A sharper variant abuses the render itself: user-supplied text that reproduces the chat template’s own role markers can forge an extra turn β€” a fake assistant reply or system line spliced into the conversation the model sees, raising injection success rates several-fold in agent benchmarks (Chang, Jun & Lee, 2026). The segment table this chapter builds β€” every inserted span, its source, its rank, and the literal role-marker boundaries β€” is exactly the artifact you need to answer “did anything in the assembled context tell the model to do this, and is every role boundary the one the assembler wrote?” Debugging fidelity and auditing injection are the same inspection.

Lab 19: the rendered-input audit

PROPOSED, not executed: no author-measured results are reported. The evidence this chapter requires is the reader’s own segment table.

Setup. Take one failing bundle (or inject loss: cap top-k below the decisive doc’s rank, or swap the chat template version). Capture the rendered bytes, template version, tokenizer id, and id array. Freeze all four.

Task.

  1. Write H1/H2/H3 with distinct artifact FORECASTs before inspecting (e.g., “H1: 4.2 absent from retrieval output; H2: present in retrieval, absent in rendered; H3: present in rendered, altered in ids”).
  2. Independent variable: the inspection point (retrieval output vs. rendered vs. ids). Controlled variables: model revision, params, seed β€” nothing re-runs until the table is complete.
  3. Build the per-segment table (chars, tokens, rank, present/absent, flags), run the round-trip decode check, and record OBSERVATION verbatim. Then run the single-segment repair (β‰₯5 trials) and record UPDATED BELIEF. Non-matching patterns are UNKNOWN with the next leg named.
  4. Pin the artifact: rendered hash + template version + tokenizer id become part of every future bundle.
Leg Artifact FORECAST OBSERVATION UPDATED BELIEF
retrieval top-k list H1: 4.2 absent ___ H1 live/exonerated
assembly rendered bytes H2: present→absent ___ H2 live/exonerated
tokenize ids round-trip H3: decode β‰  render ___ H3 live/exonerated
repair one segment fixed Γ—5 flip β‰₯ ___ ___ convicted/suspended

Success criterion. A completed segment table + round-trip result + repair row matching one pre-written pattern, with the four-part artifact pinned. A corrected prompt without the table is explicitly not completion.

Companion tool: Prompt/Context Inspector

What it accepts: the intended prompt sources, the rendered bytes + template version + tokenizer id + id array, the per-segment accounting table, and the single-segment repair series with FORECASTs. What it performs: it diffs intended vs. rendered vs. decoded, flags absent/duplicated/reordered segments with ranks, verifies the round-trip, refuses an input-fidelity verdict while any leg is unexamined, and stamps the artifact hashes into the bundle. What it can establish: what the model received (bytes and ids) and at which leg the intended input diverged β€” under this template and tokenizer only. What it cannot establish: whether the received input caused the failure (that needs the Chapter 18 swap outcome), cross-template or cross-tokenizer generality, or provider-side injections it cannot see β€” those stay UNKNOWN with the endpoint’s current logging docs as the next step. It never treats the prompt file, a paraphrase agreement, or a model self-report as input evidence. How its output changes your next action: a retrieval-leg conviction routes to ranking/cutoff repair; assembly routes to template/assembler pinning; tokenizer routes to version pinning + round-trip CI; a clean artifact with sustained failure routes forward β€” the input is certified and length/position effects (Chapter 20) are next.

Paper form, sufficient for this chapter:

TEMPLATE: ___ (v ___)   TOKENIZER: ___ (id ___)   RENDER HASH: ___   IDS HASH: ___
SEGMENTS: sys ___tok | instr ___tok | doc(rank,present): ___ | history ___tok | user ___tok
ROUND-TRIP: match / MISMATCH (diff: ___)
REPAIR (one segment Γ—5): ___  CONVICTION: H1 / H2 / H3 / UNKNOWN

Where a software implementation does not yet exist in the reader’s stack, this record is the tool. The artifact discipline precedes any automation.

Reusable procedure: every pipeline conviction gets this audit

  1. Capture the render β€” post-template, post-retrieval, pre-tokenizer bytes + versions.
  2. Capture the ids β€” array + tokenizer id, hashed.
  3. Table the segments β€” presence, rank, tokens, flags per segment.
  4. Round-trip the decode β€” mismatch convicts the tokenizer leg immediately.
  5. Repair one segment β€” re-run β‰₯5 trials against FORECASTs; pin the artifact.

Failure modes

  • Source-as-evidence. “The prompt says 4.2, so the model saw 4.2.” The file is intent; the render is fact. Debug facts.
  • Unlogged injections. Provider or framework system text that never reaches the reader’s log. Whatever cannot be captured is UNKNOWN β€” say so, and read the endpoint’s current logging documentation (changeable; attribute, don’t assert).
  • Rank blindness. Logging document text without ranks and cutoffs. The decisive section “in the index” but below top-k is absent, full stop.
  • Template drift. Upgrading a library and silently changing role markers. Pin template versions like dependencies β€” because they are.
  • Tokenizer assumption. Assuming equal strings mean equal ids across versions. Ids are the input; strings are the packaging.
  • Rankless logging. Storing retrieved text without ranks, scores, or cutoff config. Without ranks the table cannot separate “absent from the index” from “present but cut” β€” H1 and H2 collapse into one shrug.
  • One-leg audits. Certifying the render while the ids go unexamined (or vice versa). Fidelity is a three-leg claim; two legs are a leaning tower.

Limits, per contract: one audit certifies one bundle under one template/tokenizer/retrieval revision; it does not prove causation alone, does not generalize across endpoints, and rots on any version bump without re-capture. UNKNOWN wherever any leg went unlogged.

References

Debugging Checklist

  • Rendered bytes captured post-template, post-retrieval (not the source file)?
  • Template name/version + tokenizer id recorded and hashed?
  • Token-id array captured; round-trip decode checked?
  • Per-segment table built (presence, rank, tokens, flags, source)?
  • Segment table reviewed for injected instructions in retrieved content?
  • Glitch / under-trained token scan run on the id array?
  • H1/H2/H3 artifact FORECASTs written before inspection?
  • Single-segment repair run β‰₯5 trials, matched to a FORECAST?
  • Retrieval output captured with ranks/scores/cutoff (not text only)?
  • Repair run only after all three legs tabled (no leg skipped)?
  • Artifact hashes pinned into the regression bundle?

What This Chapter Established

  • Input fidelity as a byte pipeline (source β†’ template β†’ retrieval/assembly β†’ ids) with per-segment accounting and round-trip verification, demonstrated on the missing-4.2 case as H1+H2 β€” constructed illustration, no measured runs claimed.
  • Lab 19 as a proposed rendered-input audit the reader executes; the Prompt/Context Inspector contract (accepts/performs/can-establish/cannot-establish/next-action).
  • What was NOT proved: causation (certified input still needs the swap outcome), cross-version generality, or anything about provider-side behavior beyond the reader’s own captured bytes.
  • Research grounding: tokenization is a lossy, version-dependent transform (up to 15x length spread across languages β€” Petrov et al.) and some ids are defective even when round-trips match (glitch / under-trained tokens β€” Land & Bartolo); a chat model fed a mismatched template drops accuracy silently; the per-segment table doubles as an injection audit, since retrieved content can carry instructions (Greshake et al.) and forged role markers can splice fake turns into the render (Chang et al.).
  • Forward link: the bytes can be complete and still fail β€” if length forced silent cuts. The next chapter accounts for every token the window kept and every one it dropped.

Next

The rendered input is now certified byte-for-byte β€” every segment present, every id round-tripped. And the failure persists. The suspect list shrinks to what the window itself did: the context was too long, something was cut, and the cut was silent. The next chapter performs truncation forensics.