Study notes 한국어

Why did the model pick that tool?

Study notes: a small GPT written from scratch in NumPy is trained as an MCP tool selector, and gradients, hidden states and attention are used to trace which words made that decision.

Every number comes from running the code in the repository · math notes: Interpretability math.pdf · GitHub repository

0The process at a glance: following one wrong decision to its cause

Seven steps from a wrong decision to its cause. Each step is one question → one method → one answer. Click a step or use the ← → keys. Sections 1–8 below explain each method in detail.

1How the model picks a tool

A <call> marker is appended to the request, and the model predicts the next word at that position. That next word is the tool name. Training also puts the loss on this one position only (masked loss).

The model picks the most likely of 10 tools (file read / write / list, web search / fetch, weather, calendar, email, DB, git). It gets all 60 held-out requests with unseen verb–object combinations right.

2Backpropagating to the input words

It is the same backprop as in training, with two changes: we differentiate the score S = Z[<call>, y] (the logit of the output token y, the tool) instead of a loss, and stop at the input word embeddings instead of the parameters. The order is ∂S/∂Z → ∂S/∂H → ∂S/∂X.

forward: words → score backward: score → words (∂S/∂X)
# tool_attribution.py · score_and_grad
logits, _, caches = model.forward_embedded(X_token)   # ① forward (from embeddings)
G[k, y] = 1                                            # ② ∂S/∂Z :  S = Z[k, y]
GX = G @ E                                             # ③ ∂S/∂H  (Z = H·Eᵀ)
for n in reversed(range(N)):                           # ④ blocks in reverse
    GX, _ = model.block_backward(GX, caches[n], n)     #    (parameter grads dropped)
return s, GX                                           # ⑤ ∂S/∂X : one vector per word

3Same gradient, four scores

∂S/∂X is a 64-dimensional vector per word. There are several ways to turn it into one number per word, and they disagree a lot. Example → , score S = Z[<call>, chosen tool].

pushes toward the chosen tool (+) pushes away from it (−)
Look at html: grad×input is only , yet its IG is the largest at . A single-point (local) gradient misses this contribution; IG, which integrates along the whole path, catches it.

4Integrated Gradients (IG), intuitively

Grow the word embeddings from 0 (the baseline) to their real values step by step (α: 0→1) and add up the gradient at every point. Move the slider: the bars are the IG accumulated up to α, the curve below is the score at that point.

Completeness: the IG of all words always adds up to S(input) − S(baseline). The whole change in the score is split among the words with nothing left over; if the two do not match, the integral needs more steps.

5The saturation trap: differentiate the probability and you get 0

The more confident the model, the closer the probability sticks to 1 and the gradient becomes practically 0 — which wrongly suggests that "no word matters".

score = log P(tool)

log P = (P ≈ 1)

score = Z[<call>, tool] (logit)

The logit does not go through softmax, so it does not saturate.

Bar length is the gradient size |∂S/∂x| per word. On the left the values are around 1e-6, so the bars are invisible.

6Long-sentence debugging: change one word and it fails

The model is trained on long "context + request" sentences, like real request logs. The 30 context clauses are shared by all tools and co-occur with their topical tool only ~70% of the time. Accuracy looks fine — but is the model really reading the request?

1

One-word audit: change a single noun in the context

The request is untouched, so the right tool should not change. Yet most requests flip from a single noun. Below: the words that flip the decision most often (number of flips).

baseline model after augmentation
2

Point to the cause with IG

Changing server to draft turns "read file" into "write file". For the edited sentence the score is the logit of the wrong tool it picked, Z[<call>, wrong], so IG shows which words raised that wrong choice.

before the edit →

after the edit →

toward the explained tool (+) away from it (−) number under each word = IG
3

Verify the hypothesis: remove just that word

Zero out only the draft embedding in the edited sentence → . It goes back to the right tool, which confirms the cause. (Attribution gives a hypothesis; verification is a separate step.)

4

Find the root cause in the data

Count which tools draft appeared with in training. draft is also an object of write-file requests ("the draft to a file"), so the model learned "draft = write" regardless of where the word sits.

5

Fix the data and audit again

Copies of each request with a random context were added and the model retrained (counterfactual augmentation). In the same sentence, the IG of draft drops to about 0 and the request words drive the decision.

after augmentation, edited sentence →

accuracyrequests flipped by one nounflipping edits
Better, but not done. The remaining culprits are folder and weekend. They are genuine objects of other tools' requests, so shuffling contexts alone cannot fix them. Attribution has pointed to the next thing to fix.

7Following layers and paths: hidden state · attention · occlusion

IG tells us which word. Looking at the same draft flip with three other methods shows at which layer and through which path that word flipped the decision. A = the server … (correct: ), B = the draft … (wrong: ).

1

Layer-wise hidden-state diff: where the difference starts and where it spreads

Cell shade = ‖hB − hA‖ / ‖hA‖. At the embedding only the edited word differs; layer by layer, attention carries that difference to other positions. The outlined column is the decision position <call>.

2

Logit lens: from which layer is it on the wrong tool?

The <call> hidden state of each stage is read straight through the output layer. Above 0 the correct tool is ahead. Intermediate layers were not trained to be read out, so this is an approximate view.

A (correct sentence) B (wrong sentence) value = z[correct tool] − z[wrong tool]

B is still on the correct tool after layer 1 and switches to the wrong one at the layer-2 attention.

3

Attention: where does <call> take its information from at layer 2?

Shade = norm-based contribution ‖Σh A[k,j] · V[j] WO‖ (weight × size of what the word sends). Weights alone cannot tell apart a word that is "looked at a lot but has little effect", so the norm is used.

A (correct)

B (wrong)

4

Occlusion: removing a word confirms it

Each word of B is zeroed out in turn and the drop of the wrong tool's score Z[<call>, wrong] is measured directly. The main cause matches IG, but small contributions differ (effect of removing one word vs. path integral).

occlusion (zero)

IG

5

Combined diagnosis: do the four checks point at the same word?

Verdict for the draft case: draft reached the decision position through the layer-2 attention and flipped the tool choice; the link exists because draft almost always appeared with "write file" in training. IG ✓ · occlusion ✓ · removal restores the tool ✓ · layer-2 attention ✓
points at the edited wordbaselineaugmented

When all four agree it is evidence; the cases where they disagree (mostly attention) are the next thing to study.

8Summary

methodwhat it measuresstrengthcaveat
|grad|sensitivity at one pointone backward passno sign; 0 when saturated
grad×inputfirst-order Taylor termone backward pass, signedwrong in nonlinear regions
IGintegral along baseline → inputcheckable via completenessmany backward passes; depends on the baseline
occlusioneffect of removing one wordexact, intuitive, works on black-box modelsone at a time, misses interactions
hidden-state difflayer where correct and wrong inputs partshows where it changesintermediate logit lens is approximate
attentionwhere the decision position reads fromshows the pathweight ≠ influence; read with the norm