Flows & Blocks
The core data model — flows are directed trees of processing blocks.
Flows
A flow is a directed tree of processing blocks. When called via the slug API, Noukai executes the blocks in order, passing output from one to the next.
Each flow has:
- A name and slug (URL identifier)
- A steps tree (the block topology)
- A global input schema (what the API accepts)
- Versions (immutable snapshots for deployment)
Blocks
A block is a single processing step. Every block has a processor type that determines what it does.
llm — LLM Processing
Runs a prompt through a language model and returns structured output.
- Prompt: The template text sent to the LLM
- Model: Which LLM to use (e.g.,
anthropic/claude-sonnet-4-6) - Input Schema: What data the block receives
- Output Schema: The structure of the block's response
- Config: Temperature, max tokens, etc.
Use when the step requires understanding, reasoning, generation, classification, or extraction — anything that depends on language meaning.
Don't use when the transformation is purely deterministic (string formatting, math, slicing, filtering by exact match). Reach for code instead — it's faster, cheaper, and never hallucinates.
code — Custom Logic
Executes custom JavaScript code for transformations, filtering, or business logic that doesn't require an LLM.
Use when you need deterministic logic: parsing JSON, slicing arrays, formatting strings, computing scores, normalizing data, or filtering by exact criteria.
Don't use when the task involves understanding language or producing prose. code blocks can't reason — give that work to an llm block.
Common pairing: an llm block extracts structured data, then a code block reshapes it for the next step or for the final response.
passthrough — Data Forwarding
Passes input directly to output without modification. Useful for routing data between blocks or splitting a flow.
Use when you need to fan data into a parallel container without re-prompting it, or when you need a structural anchor in the tree (e.g., a join point).
Don't use when you actually need to transform the data — passthrough is purely structural.
Tree Structure
Blocks are organized in a tree with two grouping mechanisms.
Containers
Group blocks for sequential or parallel execution.
Sequential (h)
Blocks run one after another. Each block sees the previous block's output via {previous_output}.
Use when later blocks depend on earlier blocks' outputs — extracting then summarizing, classifying then routing, translating then glossing.
Don't use when the blocks are independent. Sequential execution is slower and forces a chain that doesn't need to exist.
Parallel (v)
Blocks run simultaneously. Each block sees the same upstream input; their outputs are merged into a single object keyed by block name.
Use when multiple analyses are independent — running tone, readability, and fact-checks against the same text; generating tweet, LinkedIn, and email drafts from the same source.
Don't use when one block needs another's output. Parallel branches can't see each other.
Loops
Iterate a block (or group) over an array field:
Use when you need to apply the same prompt to each element of an array — glossing each word, scoring each candidate answer, validating each item.
Don't use when you have a fixed, small number of distinct steps. A loop is for "the same logic × N items," not "N different things in a row."
Choosing a Block
Use this flowchart when designing a new step:
Input & Output Schemas
Each block defines what data it accepts and produces. Schemas enable:
- Type safety: validate data between blocks
- Documentation: self-describing pipelines
- Reliability: downstream blocks can rely on the shape of upstream output
- Object models: reusable schema types at the project level
Set an output schema on any llm block whose result is consumed by a later block — without one, you're trusting the model to produce the same shape every time.
Next Steps
- Pipeline Patterns — structural shapes and best practices for composing blocks
- Pipeline Recipes — fully worked end-to-end examples