mixle.task.compose module

Compose two models or teachers while carrying a per-stage ledger.

compose chains two models/teachers a: x -> y and b: y -> z into one callable x -> z while preserving a per-stage evidence ledger that can be reused by composition and belief-walk workflows.

a and b are any callables – a TaskModel, a CalibratedTaskModel, a teacher LLM, or a plain function. A stage that additionally exposes .score(input) -> float (a log-confidence or log-density) contributes that number to the ledger; a stage without one contributes 0.0 (“unscored”, never fabricated). The ledger is purely additive by construction – ComposedAnswer.check() asserts sum(contributions) == total_contribution exactly, the same identity mixle.inference.explain uses for a single model’s evidence.

class ComposedAnswer(answer, intermediate, stages, total_contribution)[source]

Bases: object

A composed x -> z answer plus the per-stage receipt that attributes it to both stages.

Parameters:
check(tol=1e-9)[source]

sum(contributions) == total_contribution – the ledger is exact by construction.

Parameters:

tol (float)

Return type:

bool

class ComposedModel(a, b, *, name_a='stage_a', name_b='stage_b')[source]

Bases: object

Chain a: x -> y then b: y -> z as one callable x -> z.

composed(x) returns the bare answer z (so a ComposedModel can stand in anywhere a plain teacher callable is expected – including as the a or b of another compose(), chaining further). composed.answer(x) returns the ledger-carrying ComposedAnswer instead.

Parameters:
  • a (Callable[[Any], Any])

  • b (Callable[[Any], Any])

  • name_a (str)

  • name_b (str)

answer(x)[source]

Return the composed answer with each stage’s contribution record.

Parameters:

x (Any)

Return type:

ComposedAnswer

compose(a, b, *, name_a='stage_a', name_b='stage_b')[source]

Chain a: x -> y and b: y -> z into one ledger-carrying x -> z callable.

Parameters:
Return type:

ComposedModel