AI Engineering Academy · Lezione

Strategie per restare entro i limiti del contesto

Implementerà una memoria a finestra scorrevole, il riepilogo dei messaggi e il taglio selettivo del contesto per gestire conversazioni lunghe senza superare i limiti dei token.

Lezione 4 di 413 passaggi

Strategie per restare entro i limiti del contesto è una lezione AI Engineering Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento AI Engineering Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso AI Engineering Academy include 4 lezioni in totale.

Il problema delle conversazioni sempre più lunghe

Ogni messaggio scambiato in una conversazione chat aumenta il numero di token della chiamata API successiva. In una lunga sessione di assistenza clienti o in una sessione di programmazione di diverse ore, la cronologia accumulata della conversazione può facilmente superare i 20.000-50.000 token, che dovete inviare all'API a ogni turno, pagando ripetutamente per token già elaborati.

Senza una strategia di gestione del contesto, l'applicazione raggiungerà il limite di contesto e si arresterà, oppure finirete per troncare i messaggi senza accorgervene e il modello perderà il filo del contesto importante precedente. Ogni applicazione LLM in produzione necessita di una strategia esplicita per gestire la crescita del contesto.

Strategia 1: finestra scorrevole (ultimi N messaggi)

La strategia più semplice consiste nel mantenere nel contesto solo gli ultimi N messaggi, eliminando quelli più vecchi. Questa tecnica è chiamata finestra scorrevole. È facile da implementare, offre costi prevedibili ed è sufficiente per molti casi d'uso in cui il contesto recente è più importante degli scambi precedenti.

import openai

client = openai.OpenAI()

class SlidingWindowConversation:
    def __init__(self, system_prompt, window_size=10):
        self.system = system_prompt
        self.window_size = window_size
        self.history = []

    def chat(self, user_message):
        self.history.append({'role': 'user', 'content': user_message})

        # Keep only the last N messages
        windowed = self.history[-self.window_size:]
        messages = [{'role': 'system', 'content': self.system}] + windowed

        response = client.chat.completions.create(
            model='gpt-4o-mini',
            messages=messages
        )
        reply = response.choices[0].message.content
        self.history.append({'role': 'assistant', 'content': reply})
        print(f'Context: {len(windowed)} messages ({len(self.history)} total)')
        return reply

conv = SlidingWindowConversation('You are a helpful assistant.', window_size=6)
print(conv.chat('Hello! My name is Alice.'))
print(conv.chat('What is the capital of France?'))
print(conv.chat('What is my name?'))  # Might forget if window is small

Strategia 2: troncamento basato sui token

Anziché troncare in base al numero di messaggi, il troncamento basato sui token rimuove i messaggi finché il numero totale di token non scende al di sotto di una soglia. È più preciso perché la lunghezza dei messaggi può variare notevolmente: un limite basato sul numero di messaggi potrebbe includere 10 messaggi brevi oppure 3 messaggi molto lunghi, con costi in token molto diversi.

import tiktoken

def trim_to_token_budget(
    messages, system_prompt, model='gpt-4o-mini', max_input_tokens=8000
):
    enc = tiktoken.encoding_for_model(model)

    def count(msgs):
        return sum(len(enc.encode(m.get('content',''))) + 4 for m in msgs) + 3

    # System prompt token count
    system_tokens = len(enc.encode(system_prompt)) + 4
    budget = max_input_tokens - system_tokens

    # Trim from the oldest messages until we fit
    trimmed = list(messages)
    while trimmed and count(trimmed) > budget:
        trimmed.pop(0)  # Remove oldest message

    removed = len(messages) - len(trimmed)
    if removed:
        print(f'Trimmed {removed} old messages to stay within {max_input_tokens} tokens')
    return trimmed

Strategia 3: riepilogo della conversazione

Il riepilogo comprime i turni meno recenti della conversazione in un riepilogo conciso, preservando i fatti, le decisioni e il contesto principali menzionati dall'utente. È una tecnica più sofisticata delle finestre scorrevoli perché conserva l'essenza degli scambi precedenti invece di eliminarli semplicemente.

Il funzionamento è il seguente: quando la conversazione supera una soglia, inviate al modello gli ultimi N turni meno recenti con un prompt del tipo 'Riepiloga la conversazione finora', sostituite quei turni con un singolo messaggio di sistema contenente il riepilogo e continuate la conversazione con la nuova cronologia compressa.

import openai

client = openai.OpenAI()

