## Introducing Recipes

A recipe is a Python file that defines an AI workflow on Harmony, Adaptive Engine's compute backend.

[Reinforcement learning](https://dev.adaptive-ml.com/training/post-training/rl) has many moving parts: [training](https://dev.adaptive-ml.com/optimization), [inference](https://dev.adaptive-ml.com/inference), [graders](https://dev.adaptive-ml.com/rewards). They typically run in separate systems. Most of the work in an RL pipeline is the coordination between them.

In Harmony, all of this can live in one file.

A recipe has three pieces:

- [**`InputConfig`**](https://docs.adaptive-ml.com/v0.14/harmony/config): declares the recipe's inputs
- [**`@recipe_main`**](https://docs.adaptive-ml.com/v0.14/harmony/recipe-syntax): marks the entrypoint function
- [**`RecipeContext`**](https://docs.adaptive-ml.com/v0.14/harmony/recipe-syntax): handles Harmony calls

```
    class MyConfig(InputConfig):
        ...

@recipe_main
    async def main(config: MyConfig, ctx: RecipeContext):
        # load resources, run the workflow, save
        ...
    ```

[Built-in recipes](https://docs.adaptive-ml.com/v0.14/core/recipes) ship with Adaptive Engine: [supervised fine-tuning](https://dev.adaptive-ml.com/training/post-training/sft), [RL with a grader](https://dev.adaptive-ml.com/rewards/rlaif), [RL on preferences](https://dev.adaptive-ml.com/rewards/rlhf), [evaluation](https://dev.adaptive-ml.com/evaluation), [speculative decoding draft alignment](https://dev.adaptive-ml.com/inference/optimization/speculative-decoding). Each wraps training, data loading, and monitoring into one workflow. Custom recipes use the same primitives.

## InputConfig

The recipe's inputs, declared as a Pydantic model.

```
    class SummarizationGRPO(InputConfig):
        model: Annotated[Model[model_kinds.Trainable], Field(description="Policy")]
        dataset: Annotated[Dataset[dataset_kinds.Prompt], Field(description="Prompts")]
        grader: Annotated[Grader, Field(description="Reward")]
        learning_rate: Annotated[float, Field(default=7.5e-7)] = 7.5e-7
    ```

`Model`, `Dataset`, and `Grader` are engine-aware: they reference models, datasets, and graders registered on Adaptive Engine.

## @recipe_main

Marks the recipe's async entrypoint.

```
    @recipe_main
    async def main(config: SummarizationGRPO, ctx: RecipeContext):
        ...
    ```

Harmony parses input arguments, instantiates the typed config, and calls the function.

## RecipeContext

The recipe's connection to Harmony.

```
    dataset = await config.dataset.load(ctx)
    grader = await config.grader.load(ctx)
    policy = await config.model.spawn_train("policy", ctx, max_batch_size=10000, tp=4)
    reference = await policy.clone_inf()

for prompt in dataset:
        samples = await async_map(policy.generate_tokens, [prompt for _ in range(8)])
        texts = await async_map(policy.detokenize_thread, samples)
        grades = await async_map(grader.grade, texts)
        scores = np.array([g.value for g in grades])
        advantages = (scores - scores.mean()) / (scores.std() + 1e-8)
        for sample, adv in zip(samples, advantages):
            lp = await policy.logprobs_per_token(sample)
            ref_lp = await reference.logprobs_per_token(sample)
            await policy.train_grpo(sample, lp, ref_lp, [adv] * len(lp), clip_range=0.1, kl_beta=0.01)
        await policy.optim_step(config.learning_rate, wd=0.0, max_grad_norm=1.0)

await policy.save(model_name="policy-v1", ctx=ctx)
    ```

`RecipeContext` flows into every Harmony call. Policy, reference (one-line `clone_inf`), and grader (possibly a [large judge LLM](https://dev.adaptive-ml.com/rewards/rlaif)) all live on the same GPUs in Harmony's unified architecture. The full [GRPO](/content/post/grpo-simply-explained/index.html) loop, in one file.

That's a recipe. Built-in or custom, all run on Harmony. See the [docs](https://docs.adaptive-ml.com/v0.14/harmony/overview) for more.
