Split the Task
Plan, then act. Or extract, then decide. One prompt that does four jobs is how JSON grows poetry.
Decomposition means: do not ask one completion to classify, plan, call a tool, and write a novel. One prompt that does four jobs is how JSON grows poetry. The model will try to be funny and helpful and refund-shaped at once.
Split until each completion has one job you can name in four words. If you cannot name the step in four words, it is two steps.
Split jobs. The poem request never reaches the tool list.
Extract then actThe prompt gets easier because the input got smaller. A policy prompt that only sees {"job_id": 17, "wants_refund": true} cannot be distracted by a haiku request that still lives in the raw ticket — you already dropped the haiku in extract.
This is not the tools runtime and it is not retrieval. Those tracks come later. Decomposition is a prompt move: smaller asks, smaller contracts, fewer ways to fail.
Patterns that work
- Router then worker — a short prompt picks a label (
billing/infra/handoff); a second prompt does the hard job. The router stays zero-shot and cheap. The worker can be few-shot. (LLM routing is the model-size version of this idea.) - Extract then reason — first JSON fields from the ticket; then a policy prompt that only sees those fields. Extra wishes stay out of the action policy.
- Plan then act — a plan object with step names; code runs the next allowed tool. The plan is text. The allowlist is code.
- Least-to-most — solve a small sub-question, then the full one, feeding the sub-answer in. Useful for serial math and policy trees. Cap the chain.
You can implement extract with code when the fact is a number, an id, or a keyword. Use a model for extract when the field is messy language. A second model that reads raw HTML can also be injected — extract with code when you can.
What not to split
Do not split a task into twenty micro-prompts because a blog said “agents.” Each hop is latency, cost, and a new place to drop the contract. Split when one completion is mixing jobs you can name. Do not split a summarizer into “find nouns” and “find verbs.”
Do not pass the raw HTML to a step that does not need it. Context engineering from the LLM track is this idea at packing time. Decomposition is this idea at prompt time.
Run to execute this in your browser. Nothing is sent to a server.
What printed: fields show job 17, refund true, poem true. Action is handoff because refund needs a human. The haiku did not become a tool. Refund did not become a tool name either — the policy maps it to handoff. The poem request is still in the ticket. The extract step dropped it from the action policy.
One mashed prompt would have tried to write a haiku, quote the job, and maybe “helpfully” refund.
Share a spec id across steps
When you split, log the same prompt_id family: extract-v3, act-v3. A failure in act is not a failure in extract. Traces that mash both into one span are how you debug the wrong poem.
Walkthrough: one prompt, four jobs
A single completion is asked to read a ticket, pick a tool, write a haiku, and decide a refund. JSON grows a poem key. The parser does not expect it. Retry. The model “helps” by naming refund. You will add adjectives. The split that works: extract fields (job_id, wants_refund, wants_poem) with code or a tiny prompt; act on those fields with a policy that maps refund to handoff and has no poem-tool; write a user sentence only after the action. The haiku never reaches the allowlist.
Do not split a summarizer into twenty micro-prompts. Split when jobs have different contracts.
What goes wrong if you skip this
Mashed prompts become untestable. You cannot tell whether extract or act failed. Raw HTML reaches a planner that then follows orders inside the HTML. Cost and latency hide in one span. Extra wishes become extra tools.
Decomposition means one completion, one job you can name in four words. Router then worker. Extract then reason. Plan then act. Least-to-most for serial trees, capped. The prompt gets easier because the input got smaller. Extract with code when the field is a number or id. Do not send raw HTML to a step that does not need it.
Do not split a summarizer into twenty micro-prompts. Split when contracts differ. Log extract-v3 and act-v3 so you debug the right poem.
Common mistakes
| Split? | Situation | Why |
|---|---|---|
| Yes | Ticket wants status + haiku + refund | Different contracts |
| Yes | Router label vs hard job | Cheap then expensive |
| No | Summarize an email | One job |
| No | Twenty micro-prompts | Latency tax |
| Yes, code extract | job_id digits | No model needed |
Share a spec id family across steps so a failure in act is not blamed on extract. If extract returned wants_refund: true, act should handoff — that is a unit test with no model. If you still send the raw ticket to act “just in case,” you undid the split. The haiku is back in the planner. The point of decomposition is a smaller, dumber input.
How agents use this
Separate prompts (or separate functions) for extract vs act vs write. Share a spec id in traces. If a step does not need the raw HTML, do not send the raw HTML. Extra wishes stay out of the tool loop. If you cannot name the step in four words, it is two steps.
Tip:The extract step is allowed to be boring code. Boring is how a haiku fails to become a tool.
Check your understanding