A program is made of prompts and the edges between them. It is what gets optimized.
One node on the canvas, and the unit the optimizer rewrites. It has four things worth setting:
What you would have typed into a chat box. Words in {braces} are placeholders, filled from the dataset's columns, from an earlier prompt's output field, or from an external step. A placeholder with no source is a blocking error before the run starts, not a surprise at row 40.
One line, in your words. This is not decoration: the reflection model reads it when deciding how to rewrite the prompt. A prompt described as “summarizes what the customer wants” gets rewritten differently from one described as “extracts the order number”.
Prompts return structured fields, not loose text, so the next prompt and the scorer can pick one out by name. A field has a name, a type, and optionally a description the model sees. No fields means free text, which is fine for the last prompt if your scorer compares whole output.
Each prompt can run on its own model; empty means the project default. Mixing is normal — a cheap model to classify, a better one to draft.
A prompt can be excluded from rewriting with rewritten by the optimizer. Turn it off for a prompt you have already settled, and the search spends its budget on the others.
An edge from A to B means B runs after A. Click it to say what B receives: each of B's placeholders can be mapped to one of A's output fields, or to $text for A's raw output. Anything not mapped is looked up in the dataset columns and in whatever earlier prompts on the path already produced.
A prompt with no outgoing edge is a terminal: its output is what Evaluate grades. The dashed line to the Evaluate block appears and disappears on its own to show you which prompt that currently is. The entry prompt is where a row starts; by default it is the first one you added, and you can move it.
A prompt with two or more outgoing edges is a router. It is still a prompt and it is still optimized; the only difference is that a next field is added to its output automatically, with one option per outgoing edge. The model returns the name of the edge to take.
needs_human, not option2.next cannot be parsed. Without it, an unparseable answer is a failed row.Edges may loop back to an earlier prompt — a draft-and-revise cycle is two prompts and a router. That is what max prompt calls per example caps: without it, a program that keeps deciding to revise never finishes a row. Every row stops at the cap, and the cap is part of the cost projection.