Skip to main content

Fold an Agent in Nushell

Submitted by Lennart on

In agent.nu, we explored using generate to build an LLM agent. That pattern is an unfold: starting from a seed, you grow a stream of values. It's perfect for UI-centric agents where you want to stream "thoughts" to the user as they happen.

You can read more about it here: A very simple and slightly better way to create an AI agent using nushell generate instead of a normal agent loop | docujAI

But what if you view an agent's task as a single transformation of a prompt into a completed conversation history? That's a fold.

The reduce Pattern

Nushell's reduce command (often called fold in other functional languages) is usually used for math (summing a list) or merging records. However, it's also a powerful way to manage stateful loops with a fixed maximum depth.

In agent_reduce.nu, we treat the conversation history as the accumulator:

1..$max_turns | reduce --fold $initial_history {|turn, history|
    let last_msg = $history | last
    
    # Early exit logic
    if ($last_msg.role == "model" and (not_calling_tools $last_msg)) {
        $history 
    } else {
        let next_step = call_llm $history
        $history | append $next_step
    }
}

Why use reduce?

1. The Result is the Context

While generate returns a stream of messages, reduce returns the final state. If you are building a tool that needs the complete transcript to save to a database or pass to another function, reduce gives it to you in one clean package.

2. Built-in Safety Rails

Agents can occasionally "hallucinate" loops or get stuck in tool-call cycles. By folding over a range like 1..10, you get a hard cap on iterations for free. You don't need to manually increment a counter or check a depth variable; the sequence provides the limit.

3. Clearer Intent for Batch Processing

If your agent is running as a background job (e.g., summarizing 100 documents), you don't care about the intermediate stream. You care about the final history. reduce makes this intent explicit: "Take these potential turns and condense them into a result."

Which one should you choose?

  • Use generate if you are building an interactive agent (CLI, Chatbot) where the process is as important as the result.
  • Use reduce if you are building a data pipeline agent where the agent is just a complex function that maps inputs to outputs.

Nushell gives you the choice. Whether you're unfolding a stream or folding a history, you can keep your AI logic functional, immutable, and simple.