def summarize_conversation(messages_to_summarize, model='gpt-4o-mini'):
    summary_prompt = [
        {'role': 'system', 'content': 'You summarize conversations. Be concise but preserve key facts, decisions, and any specific information the user shared (names, numbers, preferences).'},
        {'role': 'user', 'content': 'Summarize this conversation:\n' + '\n'.join(
            f"{m['role'].upper()}: {m['content']}" for m in messages_to_summarize
        )}
    ]
    resp = client.chat.completions.create(model=model, messages=summary_prompt, max_tokens=500)
    return resp.choices[0].message.content

def compress_history(history, keep_recent=4):
    if len(history) <= keep_recent:
        return history
    to_summarize = history[:-keep_recent]
    summary = summarize_conversation(to_summarize)
    summary_msg = {'role': 'system', 'content': f'Earlier conversation summary: {summary}'}
    return [summary_msg] + history[-keep_recent:]

print('Summarization strategy compresses old turns into a single summary message')

Strategia 4: memoria delle entità

La memoria delle entità estrae e mantiene una rappresentazione strutturata dei fatti principali menzionati nella conversazione — preferenze dell'utente, nomi, dettagli del progetto, decisioni prese — invece di memorizzare la cronologia grezza dei messaggi. Prima di ogni turno, i fatti memorizzati vengono inseriti nel prompt di sistema.

Questa tecnica è più efficiente in termini di token rispetto alla cronologia completa perché include solo ciò che è semanticamente importante, non ogni parola di ogni turno. La memoria delle entità funziona particolarmente bene per gli assistenti utilizzati a lungo, in cui gli utenti fanno riferimento a preferenze e fatti stabiliti molto prima nella conversazione.

import openai
import json

client = openai.OpenAI()

def extract_entities(messages, model='gpt-4o-mini'):
    prompt = [
        {'role': 'system', 'content': 'Extract key facts from this conversation as JSON: {"user_name": null, "preferences": [], "key_facts": []}'},
        {'role': 'user', 'content': '\n'.join(f"{m['role']}: {m['content']}" for m in messages)}
    ]
    resp = client.chat.completions.create(
        model=model,
        messages=prompt,
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)

conversation = [
    {'role': 'user', 'content': 'Hi, I am Alice and I prefer Python over JavaScript.'},
    {'role': 'assistant', 'content': 'Great to meet you, Alice! Python is an excellent choice.'},
    {'role': 'user', 'content': 'I am building a REST API for my e-commerce startup.'}
]
entities = extract_entities(conversation)
print(json.dumps(entities, indent=2))

Quando applicare ciascuna strategia

Scegliete la strategia in base alle caratteristiche della vostra applicazione:

  • Finestra scorrevole: semplici app di chat in cui conta solo il contesto recente e gli utenti non fanno riferimento agli scambi precedenti. È la soluzione più economica da implementare.
  • Troncamento basato sui token: qualsiasi app di produzione in cui la lunghezza dei messaggi varia in modo significativo. È sempre preferibile al troncamento basato sul numero di messaggi.
  • Riepilogo: assistenti utilizzati a lungo, sessioni di assistenza clienti, bot per la gestione dei progetti. Gli utenti si aspettano che l'assistente ricordi i fatti principali degli scambi avvenuti ore prima.
  • Memoria delle entità: assistenti personali, chatbot consapevoli delle preferenze dell'utente, sistemi di tutoring in cui il profilo dell'utente è importante per tutta la sessione.

È anche possibile combinare queste strategie: usate la memoria delle entità per i fatti fondamentali e una finestra scorrevole per la conversazione recente.

RAG come alternativa all'inserimento massivo del contesto

Per le applicazioni ad alto contenuto informativo, la strategia migliore per gestire il contesto non consiste nell'inserire affatto i documenti nel contesto; usate invece RAG (Retrieval-Augmented Generation) per recuperare solo gli estratti specifici rilevanti per la query corrente. In questo modo il contesto rimane focalizzato, i costi diminuiscono e spesso si ottengono risposte migliori rispetto all'inserimento di un intero documento.

L'idea fondamentale è che le finestre di contesto lunghe risolvono il problema ci sta?, ma non il problema il modello lo userà bene?. Un recupero preciso risolve entrambi, fornendo al modello solo le informazioni effettivamente necessarie per la domanda corrente.

Gestione corretta degli errori relativi al contesto massimo

Nonostante i vostri sforzi, in produzione potreste incontrare errori relativi al limite di contesto, soprattutto a causa di contenuti generati dagli utenti che risultano inaspettatamente lunghi. Gestite sempre esplicitamente l'errore context_length_exceeded, invece di lasciarlo propagarsi come eccezione non gestita fino all'utente.

import openai
import tiktoken

client = openai.OpenAI()

