1. Declare the shape, don’t describe it
Start from a spec rather than a prompt. A reviewer can only check rows against a declared shape, and a prose description is not one. → Structured output foroutput.schema and schema_order
→ Writing task prompts for the per-row rules that set the bar
Decision: if the columns aren’t known yet, you are still exploring. Use a prompt and
this pipeline later.
2. Watch the first run, don’t poll it
For the first run of a new spec, stream it. You are not waiting for an answer, you are looking for the agent misreading the brief, which shows up in the tool calls long before it shows up in the rows. → Live messages for the SSE routes and event names Decision: once the spec is stable, switch to polling. Streaming is for when you are still learning what the task does.3. Read rows with their sources
Fetch the rows and keep the cells rather than flattening immediately. Review is exactly the case where_sources earns its keep: a reviewer needs to see why a value is claimed.
→ Outputs and sources for cell shape and _sources
4. Correct in place
Send the reviewer’s verdict back to the same task. The plan, the rows, and the task-local files all survive; a new task would lose them. → Follow-up tasks forcontinue
→ Human in the loop for interleaving review and agent turns
Decision: continue when the reviewer is refining the same goal. Start fresh only when
the goal itself changed.
5. Repeat
Thetask_id stays valid indefinitely. Steps 3 and 4 loop as many times as review needs,
and the task keeps everything it learned.
Related
Quickstart
The single-pass version of this.
Attach a CSV
The same loop, starting from rows you already have.