In Nushell, reduce is all about taking a list and folding it down into a single value. When you plug an LLM into that "folding" process, you’re essentially giving the model a "memory" of everything it has processed in the pipeline so far.
Here are three high-level patterns for using reduce with an LLM in your terminal.
How reduce Works (The LLM Mental Model)
Before we dive in, remember the syntax: list | reduce { |it, acc| ... }.
it: The current item from your pipeline.acc: The "accumulator" (the result of the LLM's work from the previous step).
1. The "Snowball" Summary (Contextual Aggregation)
If you have a massive log file or a long document that exceeds a context window, you can’t just pipe the whole thing. Instead, you "snowball" it. You summarize the first chunk, then pass that summary (the acc) along with the next chunk (it) to the LLM to create an updated summary.
# Split a big file into 2KB chunks and "fold" them into one summary
open big_doc.txt | chunks 2000 | reduce -f "" { |it, acc|
echo $"Current Summary: ($acc)\n\nNext Chunk: ($it)" | llm "Update the summary to include the new information from the next chunk."
}
- Why this works: It prevents the LLM from "forgetting" the beginning of the file, as the accumulator constantly carries the distilled essence of the previous chunks.
2. The Sequential Refiner (The "Polishing" Loop)
Let’s say you have a rough draft of a script, and you have a list of "improvement lenses" (e.g., "make it more idiomatic," "add error handling," "document the functions").
let lenses = ["make it idiomatic nushell", "add robust error handling", "add docstrings"]
let initial_code = (open my_script.nu)
$lenses | reduce -f $initial_code { |it, acc|
echo $acc | llm $"Refactor this code using the following instruction: ($it)"
}
- Why this works: Instead of asking the LLM to do ten things at once (which often leads to hallucinations or missed instructions), you force it to focus on one specific improvement at a time, building upon the previous version.
3. The "Tournament" Selection (Finding the Best Item)
Suppose you have a list of 50 generated taglines or ideas. You want the LLM to pick the absolute best one. If you give it all 50, it might get overwhelmed. With reduce, you can make it run a "tournament."
ls *.txt | get name | reduce { |it, acc|
llm $"Between these two filenames, which one is more descriptive for a project about AI?
A: ($it)
B: ($acc)
Return only the best filename."
}
- Why this works: This performs a pairwise comparison. The "winner" stays in the accumulator and faces the next "challenger" in the list until only one remains.
A Quick Tip on Performance
Using reduce with LLMs is linear and sequential. Because each step depends on the output of the previous one, you can't parallelize this. It’s a slow-cooker method, not a microwave. If you're running this on a long list, you might want to add a print statement inside the block so you can watch the LLM "think" in real-time.