mixle.task.toolcall module¶
distill_tool_caller – train a tiny model to do function calling, with the honesty contract.
Tool calling decomposes into two problems the task spine already solves, composed under one gate:
which tool (or none) – a calibrated classification student (
solve()over the request text: conformal answer-or-escalate + optional OOD gate);the arguments – one token-level extractor per tool (
distill_extractor()), distilled from the teacher’s own argument fills.
teacher(request) -> {"tool": name, "args": {...}} ({"tool": None} for no-op) is whatever does the
job today – a frontier LLM behind mixle.task.llm, an agent loop, or a rule. The returned
ToolCaller emits a call ONLY when the selector is conformally confident AND every required
argument extracts; anything else escalates to the teacher – a malformed or guessed call is never
emitted silently. Escalations are harvested as traces for the next distillation round, exactly like
solve.
This covers single-step function calling. Multi-step planning / problem decomposition is NOT claimed
here: that needs trace-SFT on the causal LM (the primitives exist – LM.fit + the SFT loss-mask)
and an execution-verified loop, and is tracked as its own rung.
- class ToolSpec(name, args, required=None)[source]
Bases:
objectOne callable tool: its name and the argument fields to extract from the request text.
- name: str
- class ToolCaller(selector, extractors, tools, teacher, selection_agreement, n_requests=0, n_escalated=0, harvested=<factory>)[source]
Bases:
objectA distilled function-caller: emit a call only when selection AND arguments are trustworthy.
- Parameters:
- selector: Solution
- selection_agreement: float
- n_requests: int = 0
- n_escalated: int = 0
- try_local(request)[source]
The local decision alone: a trustworthy call / no-op, or
None(= must escalate).No teacher, no stats — this is what a server without the frontier can run.
- save(path)[source]
Persist selector + per-tool extractors + specs as one artifact directory;
load()restores.
- distill_tool_caller(teacher, requests, tools, *, seed=0, selector_kw=None, extractor_kw=None)[source]
Distill the teacher’s function-calling into a tiny selector + per-tool argument extractors.
- Parameters:
teacher (Callable[[str], dict]) –
teacher(request) -> {"tool": name-or-None, "args": {field: value}}— the frontier LLM / agent / rule currently doing the calling. It labels everything; it remains the fallback.requests (Sequence[str]) – example request texts covering the tools.
tools (Sequence[ToolSpec]) – the tool specs (names + argument fields;
requireddefaults to all).extractor_kw (dict | None) – knobs forwarded to
solve()anddistill_extractor().seed (int)
selector_kw (dict | None)
extractor_kw
- Return type:
ToolCaller