Ask an LLM for a probability and it will hand you a confident-sounding number. Ask it twice, under two different conditions, and it will often hand you the same number. BIRD is a framework that routes the question through explicit factors and a learnable Bayesian combination instead — and beats GPT-4 by 35 points doing it.
You are building a planning assistant. Given a scenario — “you want to charge your phone while using it” — and an additional condition — “you'll be pacing around the room” — the assistant has to choose between two products: a short cord or a long cord. You do not want a yes/no answer. You want a probability: how strongly does this condition support “short cord is better” versus “long cord is better”? A downstream rule (“if confidence < 60%, ask a follow-up question”) depends on that number being real.
So you do the obvious thing. You prompt an LLM: “Given this scenario and this condition, what is the probability that a shorter cord is the better choice? Answer with a percentage.” It answers. You change the condition to something that clearly favors the opposite outcome, ask again. It answers again.
The paper this session is built on — BIRD (Bayesian Inference fRom abduction and Deduction, Feng, Zhou, Lin & Roth, University of Pennsylvania, 2024) — opens with exactly this experiment, run on two real examples: one temporal-reasoning scenario, one planning scenario. In both cases, GPT-4 returns the same probability for two conditions that a human reader can tell apart instantly — one condition obviously supports the first outcome, the other obviously supports the second, and GPT-4's number does not move. BIRD, run on the same two examples, returns two different, correctly-ordered numbers.
BIRD's authors quantify this precisely, and the number is more alarming than “LLMs are somewhat miscalibrated.” They set up a forced-choice evaluation: given a scenario, an outcome, and two different additional conditions that both plausibly bear on it, decide which condition better supports the outcome. Three possible labels — condition 1 is stronger, condition 2 is stronger, or they're equally strong — so guessing at random gets an F1 of 0.333.
Here is what direct prompting scores against that floor, measured by comparing the LLM's own verbalized probabilities against human judgments on 350 held-out examples:
| Method | Average F1 | vs. random guessing (0.333) |
|---|---|---|
| Random guessing | 0.333 | — |
| GPT-3.5, chain-of-thought | 0.283 | worse by 0.050 |
| GPT-4, chain-of-thought | 0.289 | worse by 0.044 |
| Llama-2-70B-Instruct, vanilla verbalization | 0.311 | worse by 0.022 |
| Llama-2-70B-Instruct, chain-of-thought | 0.294 | worse by 0.039 |
| BIRD (trained) | 0.592 | better by 0.259 |
Read the first four data rows again. Every direct-prompting baseline scores below random guessing. Not slightly better than chance with room to improve — strictly worse than a coin flip on a three-way question. GPT-4's chain-of-thought reasoning, the technique that improved accuracy on math and logic benchmarks by double digits, makes probability estimation for this task worse than saying nothing and rolling dice.
Worse-than-chance is not a fluke of one dataset. It has a specific cause. A model that verbalizes “confidence” is drawing on a language habit: sentences that sound decisive tend to use similar percentage language regardless of which side has the stronger evidence. If that habit is even mildly anti-correlated with the true answer — for instance, if the model is more likely to hedge exactly when it is actually right, or overstate confidence exactly when a scenario superficially resembles a different, well-known pattern — the resulting F1 can dip below the score of pure noise. Random guessing has no systematic bias to be anti-correlated with anything; a biased-but-wrong heuristic can be worse than nothing.
This also answers the natural follow-up: “doesn't a bigger, newer model fix this?” GPT-4 chain-of-thought (0.289) barely beats GPT-3.5 chain-of-thought (0.283), and both remain below chance. Scale did not touch the problem, because the problem is not capacity — it is that verbalized probability was never the output of any calculation. A bigger model produces a more fluent guess. It does not produce a computed one.
Scoped honestly, upfront: BIRD (and this session) handles decisions between two complementary outcomes — extending to more than two requires the hierarchical decomposition mentioned briefly in Chapter 1 (pick A vs. everything else, then subdivide), not a direct N-way generalization of Equation 4. It produces a discrete-outcome probability, not a continuous quantity — if what you actually need is “how many minutes will this take,” that's a different problem than “is outcome A or outcome B more likely.” And every equation in Chapters 4–6 assumes the abducted factors are genuinely independent given the context — a working assumption, not a verified one, and Chapter 9 comes back to what happens when it's wrong. Within that scope, the results in Chapter 7 are real and reproducible from the paper's own tables; outside it, you're extrapolating.
Every bar here is a real number from BIRD's Table 1 (Average F1 column). The dashed line is random guessing. Notice which bars fall below it. Toggle the button to add the “Explicit Comparison” baselines — an easier setting where the model sees both conditions at once and just picks the stronger one (no probability, no argmax over separate calls) — to see that BIRD still wins even against its easiest competitor.
Before building anything, state the requirement precisely — because BIRD's whole architecture falls out of it. A trustworthy probability estimate should have two properties a single fluent guess cannot guarantee:
1. Sensitivity. Change the evidence, and the number should move. Two conditions that a human agrees point in opposite directions should not produce the same percentage.
2. Traceability. You should be able to point at why the number is what it is — which piece of evidence pushed it up, which pushed it down — not just receive a scalar with no audit trail.
A single next-token-prediction call gives you neither. It gives you one forward pass that happens to end in digits. BIRD's answer is to stop asking the LLM to compute a probability at all, and instead ask it to do two things it is actually good at — imagine relevant factors, and judge outcomes under a fully specified world — and let an explicit, inspectable Bayesian model do the arithmetic. That split is the subject of the rest of this session.
It's worth asking why this framework arrives now, on a 2024 paper, and not a decade earlier — Bayesian combination of expert judgments is 1980s decision theory, and abduction-then-deduction is centuries older than that. The answer is that BIRD is a recombination of pieces that individually matured elsewhere, and none of the three alone would be sufficient:
| Ingredient | What it supplies | Why it was missing before |
|---|---|---|
| Instruction-following LLMs reliable at narrow classification | The abduction, pruning, and entailment steps all reduce to short, well-posed classification calls — a capability that only became consistently reliable with modern instruction-tuned models | Earlier language models completed plausible text; they didn't reliably answer a narrow yes/no or which-of-these-values question the way a classifier would |
| A combination formula that needs no likelihood term | Bordley's 1982 log-odds pooling formula, which sidesteps ever estimating P(f|Oi) | Sitting unused in the decision-theory literature for over 40 years, waiting for a source of individually-reliable P(Oi|fj) judgments to plug into it — which LLMs only recently became |
| Entailment as a mature, well-studied NLP task | A ready-made task formulation (does text A imply fact B) with known failure modes and known ways to make it more conservative (majority voting, ensembling prompt styles) | Without a solid entailment primitive, mapping free-text conditions onto fixed factor values would itself have been the unreliable step |
Read the table as a recipe: two of the three ingredients (the combination formula, the entailment task formulation) are decades old and were baked by other people for other reasons. The genuinely new part is narrow, and it's the part Chapters 2 and 6 spend the most time on — getting the abduction and factor generation stage to produce good enough factors that the old, borrowed machinery has something reliable to work with.
It helps to see the failure as code, not just as a table. Here is the entire naive pipeline — the one that produced the sub-random numbers above:
python # the naive approach: one forward pass, hope the digits are meaningful prompt = f"Scenario: {S}\nCondition: {U}\n" \ f"What is the probability that '{O1}' is the better outcome? " \ f"Think step by step, then answer with a percentage." response = llm(prompt) # -> "...reasoning... I'd estimate around 70%." p = parse_percentage(response) # -> 0.70, a single float, no audit trail
Nothing in that function signature enforces sensitivity to U. Swap U for a
condition that argues the opposite direction, and p might still land near 0.70, because the
model's real computation was “produce text that sounds like a confident percentage estimate for a
question shaped like this,” not “evaluate how U changes the odds.” Chain-of-thought
adds a reasoning string in between, but parse_percentage is still reading the last
number out of a single, unconstrained generation — there is no structural reason the number at the end
has to be a function of the reasoning that precedes it.
Return to the planning-assistant framing that opened this chapter. Suppose the actual downstream rule is:
“if P(short cord better) < 0.4, default to the long cord without asking; if
0.4 ≤ P ≤ 0.6, ask the user a clarifying question; otherwise default to the short
cord.” Now trace what happens with a naive p that hovers near 0.7 regardless of
U: the system silently defaults to “short cord” on every single request, including
the ones where the user explicitly said they'd be pacing around the room. The bug isn't in the threshold
logic — it's upstream, in a probability that was never actually a function of the evidence it claims to
summarize. A threshold rule can only be as trustworthy as the number it's built on.
estimate(S, U1) ≠ estimate(S, U2) whenever a human would agree U1 and
U2 point in different directions. Nothing about next-token prediction enforces this contract.
Chapters 1–6 build a pipeline that does — not by making the LLM smarter, but by never letting a
single LLM call be the last step before the number ships.
There is a more precise way to state why sub-chance performance is possible, beyond “language habits can be anti-correlated.” A random guesser's errors are independent of the true label by construction — wrong exactly 2/3 of the time on a 3-way task, uniformly spread across the two wrong answers. A language model's verbalized confidence is not independent noise; it is a learned function of surface features of the prompt — sentence length, hedging words, how many concrete details the condition supplies. If any of those surface features happen to correlate with the wrong label more often than the right one in this particular task distribution, the model's errors become systematically skewed rather than uniformly spread, and a systematically skewed guesser can score below a uniformly random one on a metric like F1 that rewards balanced correctness. This is precisely why BIRD's authors don't try to prompt-engineer their way out of the problem in Chapter 0's baselines — better phrasing tunes which surface features the model leans on, but doesn't remove the underlying issue that some surface feature, not the evidence, is driving the number.
One more baseline is worth computing by hand, because it closes off an obvious objection: “maybe direct prompting is bad, but surely a system that doesn't even look at the evidence and just always guesses the single most common label would do better than these fancy-sounding but wrong percentages?” Chapter 7's human-labeled evaluation set breaks down as 44.0% “condition 1 wins,” 43.7% “condition 2 wins,” and 12.3% “tied” — so a majority-class guesser that always predicts “condition 1 wins” gets 44.0% of individual examples right by construction, without reading a single word of any scenario.
That sounds better than 33.3% at first glance — but F1 specifically punishes this strategy. A guesser that never predicts “condition 2” or “tied” has 0% recall on both of those labels: it gets every single one of those examples wrong, no matter how obviously they should have been labeled that way. Its F1 on “condition 2” and on “tied” is exactly zero, and macro-averaging that zero in with a decent score on “condition 1” drags the overall average F1 down well below what raw accuracy would suggest — for the identical reason this chapter's title problem exists in the first place: a method that is confidently, uniformly wrong on two-thirds of the label space cannot average its way to a respectable F1, no matter how often its one favored label happens to be right.
Chapter 0 diagnosed the disease: a single forward pass that outputs “probability: 70%” is not a calculation, it's a completion. The cure requires naming exactly which step in the reasoning process is missing, and that requires three words philosophers have used since Aristotle and Peirce — because it turns out LLM prompting research reinvented all three, and knowing the names makes BIRD's architecture almost obvious.
Given a context C (a scenario plus whatever partial information you have) and a decision Y (which of two outcomes is more likely), there are three distinct logical moves you could make:
| Move | Formally | What it does | Example |
|---|---|---|---|
| Induction | C → Y | Jump straight from evidence to conclusion, using a learned statistical association | “Sounds like the kind of scenario where the answer is usually X” |
| Abduction | C → Z | Infer the best explanatory structure underlying the evidence — not the answer, the relevant factors | “What are the 3–5 things that would actually determine this?” |
| Deduction | C, Z → Y | Given the structure and the evidence mapped onto it, derive the conclusion by a fixed rule | “Given these factor values, the Bayesian math says Y with probability p” |
A vanilla LLM prompted for a probability performs pure induction: C → Y in one shot, using whatever statistical pattern its training data associated with sentences that look like this one. Chain-of-thought prompting looks like it adds structure — the model writes out reasoning steps — but the final number is still produced by the same induction machine; the intermediate text is not constrained to be a reusable, checkable structure. It's induction wearing a lab coat.
BIRD's problem statement, stripped to its essentials: you have a scenario S (a general situation, e.g. “you want to charge your phone while using it”) and an additional condition U (extra information or a preference, e.g. “you'll be pacing around the room”). Together they form the context C = (S, U). There are two complementary outcomes, O1 and O2 (“a shorter cord is better” vs. “a longer cord is better”). The task is to compute P(Oi|C) for i = 1, 2.
Instead of estimating that directly, BIRD introduces a set of factors — discrete variables that together form a complete information space F, and routes the computation through them:
Read this the way you'd read any marginalization: to know how likely Oi is given partial information C, sum over every possible fully specified world f in F, weighting each world's contribution P(Oi|f) by how consistent that world is with what you actually observed, P(f|C). It's the law of total probability, and it is the one piece of real, unavoidable Bayesian machinery in this whole framework — everything else is about how to fill in its two factors without asking an LLM to compute either one in a single unreliable step.
It is worth being precise about exactly how many LLM calls carry real risk in this pipeline, because that is what makes BIRD more trustworthy than a single forward pass, not just slower. The LLM is used for:
1. Abduction (once per scenario, reusable across every condition you'll ever apply to it) — generate the factors.
2. Coarse classification (once per factor value, also reusable) — does this factor value support O1, O2, or neither?
3. Entailment (once per new condition U) — which factor values does this specific condition imply?
Notice what's not on that list: the LLM is never asked “what is the probability?” directly. The arithmetic that turns factor values into a number is Equations 2, 4, 8 and 9 — fixed, auditable formulas with no LLM in the loop. This is why BIRD is controllable: the same scenario S always produces the same factor structure F, no matter how many different conditions U you later throw at it, and the final number is a deterministic function of which factor values got entailed — not of how the condition happened to be phrased.
There's a second reason abduction matters, beyond controllability: it turns an intractable estimation problem into a tractable one. Directly estimating P(Oi|C) for arbitrary text C requires the LLM to implicitly integrate over every possible interpretation of C in a single forward pass — exactly the step that Chapter 0 showed produces noise. Factoring C through F means each LLM sub-call only has to answer a much narrower question (“is this one factor value implied?” or “does this one factor value support O1?”), and narrow, single-fact questions are exactly the kind of thing LLM classification is reliable at. You're not making the model smarter. You're decomposing the question into pieces small enough that the model's existing reliability transfers.
It is worth writing the entire architecture as pseudocode once, so every later chapter has a place to point back to. Read the comments as a map of which section of this session builds which line:
python def bird_estimate(S, O1, O2, U): # --- computed ONCE per scenario S, reused for every future U --- factors = abduct_factors(S, O1, O2) # Ch.2 — LLM: sentences, then summarize factors = prune_neutral(factors, O1, O2) # Ch.2 — LLM: 3-way classify, drop all-neutral p_init = {f: classify_support(f, O1) for f in factors.values()} # Ch.4 — Eq.5, 75/50/25 p_j = train_probabilities(factors, p_init) # Ch.6 — Eq.6-7, MSE + margin loss # --- computed FRESH for every new condition U --- observed = llm_entailment(S, U, factors) # Ch.3 — Eq.8-9, hierarchy + direct prompts weights = assign_weights(observed, factors) # 1.0 on entailed value, 1/card(F_j) elsewhere # --- fixed arithmetic, no LLM in the loop --- return marginalize(p_j, weights, factors) # Ch.5 — Eq.1-2, sum over f in F
Two lines are worth staring at. abduct_factors through train_probabilities take
only S, O1, O2 as arguments — never U. That is the
formal statement of “abduction is a fixed, reusable structure.” llm_entailment is the
only LLM call that ever sees the specific condition U, and its entire job is a narrow,
well-posed classification (“which of these already-fixed factor values does this text imply”)
— nothing about it resembles the open-ended “what's the probability” question from Chapter 0.
Controllability is an abstract-sounding property until you see it hold across multiple real conditions on the same scenario. Take the charging-cord scenario again, and three different additional conditions a user might supply:
| Condition U | Entailed factor values | Unobserved |
|---|---|---|
| “You'll be pacing around the room.” | a2 | FB, FC |
| “The outlet is on the far wall from your desk.” | b2 | FA, FC |
| “You hate cables pooling on the floor and you like to walk while you talk.” | a2, c1 | FB |
Every row maps onto the same three factors, defined once. Nothing about the second condition's completely different phrasing invents a new factor called “outlet position preference” that happens to overlap with FB — it's literally FB, because FB was fixed during abduction before any of these three conditions existed. This is what “the same additional condition is consistently mapped to the same factor structure” means operationally, and it's the property that makes BIRD's outputs comparable across many different user inputs to the same underlying decision.
The paper notes two more consequences of this design that are easy to miss. First: because entailment can run at any point after abduction, a condition doesn't have to arrive all at once — it can be supplied incrementally, across multiple turns of a conversation, and each new sentence just updates which factors move from unobserved to observed. Second: the framework as stated handles exactly two complementary outcomes, but a decision with more than two options decomposes into this same binary machine applied hierarchically — pick outcome A vs. “everything else,” then within “everything else” pick B vs. the remainder, and so on. Neither extension requires touching Equations 1–9; both fall out of treating abduction as a one-time investment and entailment as the only per-interaction cost.
This isn't the first attempt to make LLM uncertainty trustworthy, and it's worth placing BIRD against the alternatives explicitly, because each one fixes a different piece of Chapter 0's problem and leaves another piece untouched.
| Approach | What it estimates uncertainty from | What it doesn't give you |
|---|---|---|
| Logit-based methods (e.g. token-probability confidence) | The model's own next-token probabilities during generation | These capture uncertainty about which token comes next, not uncertainty about the semantic claim the tokens express — a model can be very sure of its next word while being wrong about the fact |
| Fine-tuning to elicit calibrated confidence | A model trained end-to-end to output better-calibrated numbers | Requires heavy computation (a full fine-tuning run) per model, per domain, and the calibration signal is only as good as the training objective that produced it — no inspectable structure explaining any single number |
| Verbalized uncertainty (ask the model to say how sure it is) | The same single forward pass Chapter 0 already showed is unreliable | The paper this session cites for this approach (Xiong et al. 2024) found LLMs are “often overconfident when directly verbalizing their confidence” — the exact failure Chapter 0 measured |
| BIRD | An external, fixed Bayesian model over LLM-supplied factors and judgments | Doesn't require fine-tuning the base LLM at all; every number traces back to an inspectable factor |
The common thread in the first three rows: every prior approach still asks the LLM's forward pass to be the final source of the number, whether that number comes from logits, from a fine-tuned head, or from verbalization. BIRD is the odd one out in this table specifically because the arithmetic that produces the final probability lives outside the LLM entirely — Equations 1, 2, 4, 8, and 9 are ordinary Python, not a forward pass, and the LLM only ever answers the narrow sub-questions that feed those equations.
Chapter 1 mentioned in passing that a decision with more than two options decomposes into this same binary machine, applied hierarchically. It's worth seeing that claim as actual numbers before moving on, because “hierarchically” can otherwise sound like hand-waving standing in for a real answer.
Suppose the real decision is a three-way commute choice — bike, bus, or drive — not the two-way choice this session builds everything around. The hierarchical trick: first ask a binary question, bike vs. “not bike,” then, only within “not bike,” ask a second binary question, bus vs. drive. Two applications of the same two-outcome machine this whole session is built around, chained one after the other.
Say the first-level factors (weather, distance, how much gear you're carrying) combine, by whatever process Chapters 2–6 will build, to P(bike) = 0.30, so P(not bike) = 0.70. That second number is not the end of the computation — it's the total probability mass available to split between bus and drive at the second level. A separate set of factors (is transit running on schedule, is there parking near the destination) feeds a second binary decision conditioned on already being in the “not bike” branch: say that comes out to P(bus | not bike) = 0.60, so P(drive | not bike) = 0.40.
Two completely separate two-outcome computations, each built exactly the way Chapters 2–6 build the charging-cord one, and multiplying down the tree recovers a valid three-way distribution that sums to 1. No new machinery, no N-way generalization of any equation this session derives — just two independent binary questions, one nested inside the other, which is exactly what Chapter 1 meant by “decomposes hierarchically” and exactly why the paper never needed to derive a three-outcome or N-outcome version of Eq. 4.
Chapter 1 left a gap: how does an LLM “imagine the relevant factors” for a scenario, and what exactly comes out? This chapter opens that box.
The obvious method is to prompt the LLM once: “list the factors that would affect this decision, and their possible values.” BIRD's authors tried this and found it underperforms a two-stage alternative, for a specific, testable reason: a direct listing request makes the model reach for summarization mode — it produces the factors a textbook would list, not the ones its own training data actually associates with the scenario. It leaves the model's “imagination” — the broad associative knowledge baked into its weights by pretraining — mostly untapped.
So BIRD splits factor generation into two stages that engage a different capability at each step:
Stage 1 — generate situations, not factors. Prompt the LLM to write sentences describing situations that would make outcome O1 more likely, and separately, situations that would make O2 more likely — ten of each. This is a generative, low-constraint task; the model is free to draw on anything in its training distribution that resembles this scenario, without worrying about formalizing anything yet.
Stage 2 — summarize the sentences into factors. Only after twenty concrete situations exist does the LLM get asked to abstract them into a small number of named factors, each with a discrete set of values.
Not every generated factor is useful. Some — “the cell phone's model,” in the charging-cord example — turn out to have no bearing on the decision at all: every value of that factor supports neither outcome over the other. BIRD prunes these by asking the LLM to classify, for each candidate factor value, whether it supports O1, supports O2, or is neutral. A factor where every one of its values comes back neutral contributes nothing and is dropped before the factor space is even built. This pruning step matters enormously for what follows, and Chapter 7 will show you the exact number: dropping non-decisive factors this way improves final decision accuracy by 4.4 percentage points on average and cuts the “I don't know” rate by nearly 17 points, compared to skipping straight to the direct one-shot listing.
Say abduction (after pruning) leaves three decisive factors for the charging-cord scenario. Each is binary — two possible values — which is the simplest case, chosen here purely for hand-computability. It follows the identical product-space logic the paper itself uses to illustrate the mechanism, just with fewer factors: the paper's own worked example is a six-factor charging-station scenario (Figure 2), where it notes plainly “there are 26 elements in total” — the same multiplication rule this chapter is about to apply, scaled to twice as many factors. Nothing about the mechanism changes between three factors and six; only the arithmetic gets harder to do by hand, which is exactly why this session starts at three.
| Factor | Value 1 | Value 2 |
|---|---|---|
| FA — distance you move from the outlet | a1: stay within arm's reach | a2: pace around the room |
| FB — where the outlet sits relative to your seat | b1: right next to your seat | b2: on the far wall |
| FC — how you feel about slack cord | c1: want it taut and tidy | c2: don't mind extra cord |
F is the product space of all three value sets — every combination of one value from each factor is one point f = (fA, fB, fC) in F:
Eight fully-specified “possible worlds” — (a1,b1,c1), (a1,b1,c2), (a1,b2,c1), and so on through all eight combinations. This is the “complete information space” from Chapter 1's marginalization formula: F is exactly this set of eight points, and P(Oi|C) is a weighted average over all eight.
Three binary factors is deliberately small for teaching. Real scenarios abduct more factors, and factors are frequently non-binary (BIRD's actual datasets use factors with anywhere from 2 to several values each). Watch what happens as N grows, holding every factor binary:
At ten factors, the “complete information space” already has over a thousand fully-specified worlds. No one hand-enumerates that, and critically, no single condition U will ever observe more than a handful of them — most scenarios entail two or three factor values, not ten. This is exactly the gap that Chapter 3's treatment of unobserved factors exists to close, and it is exactly why Chapter 4's independence assumption exists: without it, computing P(Oi|f) for a general f would require enumerating conditional probabilities over an exponentially large joint space. With it, the computation becomes a product of N independent, individually-estimable numbers — one per factor, not one per combination.
Slide the number of abducted (post-pruning) binary factors. Each small square is one fully-specified world f ∈ F. Watch how fast a grid you could once count by eye becomes one you can only describe by formula.
It helps to see plausible output from the free-form generation step, because the two-stage design only makes sense once you can picture what stage 1 actually produces. For the charging-cord scenario, prompting for situations that support O1 (shorter cord) versus O2 (longer cord) separately might yield something like:
| Supports O1 (shorter cord) | Supports O2 (longer cord) |
|---|---|
| “You always sit at the same desk when you're on a call.” | “You like to pace while you talk.” |
| “Your outlet is right beside your favorite chair.” | “The nearest outlet is across the room.” |
| “You keep a tidy desk and hate loose cable slack.” | “You don't mind cable pooling on the floor.” |
Notice these are free sentences, not yet formalized — some describe behavior (“paces while talking”), some describe environment (“outlet across the room”), some describe preference (“hates cable slack”). Stage 2 is exactly the operation of noticing that these ten-plus-ten sentences cluster into a small number of underlying dimensions — behavior, environment, preference — and formalizing each cluster into one named factor with two (or more) values. The clustering step is also where BIRD's authors report the strongest diversity gain over asking for factors directly: a direct-listing prompt tends to converge on the two or three most stereotypical factors and stop, while clustering twenty concrete situations surfaces dimensions a direct request would never think to list.
python def prune_neutral(factors, O1, O2): kept = {} for name, values in factors.items(): labels = [classify_support(v, O1, O2) for v in values] # LLM: O1 / O2 / neutral if len(set(labels)) > 1 or "neutral" not in labels: kept[name] = values # at least one value is decisive, or values disagree — keep it # else: every value came back "neutral" — e.g. "the cell phone's model" — drop it return kept
This is the same classification call that Chapter 4 reuses to set each surviving value's initial probability — pruning and initialization are two readings of one LLM call, not two separate passes. A factor value that gets labeled “supports O1” here is exactly the value that receives 75% in Equation 5.
One more detail from the paper's experimental settings worth folding in here: this classification call isn't run once and trusted blindly — it's run three times at temperature 0.7, and the majority label wins. A single sample at nonzero temperature can land on “neutral” by chance even for a genuinely decisive factor value, or vice versa; three independent samples and a vote is the same self-consistency principle Chapter 3's entailment step uses, applied one step earlier, at the point where the factor space itself is still being shaped. Getting this vote wrong at the pruning stage is more consequential than getting one entailment call wrong later — a wrongly-pruned factor is gone from F for every future condition on this scenario, while a single bad entailment call only affects one condition.
Real abducted factors aren't always binary. A factor like “time of day” might have three values (morning, afternoon, evening); “room type” might have four. The size formula from earlier generalizes directly — it's the product of each factor's own value-set size, not a fixed base raised to a power:
Concretely: two binary factors and one three-valued factor gives |F| = 2 × 2 × 3 = 12, not 23 = 8. The binary case in this session's worked examples is the simplest instance of this formula, chosen for hand-computability — not a restriction the framework itself imposes. Everything downstream (Chapters 3–5's marginalization, Chapter 4's Eq. 4 combination) is written in terms of P(Oi|fj) for a general value fj in a general factor Fj, and never assumes |Fj| = 2.
The paper explicitly frames its factors as “similarly found in Bayesian networks” (Koller & Friedman, 2009). If you've seen a Bayes net drawn as a graph — nodes for random variables, arrows for dependencies — BIRD's factor space is the special case where every factor is a root node with no parents, feeding directly into a single outcome node Oi, and no factor has an arrow pointing to another factor. That flatness is not an oversight; it's what makes the conditional-independence assumption in Equation 2 legal, and it's why abduction's instruction to find factors that are “least relevant to each other” (Chapter 1) matters mechanically, not just stylistically: a genuine Bayes net with dependencies between factors would need a different, more expensive computation than the flat product Equation 2 uses. Chapter 9 returns to what happens when that flatness assumption is actually violated.
This also explains something about the pruning step from earlier in this chapter that's easy to miss on first read: pruning doesn't just remove factors that are useless on their own (the neutral ones). It's implicitly also the framework's only defense against factors that overlap with each other — if two candidate factors from stage 1's free-form sentences turn out to be near-paraphrases, a careful pass through the classification step in the pruning loop is where a human reviewer, or a more careful LLM prompt, would need to catch it. The paper's ablation (Chapter 7) measures the value of pruning against a direct-generation baseline, but doesn't separately measure how often near-duplicate factors slip through — a genuine open question this session's Chapter 9 will flag as an untested assumption, not a solved one.
One more useful arithmetic habit before moving on. Take a slightly bigger factor space than the running three-binary-factor example — say four factors with sizes 2, 3, 2, and 4 — so |F| = 2 × 3 × 2 × 4 = 48 worlds total. Now ask: if a condition entails a specific value of just the third factor (the one with 2 possible values), how many of those 48 worlds survive with nonzero weight?
Pinning one factor to a single observed value doesn't just add information — it divides the surviving space by exactly that factor's own cardinality, because every combination of the other factors is still free to vary, and every one of those combinations paired with the pinned value is still a live world. Observe a second factor (say the one with 4 values) on top of that, and the surviving count divides again: 24 ÷ 4 = 6. This is exactly the mechanical content behind this chapter's earlier claim that “most of that space always stays genuinely unknown” — each single observed fact prunes the space by a factor equal to how many values that one dimension could have taken, not by some fixed amount, and a condition would need to observe every factor before the space collapses to the single surviving world Chapter 5's Stage 3 reaches.
Chapter 2 built F — eight possible worlds, fixed once per scenario. Now a specific condition U arrives: “you'll be pacing around the room while on the call, and you like your cord tidy with no slack on the floor.” The question this chapter answers: how does that one sentence turn into P(f|C), a weight over all eight worlds?
BIRD calls this step entailment deliberately, not classification. The task given to the LLM is not “what does this condition mean” in the abstract — it's the much narrower, much more reliable question “does this condition entail (necessarily imply) this specific factor value?” Entailment is a task LLMs are well-practiced at and, crucially, one where the standard failure mode is underconfidence rather than fabrication: a well-calibrated entailment judgment says “not entailed” when the text is silent on the matter, rather than inventing an implication that isn't there.
BIRD runs two prompt styles and takes a majority vote across three samples: a hierarchy prompt (first decide which factors are touched by the condition at all, then for each touched factor, decide which value) and a direct prompt (for one specific factor-value pair, just ask “implied, yes or no”). The split exists because the two prompts trade off differently with scenario complexity: on their hardest dataset (temporal reasoning, dense with implicit timing cues) the direct prompt alone proved more reliable; on simpler datasets the hierarchy prompt, which is cheaper per factor, was favored 2-to-1 in the vote.
For our condition — “pacing around the room” and “wants it tidy” — the entailment step finds: FA is implied, value a2. FC is implied, value c1. FB (where the outlet sits) is never mentioned — not implied at all.
For an observed factor — one whose value the condition entails — BIRD assigns all the probability mass to that single value:
For an unobserved factor — one the condition never mentions — BIRD does something that looks almost too simple to be the answer, and is worth sitting with: it assigns equal probability to every possible value.
For our binary FB: P(b1|C) = P(b2|C) = 0.5 each.
Put the whole thing together for our example. Of the eight worlds in F, only the ones consistent with both observed values — a = a2 and c = c1 — get any weight at all: any world with a = a1 or c = c2 is weighted exactly 0, because the condition directly contradicts it. That leaves exactly two surviving worlds, distinguished only by the unobserved factor FB:
This is Equation 2 from the paper — the conditional-independence version of the marginalization sum — made concrete: P(f|C) is a product of per-factor terms, ∏j P(fj|C), and because two of the three factors are pinned to a single value (probability 1), the product collapses to just the unobserved factor's contribution.
Four factors, each drawn as a row of possible values. Slide how many of them the condition entails (observed — probability collapses onto one value, shown solid) versus leaves untouched (unobserved — probability spreads evenly, shown faded). Watch the “surviving worlds” counter at the bottom: it is the number of nonzero-weight points left in F.
This is a good moment to be honest about a real failure mode, because it will matter in Chapter 9. If entailment fails to detect that the condition implies a2 — say the sentence is phrased obliquely and the LLM's majority vote lands on “not implied” — then FA becomes unobserved by mistake, its probability spreads uniformly across a1 and a2, and the final P(Oi|C) drifts toward the fully-unobserved 50% baseline instead of reflecting what the condition actually said. Entailment errors don't crash the system — they silently dilute the answer toward neutral. That is a gentler failure than a confidently wrong number, but it is still a failure, and it is the single largest source of BIRD's “unknown” outputs, which Chapter 9 quantifies exactly.
The hierarchy prompt and the direct prompt ask conceptually different questions, and it's worth seeing both in pseudocode to understand why the paper ensembles them rather than picking one:
python def hierarchy_prompt(S, U, factors): # Step A: which FACTORS (not values yet) does U touch at all? touched = llm(f"Scenario: {S}\nCondition: {U}\n" f"Which of these factors does the condition address: {list(factors)}?") entailed = {} for name in touched: # Step B: for each touched factor, which VALUE is implied? entailed[name] = llm(f"Condition: {U}\nWhich value of {name} is implied: " f"{factors[name]}, or none?") return entailed def direct_prompt(S, U, factor_name, value): # one factor-value pair at a time: yes/no, does U entail this specific value? return llm(f"Condition: {U}\nDoes this imply that {factor_name} = {value}? yes/no") == "yes"
The hierarchy prompt is cheaper — one call per factor plus one call per touched factor, rather than one call per factor-value pair — but it risks a compounding error: if step A wrongly decides a factor isn't touched, step B never runs and a real implication gets silently dropped. The direct prompt checks every value independently, which costs more calls but doesn't let one wrong “not touched” judgment suppress a whole factor. That's exactly the tradeoff the paper's per-dataset setting encodes.
| Dataset | Complexity | Votes: hierarchy (x) / direct (3−x) | Why |
|---|---|---|---|
| Today (temporal reasoning) | highest — dense, implicit timing cues | x = 1: mostly direct | Step A of the hierarchy prompt is more likely to miss a subtly-implied factor when the condition is dense; checking every value independently is safer |
| Common2sense, Plasma | lower — more explicit conditions | x = 2: mostly hierarchy | Cheaper, and step A's risk of missing a touched factor is lower when conditions state things plainly |
Three samples, majority vote, per condition — this is the same self-consistency principle chain-of-thought baselines use for their final answer, applied here to the much narrower entailment sub-task instead of to the final probability itself. When the three samples disagree on which value a direct prompt implies, the paper falls back to the pruning-style prompt from Chapter 2 to force a single choice.
It's useful to see Equations 8 and 9 as a small piece of code, because the two-branch structure maps one-to-one onto observed versus unobserved:
python def assign_weights(entailed, factors): weights = {} for name, values in factors.items(): if name in entailed: # Eq.8 — observed weights[name] = {v: (1.0 if v == entailed[name] else 0.0) for v in values} else: # Eq.9 — unobserved weights[name] = {v: 1.0 / len(values) for v in values} return weights
For our running example, calling this with entailed = {'F_A': 'a2', 'F_C': 'c1'} produces
weights['F_A'] = {'a1': 0.0, 'a2': 1.0},
weights['F_B'] = {'b1': 0.5, 'b2': 0.5},
weights['F_C'] = {'c1': 1.0, 'c2': 0.0} — exactly the numbers used in this
chapter's grid and Chapter 5's full computation.
Chapter 1 mentioned that a condition can arrive incrementally, across turns, rather than all at once. Trace what that looks like mechanically, because it's a direct consequence of everything built so far and nothing new needs to be invented for it:
python weights = {name: {v: 1.0/len(vals) for v in vals} for name, vals in factors.items()} # start: everything unobserved # turn 1: "you'll be pacing around the room" new_entailed = llm_entailment(S, "you'll be pacing around the room", factors) weights.update(assign_weights(new_entailed, factors)) # F_A collapses to {a2: 1.0, a1: 0.0} print(marginalize(p_j, weights, factors)) # 0.321 — Chapter 5 Stage 1 # turn 2, later in the same conversation: "oh, and I like the cord tidy" new_entailed = llm_entailment(S, "I like the cord tidy", factors) weights.update(assign_weights(new_entailed, factors)) # F_C collapses too; F_A stays as turn 1 left it print(marginalize(p_j, weights, factors)) # 0.500 — Chapter 5 Stage 2
Each turn only ever runs entailment against the new sentence and only ever updates the factors that sentence touches; a factor already pinned by an earlier turn is untouched by a later one unless the later turn explicitly revises it. This is why P(f|C) can be maintained as running state across a conversation rather than recomputed from the full transcript every time — the marginalization call at the end of each turn is cheap precisely because weights only ever tighten (unobserved → observed), never re-expand, as a conversation proceeds.
Real conversations aren't always monotonic — a user might say “actually, I changed my mind, I'll
be sitting still the whole time” after already establishing a2 (pacing) in turn 1. Nothing in
the weight-assignment code from Chapter 3 prevents this: assign_weights is a pure function of
whatever the most recent entailment call returns for that factor, so a later, contradicting entailment call
simply overwrites the earlier weight — FA flips from {a1: 0.0, a2: 1.0}
back to {a1: 1.0, a2: 0.0}. There's no special-cased “revision” logic
required, because P(fj|C) was never defined as an accumulation of every sentence ever said about
factor j — it's defined as the current best read of what the most complete version of C implies, and a
later sentence updating an earlier one is just what a more complete C looks like. This is also, incidentally,
why running entailment against the full transcript at the end of a long conversation (rather than
turn-by-turn) is a legitimate implementation choice too, and would arrive at the same final weights —
the incremental version is a cost optimization, not a different answer.
Every worked example so far in this chapter used binary factors, where an unobserved factor's weight is always a clean 0.5. It's worth checking Eq. 9 on a factor with more than two values, because that's the general case the formula actually has to handle — Chapter 2 already noted real abducted factors aren't always binary — and it's exactly the kind of factor Chapter 8's aggregator widget will let you play with directly.
Suppose abduction also surfaced a fourth factor for the charging-cord scenario — FD, room clutter, with three values: tidy (d1), moderately cluttered (d2), and very cluttered (d3). A condition that says nothing about the room's state leaves FD completely unobserved. Eq. 9 says:
Same principle as the binary case — spread the weight uniformly across every possible value — just with a denominator of 3 instead of 2. Now combine this with the original three-factor example: a condition entailing FA=a2 and FC=c1, with FB and the new FD both unobserved. The full factor space now has 2 × 2 × 2 × 3 = 24 worlds; the surviving, nonzero-weight ones are those consistent with a2 and c1, which is 1 × 2 × 1 × 3 = 6 worlds (FB's two values times FD's three), each carrying weight 0.5 × 0.333 ≈ 0.167.
Chapters 2 and 3 built the two things the marginalization formula needs weights for — the space F and the observation weights P(f|C). The one piece left unbuilt is the other half of the sum: P(Oi|f), the probability of the outcome given a fully specified world. This chapter is about why that number is hard to get directly, and the elegant trick BIRD borrows to get it anyway.
Textbook Bayesian inference would build P(Oi|f) from Bayes' rule: start with the likelihood P(f|Oi) — “if Oi were true, how likely is this particular world f?” — multiply by the prior P(Oi), and normalize. BIRD's authors tried asking the LLM for exactly that likelihood, and it is a substantially harder question than it looks. To answer “if a shorter cord really is better, how likely is it that you're pacing the room with a taut-cord preference,” the model has to invert cause and effect and imagine a distribution over hypothetical worlds consistent with a fixed conclusion — a speculative, underconstrained judgment prone to the exact same fluency-without-computation failure from Chapter 0.
Compare that to the forward question: “given this fully-specified world (you're pacing, you want it tidy), how likely is a shorter cord the better choice?” That's a direct, well-posed judgment about a completely described situation — the kind of single-fact classification LLMs are reliable at, the same reliability Chapter 1 leaned on for entailment.
The general form (Bordley, 1982) combines N per-factor probabilities P(Oi|fj) into one joint probability P(Oi|f), using a per-factor weight wj and a prior P(Oi):
BIRD makes it tractable with two choices, both justified by the same fact: there is no prior information suggesting anything other than the neutral answer. Equal weights, wj = 1 for every factor (no factor is a priori trusted more than another — that's what “least relevant to each other, covering different angles” from Chapter 2's abduction step is for). And a 50% prior, P(Oi) = 0.5 (before seeing any factor, both outcomes are equally likely by construction — they were defined to be complementary). Substituting both collapses the formula to something you can compute on paper:
This is the single most important formula in the whole session. Everything from here to Chapter 8 is either computing its inputs or using its output.
Before training (Chapter 6 covers the trained version), BIRD initializes each factor's probability from the same three-way classification used for pruning in Chapter 2 — does this factor value support Oi, support the opposite outcome, or sit neutral:
These exact numbers — 75%, 50%, 25% — are the real values from the paper, and they're the ones we'll hand-compute with next.
Suppose two factors both support O1 (each initialized at 75%). Plug into Eq. 4:
Two independently-moderate 75% opinions combine into a 90% joint opinion — stronger than either one alone. This is what “independent evidence compounds” looks like as arithmetic: agreement between separate sources is more convincing than either source individually, exactly the intuition behind combining two witness testimonies that corroborate each other.
Now suppose one factor supports O1 (75%) and another supports O2 just as strongly — which means it supports O1 at only 25%:
Equally strong, opposing evidence cancels exactly to a coin flip. Notice this is symmetric by construction: Eq. 4 is built from products, and swapping which factor “wins” a symmetric tie leaves the denominator unchanged.
python def eq4(probs): # probs: list of P(Oi | f_j) for j = 1..N num = prod(probs) comp = prod([1 - p for p in probs]) return num / (num + comp) print(eq4([0.75, 0.75])) # 0.9 — agreement compounds (worked example 1) print(eq4([0.75, 0.25])) # 0.5 — conflict cancels (worked example 2)
Now a third case, mixing agreement with different strengths rather than a flat 75/25 — this is the shape real training-refined probabilities take (Chapter 6 replaces the coarse 75/50/25 buckets with continuous values like these). Three factors, all leaning toward O1 but by different amounts: 0.60, 0.75, and 0.90.
Three moderately-to-strongly agreeing factors combine to 97.6% — stronger than the weakest (0.60), stronger than the strongest alone (0.90), stronger even than two 90%'s combined (0.9×0.9 ÷ (0.81+0.01) = 0.988 would need two 90s; three mixed factors land close to that with one much weaker contributor). Independent, agreeing evidence keeps compounding as you add more of it, even when individual pieces are only moderately confident — this is the same mechanism a spam filter or a medical test panel relies on: no single weak signal is convincing, but several independent weak signals pointing the same way are.
Bordley's derivation offers a second case beyond equal weights — one where the sum of weights exceeds 1, capturing a decision-maker who becomes more certain as more independent factors accumulate, rather than less. BIRD adopts exactly this regime with the simplest possible instantiation, wj = 1 for every factor. The paper's stated justification is symmetry of ignorance: abduction was explicitly designed (Chapter 2) to produce factors that are “least relevant to each other” and jointly cover “all the possible individual factors/angles” — if the factor-generation step already did its job, there is no principled basis left for trusting one surviving factor's judgment over another's. A learned, unequal weighting would need its own supervision signal and its own risk of overfitting to quirks of one dataset; equal weights is the assumption that adds no additional free parameters beyond what Chapter 6's training already fits.
P(Oi) = 50% is not a general default — it's a consequence of a specific setup decision. Because O1 and O2 are defined as complementary (Chapter 1's problem statement: “the two outcomes are complementary”), and because the framework has no information at the scenario level (before any factor is even considered) that favors one over the other, 50/50 is the only prior consistent with “no information yet.” If a deployment had a genuine base rate — say, historical data showing shorter cords get chosen 70% of the time across all past decisions regardless of condition — Equation 3's general form accepts that directly as P(Oi); Equation 4 is specifically the 50%-prior special case, chosen because BIRD's benchmark scenarios don't supply such a base rate.
The formal derivation (Bordley, 1982, formalized further in the paper's Appendix A.2) rests on two conditions that sound intimidating in notation but are simple statements once translated. The first, a weak ordering on odds ratios, just says: if you'd trust one set of factor-implied odds at least as much as another set in one scenario, you'd make the same comparison consistently in any other scenario with the identical odds — your ranking of “how convincing is this combination of evidence” doesn't contradict itself from one case to the next. This is barely an assumption at all; it's closer to a definition of what it would even mean to have a consistent notion of “more convincing.” The second, a noninteraction property, says that how much you learn from factor j doesn't depend on which values the other factors happen to hold — which is exactly the conditional-independence assumption Chapter 2 already built into the factor space by design. Given both, Bordley proves this multiplicative form is the only continuous formula satisfying them — not one reasonable choice among many, but the unique one. That's a stronger justification than “this formula seems to work” — it's “any formula with these two sane properties would have to reduce to this one.”
It's worth seeing, concretely, why Eq. 4's specific multiplicative form earns its place over the simplest alternative anyone would reach for first: just average the per-factor probabilities. Take the two agreeing 75% factors from worked example 1.
The arithmetic mean returns exactly 0.75 — the same number a single 75%-confident factor would have given on its own. That's the tell: averaging treats a second piece of agreeing evidence as if it contributed nothing new, because averaging two identical numbers just returns that number back. Two independent witnesses who both say “I'm 75% sure” about the same conclusion is genuinely more convincing than either witness alone — and a combination rule that can't move past what one witness already told you has thrown away the second witness's information entirely.
Run it the other direction, on the conflicting-evidence case (worked example 2: one factor at 75%, one at 25%). The arithmetic mean gives (0.75+0.25)÷2 = 0.50 — which happens to match Eq. 4's answer here, by coincidence of symmetry, not because averaging is secretly correct. The agreement breaks the moment the two factors aren't perfectly symmetric opposites, which the compounding case just above already demonstrated.
Every piece is on the table: F (Chapter 2), P(f|C) for observed and unobserved factors (Chapter 3), and P(Oi|f) via Eq. 4 (Chapter 4). This chapter runs the complete pipeline, by hand, on the charging-cord scenario, and watches P(O1|C) move as information arrives — one factor at a time.
Recall the three factors and their initial per-value probabilities of supporting O1 (“a shorter cord is better”), all from Eq. 5's real 75/50/25 scheme:
| Factor value | Supports | P(O1|value) |
|---|---|---|
| a1 — stay within arm's reach | O1 (shorter cord) | 0.75 |
| a2 — pace around the room | O2 (longer cord) | 0.25 |
| b1 — outlet next to your seat | O1 | 0.75 |
| b2 — outlet on the far wall | O2 | 0.25 |
| c1 — wants it taut, no slack | O1 | 0.75 |
| c2 — doesn't mind extra cord | O2 | 0.25 |
Before any condition U is even supplied, all three factors are unobserved. By Eq. 9, every value of every factor gets uniform weight (0.5 each), so P(f|C) = 0.5 × 0.5 × 0.5 = 0.125 for every one of the eight worlds — a uniform distribution over F. Marginalizing (Eq. 1) an Eq.-4-computed P(O1|f) uniformly over a factor space this symmetric returns exactly the 50% prior. No condition, no information, 50/50 — the framework's floor state matches the assumption it was built on.
Condition: “you'll be pacing around the room.” This entails a2 only; FB and FC stay unobserved. Four worlds survive with equal weight (0.25 each, since two unobserved binary factors split 0.5 × 0.5). Compute P(O1|f) via Eq. 4 for each:
One entailed fact — “you'll be pacing” — and P(O1|C) already moved from a neutral 50% to 32.1%, correctly leaning toward O2 (longer cord), because pacing is the one thing the condition told us and it individually points toward O2.
Condition: “you'll be pacing around the room, and you like your cord tidy with no slack.” Now a2 and c1 are both entailed; only FB stays unobserved. Two worlds survive, each weight 0.5 — and we already computed both of them in Stage 1:
This is the most important row in the whole hand-computation, precisely because it is not what naive intuition predicts. We added a second piece of information — “wants it tidy,” which on its own supports O1 at 75% — and the answer went back up to exactly 50%, not somewhere between 32.1% and 75%.
Condition additionally specifies the outlet is right next to your seat: b1 is now entailed too. Every factor is observed; exactly one world in F survives with weight 1, and we computed its P(O1|f) back in Stage 1:
Fully observed, the framework reports 75% confidence in the shorter cord — even though the very first fact we learned (pacing around the room) on its own pointed the other way. The full picture matters more than any single factor, and BIRD's marginalization is precisely the machinery that makes that true honestly rather than by accident.
| Stage | What's observed | P(O1|C) |
|---|---|---|
| 0 | nothing | 0.500 |
| 1 | FA = a2 | 0.321 |
| 2 | FA = a2, FC = c1 | 0.500 |
| 3 | FA = a2, FB = b1, FC = c1 | 0.750 |
All eight worlds in F, laid out as rows. The button cycles through the four observation stages above. Weight-zero worlds (contradicted by an observed factor) fade out; the surviving worlds' individual P(O1|f) and P(f|C) weight combine, live, into the number at the bottom.
Chapter 4's odds-multiplication shortcut is a good way to sanity-check the 0.321 result from Stage 1 without re-doing all four Eq. 4 computations. Convert each surviving world's per-factor probabilities to odds (P ÷ (1−P)), multiply, then convert back — and separately average the four resulting probabilities weighted by 0.25 each, exactly as before:
Both match the direct Eq. 4 arithmetic from before, which is exactly the point of the odds view: it's not a different formula, it's the same combination read as multiplying independent likelihood ratios — a useful mental check whenever you want to verify a hand computation without redoing every multiplication from scratch.
The interactive widget below implements precisely the loop this chapter just ran by hand: for each of the eight worlds in F, compute its weight P(f|C) as a product of per-factor terms (1 or 0 for observed factors, 0.5 for unobserved ones — Equations 8–9), compute its P(O1|f) via Eq. 4, and accumulate the weighted sum. The four stages correspond exactly to the four rows in the summary table above. Watch two things as you click through: which rows fade to near-invisible (weight-zero, contradicted by an observed factor) versus stay solid, and how the bar length of each surviving row's P(O1|f) never changes across stages — only which rows get to vote, and how much weight each vote carries, changes. That distinction (fixed per-world probabilities, moving observation weights) is the entire mechanical content of marginalization.
Everything so far used exactly three factors, matching the paper's own illustrative “23 elements” description. Nothing about the method caps N at 3 — add a fourth binary factor, FD (“how urgently you need to leave the room during the call”: d1 = rarely, supports O1 at 75%; d2 = often, supports O2, so P(O1|d2) = 25%), and F now has 24 = 16 worlds instead of 8. Repeat Stage 3 (all of FA, FB, FC observed at a2, b1, c1) but leave the new FD unobserved:
Two things worth noticing. First, adding a fourth fully-agreeing factor value (d1, on top of the three already-agreeing observed values) pushed the fully-observed answer from 0.75 up to 0.90 — worked example 1's “agreement compounds” lesson, now with three agreeing factors instead of two. Second, once you average in the still-unobserved FD, the four-factor answer (0.700) is actually lower than the three-factor Stage 3 answer (0.750) — adding a factor to the space, even one that individually favors O1, can pull the marginalized answer either direction once you account for the uncertainty it introduces while unobserved. More factors mean more potential precision when observed, and more potential dilution when they aren't — there's no free lunch from simply abducting more factors without also having conditions that entail them.
Stage 2 showed a condition that adds a fact pointing opposite to the first (a2 favors O 2, c1 favors O1) landing back at exactly 50%. It's worth hand-computing the branch where the second fact agrees with the first, to see the contrast directly rather than take it on faith.
Condition: “you'll be pacing around the room, and the outlet is on the far wall from your desk.” Now a2 and b2 are both entailed — both individually favor O 2 (25% each toward O1) — and FC stays unobserved. Two worlds survive, weight 0.5 each: (a2,b2,c1) and (a2,b2,c2), both already computed back in Stage 1's table.
Two agreeing facts (both pointing toward O2) pull the answer from 50% (nothing observed) down to 14.3% — far more confident than either fact alone (32.1% from a2 alone), and further from neutral than the opposing-evidence branch ever got. Lay the two branches side by side and the shape of marginalization becomes visible as a genuine fork, not just a formula:
| Second fact observed | Direction | P(O1|C) |
|---|---|---|
| none (FA only) | — | 0.321 |
| FC = c1 (agrees with O1, opposes a2) | opposing | 0.500 |
| FB = b2 (agrees with a2, both favor O2) | agreeing | 0.143 |
Same starting point (32.1%), same-sized new fact, two opposite trajectories — one pulled back toward neutral, the other pushed further away from it — entirely determined by whether the new fact agrees or disagrees with what was already known. Marginalization has no built-in direction; it just honestly compounds whatever the observed factors actually say, which is the same point Chapter 4's worked examples 1 and 2 made in the abstract, now shown as two branches of the identical concrete scenario.
For anyone who wants to check any of this session's hand arithmetic without trusting a spreadsheet, the whole computation is short enough to brute-force directly — enumerate every world in F, weight it, sum:
python from itertools import product values = {'A': ['a1','a2'], 'B': ['b1','b2'], 'C': ['c1','c2']} p = {'a1':0.75,'a2':0.25,'b1':0.75,'b2':0.25,'c1':0.75,'c2':0.25} observed = {'A':'a2', 'C':'c1'} # Stage 2: A and C observed, B unobserved total = 0.0 for a, b, c in product(values['A'], values['B'], values['C']): weight = int(observed.get('A',a)==a) * 0.5**('B' not in observed) * int(observed.get('C',c)==c) if weight > 0: total += weight * eq4([p[a], p[b], p[c]]) print(total) # 0.5 — matches Stage 2 exactly
Every computation in Chapter 5 used the initial factor probabilities — the blunt 75/50/25 scheme from a single three-way classification. That scheme is a reasonable starting point, but it throws away information: it can't distinguish a factor that barely supports O1 from one that supports it overwhelmingly — both just get 75%. This chapter covers how BIRD refines those three coarse buckets into continuous, learned probabilities, and why the refinement measurably helps.
You cannot get ground-truth P(Oi|fj) values from a labeled dataset — nobody annotated “factor value a2 in isolation has probability exactly 0.23 of supporting O1.” BIRD's trick: the LLM is reliable at judging outcomes under complete information (that's the well-posed forward question from Chapter 4). So sample 128 fully-specified instances f′ ∈ F per scenario, and for each, prompt the LLM to output a verbalized probability from a fixed seven-point vocabulary:
These 128 verbalized-and-mapped judgments become the supervision signal, denoted PLLM(Oi|f′). The learning problem: find per-value probabilities P(Oi|fj) such that, when combined through Eq. 4 for any sampled f′, the result matches what the LLM judged when it could see the entire f′ at once.
Two loss terms, added together:
Mean squared error between the Eq.-4-combined estimate and the LLM's complete-information judgment, the ordinary regression signal.
A margin-ranking term that separately protects each individual factor value's direction. It computes a “trained” per-value probability by marginalizing over the remaining factors (holding fj fixed, averaging Eq. 4's output across the other N−1 factors' possible values) and penalizes it if that trained probability crosses to the wrong side of 50% relative to where the initial classification (Eq. 5) said the value pointed:
The paper trains with SGD, learning rate 0.01, 20 epochs, batch size 4, α = 10, ε = 0.
The paper runs this as an ablation, comparing four ways of getting P(Oi|f) into Eq. 4. One bookkeeping note before the numbers: the paper only publishes this specific four-way breakdown — 1/2 assumption, 1/N assumption, fixed initial probability, and fully trained — for Llama-3.1-70B, not for the Llama-2-70B run this session has used everywhere else (Chapters 0 and 7 both quote Llama-2's headline trained average, 0.592). The two models' trained scores are close but not identical — Llama-3.1 trained lands at 0.588 — close enough that the comparison below is fully representative of the point it's making, but every row in this specific table is Llama-3.1's, not Llama-2's:
| Variant | How P(Oi|fj) is set | Average F1 (Table 1, Llama-3.1) |
|---|---|---|
| 1/2 assumption | no LLM classification at all — decide only if every factor unanimously agrees | 0.480 |
| 1/N assumption | simple vote-count across factors | 0.532 |
| Fixed initial prob | raw 75/50/25 from Eq. 5, no training | 0.568 |
| Trained prob | learned via MSE + margin-ranking | 0.588 |
Trained probabilities win, but notice the gap to the fixed initial probabilities is only 2.0 points (0.588 vs 0.568) — the crude 75/50/25 scheme is already most of the way there, because most of BIRD's power comes from routing through explicit factors and honest marginalization at all, not from the fine-tuning of any one number. Training is a real, measurable refinement, not the source of the framework's core advantage. Notice too how much of the total climb happens before training ever enters the picture: going from the crudest baseline (1/2 assumption, 0.480) to the fixed, untrained 75/50/25 scheme (0.568) is an 8.8-point jump, more than four times the further 2.0-point gain training buys on top of it. The expensive-sounding machinery from Chapters 2 through 5 — abduction, entailment, marginalization — is doing almost all of the work; Chapter 6's training loop is a genuine but modest polish on top of it, not the reason BIRD beats the baselines in the first place.
Every bar is Table 1's real Average F1 for that variant (Llama-3.1). The gray band marks where GPT-4 chain-of-thought sits (0.289) — every BIRD variant, even the crudest ablation (1/2 assumption, no LLM classification at all), clears it comfortably, by 66% or more.
python # one training run per scenario S — the 3 factors from this session's example p = {name: init_from_eq5(name) for name in all_factor_values} # trainable, starts at 0.75/0.50/0.25 opt = SGD(p.values(), lr=0.01) for epoch in range(20): for batch in sample_batches(all_128_instances(F), batch_size=4): for f_prime in batch: p_llm = verbalize_and_map(f_prime) # Eq: 7-word scale -> 0/20/40/50/60/80/100% p_est = eq4([p[fj] for fj in f_prime]) # Eq.4 with CURRENT trainable values loss_mse = (p_est - p_llm) ** 2 loss_mr = 0.0 for fj in f_prime: p_trained = marginalize_over_others(p, fj, F) # Eq.6 — average Eq.4 over F* y_target = sign(p_init[fj] - 0.5) loss_mr += max(0, -y_target * (p_trained - 0.5) + EPSILON) loss = loss_mse + ALPHA * loss_mr # ALPHA = 10 loss.backward(); opt.step(); opt.zero_grad()
Two things to notice in the loop. First, p_llm is computed once per sampled instance and never
updated — it is fixed supervision, the LLM's complete-information judgment. Second,
p_trained in the margin-ranking term is not the same quantity as p_est:
p_est plugs the current trainable values straight into Eq. 4 for one specific sampled instance;
p_trained (Eq. 6) holds one factor value fj fixed and averages Eq. 4's
output over every possible completion of the remaining factors. It answers a different question —
“on average, across every way the rest of the world could be, does this one value still point toward
Oi?” — which is exactly what the margin-ranking term needs to check a value's
direction independent of which particular instance it was sampled alongside.
Suppose there are only two other factors besides the one you're checking, FB and FC, each binary — so ƒ* (“the remaining factors”) has 2 × 2 = 4 combinations. Holding FA = a2 fixed, Equation 6 says average Eq. 4's output over all four:
This is not a coincidence — it's the exact same arithmetic as Chapter 5's “observe FA only” stage, because both computations ask the identical question: averaged over everything else being unknown, how much does a2 alone move the needle? Equation 6 reuses the machinery Chapter 5 already built; it isn't a new algorithm, just the same marginalization aimed at one factor value in isolation, used here as a training-time consistency check rather than a deployment-time answer.
| Hyperparameter | Value | Role |
|---|---|---|
| Learning rate | 0.01 | Small steps — there are only 128 training instances per scenario, so overshooting risks destroying the 75/50/25 initialization's information rather than refining it |
| Epochs | 20 | Enough passes over 128 instances (batch size 4 → 32 steps/epoch, 640 steps total) to converge without needing early stopping infrastructure |
| Batch size | 4 | Small batches on a small dataset — more gradient updates per epoch than large-batch training would give |
| α (margin weight) | 10 | Weights the direction-preserving term an order of magnitude above raw MSE fit — a strong prior that flipping a factor's sign is a much worse mistake than being numerically imprecise |
| ε (margin) | 0 | No slack required beyond crossing 0.5 in the correct direction — the penalty activates only once a value's trained probability would cross to the wrong side of neutral |
One more real capability worth naming here: because Eq. 4 takes each P(Oi|fj) as a plain input, nothing stops a human expert from overriding a specific factor's learned value directly — substitute the human-preferred number in place of the trained one, and Eq. 4 combines it with the rest exactly as before. The paper offers this as one more reason BIRD doesn't use the classical P(f|Oi) likelihood formulation from Chapter 4: it would be far harder for a human reviewer to state a preference over an inverted, hypothetical-world likelihood than to simply say “no, a2 should support O1 at 30%, not 25%” and have that number flow straight into the same combination formula everything else uses.
Two design choices in this training step are worth pausing on, because both trace back to earlier chapters in this session. First: 128 is a sample, not the whole space — our toy 3-factor example only has 8 worlds total, so 128 would be redundant there, but real abducted factor spaces (Chapter 2 showed these can run into the hundreds or thousands of worlds for even a handful of multi-valued factors) are far larger than 128, and sampling is the only tractable way to get training signal without enumerating everything. Second, and more pointed: the supervision comes from a verbalized, categorical judgment (“likely,” “very unlikely”) mapped to a number, not from asking the LLM to output a raw percentage directly. This is a direct callback to Chapter 0 — that chapter's entire argument was that asking an LLM to verbalize a raw percentage produces an unreliable number. Constraining the judgment to seven coarse buckets removes the LLM's ability to manufacture false precision (there is a real difference between an LLM confidently saying “73%” with no basis for the third digit, and an LLM choosing between “likely” and “very likely”), while still being informative enough, combined across 128 samples and fit through a proper loss function, to meaningfully refine the coarse 75/50/25 starting point. The categorical scale is coarser per-judgment, but the aggregate training signal it produces is more trustworthy than 128 raw, uncalibrated percentages would have been.
Put a concrete number on the training run's size, since “SGD, lr=0.01, 20 epochs, batch=4” reads as boilerplate until you compute what it means: 128 instances at batch size 4 is 32 batches per epoch, times 20 epochs, is 640 total gradient steps — to fit a handful of trainable parameters (one number per factor value; three factors with two values each is only 6 numbers). This is not a large-scale training run in any sense this course has used the term elsewhere — it's closer to fitting a tiny logistic regression than training a network. That scale mismatch (640 steps, 6 parameters) is itself informative: BIRD's per-scenario training cost is small enough to redo on demand every time abduction produces a new factor set, which is part of why the framework's authors treat the trained-vs-fixed-initial-probability gap (2.0 F1 points, Chapter 6's ablation table) as a genuine but modest refinement rather than the main event — there simply isn't much capacity in 6 free numbers to overfit or to dramatically outperform a reasonable fixed starting point.
It's worth imagining the counterfactual to appreciate what the margin-ranking term actually buys, since “10” is otherwise just a number. Set α = 0 and only MSE remains. Now suppose one of the 128 sampled complete-information instances happens, by chance, to be a case where the LLM's complete-information judgment (PLLM) disagrees with what the coarse Eq. 5 classification originally said about one of its factors — not impossible, since Eq. 5's classification looks at a factor value in isolation while PLLM judges a whole fully-specified world. Pure MSE has no reason to resist letting that one factor's learned value drift across 50% to fit this instance better, even if doing so contradicts every other instance's implied direction for that same factor. With α = 10, that drift is penalized ten times more heavily than a comparable numeric fitting error, which is precisely why the paper can afford a small, noisy, 128-instance training set without the smallness turning into instability: the margin term acts as a strong prior toward “keep the sign Eq. 5 already gave you,” and only the aggregate weight of many instances, not one outlier, is allowed to flip it.
One more number worth deriving from the same hyperparameters, because it answers a natural worry: with only 128 training instances, is this training loop actually learning something, or just memorizing a handful of examples? Each epoch is a full pass over all 128 instances (32 batches of 4), and there are 20 epochs, so every one of the 128 sampled instances participates in exactly 20 gradient updates over the course of training — not the full 640 steps each, but 640 ÷ 128 = 20 visits per instance on average, since batching and epoching just partition the same 128 instances repeatedly. Twenty visits to each data point, fitting six free numbers total (one probability per factor value; three factors with two values each), is closer to repeatedly polishing a small, fixed estimate than to learning a pattern from data the model hasn't already seen — consistent with this chapter's framing of training as refinement, not as the source of BIRD's core advantage.
The last six chapters built the machine. This one holds it to the numbers — three experiments, on Llama-2-70B-Instruct, across three datasets: Common2sense (commonsense reasoning, 216 scenarios, 3,822 instances, roughly 9 additional conditions on average supporting each outcome), Today (temporal reasoning, 1,000 instances), and Plasma (procedural planning, 279 scenarios, 1,395 instances, roughly 5 additional conditions supporting the less common outcome).
This is the F1-against-human-judgment test from Chapter 0, broken down by category. “Different1” and “Different2” are cases where the two conditions genuinely favor opposite sides; “Same” is the harder case where both conditions equally support the outcome, and the model has to recognize a tie rather than manufacture a winner:
| Method | Different1 | Different2 | Same | Average |
|---|---|---|---|---|
| GPT-4, Explicit Comparison† | 0.588 | 0.533 | 0.300 | 0.540 |
| BIRD, trained | 0.614 | 0.624 | 0.450 | 0.592 |
† Explicit Comparison is an easier setting: the model sees both conditions side by side and just picks the stronger one directly, rather than scoring each independently — not a fully fair comparison, and still BIRD wins.
Look at the “Same” column: 0.300 vs 0.450 — a fifty-percent relative jump, and by far the widest gap of the three categories (Different1's gap is only 0.026; Different2's is 0.091). Recognizing that two conditions tie is exactly where a model that's pattern-matching toward “something must be stronger” fails hardest, and exactly where routing through explicit, separately-scored factors pays off most: if neither condition entails any additional factor beyond what the other already did, BIRD's marginalization correctly produces near-identical numbers for both, instead of manufacturing a winner where the human labelers themselves called it a tie.
Verify the abstract's headline claim by hand: BIRD's F1 (0.592) minus GPT-4 chain-of-thought's F1 (0.289) is 0.303, i.e. 30.3 percentage points — matching the paper's own results-section sentence, stated plainly: “our framework exhibits superior alignment with human preference, with both models achieving an F1 of 59%, more than 30% higher than GPT-4.” The paper makes a second, separate claim against the easier EC setting — and is explicit that EC is unfair to BIRD, since it lets the model see both conditions side by side and just pick the stronger one, a structural advantage no other row in this table gets: “even under this setting that is unfair to our framework, BIRD still outperforms GPT-4 by 5%.” Checked against the real numbers: 0.592 (BIRD, Llama-2) minus 0.540 (GPT-4 EC) is 0.052, a 5.2-point gap, matching that claim almost exactly. (Against Llama-2's own EC score, 0.503, the gap is 0.089 — about 9 points; the paper doesn't single this comparison out by name, but it's the identical arithmetic, checkable from the same table.) These aren't approximate — they're the paper's own arithmetic, run by hand against its own table.
A second question: when forced to pick a single outcome (not just rank two conditions), how does BIRD compare to chain-of-thought with self-consistency — and what happens on the instances BIRD can't resolve at all?
| Dataset | BIRD (trained), accuracy when it answers | CoT + self-consistency | BIRD's “unknown” rate |
|---|---|---|---|
| Today | 73.9% | 71.5% | 54.0% |
| Common2sense | 89.0% | 93.8% | 34.6% |
| Plasma | 74.0% | 76.8% | 31.4% |
BIRD wins on the hardest dataset (Today) and loses on the two easier ones — the paper is direct about why: probability estimation and hard-label classification are different objectives, and CoT sometimes reaches the right label by leaning on incidental cues in the raw context that a structured, factor-based decomposition deliberately doesn't have access to (Chapter 9 shows the exact example). The real cost, though, is the “unknown” column: BIRD declines to answer at all when the condition doesn't entail any factor, 54% of the time on Today.
Put a number on what that costs in instances, not just percent: Today has 1,000 instances — 54% unknown means 540 instances need a CoT fallback, leaving 460 resolved directly by BIRD. Common2sense has 3,822 instances — 34.6% unknown is roughly 1,322 instances needing fallback, 2,500 resolved directly. Plasma's 1,395 instances at 31.4% unknown is about 438 needing fallback, 957 resolved.
The ablation promised back in Chapter 2, verified by hand:
| Dataset | Direct accuracy | Abduction accuracy | Δ accuracy | Direct unknown% | Abduction unknown% | Δ unknown |
|---|---|---|---|---|---|---|
| Today | 70.9 | 73.9 | +3.0 | 74.1 | 54.0 | −20.1 |
| Common2sense | 84.2 | 89.0 | +4.8 | 54.9 | 34.6 | −20.3 |
| Plasma | 68.6 | 74.0 | +5.4 | 40.7 | 31.4 | −9.3 |
The accuracy figure matches the paper's own summary exactly — Section 4.2 states plainly that “our proposed method, on average, surpasses the direct method by 4.4%/3.9% in accuracy for Llama-2/Llama-3.1,” and this session's Llama-2 hand-computation reproduces that 4.4% to the decimal. (The same table's Llama-3.1 row, not shown here since this session stays on Llama-2 throughout Chapter 7, averages to the paper's other quoted figure, 3.9%.) The unknown-rate reduction, 16.6 points on average above, is this session's own computation from the same real table — the paper reports each dataset's unknown-rate drop individually but doesn't state a single headline average for it the way it does for accuracy, so treat 16.6 as an honest summary of real numbers rather than a quoted claim. Either way, the two-stage generate-then-summarize abduction process from Chapter 2 isn't a stylistic preference — it measurably produces factors that cover more of the conditions people actually write.
BIRD's probabilities also transfer as a training signal: fine-tuning a T5-large model with BIRD-estimated soft probabilities instead of hard labels raised average cross-domain accuracy from 67.9% (hard-label supervision) to 68.9% — a +1.0 point gain. A second base model tested the identical setup: PatternTime rose from 69.7% to 71.2%, a +1.5 point gain. The two gains aren't identical — averaged together they land near +1.3 points, which is the useful one-line summary, but the honest version is two different models each showing a real, positive gain of a different size, not one number reproduced twice. And when BIRD is used to generate a yes-or-no follow-up question targeting an unobserved factor, crowdworkers preferred BIRD's question over a directly-generated one 52.8% of the time, versus 32.8% for the direct question (14.4% tied) — on 250 Common2sense examples, that's 132 BIRD wins, 82 direct wins, 36 ties, and 132+82+36 checks out to exactly 250.
A results table is only as trustworthy as the human judgments it's measured against, so it's worth seeing how those 350 examples were collected. The paper recruited 386 distinct MTurk annotators, restricted to workers with a 98%+ HIT acceptance rate located in the US, capped at 5 examples per annotator, and paid for at least one minute of consideration per example ($15/hour effective rate). Each example first got 5 independent labels; if fewer than 4 of 5 agreed (under 80%), 2 more annotators were added and the example was accepted only if 5 of the resulting 7 agreed (over 70%). The final 350-example set breaks down as 44.0% labeled “condition 1 wins,” 43.7% “condition 2 wins,” and 12.3% “tied” — close to balanced, which is exactly what you want from an evaluation set: a model that always guesses the majority class shouldn't be able to coast to a high score.
The unknown-rate ordering — Today worst at 54.0%, then Common2sense at 34.6%, then Plasma best at 31.4% — tracks exactly the complexity ordering Chapter 3 used to justify its per-dataset entailment settings (x=1, mostly-direct prompting for Today; x=2, mostly-hierarchy for the other two). This isn't two independent facts landing in the same order by chance: a dataset whose conditions are dense and implicit enough to need the more conservative, per-value direct entailment prompt is, for the identical reason, a dataset where more conditions will fail to entail any factor value cleanly. The unknown rate is a downstream symptom of the same underlying difficulty the entailment-prompt choice was already responding to.
Table 3's five evaluation columns hide two details worth surfacing. “Today (exp)” is a variant of the Today benchmark evaluated with gold explanations supplied at test time — a strictly easier setting than the plain “Today” column right next to it, which explains why every row scores higher in the (exp) column than the plain one. And PatternTime is simply a second base model the paper reruns the identical hard-label-vs-BIRD-prob comparison against, independent of T5-large — its exact architecture isn't the point; what matters is that a real, positive gain (+1.0 for T5-large, +1.5 for PatternTime) shows up under a second, differently-built model, which is the detail that turns “soft probabilities helped once” into “soft probabilities help in general,” the standard you'd want before trusting a training-signal claim on your own model.
The soft-label distillation result deserves one more layer: the experiment fine-tunes a T5-large model, adding Common2sense instances (only the ones where BIRD's estimated probability supports the correct outcome) on top of an existing training set, then evaluates cross-domain on two temporal-reasoning benchmarks (Matres, Tracie) and two others (Today, Plasma) the model was never fine-tuned on directly. Training with BIRD's soft probabilities (a continuous target, e.g. 0.72) instead of hard labels (a discrete 0 or 1) gives the downstream model a gradient signal proportional to how confident BIRD actually was — an easy, confidently-73%-supported instance and a borderline 51%-supported instance both count as “correct” under hard labels, but only the soft-label loss tells the smaller model to trust the first one more than the second. The result held on a second base model (PatternTime) too, with a comparable +1.5-point gain (against T5-large's +1.0) — consistency in direction, even without identical magnitude, across two different base architectures is meaningfully stronger evidence than a single result.
F1 is the harmonic mean of precision and recall:
where precision is “of the times the method predicted a given label, how often was it right,” and recall is “of the times that label was actually correct, how often did the method catch it.” The harmonic mean (rather than a simple average) specifically punishes a method that's strong on one of the two and weak on the other — a method with 90% precision but 10% recall on a label scores an F1 near 18%, not 50%, because the harmonic mean is dragged down toward its smaller input. That matters here because the “Same” label is the minority-feeling case (12.3% of the human-labeled set, versus 44.0% and 43.7% for the two “different” labels) — a method that never predicts “tied” would still post a respectable-looking overall accuracy while scoring an F1 near zero specifically on that category, which is exactly the kind of failure the per-category breakdown in the table above is designed to expose.
The EC (Explicit Comparison) baseline's advantage is easiest to see as a concrete input/output contrast. Under the standard setting BIRD and the other baselines are scored in, the model sees one condition at a time and has to output an independent probability for it — call it twice, once per condition, and compare the two returned numbers afterward. Under EC, the model sees both conditions in the same prompt and just picks the winner directly — a single classification call with the comparison built in, rather than two separate probability estimates that then need to agree with each other after the fact. Seeing both options side by side and picking the better one is mechanically easier than scoring each in isolation and hoping the two scores end up correctly ordered; it's the difference between a multiple-choice question and two separate open-ended ones that happen to need consistent answers. That EC still loses to BIRD by roughly 5 points despite this structural advantage is why the paper itself calls the EC comparison unfair to BIRD, not the reverse.
The real four-column table above, as grouped bars. Watch the “Same” group especially — it's where the gap is widest.
It's worth being disciplined about which differences in Chapter 7's tables deserve real weight. The F1 comparison (Table 1) is measured on 350 human-labeled examples — a modest evaluation set, appropriate for the F1 gaps under discussion (0.052, 0.089, 0.303) because they're all far larger than sampling noise on 350 examples would plausibly produce, but not large enough to trust differences of a point or two between close variants. The hard-label accuracy comparison (Table 2) runs on the full datasets — 1,000 (Today), 3,822 (Common2sense), 1,395 (Plasma) instances — which is why the paper is willing to draw a real conclusion from Today's accuracy gap (73.9% vs. 71.5%, a 2.4-point BIRD win) while treating Common2sense's similarly-sized gap in the other direction (89.0% vs. 93.8%, a 4.8-point CoT win) as a genuine, not noise-level, result too — both gaps are measured against thousands of instances, not the smaller 350-example F1 set. The general rule worth carrying forward: a table's trustworthiness is bounded by its smallest evaluated subset, and the honest response to a close call on a small sample is to say so, not to round it into a confident claim.
Chapter 0 opened with a concrete downstream rule: default to the long cord if P < 0.4, ask a follow-up question if 0.4 ≤ P ≤ 0.6, otherwise default to the short cord. It's worth translating BIRD's F1 advantage over the EC baseline — 0.592 vs. 0.540, a 5.2-point gap — back into that concrete frame, because an F1 difference on an abstract benchmark can otherwise feel disconnected from what actually changes for a user running that rule.
F1 measures how well a method's judgments rank against human judgments across the whole evaluation set, not how often any single number crosses a specific threshold — so a 5.2-point F1 gap doesn't mean “5.2% of decisions flip.” What it does mean, concretely: on the borderline cases near a threshold like 0.4 or 0.6 — the ones where the downstream rule's behavior actually depends on getting the number right, not just roughly in the right direction — the method with the higher F1 is measurably more likely to land on the side of the threshold a human labeler would agree with. And EC's own structural advantage (seeing both conditions at once, this chapter's earlier footnote on why EC is an easier question) makes this gap conservative, not generous, toward BIRD: EC gets to use side-by-side context BIRD is denied, and BIRD still comes out 5.2 points ahead.
This is the same argument Chapter 0 made in the abstract, now closed with a real number instead of a placeholder: a downstream system gating on a probability doesn't need that probability to be perfect, but it does need small differences near a threshold to be trustworthy rather than noise. F1's measured gap is exactly the kind of evidence that distinguishes “trustworthy near the threshold” from “might as well be random near the threshold” — the second description being precisely where Chapter 0's four sub-random direct-prompting baselines lived.
Time to stop tracing one fixed example and build your own. This simulation is the entire pipeline from Chapters 3 and 4 running live: you define up to four factors, decide for each one whether the condition observes it and how strongly it leans, and watch P(O1|C) recompute in real time — via the exact Eq. 4 combination and Eq. 2/8/9 marginalization you hand-computed in Chapter 5.
Four factor rows. For each: toggle observed (the condition entails one specific value) or unobserved (the condition never mentions it, so BIRD spreads probability uniformly — Eq. 9). When observed, pick how strongly that value leans: strongly O1 (90%), leans O1 (75%), neutral (50%), leans O2 (25%), or strongly O2 (10%). Watch the per-factor odds bars on the right and the combined gauge at the bottom — and notice how adding an unobserved factor never changes the answer at all, while flipping one observed factor's lean can swing it hard.
1. Leave every factor unobserved, then observe just one at the extreme (90% or 10%). Watch P(O1|C) move from exactly 50% to somewhere well past it in one step — but not all the way to 90%. A single strong factor pulls hard, but Eq. 4 still averages it against the neutral 50%-weighted mass of the other unobserved factors sitting in the sum; it doesn't dominate outright until more factors corroborate it, echoing the “agreement compounds” arithmetic from Chapter 4.
2. Set two factors to opposite extremes (one at 90%, one at 10%) and leave the rest unobserved. This is Chapter 4's conflicting-evidence example, scaled to a live UI: watch the combined answer snap back toward 50%, then nudge just one of the two slightly (say 90% → 85%) and watch how little that changes it — symmetric conflict is a stable equilibrium, not a coin flip that any small perturbation breaks.
3. Toggle a factor from unobserved to observed-neutral (50%). This should do nothing to the final number. If it visibly moves the gauge in your build, something violates Eq. 9 — a neutral, observed factor and a symmetric, unobserved factor should marginalize to the identical contribution, and BIRD's own math guarantees they do.
4. Observe all four factors at a mild, identical lean (say, all four at 60%). No single factor is individually convincing — 60% is barely more than a coin flip — but watch the combined answer climb well past any one of them. This is worked example 3 from Chapter 4, generalized to four factors instead of three: independent, weakly-agreeing evidence keeps compounding as you add more sources, the same mechanism that makes four so-so witnesses more convincing together than any one alone.
5. Reproduce Chapter 5's Stage 1 exactly, then check the widget against your own hand arithmetic. Set FA observed at 25% (a2, leans O2), and leave the other two unobserved at 50%. The gauge should read 32.1% — the same number you computed by hand in Chapter 5's Stage 1. If your build shows something else, the bug is almost always a marginalization order-of-operations mistake: Eq. 4 combines the per-factor probabilities first, for each fully-specified world, and only then do you average those combined values across the unobserved worlds — averaging the raw factor probabilities before combining them is a different (and wrong) computation.
| Symptom | Likely bug | Where it's covered |
|---|---|---|
| Answer is stuck near 50% no matter what you observe | Averaging raw per-factor probabilities before combining, instead of combining first (Eq. 4) then averaging surviving worlds (Eq. 1–2) | Chapter 5 |
| Toggling a factor to unobserved changes the answer even when its value was already neutral (50%) | Unobserved factors coded as something other than a flat 0.5 — e.g. accidentally weighting toward whichever value appears first in a list | Chapter 3, Eq. 9 |
| Combined probability exceeds 1.0 or goes negative | Eq. 4's denominator forgot the complement term — it must be numerator ÷ (numerator + complement-product), not numerator ÷ complement-product | Chapter 4, Eq. 4 |
| A “neutral” classification from pruning got coded as 0% or 100% instead of 50% | Confusing “neutral” (Eq. 5's middle case) with “supports the opposite outcome” (25%) — they are different labels with different numeric targets | Chapter 2, Eq. 5 |
| Two conditions that a human would call a tie produce noticeably different probabilities | Entailment mapped the two conditions onto different factor values when they should have mapped onto the same ones — check the entailment step, not the combination formula | Chapter 3 |
The widget is most useful when you arrive with a scenario already worked out on paper, then use the sliders to check your hand computation — not the other way around. Fill in the blanks for a decision you actually care about:
| Slot | Your answer |
|---|---|
| Scenario S | … a one-sentence situation with a genuine two-way choice |
| O1 / O2 | … two complementary outcomes (if you can't state the opposite of O1 in one sentence, your outcomes aren't complementary yet) |
| Factor 1, 2, 3… | … name 2–4 things that would change your answer if you knew them — not facts you already know, dimensions along which the truth is currently unknown |
| For each factor: which value supports which outcome, and how strongly (75/50/25, or your own trained-style estimate) | … be honest about which ones you're genuinely unsure of — those are 50%, not a guess dressed up as 75% |
| Condition U you actually have right now | … which of your factors does it observe? Leave the rest unobserved, deliberately |
Work out P(O1|C) by hand using Eq. 4 and the marginalization pattern from Chapter 5, then enter the same setup into the widget above and confirm the gauge agrees. If it doesn't, you've either made an arithmetic slip or found a genuine bug — the troubleshooting table just above tells you which is more likely given the specific symptom. This is the single most useful exercise in the entire session for retention: everything up to this point has been watching this session's authors' arithmetic; this is the first time it's yours.
Two worked answers, so you have something to check a first attempt against before consulting the widget. Take “deciding whether to accept a job offer,” O1 = accept: factors might be compensation (well above market → 85%), team fit from the interview loop (mixed signals → unobserved, 50%), and commute (much longer than current → 20%). With compensation and commute observed, team fit unobserved: numerator = 0.85 × 0.5 × 0.20 = 0.085; complement = 0.15 × 0.5 × 0.80 = 0.06; P(accept) = 0.085 ÷ 0.145 ≈ 58.6% — a real number, closer to a coin flip than either factor alone would suggest, which is exactly what “great pay, bad commute” should feel like. Or “whether to refactor a piece of code before shipping,” O1 = refactor first: factors could be how much the code will be touched again (frequently → 80%), how close the deadline is (very close → 15%), and test coverage (good coverage → unobserved here, 50%). Work out your own number before checking it against the widget.
python def aggregate(factor_rows): # factor_rows: list of {observed: bool, lean: float} — lean is P(O1 | this value) when observed p_per_factor = [row['lean'] if row['observed'] else 0.5 for row in factor_rows] return eq4(p_per_factor) # same eq4() from Chapter 4 — nothing new
That is genuinely the whole widget. There is no separate “unobserved-factor logic” branch inside the aggregation step itself — an unobserved factor contributes exactly 0.5 to Eq. 4's product, the same value a fully-observed, perfectly-neutral factor would contribute. Chapters 3 and 4 built two ideas that look different on paper (marginalization over a whole information space; log-odds combination of individual factors) and this widget is the demonstration that, once you fix “unobserved → 0.5,” they collapse into one function you can fit in four lines.
Every worked example so far used the charging-cord scenario, and it would be reasonable to worry the arithmetic secretly depends on it. It doesn't — here is a completely different scenario, hand-specified the same way, that you can punch directly into the widget above to check.
Scenario: “deciding whether to bring an umbrella.” O1 = bring it, O2 = leave it home. Three abducted factors: Fsky (gray vs. blue), Fforecast (rain predicted vs. not), Fhistory (you've been caught without one before vs. you always check the forecast and it's been reliable). Suppose today's condition entails gray sky and a rain forecast, and says nothing about your history with forecasts:
Two strongly agreeing, independently-observed factors (0.80 and 0.90) compound to 97.3% confidence — even with a third factor sitting completely unobserved at its neutral 0.5. Set the widget's three rows to these exact numbers (two observed at 0.80/0.90, one unobserved) and you should see the gauge land at 97.3%, confirming that nothing in Eq. 4 or Eq. 9 was ever specific to cords, factors named FA/FB/FC, or the particular scenario this session used to build intuition. The math is the scenario-agnostic part; only the factor names and their supporting sentences come from abduction (Chapter 2), which is genuinely scenario-specific.
The umbrella example above stacked two strong, agreeing factors (0.80 and 0.90) to reach 97.3%. It's worth pushing that pattern one step further by hand, because “compounding” can otherwise sound like a vague intensifier rather than an arithmetic fact with a specific shape. Take three factors, all only moderately confident on their own — 0.80, 0.80, and 0.80 — all independently observed and all agreeing:
Three factors, none individually more confident than “fairly sure,” combine to 98.5% — past the two-factor umbrella example's 97.3%, and closing in on certainty fast. Push it to five agreeing factors at 0.80 each and the complement term shrinks to 0.25 = 0.00032 against a numerator of 0.85 ≈ 0.328, landing at P ≈ 0.999. Set the widget's four rows to four agreeing factors near 0.80–0.85 each and watch the gauge push hard toward one extreme — not because any single row is dramatic on its own, but because independent, agreeing evidence compounds multiplicatively, not additively, and multiplicative compounding saturates fast.
Compare this directly to Chapter 6's real ablation numbers: even the crudest variant (1/2 assumption, unanimous-agreement-only, 0.480 average F1) already clears GPT-4 chain-of-thought's 0.289 by a wide margin, precisely because factors that individually classify only coarsely still compound once several of them agree — the same multiplicative mechanism this widget lets you feel under your own fingers, not just read as a formula on a page.
Eq. 4 looks like decision-theory notation, but it is secretly something you already know from the rest of this course. Divide the numerator and denominator of Eq. 4 by ∏j(1−P(Oi|fj)):
That's exactly the algebraic form of a sigmoid: σ(x) = 1 ÷ (1 + e−x), which equals O ÷ (O+1) when x = ln(O). And ln(O) = ∑j ln(oddsj) — the sum of each factor's logit (log-odds). Put together:
That is precisely the shape of a logistic regression with every weight fixed at 1 and no bias term — sum the logits, squash with a sigmoid. If you've built a classifier head on top of a language model, you've already implemented this exact operation; BIRD's “novel Bayesian combination formula” is, once you strip the decision-theory framing, the single most standard operation in this entire course, applied to per-factor LLM judgments instead of learned neural weights.
| P(Oi|fj) | 0.10 | 0.25 | 0.50 | 0.75 | 0.90 |
|---|---|---|---|---|---|
| logit | −2.197 | −1.099 | 0.000 | 1.099 | 2.197 |
This table is exactly what the widget's sliders are secretly manipulating: moving a factor's lean from 50% to 90% is moving its logit contribution from 0 to +2.197; two factors both at 75% sum to a combined logit of 2.197, and σ(2.197) = 0.9 — matching worked example 1 from Chapter 4 exactly. Unobserved factors contribute a logit of exactly 0 (neither pushing the sum up nor down), which is the algebraic reason “unobserved” and “observed-at-50%” are indistinguishable to the final answer — they contribute the identical zero to the sum.
BIRD is not a solved problem wearing a bow. It has two real, quantified weaknesses, and knowing exactly where they bite is what makes the difference between using this framework well and deploying it somewhere it quietly fails.
Before the failure modes, one honest accounting: nothing in this session was free. Tally the LLM calls per scenario. Abduction (Chapter 2): 2 generation calls (10 sentences per outcome) + 1 summarization call = 3. Pruning and initialization (Chapter 2, this chapter's earlier note): 3 samples × N factors for the majority-vote classification. For our running 3-factor example, that's 9 calls, one-time, reusable forever. Per condition, entailment (Chapter 3) costs up to 3 samples × (1 + N) calls under the hierarchy prompt, or 3 × (values per factor × N) under the direct prompt — for our example, roughly 12 calls per new condition. Compare that to the naive baseline from Chapter 0: one call. BIRD is somewhere between 3× and 20× more expensive per scenario in raw API calls, concentrated almost entirely in the one-time abduction and pruning cost, with entailment adding a smaller, recurring cost per condition. That is the real trade this session has been making since Chapter 0: engineering and inference cost, spent once per scenario, in exchange for a probability that a downstream system can actually act on — the same “compute per request vs. engineering per capability” tradeoff that shows up whenever a single fluent guess is replaced with a structured, checkable pipeline.
You already have the numbers from Chapter 7: 54.0% unknown on Today, 34.6% on Common2sense, 31.4% on Plasma. Every one of these is a case where entailment (Chapter 3) couldn't map the condition onto any factor — not a wrong answer, an absent one. The paper's own diagnosis: this is “due to the imperfect or incomplete abductive factors generated by the LLM, and not a fundamental flaw of BIRD” — a solvable engineering gap (better factor coverage), not a limit of the math. But it is a real, present-tense cost: on Today, more than half of all instances currently need a chain-of-thought fallback, which reintroduces exactly the uncalibrated-probability problem from Chapter 0 for those cases.
The paper documents a specific instance where chain-of-thought's lack of structure is an advantage. Scenario: choosing between habanero peppers and jalapeño peppers for spiciness. Condition: the recipe uses “a significant amount of habanero peppers relative to other ingredients.” The correct answer — habanero makes it hotter — follows from general knowledge about the Scoville scale, which chain-of-thought reaches directly. But the condition's actual content (a quantity claim) doesn't map cleanly onto a pre-abducted factor about which pepper is used at all; a rigid factor structure can miss a side-signal like this that raw, unstructured context handles by brute-force association.
This one isn't in the paper's results tables — it's a structural risk worth naming because Chapter 2 leaned on it and Chapter 4's whole derivation assumes it away. Equation 4 treats every factor's contribution as independent evidence, multiplying odds together. If two abducted factors are secretly correlated — say “paces around the room” and “prefers an open floor plan” both got kept as separate factors, but in practice almost every scenario that entails one also entails the other — then observing both doesn't give you two independent pieces of evidence, it gives you the same piece of evidence counted twice. Eq. 4's multiplicative combination would then overstate confidence, the same way a naive-Bayes spam filter over-trusts two correlated features more than a single one warrants. Chapter 2's pruning step guards against irrelevant factors (the neutral ones); it does not explicitly test for redundant factors that pass the relevance test individually but overlap with each other. This is a gap the abduction step's “least relevant to each other” instruction is aimed at closing by prompting alone, not one the deductive math itself verifies.
Failure 3 is easiest to trust once you've watched it happen in real arithmetic, not just read the argument in prose. Suppose abduction genuinely produces two “separate” factors that are, in reality, the same underlying evidence restated — say Fpace (“you'll be pacing around the room”) and Fopen (“you prefer an open floor plan”), where in this population almost everyone who paces also happens to prefer open floor plans, and vice versa. Both get classified, honestly and correctly in isolation, as each individually supporting O2 (longer cord) at the same strength as FA did earlier in this session — 75% toward O2, i.e. P(O1|value) = 0.25 each.
Treat them as independent, the way Eq. 4 always does, and observe both:
Ninety percent confidence in O2, from what the framework treats as two independently corroborating pieces of evidence. But if Fpace and Fopen are really the same fact wearing two names — if knowing one already tells you the other with near certainty in this population — then the condition only actually supplied one genuine piece of evidence, and the honest answer should stay near where a single such factor alone would land: 25% (i.e. 75% confidence in O2), not 10% (90% confidence). That's a 15-percentage-point overconfidence artifact, purely from double-counting one piece of evidence as two — and it gets worse, not better, the more correlated near-duplicate factors survive pruning, because each additional near-duplicate multiplies the same odds ratio back in.
The paper names imperfect factor generation as the root cause of Failure 1 and calls better coverage future work, without specifying a fix. A few concrete directions follow naturally from what Chapter 2 already showed matters: sampling more than ten situations per outcome in stage 1 (more raw material for the summarization step to draw distinct factors from); running entailment with a wider net — checking against near-synonyms of each factor value, not just exact implication; or allowing multi-hop entailment, where a condition implies an intermediate fact that in turn implies a factor value, rather than requiring the factor value to be implied in one step. None of these change Equations 1–9 — they're all upstream, in Chapter 2 and Chapter 3's territory, which is exactly why the paper calls the current unknown rate an engineering gap rather than a mathematical limit.
| You need… | Reach for | Why |
|---|---|---|
| A single hard-label decision, and you'll accept an unexplainable answer | Chain-of-thought + self-consistency | Higher raw accuracy on 2 of 3 tested datasets; no “unknown” outputs to route around |
| A probability you can act on downstream (thresholds, ranking, follow-up logic) | BIRD | More than double the F1 against human judgment; the only method that reliably distinguishes two conditions rather than returning a flat guess |
| The same scenario asked under many different conditions over time | BIRD | Abduction (Chapter 2) is computed once and reused; every new condition is cheap entailment + arithmetic, not a fresh reasoning chain |
| A training signal for a smaller downstream model | BIRD's soft probabilities | +1.3 points over hard labels, reproduced across two base models (Chapter 7) |
| An interactive agent that should ask a good follow-up question | BIRD's unobserved-factor targeting | Preferred by humans 52.8% vs. 32.8% over a directly-generated question (Chapter 7) |
BIRD's marginalization (Eq. 1–2) is the law of total probability, applied to text instead of numbers. If the phrase “sum over the complete information space, weighted by how consistent each state is with what you observed” felt familiar, it should — it's the same operation a robot performs every time it updates a belief about where it is:
That's not a loose metaphor. A Bayes filter maintains a belief distribution over where a robot is, updates it with predict (apply a motion model, spreading uncertainty — the direct analogue of Chapter 3's “unobserved factor → uniform” treatment) and correct (fold in a sensor reading, concentrating probability on states consistent with it — the direct analogue of Chapter 3's “observed factor → probability 1 on the entailed value”). BIRD's C = (S, U) plays the role of the accumulated sensor readings; F plays the role of the state space; Eq. 1's marginalization sum is, symbol for symbol, the same operation. The domains differ — centimeters and radians versus factor values and outcomes — the update rule doesn't.
| Eq. | Statement | One-line meaning | Built in |
|---|---|---|---|
| 1 | P(Oi|C) = ∑f P(Oi|f)P(f|C) | Marginalize over every fully-specified world, weighted by consistency with what you observed | Ch.1 |
| 2 | … = ∑f P(Oi|f) ∏j P(fj|C) | Same, assuming factors are conditionally independent given C | Ch.3 |
| 4 | P(Oi|f) = ∏P(Oi|fj) ÷ [∏P(Oi|fj) + ∏(1−P(Oi|fj))] | Combine independent per-factor judgments into one, equal weights, 50% prior | Ch.4 |
| 5 | Pinit ∈ {25%, 50%, 75%} | Coarse three-way classification seeds every factor value's starting probability | Ch.2, 4 |
| 6 | Ptrained(Oi|fj) = average of Eq.4 over the remaining factors | The direction-check used by the margin-ranking loss during training | Ch.6 |
| 8 | P(fj|C) ∈ {0, 1} | An observed factor collapses all weight onto its entailed value | Ch.3 |
| 9 | P(fj|C) = 1 ÷ |Fj| | An unobserved factor spreads weight uniformly — honest ignorance | Ch.3 |
The shortest path from this session to a working prototype on a scenario of your own choosing runs through four questions, in order. One: can your decision be framed as two complementary outcomes, or decomposed hierarchically into a sequence of such choices (Chapter 1)? If your options aren't naturally binary, this framework doesn't directly extend without that decomposition step. Two: can an LLM generate 8–10 free-form situations per outcome that a domain expert would recognize as plausible and distinct (Chapter 2)? If the domain is unfamiliar enough that the LLM's abduction step produces generic or repetitive factors, expect a higher unknown rate downstream, for the same reason Today's unknown rate (54%) exceeds Plasma's (31.4%) — harder-to-abduct domains propagate difficulty forward. Three: do you have, or can you cheaply construct, 350-ish human-labeled examples to validate against, in the style of Chapter 7's evaluation (not to train on — Chapter 6's 128 training instances are self-supervised from the LLM, but you still need an external check that the whole pipeline is producing sane numbers)? Four: is your deployment tolerant of an explicit “unknown,” with a fallback path, or does it require an answer every time? If the latter, budget for a CoT (or similar) fallback exactly as Chapter 7's Today/Common2sense/Plasma evaluations did, and expect the fallback rate to be substantial until your factor generation is well-tuned to the domain.
This session showed a Bayesian model bolted onto an LLM, with the LLM supplying structure and judgments and a fixed formula doing the arithmetic. The next reasoning session in this course turns the question around: what happens when you let the model reason step by step and spend variable compute doing it — test-time compute, process reward models, and the tradeoffs between thinking longer and thinking structured. Keep BIRD's core lesson with you going in: a probability is only as trustworthy as the process that produced it, and fluency is not that process.
| Feng, Y., Zhou, B., Lin, W., & Roth, D. (2024). BIRD: A Trustworthy Bayesian Inference Framework for Large Language Models. arXiv:2404.12494 |
| Bordley, R. F. (1982). A multiplicative formula for aggregating probability assessments. Management Science, 28(10), 1137–1148. — source of the log-odds pooling formula behind Eq. 3–4. |
| Wei, J. et al. (2022). Chain-of-thought prompting elicits reasoning in large language models. NeurIPS. — the CoT baseline BIRD is measured against throughout. |
| Feng, Y., Zhou, B., Wang, H., Jin, H., & Roth, D. (2023). Generic temporal reasoning with differential analysis and explanation. ACL. — source of the Today dataset and problem formulation BIRD builds on. |
| Koller, D., & Friedman, N. (2009). Probabilistic Graphical Models: Principles and Techniques. MIT Press. — the Bayesian-network framing Chapter 2 and Chapter 9 draw on for BIRD's factor structure. |
| Xiong, M. et al. (2024). Can LLMs express their uncertainty? An empirical evaluation of confidence elicitation in LLMs. ICLR. — source of the finding, cited in Chapter 1, that verbalized LLM confidence tends toward overconfidence. |
| Kadavath, S. et al. (2022). Language models (mostly) know what they know. arXiv:2207.05221. — representative of the logit-based calibration methods contrasted with BIRD in Chapter 1. |
| Singh, S. et al. (2021). COM2SENSE: A commonsense reasoning benchmark with complementary sentences. Findings of ACL-IJCNLP. — source of the Common2sense dataset used throughout Chapter 7. |
| Brahman, F. et al. (2023). PlaSma: Making small language models better procedural knowledge models for (counterfactual) planning. — source of the Plasma dataset used throughout Chapter 7. |
The paper opens by promising three properties — interpretable, controllable, trustworthy — and it's worth closing by checking each one against what this session actually demonstrated, rather than taking the labels on faith.
| Claim | Where this session verified it |
|---|---|
| Interpretable — the factor structure shows the reasoning, and BIRD outputs a probability with an audit trail | Chapter 5's instance ledger: every stage's number decomposes into named factor values and their individual contributions, not a black-box scalar |
| Controllable — the same condition always maps to the same factors; the final number depends only on what got entailed | Chapter 1's three-condition table: different phrasings, same fixed factor structure; Chapter 3's weight-assignment code, which is a pure function of entailed values |
| Trustworthy — more aligned with human judgment than direct prompting, and honest when it lacks enough information | Chapter 7's F1 and ablation tables (quantitative); Chapter 9's unknown-rate discussion (honesty about limits, rather than a confident wrong answer) |
All three hold up under the numbers this session walked through by hand — not as marketing language, but as properties with specific chapters and specific arithmetic behind them. That traceability, more than any single F1 number, is the actual deliverable of routing probability estimation through abduction and deduction instead of a single fluent guess.