AI-prompt engineering · leksjon

Map-Reduce-mønster for oppsummering

Oppsummer hver del uavhengig, og sammenfatt deretter oppsummeringene.

Leksjon 2 av 413 trinn

Map-Reduce-mønster for oppsummering er en gratis leksjon i AI-prompt engineering på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i AI-prompt engineering, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i AI-prompt engineering inneholder totalt 4 leksjoner.

Map-reduce-mønsteret

Når et dokument overskrider kontekstvinduet til en LLM, kan du ikke sende inn hele dokumentet på én gang. map-reduce-mønsteret løser dette:

  • Map: oppsummer hver chunk uavhengig
  • Reduce: sammenstill oppsummeringene av alle chunkene til én endelig oppsummering

Dette gjenspeiler den klassiske MapReduce-metoden fra distribuerte systemer – den samme del-og-hersk-logikken brukt på språkoppgaver.

Steg 1: Map-fasen

I map-fasen sendes hver chunk til LLM-en sammen med en prompt for oppsummering. Modellen returnerer en kort oppsummering av bare denne chunken. Disse oppsummeringene samles i en liste.

Hver oppsummering bør være mye kortere enn den opprinnelige chunken – vanligvis 10–20 % av den opprinnelige lengden. Det er denne komprimeringen som gjør reduce-steget mulig.

import openai

client = openai.OpenAI(api_key='sk-...')

def summarize_chunk(chunk, model='gpt-4o'):
    resp = client.chat.completions.create(
        model=model,
        messages=[
            {'role': 'system', 'content': 'Summarize the following text concisely in 3-5 sentences.'},
            {'role': 'user', 'content': chunk}
        ]
    )
    return resp.choices[0].message.content

def map_phase(chunks):
    return [summarize_chunk(c) for c in chunks]

Steg 2: Reduce-fasen

I reduce-fasen settes alle chunkoppsummeringene sammen og sendes til LLM-en sammen med en synteseprompt. Modellen produserer én sammenhengende, endelig oppsummering.

Hvis chunkoppsummeringene fortsatt er for lange til å få plass i ett kontekstvindu, kan reduce brukes rekursivt – oppsummer først grupper av oppsummeringer, og sammenstill deretter disse.

def reduce_phase(chunk_summaries, model='gpt-4o'):
    combined = '\n\n'.join(
        f'Section {i+1}:\n{s}'
        for i, s in enumerate(chunk_summaries)
    )
    resp = client.chat.completions.create(
        model=model,
        messages=[
            {'role': 'system', 'content': 'You are given summaries of consecutive sections of a document. Write a single coherent summary of the entire document.'},
            {'role': 'user', 'content': combined}
        ]
    )
    return resp.choices[0].message.content

Slik settes det sammen: rå API-kall

Her er hele map-reduce-pipelinen med rå OpenAI API-kall – uten behov for et rammeverk. Dette gir deg full kontroll over prompter og parametere i hver fase.

def map_reduce_summarize(document, chunk_size=1000):
    chunks = fixed_chunk(document, max_tokens=chunk_size)
    print(f'Chunks: {len(chunks)}')

    chunk_summaries = map_phase(chunks)
    print(f'Map phase complete. Summaries: {len(chunk_summaries)}')

    final_summary = reduce_phase(chunk_summaries)
    return final_summary

with open('long_report.txt') as f:
    doc = f.read()

result = map_reduce_summarize(doc)
print(result)

LangChain MapReduceDocumentsChain

LangChain tilbyr en ferdig MapReduceDocumentsChain som håndterer chunking, parallelle map-kall og reduce-steget. Den er praktisk, men mindre fleksibel enn rå API-kall.

from langchain_openai import ChatOpenAI
from langchain.chains.summarize import load_summarize_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.docstore.document import Document

llm = ChatOpenAI(model='gpt-4o', openai_api_key='sk-...')
splitter = RecursiveCharacterTextSplitter(chunk_size=3000, chunk_overlap=200)

with open('long_report.txt') as f:
    text = f.read()

docs = splitter.create_documents([text])
chain = load_summarize_chain(llm, chain_type='map_reduce')
result = chain.invoke(docs)
print(result['output_text'])

Parallellisering av map-fasen

Oppsummeringen av hver chunk er uavhengig, så map-fasen kan parallelliseres. Ved å bruke Pythons ThreadPoolExecutor sendes alle API-kallene for chunkene samtidig, noe som reduserer den faktiske kjøretiden betydelig.

from concurrent.futures import ThreadPoolExecutor, as_completed

def map_phase_parallel(chunks, max_workers=10):
    summaries = [None] * len(chunks)
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {
            executor.submit(summarize_chunk, chunk): i
            for i, chunk in enumerate(chunks)
        }
        for future in as_completed(futures):
            idx = futures[future]
            summaries[idx] = future.result()
    return summaries

Rekursiv reduce

Når et dokument er svært langt, kan selve chunkoppsummeringene overskride kontekstvinduet. Bruk reduce rekursivt: grupper oppsummeringene i partier, reduser hvert parti, og reduser deretter oppsummeringene av partiene.

