Uncertainty¶
mixle has several uncertainty surfaces, all with the same design bias:
uncertainty should change behavior. It should decide whether to answer,
escalate, collect more data, or report which evidence source mattered.
This page covers:
uncertainty over LLM answers;
claim-level reliability for generated text;
epistemic versus aleatoric decomposition;
the
uqdispatcher for fitted models, point predictors, ensembles, and LLM-like callables;conformal answer-or-abstain behavior;
cross-modal latent evidence fusion;
calibrated task cascades.
Unified uq Dispatcher¶
mixle.inference.uq provides one front door when the caller owns a
heterogeneous predictor and wants Mixle to choose an uncertainty route from the
object’s capabilities.
from mixle.inference import uq
fitted_uq = uq(model, training_rows)
interval_uq = uq(point_predictor, (x_cal, y_cal), alpha=0.1)
llm_uq = uq(generate, example_prompts, alpha=0.1)
UQResult exposes method-specific accessors:
sample_modelsandcredible_intervalfor fitted Mixle models through a Laplace parameter posterior;intervalandepistemic_stdfor point predictors or ensembles through split conformal calibration;semantic_entropyandconfidentfor LLM-style generation callables.
Use the specialized APIs below when you already know the exact uncertainty
method. Use uq when the application boundary should accept several kinds
of predictor behind one call.
LLMUncertainty¶
LLMUncertainty wraps any stochastic callable:
generate(prompt) -> answer
It samples multiple answers, clusters them by meaning, and returns the majority meaning plus a confidence and semantic entropy.
from mixle.reason import LLMUncertainty
def equivalent(a, b):
return str(a).strip().lower() == str(b).strip().lower()
llm_uq = LLMUncertainty(generate, equivalent=equivalent, n=20)
assessment = llm_uq.assess("Which city is the Eiffel Tower in?")
print(assessment.answer)
print(assessment.confidence)
print(assessment.semantic_entropy)
print(assessment.clusters)
High confidence means most samples fell into the same meaning cluster. High semantic entropy means the model is disagreeing with itself about the answer, not just rephrasing it.
These quantities are decision signals, not truth guarantees. Use retrieval, tools, labels, or human review when factual correctness matters.
Equivalence Matters¶
The default equivalence relation is exact equality. That is fine for labels or normalized short answers. For prose, pass a domain-specific relation:
import re
def normalize_city(text):
return re.sub(r"[^a-z]", "", text.lower())
llm_uq = LLMUncertainty(
generate,
equivalent=lambda a, b: normalize_city(a) == normalize_city(b),
n=20,
)
In production this relation might use canonicalization, embeddings, entailment, or a task-specific parser.
Version the equivalence relation with the artifact. Changing it changes the clusters, confidence, entropy, and abstention threshold.
Epistemic and Aleatoric Split¶
Use several prompts as ensemble members, for example paraphrases of the same
question. decompose separates disagreement across members from spread
within each member.
dec = llm_uq.decompose(
[
"Who discovered penicillin?",
"Name the scientist credited with discovering penicillin.",
"Penicillin was discovered by whom?",
],
n=10,
)
print(dec.epistemic)
print(dec.aleatoric)
print(dec.total)
Epistemic uncertainty is reducible uncertainty: model or prompt sensitivity. Aleatoric uncertainty is within-member ambiguity: the question or output space itself remains variable.
Calibrated Answer-or-Abstain¶
Sampling confidence is still only a signal until calibrated. calibrate uses
labeled examples to choose the lowest confidence threshold whose answered set
has empirical error at most alpha.
examples = [
("Capital of France?", "Paris"),
("2 + 2?", "4"),
]
llm_uq.calibrate(examples, alpha=0.1)
answer = llm_uq.answer("Capital of Japan?")
if answer is None:
escalate_to_human_or_frontier_model()
else:
print(answer.answer)
After calibration, answer returns None below the threshold. This is the
important behavioral change: the LLM can abstain instead of hallucinating.
Calibration examples should match the served prompt distribution. A threshold learned on short factual questions should not be reused for extraction, planning, or legal/scientific summaries without new evidence.
Claim-Level Reliability¶
A response can have a stable main answer and still contain one fabricated
detail. assess_claims takes one sampled response, extracts claims, and
checks whether independent samples corroborate each claim.
info = llm_uq.assess_claims(
"Summarize the contract renewal and include dates and parties.",
threshold=0.6,
)
print(info.reliability)
for claim in info.fabricated:
print(claim.claim, claim.support)
Defaults:
claim extraction is sentence-like splitting;
corroboration uses information-weighted content overlap across samples.
For serious text, pass your own extractor or entailment-based corroborator:
info = llm_uq.assess_claims(
prompt,
extract=my_claim_extractor,
corroborates=my_entailment_check,
)
Uncertainty Helpers¶
The underlying decomposition functions are available from
mixle.inference.uncertainty:
from mixle.inference.uncertainty import (
Clustering,
UncertaintyDecomposition,
cluster_samples,
decompose_entropy,
decompose_uncertainty,
decompose_variance,
marginalize_meaning,
posterior_ensemble,
predictive_distribution,
semantic_entropy,
)
Use them when you already have samples, probability vectors, or prediction ensembles and do not need the LLM wrapper.
UncertaintyDecomposition is the shared result object for epistemic,
aleatoric, and total uncertainty summaries. predictive_distribution and
posterior_ensemble build ensemble-style predictive objects from fitted or
posterior models, decompose_variance performs the variance analogue of the
entropy split, and marginalize_meaning aggregates probabilities over
semantic clusters represented by Clustering.
Cross-Modal Reasoning¶
mixle.reason.reason fuses evidence into a shared latent belief. Each
evidence source is a linear-Gaussian observation:
y = H z + noise, noise ~ N(0, R)
Example:
import numpy as np
from mixle.reason import Evidence, Latent, reason
prior = Latent.vector(2, mean=0.0, var=10.0)
evidence = [
Evidence(np.array([[1.0, 0.0]]), np.array([2.0]), 0.2, name="sensor-a"),
Evidence(np.array([[0.0, 1.0]]), np.array([-1.0]), 0.5, name="sensor-b"),
]
ans = reason(prior, evidence)
print(ans.mean)
print(ans.interval(level=0.9))
print(ans.information_gain())
print(ans.attribution(normalize=True))
ReasonedAnswer exposes:
posterior mean and covariance;
credible intervals;
total information gain;
per-modality attribution;
prediction-level epistemic/aleatoric variance split.
Mechanistic Latents¶
Latent.mechanistic builds a Gaussian prior over a trajectory constrained by
a linear dynamical law. Evidence at one time step updates all time steps through
the dynamics.
A = np.array([[1.0, 0.1], [0.0, 1.0]])
prior = Latent.mechanistic(A, steps=20, process_cov=0.01 * np.eye(2))
Use block_selector from mixle.reason.core to observe a specific time
block of the stacked trajectory.
For mechanistic latents, record the dynamical law, process covariance, observation selector, and evidence times. Those assumptions define how one observation updates unobserved trajectory steps.
Task Calibration¶
For local task models, uncertainty becomes an answer/escalate decision through
CalibratedTaskModel and Cascade:
from mixle.task import CalibratedTaskModel, Cascade
model = CalibratedTaskModel(student, alpha=0.1).calibrate(cal_x, cal_y)
cascade = Cascade(model, teacher)
y = cascade("new request")
See Task Distillation for the full serving workflow.
Track answered accuracy and escalation rate together. A cascade that answers too often can be unsafe; a cascade that escalates everything may be correct but not useful.
Choosing the Right Tool¶
Need |
Use |
|---|---|
Does the LLM know the answer? |
|
I have a fitted model or predictor and want Mixle to pick a UQ route |
|
Should the LLM answer or abstain? |
|
Which claim in this answer is suspect? |
|
Is uncertainty due to prompt/model sensitivity? |
|
How do multiple modalities update a latent? |
|
Should a local task model escalate? |
|
Release Evidence¶
For uncertainty workflows, preserve:
sample count, prompt template, model identifier, and sampling settings;
equivalence, claim extraction, and corroboration functions;
calibration examples, alpha, learned threshold, and abstention policy;
false-answer and unnecessary-abstention rates;
evidence model assumptions for cross-modal or mechanistic latents; and
cascade scorecards separating answered quality from escalation behavior.