def chat_with_context_guard(messages, model='gpt-4o-mini', max_tokens=100000):
    enc = tiktoken.encoding_for_model(model)
    total = sum(len(enc.encode(m.get('content',''))) + 4 for m in messages) + 3

    while total > max_tokens and len(messages) > 2:
        # Remove the second message (keep system prompt)
        removed = messages.pop(1)
        total -= len(enc.encode(removed.get('content',''))) + 4
        print(f'Trimmed a message. New total: {total} tokens')

    try:
        return client.chat.completions.create(model=model, messages=messages)
    except openai.BadRequestError as e:
        if 'context_length' in str(e):
            return {'error': 'Message history too long. Please start a new conversation.'}
        raise

Persistenza del contesto tra le sessioni

In un'applicazione reale, gli utenti chiudono e riaprono l'app. Il server viene riavviato. La gestione del contesto deve tenere conto della persistenza tra le sessioni, non solo all'interno di una singola sessione. Ciò significa memorizzare la cronologia delle conversazioni in un database e caricarla all'inizio di ogni sessione.

Un approccio sensato consiste nel memorizzare la cronologia completa e non elaborata in PostgreSQL per finalità di audit e fine-tuning, ma, quando si carica il contesto per una nuova chiamata API, applicare la strategia di riepilogo o troncamento per rientrare nel budget di token. In questo modo non perdete mai i dati, ma non pagate la cronologia completa a ogni richiesta.

Monitoraggio della crescita del contesto in produzione

Registrate il numero di token di ogni chiamata API e monitoratelo nel tempo in base all'ID della conversazione. Una conversazione sana dovrebbe mostrare una crescita graduale seguita da un plateau, quando entra in funzione il riepilogo. Una conversazione che cresce senza limiti fino a raggiungere il limite di contesto indica che la logica di troncamento non funziona correttamente.

Monitorate anche la lunghezza media del contesto in tutte le conversazioni. Se aumenta nel tempo, potrebbe indicare che il prompt di sistema predefinito sta crescendo (a causa dell'aggiunta di funzionalità), che gli utenti stanno incollando input più lunghi oppure che RAG sta restituendo blocchi progressivamente più grandi. Ognuno di questi problemi richiede una soluzione diversa.

Combinazione delle strategie: un modello per la produzione

Un sistema robusto di gestione del contesto in produzione combina più strategie organizzate a livelli:

  1. Prima di assemblare il contesto: verificate il budget di token e registratelo
  2. Applicate l'estrazione delle entità: inserite un blocco di memoria strutturato con i fatti principali
  3. Aggiungete la cronologia recente: includete alla lettera gli ultimi 6-10 messaggi
  4. Riepilogate la cronologia meno recente: se esiste una cronologia precedente, inserite un riepilogo aggiornato
  5. Controllo di sicurezza: se il totale supera ancora il budget, troncate i messaggi alla lettera più vecchi

Questo approccio a livelli preserva le informazioni più importanti (memoria delle entità e contesto recente), degradando gradualmente la cronologia meno recente in riepiloghi e ricorrendo al troncamento solo come ultima risorsa.

Verifica rapida

Verificate la vostra comprensione dei concetti di AI Engineering trattati in questa lezione.

Riepilogo della lezione

In questa lezione avete imparato che: le finestre scorrevoli e il troncamento basato sui token sono strategie semplici che eliminano il contesto meno recente per rimanere entro i limiti, il riepilogo comprime i turni meno recenti in una rappresentazione compatta preservando i fatti principali e la memoria delle entità estrae fatti strutturati per una memoria a lungo termine efficiente in termini di token durante una conversazione. Ora analizzeremo come fare in modo che gli LLM restituiscano JSON affidabile usando la modalità JSON e gli output strutturati.

Gratis per iniziare

Impara Python con un tutor IA — gratis

Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.

Corsi
30
Lezioni
120

Domande Frequenti

La lezione «Strategie per restare entro i limiti del contesto» è gratuita?

Sì — il testo completo di «Strategie per restare entro i limiti del contesto» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso AI Engineering Academy, passa a CoddyKit PRO. Il corso AI Engineering Academy include 4 lezioni in totale.

Cosa imparerò in «Strategie per restare entro i limiti del contesto»?

Implementerà una memoria a finestra scorrevole, il riepilogo dei messaggi e il taglio selettivo del contesto per gestire conversazioni lunghe senza superare i limiti dei token. Eserciti AI Engineering Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare AI Engineering Academy?

Non è richiesta alcuna esperienza precedente. AI Engineering Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Strategie per restare entro i limiti del contesto»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione AI Engineering Academy?

Sì. Ogni lezione AI Engineering Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Che cos'è un token?
  2. Finestre di contesto: dimensioni e implicazioni
  3. Calcolare e prevedere i costi delle API
  4. Strategie per restare entro i limiti del contesto
← Torna a AI Engineering Academy