The scripts are in the repository, not in the installed package. Clone it,
then
cd recipes/03-select/character before running the commands below. Browse this recipe on GitHub.Run it
python run.py with the defaults (--seed 0 --k 4). The
student and the judge are both scripted, so this is deterministic:
python measure.py --demo (--seed 0, k=4) plays the untrained and the
“trained” scripted student on the same 36 holdout and control tasks and
runs delta_report(target="marker:trait", must_not_regress=["on_task", "no_filler"]):
--after plays a student that landed the
training, which is what the measure demo compares against.
With a model
You are Sol, an assistant., no constitution), the judge is an LLM
that gets the principle in its system prompt, and judge_vs_spec becomes a
real number. --write-prompts N has the model write N more prompts per
trait, few-shot from the spec’s, split train/holdout by hash. --teacher
samples one more reply per train prompt with the constitution in the system
prompt, the distillation teacher of Maiya et al.; pairs then carry
same_policy=false where the chosen side is the teacher’s.
Leave --judge-url off and the model grades itself. The report still runs;
the judge_vs_spec line is where self-preference shows up: a model grading
its own replies favors them [2].
One live run, hosted Qwen3-4B-Instruct as the student and hosted Phi-4 as
the judge, --no-texture --k 4, 239 rows in 148 seconds:
train, holdout, eval; the eval split is the spec’s labeled replies
with gold_reward) and on the platform catalog.
Two things that run says, neither visible without the spec rows and the
markers:
- The judge is lenient. Phi-4 passed 10 of the spec’s 20 BAD replies
(
pass_when_gold_fail0.50). Those are exactly the rows a preference set would train toward. Fix the judge prompt, or use a stronger judge, before reading the pass rates. - The spec is this model’s default character. Qwen3-4B lands the
spec’s traits 78% of the time and holds them under “drop the act” (0.97).
One mixed prompt, one pair: there is nothing here to train on. That is
the expected result for an instruct model on the industry-default spec.
A distinct persona, or
--write-promptsfor harder situations, is where the contrast comes from. Writing the constitution is the small part.
What each number is for
The pipeline
The reward on a trait prompt is
trait AND on_task. The spec is explicit
that style “enhances rather than distracts from” helpfulness, and the
steroids example in the character chapter makes the same point: every persona
still refuses [1]. A reply
that has the character and drops the task is a 0.
What is not here
- A trainer of your own.
out/pairs.jsonlisprompt,chosen,rejectedas message lists, what a DPO trainer reads;out/sft.jsonlcarries a loss mask.recipes/04-train/identity/train_modal.pyis a LoRA pattern to copy. The hosted path iswai.train(ds_id, method="dpo")on the pushed rows. - Maiya’s third stage. Introspective SFT (the trained model writing about its own values) needs the trained model. Run it after DPO with the same judge.
- Persona vectors, activation capping, persona subnetworks [1]. No gradient, no data; a different tool.
- A prompt-disjoint holdout offline. The adversarial set reuses the
train prompts with a “drop the act” suffix (Maiya’s robustness test).
--write-promptsgives a real one.
Files
Tests:
pytest tests/api/test_character_example.py tests/recipes/test_character.py -q.
References
- Lambert, N. Reinforcement Learning from Human Feedback. arXiv:2504.12501, 2025. Chapter Model Character and Products.
- Panickssery, A., Bowman, S. R., Feng, S. LLM Evaluators Recognize and Favor Their Own Generations. arXiv:2404.13076, 2024.
- Bai, Y. et al. Constitutional AI: Harmlessness from AI Feedback. arXiv:2212.08073, 2022.
- Shao, Z. et al. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. arXiv:2402.03300, 2024.
- Yuan, Z. et al. Scaling Relationship on Learning Mathematical Reasoning with Large Language Models. arXiv:2308.01825, 2023.
- Zheng, L. et al. Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena. NeurIPS 2023. arXiv:2306.05685.
- Gao, L., Schulman, J., Hilton, J. Scaling Laws for Reward Model Overoptimization. ICML 2023. arXiv:2210.10760.
- Rafailov, R. et al. Direct Preference Optimization: Your Language Model is Secretly a Reward Model. NeurIPS 2023. arXiv:2305.18290.
- Lambert, N. Reinforcement Learning from Human Feedback. arXiv:2504.12501, 2025. Chapter Regularization.