Scaffold a new training recipe for the Tinker cookbook following repo conventions. Use when the user wants to create a new recipe, training script, or experiment.
Scanned 9/1/2026
Install to Claude Code
npx -y skills add uiuc-kang-lab/rlvr_generalization_bounds --skill new-recipe --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of New Recipe?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/uiuc-kang-lab-new-recipe)More formats (shields.io, HTML) on the badges page.
---
name: new-recipe
description: Scaffold a new training recipe for the Tinker cookbook following repo conventions. Use when the user wants to create a new recipe, training script, or experiment.
disable-model-invocation: true
argument-hint: "[recipe-name]"
---
# Create a New Training Recipe
Scaffold a new training recipe in `tinker_cookbook/recipes/` following repo conventions.
## Step 1: Understand the request
Ask the user:
- **Recipe name**: What to call it (becomes the directory/file name under `recipes/`)
- **Training type**: SL, RL, DPO, distillation, or hybrid
- **Key details**: Model, dataset, environment, reward signal, etc.
## Step 2: Read existing recipes for patterns
Before writing any code, read the most relevant existing recipe:
- **SL-based**: Read `tinker_cookbook/recipes/sl_basic.py` and `tinker_cookbook/recipes/chat_sl/train.py`
- **RL-based**: Read `tinker_cookbook/recipes/rl_basic.py` and `tinker_cookbook/recipes/math_rl/train.py`
- **DPO-based**: Read `tinker_cookbook/recipes/preference/dpo/train.py`
- **Distillation-based**: Read `tinker_cookbook/recipes/distillation/on_policy_distillation.py`
- **Multi-turn RL**: Read `tinker_cookbook/recipes/harbor_rl/train.py`
Also read `CLAUDE.md` for conventions.
## Step 3: Follow repo conventions
Every recipe MUST follow these patterns:
### File structure
```
tinker_cookbook/recipes/<recipe_name>/
├── __init__.py # Empty or minimal
├── train.py # Main entry point with CLIConfig + cli_main
└── <env_or_data>.py # Dataset/environment definitions (if needed)
```
Or for simple recipes: `tinker_cookbook/recipes/<recipe_name>.py`
### CLI pattern (use `@chz.chz` for config)
```python
@chz.chz
class CLIConfig:
model_name: str = "meta-llama/Llama-3.1-8B"
learning_rate: float = 1e-4
# ... all configurable parameters with defaults
async def cli_main(cli_config: CLIConfig):
# Build full config from CLI config
# Call training main function
if __name__ == "__main__":
cli_config = chz.entrypoint(CLIConfig)
asyncio.run(cli_main(cli_config))
```
### Required elements
1. **`@chz.chz` config class** with sensible defaults
2. **`model_info.get_recommended_renderer_name(model_name)`** for renderer — never hardcode
3. **`cli_utils.check_log_dir()`** before training to avoid clobbering
4. **`checkpoint_utils.resolve_renderer_name_from_checkpoint_or_default_async()`** if loading checkpoints
5. **Explicit typing** — no `Any` or `type: ignore`
6. **Auto-generated log paths** with model name, hyperparams, and timestamp
### Naming conventions
- Subscript suffixes for tensors: `_P` (problems), `_G` (groups), `_T` (tokens), `_D` (datums)
- Use `safezip`, `timed`, `scope` helpers where appropriate
- Use `ml_log.log_metrics` for metrics, `logtree` for transcripts
### Entry point
Recipe must be runnable as:
```bash
python -m tinker_cookbook.recipes.<recipe_name>.train [chz overrides]
```
## Step 4: Create the recipe
Write the recipe files following the patterns above. Place them in `tinker_cookbook/recipes/$ARGUMENTS/`.
## Step 5: Add tests
The repo has two layers of testing. **Both should be added for every new recipe.**
### Smoke test (required)
Create `tests/recipes/test_recipe_<name>.py` — a minimal test that runs the recipe for 2 training steps and verifies clean exit. CI auto-discovers these files and runs them daily.
```python
import pytest
from tests.helpers import run_recipe
@pytest.mark.integration
def test_<recipe_name>():
run_recipe(
"tinker_cookbook.recipes.<recipe_name>.train",
[
"behavior_if_log_dir_exists=delete",
# Override params to make it fast:
# "groups_per_batch=4", "group_size=2", "batch_size=16", etc.
],
)
```
Key conventions:
- `run_recipe()` launches the module as a subprocess and automatically passes `max_steps=2` (configurable via the `max_steps` parameter)
- The recipe runs for 2 training steps and exits naturally — the test passes on clean exit (exit code 0)
- Always pass `behavior_if_log_dir_exists=delete` to avoid conflicts in repeated CI runs
- Override batch sizes / group sizes to small values so the test completes quickly
- Mark tests with `@pytest.mark.integration` — these require `TINKER_API_KEY`
- See `tests/helpers.py` for `run_recipe()` details and `tests/conftest.py` for fixtures
### Unit tests (for testable components)
Place unit tests next to the code they test using the `*_test.py` naming convention:
```
tinker_cookbook/recipes/<recipe_name>/<component>_test.py
```
For example:
- `tinker_cookbook/recipes/math_rl/math_env_test.py` — tests environment logic
- `tinker_cookbook/renderers/parsing_test.py` — tests parsing helpers
Unit tests should:
- Run without `TINKER_API_KEY` (no network calls)
- Be fast (< 1s per test)
- Use standard pytest features (fixtures, parametrize, marks)
- Test picklability if the component needs to be serialized for distributed rollout
### Running tests locally
```bash
# Unit tests only (no API key needed)
uv run pytest tinker_cookbook/
# Integration / smoke tests (requires TINKER_API_KEY)
uv run pytest tests/recipes/test_recipe_<name>.py -v -x -s
```
### CI integration
- **Unit tests** (`pytest tinker_cookbook/`) run on every PR via `.github/workflows/pytest.yaml`
- **Integration tests** (`pytest tests/`) run daily and on manual trigger via `.github/workflows/smoke-test-recipes.yaml`
- Adding `tests/recipes/test_recipe_<name>.py` is all that's needed — CI auto-discovers it
## Step 6: Verify
- Ensure the recipe is importable: `python -c "from tinker_cookbook.recipes.<name> import train"`
- Check that CLI help works: `python -m tinker_cookbook.recipes.<name>.train --help`
- Run the smoke test locally: `uv run pytest tests/recipes/test_recipe_<name>.py -v -x -s`
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!