def recursive_reduce(summaries, batch_size=10):
    while len(summaries) > 1:
        batches = [
            summaries[i:i + batch_size]
            for i in range(0, len(summaries), batch_size)
        ]
        summaries = [reduce_phase(batch) for batch in batches]
        print(f'Reduced to {len(summaries)} summaries')
    return summaries[0]

Bevare viktige detaljer

En vanlig svakhet ved naiv map-reduce er at viktige detaljer går tapt under komprimeringen. Tiltak:

  • Be map-steget bevare navn, tall og datoer
  • Be reduce-steget kontrollere om det finnes motsetninger mellom seksjonene
  • Bruk større chunker slik at map-konteksten blir rikere
  • Kjør en verifiseringsrunde: spør modellen om viktige entiteter fra originalen finnes i den endelige oppsummeringen
MAP_PROMPT = '''Summarize the following section in 5 sentences.
Preserve all key names, numbers, dates, and conclusions.

Section:
{chunk}'''

Refine-kjeden: et alternativt mønster

refine-kjeden er et alternativ til map-reduce. Den behandler chunker sekvensielt: oppsummeringen av chunk N sendes sammen med chunk N+1, og modellen oppdaterer den løpende oppsummeringen. Dette gir et mer sammenhengende resultat, men kan ikke parallelliseres og er tregere.

Bruk refine når narrativ sammenheng er viktig (for eksempel i juridiske kontrakter). Bruk map-reduce når hastighet er viktig (for eksempel ved grupper av nyhetsartikler).

def refine_summarize(chunks):
    current_summary = summarize_chunk(chunks[0])
    for chunk in chunks[1:]:
        prompt = (
            f'Existing summary:\n{current_summary}\n\n'
            f'New section:\n{chunk}\n\n'
            'Update the summary to incorporate the new section.'
        )
        resp = client.chat.completions.create(
            model='gpt-4o',
            messages=[{'role': 'user', 'content': prompt}]
        )
        current_summary = resp.choices[0].message.content
    return current_summary

Kostnads- og tokenhåndtering

Map-reduce gjør mange API-kall. For et dokument med 100 chunker og gpt-4o til 5 dollar per 1 million inputtoken:

  • Map: 100 chunker × 1000 token = 100 000 inputtoken ≈ 0,50 dollar
  • Reduce: ~10 000 token (oppsummeringer) ≈ 0,05 dollar
  • Totalt: ~0,55 dollar per dokument

Reduser kostnadene ved å bruke gpt-4o-mini til map-fasen (0,15 dollar per 1 million) og gpt-4o bare til reduce. Denne hybridtilnærmingen reduserer kostnadene med 70 % med minimalt kvalitetstap.

def map_phase_cheap(chunks):
    # Use mini model for map — cheaper, sufficient for chunk summaries
    return [
        summarize_chunk(c, model='gpt-4o-mini')
        for c in chunks
    ]

def reduce_phase_quality(summaries):
    # Use full model for final synthesis
    return reduce_phase(summaries, model='gpt-4o')

Når bør map-reduce brukes

Map-reduce-oppsummering egner seg best til:

  • Dokumenter som er lengre enn modellens kontekstvindu
  • Batchoppsummering av mange dokumenter (parallelliser også på dokumentnivå)
  • Situasjoner der du trenger kontroll over prompten i hvert steg

Det egner seg dårligere til å trekke ut et bestemt faktum (bruk gjenfinning i stedet), eller når dokumentet er kort nok til å få plass i konteksten (oppsummer det direkte).

Kunnskapstest

Hva skjer i reduce-fasen i map-reduce-mønsteret for oppsummering?

Oppsummering: Map-reduce-oppsummering

Map-reduce-mønsteret håndterer dokumenter som er for lange for ett enkelt LLM-kall:

  • Map: oppsummer hver chunk uavhengig – kan parallelliseres
  • Reduce: sammenstill chunkoppsummeringene til én endelig oppsummering
  • Rekursiv reduce: bruk dette når selve oppsummeringene er for lange
  • Kostnadstips: bruk en rimelig modell til map og en kvalitetsmodell til reduce

LangChain tilbyr en ferdig implementasjon med MapReduceDocumentsChain. I neste leksjon lærer du om hierarkisk oppsummering av bøker og forskningsartikler.

Gratis å komme i gang

Lær deg AI-prompt engineering med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
53
Leksjoner
199

Ofte stilte spørsmål

Er leksjonen «Map-Reduce-mønster for oppsummering» gratis?

Ja – du kan lese valgfritt 3 av leksjonene i læringsstien AI-prompt engineering, inkludert «Map-Reduce-mønster for oppsummering», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i AI-prompt engineering inneholder totalt 4 leksjoner.

Hva lærer jeg i «Map-Reduce-mønster for oppsummering»?

Oppsummer hver del uavhengig, og sammenfatt deretter oppsummeringene. Du øver på AI-prompt engineering med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med AI-prompt engineering?

Ingen tidligere erfaring er nødvendig. AI-prompt engineering på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Map-Reduce-mønster for oppsummering»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne AI-prompt engineering-leksjonen?

Ja. Alle AI-prompt engineering-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Strategier for oppdeling av lange tekster
  2. Map-Reduce-mønster for oppsummering
  3. Hierarkisk oppsummering
  4. Bevare kontekst på tvers av deler
← Tilbake til AI-prompt engineering