| name | splitty-design |
| description | Design a splitty pipeline YAML file from a user's natural-language request. Use when the user describes an analysis goal but has not provided a pipeline file, or when they say "design a pipeline for X", "what pipeline would you use for Y", or "make a splitty pipeline that does Z". Outputs a validated pipeline.yaml. Does not run the pipeline. |
splitty-design
Translate a user request into a valid splitty pipeline YAML file.
Inputs you have
- The user's natural-language description of the goal.
- The corpus / input source (file, glob, or
@stdin).
- Optional constraints (output format, model preferences, parallelism limits).
Procedure
1 — Read the schema and examples
You must read these before authoring:
${CLAUDE_PLUGIN_ROOT}/docs/pipeline-schema.md
- At least one of:
${CLAUDE_PLUGIN_ROOT}/pipelines/examples/map-reduce-summary.yaml
${CLAUDE_PLUGIN_ROOT}/pipelines/examples/classify-and-extract.yaml
${CLAUDE_PLUGIN_ROOT}/pipelines/examples/fan-out-fan-in.yaml
Pick the example closest to the user's goal as your starting template.
2 — Decide the topology
Map the request to one of these patterns. If unsure, ask the user.
| Goal shape | Topology |
|---|
| Summarize / extract one thing per chunk → one report | map → terminal(custom) |
| Filter chunks, then expensive analysis on survivors | map(classify) → gate → map(extract) → terminal |
| Two independent analyses combined per chunk | map(A) ∥ map(B) → map(merge) → terminal |
| Aggregate counts / structured records | map(extract-json) → terminal(strategy: concat-json) |
| Iteratively refine a draft | reduce(draft) → loop(critique→revise) → terminal |
3 — Pick chunker settings
| Strategy | Use when |
|---|
paragraphs | Prose, notes, long-form documents (default) |
lines | Logs, CSV-ish, line-oriented text |
tokens | Need consistent prompt sizing across chunks |
fixed | Binary-ish or unstructured streams |
none | Pipeline must see entire input as one chunk |
Default chunk sizes:
- paragraphs:
size: 2000 (chars), overlap: 0
- lines:
size: 200 (lines)
- tokens:
size: 1000
- fixed:
size: 4000 (chars)
4 — Author each stage
For every map, reduce, and custom-strategy terminal stage, write:
id — kebab-case, descriptive (extract-entities, not s1)
agent_def.system — the persona in 1-3 sentences. Be specific about role
and constraints (e.g., "You never invent facts", "You output strict JSON").
agent_def.tools — almost always [Read, Write]. Add Grep / Glob only
if the stage genuinely needs to look outside its input.
agent_def.model — haiku for cheap classification, sonnet (default) for
most analysis, opus only for hard synthesis at the terminal.
instructions — the precise task: format, length, what to include, what to
exclude. Include negative constraints (no prose, no commentary, no fences).
output_format — json whenever downstream stages will programmatically
consume the output. markdown only at the terminal.
For gate stages: write a condition that operates on JSON keys produced
upstream. Keep it simple — see docs/pipeline-schema.md for supported syntax.
For terminal with strategy: concat | concat-json | deep-merge: no
agent_def needed; the union is mechanical.
5 — Write the file
Save to .splitty/pipelines/<name>.yaml in the user's workspace. If the
directory does not exist, create it. Use the user's stated name or derive a
kebab-case one from the goal.
6 — Validate
Run:
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/splitty.py validate <path>
If validation fails, fix the issues and re-validate. Do not hand off an
invalid pipeline.
7 — Show the user
Print:
- The path to the saved pipeline.
- A short ASCII diagram of the topology.
- The 1-line description of each stage (id + role).
Then ask: "Run it now?" Do not autorun unless the user said so explicitly
in their original request.
Anti-patterns to avoid
- One mega-stage doing many things. Split into discrete filters, each with
a single responsibility. The whole point of the plugin is composition.
- Vague personas like "you are a helpful assistant". Personas should
declare a specific filtering role and its hard constraints.
- Markdown output before the terminal. Intermediate stages should output
JSON whenever possible so downstream stages can consume them programmatically.
- Fan-out without fan-in. Every leaf must be a terminal. The validator
enforces this; if you hit the error, add a synthesizer.