thinking-probes: read the reasoning field under both names#13
Conversation
@Blackwellboy's offlabel#8 fix landed in spine-probes/run_probes.py but not in the thinking probes, which is the worse place to be missing it: these two tools exist specifically to measure whether a model reasons. llama.cpp populates reasoning_content; vLLM exposes reasoning. Reading only the first makes every arm on a vLLM lane classify as NO_REASONING, so thinking_ab would report a model as never thinking and persona_ab would report the persona gate as perfectly effective in all four cells. Both are fabricated results, and they are the same class of error as the enable_thinking claim these tools were written to correct: concluding from a field rather than measuring the thing. README gains the field-name note and one guard rail: NO_REASONING across every arm including true means check the field name before believing it, since a stack exposing thinking under a third name still reads as silent here. Signed-off-by: Christopher Maher <chris@mahercode.io>
|
Good catch on the two probes, and you are right that they were the worse place to be missing it. A tool whose whole job is to detect reasoning reporting NO_REASONING on every arm is a fabricated result that looks like a finding, which is the same failure mode twice over. One mechanical thing, not about the change itself: the diff carries two compiled artifacts. I did exactly this on #9 and caught it just before it merged. The repo root The guard rail in the README is the part I like most here. NO_REASONING across every arm including |
|
Reviewed the diff properly rather than just agreeing with the premise. Three things checked, two clean, one suggestion. The fallback matches what merged into reasoning = (ch["message"].get("reasoning_content")
or ch["message"].get("reasoning") or "")
The parse paths you describe are the ones the code implements. On the guard rail, one suggestion. The README note is the right instinct and I would go one step further, because this failure mode is silent by construction and a documentation guard rail only works on someone who reads the documentation at the moment they need it. The condition you describe is machine-checkable: if every arm including
That turns your guard rail from advice into a positive control, which matters more here than usual, because the thing being measured is absence, and absence is exactly what a wrong key also produces. On the third-field-name case specifically, your wording covers it correctly. Worth noting the partial protection people may not realise they have: a third-name stack that still leaves I am updating trap 1 in our own template-traps registry to list these two probes as affected surfaces alongside the spine runner. That entry previously read as three occurrences of the field-name problem, and with these it is five, across three different tools. Worth recording because the pattern is now clearly "any tool that reads a reasoning field" rather than "a bug that happened to some scripts". Separate mechanical note in my earlier comment about the two |
Follow-up to #8. @Blackwellboy's fallback landed in
spine-probes/run_probes.py, but the two thinking probes still readreasoning_contentonly.That is the worse place to be missing it, because those two tools exist specifically to measure whether a model reasons:
thinking_ab.pywould classify every arm asNO_REASONINGon a vLLM lane, reporting that the model never thinkspersona_ab.pywould show 0 reasoning in all four cells, reporting the persona gate as perfectly effective including in the controlBoth are fabricated results, and both are the same class of error as the
enable_thinkingclaim these tools were written to correct: concluding from a field instead of measuring the thing.Verified the parse path both ways:
README gains the field-name note plus one guard rail:
NO_REASONINGacross every arm includingtruemeans check the field name before believing it, since a stack exposing thinking under a third name would still read as silent.All three scripts still run and exit clean. No em or en dashes in the changed files.
Assisted-by: Claude Code (Opus), reviewed by me