mixle.task.sft_plan module¶
sft_planner – trace-SFT for generating tool plans with parser-gated validation.
The generative rung above distill_planner(). The step-students decompose by
classifying the next action; this trains a small causal LM (LM) on serialized teacher
traces with the prompt-masked SFT objective (LM.fit_pairs) so the whole plan is generated:
request \n=> tool(k=v; k=v) | tool(k=v) | done \n
Free-form generation needs a strict validation boundary. The emitted text must parse under the plan grammar, every tool must exist, and every required argument must be present. Anything else escalates to the teacher and the trace is harvested. The model may emit arbitrary text, but only verified plans leave the function.
What this adds over the step-students (and what it does not): one model covers every tool with variable-length plans and can generalize over entity values it did not see during training. It does not infer unsupported tool compositions from absent traces; those cases escalate for teacher handling and future data collection.
- class GenerativePlanner(lm, codec, tools, teacher, plan_agreement, max_new=160, constrained=True, conf_floor=None, lm_config=<factory>, n_requests=0, n_escalated=0, harvested=<factory>)[source]
Bases:
objectA plan-writing LM behind a parse-and-validate gate: only verified plans leave; the rest escalate.
- Parameters:
- lm: Any
- codec: _CharCodec
- plan_agreement: float
- max_new: int = 160
- constrained: bool = True
- lm_config: dict
- n_requests: int = 0
- n_escalated: int = 0
- try_plan(request)[source]
Generate, parse, validate (grammar + specs + copy-fidelity);
None= must escalate.With
constrained=True(default) the decode itself runs inside the plan grammar (mixle.task.constrained.constrained_plan_decode()): malformed text and copy-drifted values are unrepresentable, and the parse/validate below is a pure backstop.
- save(path)[source]
Persist the plan-writing LM (weights + builder config), codec, specs, and gates;
load()restores.
- sft_planner(teacher, requests, tools, *, holdout=0.2, seed=0, d_model=96, n_layer=3, n_head=4, block=192, epochs=30, lr=3e-3, device='cpu', constrained=True)[source]
Trace-SFT a small causal LM into a plan writer, verified on held-out requests.
Traces serialize as
request\n=> tool(k=v; ...) | ... \npairs;LM.fit_pairstrains with the prompt masked so only plan tokens carry loss; generation stops at newline. Held-out agreement is plan-level exact match (tools + required args, in order) on requests the LM never saw.