Gå til hovedindhold

Simpel arbejdsgang til redigering af tekst med reduce og generate i Nushell

Indsendt af Lennart den

Til en simpel redaktionel arbejdsgang ville jeg næsten helt sikkert vælge reduce, men det "seje" valg (og det, der føles mere som en selvstændig agent) er generate.

Du beslutter dig baseret på hvordan din "arbejdsgang" rent faktisk ser ud:

Mulighed 1: Brug reduce (Den "lineære afpudser")

Brug reduce, hvis du har et fast sæt operationer, du vil køre på et stykke tekst (f.eks. "Ret grammatik" "Forkort" "Skift tone").

I dette scenarie "folder" du en liste af instruktioner over din tekst.

let tasks = ["fix grammar", "make it sound more professional", "convert to markdown"]
let original_text = "i is writing a nushell script for agents"

let final_draft = ($tasks | reduce -f $original_text {|task, current_text|
    # Each step takes the output of the previous LLM call
    call-brain $"Apply this edit: ($task)" $current_text
})

  • Bedst til: Konsistens. Du ved præcis, hvor mange trin der er involveret.
  • Logik: .

Mulighed 2: Brug generate (Den "iterative forfiner")

Brug generate, hvis du vil have agenten til at blive ved med at redigere, indtil den er tilfreds. generate opretter en strøm, hvilket er perfekt til en "Redaktionel Loop", hvor agenten ser på sit eget arbejde og beslutter, om det har brug for endnu en gennemgang.

# generate {|state| {out: <value_to_emit>, next: <next_state>} } <initial_state>
let initial_state = { text: "The draft...", count: 0, done: false }

let editorial_history = (generate {|state|
    if $state.done or $state.count > 3 { return null } # Exit condition

    let feedback = (call-brain "Review this text. Is it perfect? Respond with 'YES' or feedback." $state.text)
    
    if ($feedback | str contains "YES") {
        {out: $state.text, next: {done: true}}
    } else {
        let new_text = (call-brain $"Apply this feedback: ($feedback)" $state.text)
        {out: $new_text, next: {text: $new_text, count: ($state.count + 1), done: false}}
    }
} $initial_state)

let final_result = ($editorial_history | last)

  • Bedst til: Kvalitet. Den efterligner en menneskelig redaktør, der sender et udkast tilbage flere gange.
  • Logik: Start -> Er det godt? -> Nej? -> Rediger og gentag.

Sammenligningstabel

Funktion reduce generate
Flow Deterministisk (1 -> 2 -> 3) Dynamisk (Loop indtil færdig)
Afslutning Slutter, når listen over opgaver er tom Slutter, når en betingelse er opfyldt (eller grænse nået)
Synlighed Sværere at se mellemliggende trin undervejs Udsender hver version som et strømedlem (godt til logning)
Anvendelsesscenarie Batch-behandling Selvkorrigerende agenter

Min anbefaling

Hvis du bygger et Agent System med xs, skal du bruge generate.

Hvorfor? Fordi generate tillader LLM'en at bestemme den "næste tilstand". Den kan udskrive det aktuelle udkast til en xs-strøm i hver iteration, hvilket giver dig et perfekt revisionsspor af, hvordan den "redaktionelle hjerne" udviklede teksten.

Vil du have, at jeg viser dig, hvordan du pakker den generate-loop, så den skriver hver "revision" til en xs-strøm i realtid?

Hold dig opdateret, hvis du vil lære mere om xs (cross.stream), event sourcing og nushell med AI og LLM'er.