IntermédiaireLLM
18 min de lecture10 vues

Gérer le Context Window et la Mémoire des LLMs

Comprenez les limites de mémoire des LLMs, le phénomène lost-in-the-middle, et maîtrisez les stratégies pour gérer efficacement de longs contextes en production.

Le context window : la "RAM" du LLM

Un LLM n'a pas de mémoire persistante entre les sessions. Tout ce qu'il "sait" lors d'une conversation se trouve dans sa fenêtre de contexte : une zone tampon de taille fixe contenant l'historique, le prompt système, les documents injectés et la réponse en cours.

┌─────────────────────────────────────────────┐
│  System prompt (instructions permanentes)   │
│  ─────────────────────────────────────────  │
│  Message 1 (user) / Message 2 (assistant)   │
│  ... historique complet ...                 │
│  ─────────────────────────────────────────  │
│  Documents RAG injectés                     │
│  ─────────────────────────────────────────  │
│  Réponse en génération →                    │
└─────────────────────────────────────────────┘
         LIMITE : X tokens maximum

Quand la limite est atteinte, le modèle ne génère pas d'erreur visible : il oublie silencieusement les tokens les plus anciens, ou l'API retourne une erreur context_length_exceeded.


L'évolution explosive des context windows

ModèleAnnéeContext windowÉquivalent pages A4
GPT-320204 096 tokens~5 pages
GPT-4 Turbo2023128 000 tokens~160 pages
Claude 3.5 Sonnet2024200 000 tokens~250 pages
Gemini 2.0 Flash20251 048 576 tokens~1 300 pages

Cette progression est spectaculaire, mais un grand contexte ne garantit pas une utilisation uniforme de toute l'information.


Lost-in-the-middle : l'angle mort des LLMs

Une étude de Stanford/UC Berkeley (2023) a démontré un phénomène contre-intuitif : les LLMs exploitent bien mieux les informations au début ou à la fin du contexte que celles placées au milieu.

Ne supposez jamais qu'un LLM "lit" uniformément tout le contexte fourni. Placez les informations critiques en début ou en fin de prompt.


Stratégies de gestion du contexte

1. Truncation simple

def truncate_history(messages: list, max_tokens: int, model: str = "gpt-4o") -> list:
    import tiktoken
    enc = tiktoken.encoding_for_model(model)
    total = sum(len(enc.encode(m["content"])) for m in messages)

    while total > max_tokens and len(messages) > 1:
        removed = messages.pop(1)  # Garder le system prompt
        total -= len(enc.encode(removed["content"]))
    return messages

2. Summarization progressive

Résumer périodiquement les anciens échanges et les compresser en un seul message de contexte. Plus coûteux mais préserve la cohérence narrative.

3. RAG comme alternative

Au lieu d'injecter tout un document dans le contexte, indexez-le dans une base vectorielle et récupérez uniquement les passages pertinents à chaque requête.


Micro-exercice : démontrer le lost-in-the-middle

from openai import OpenAI

client = OpenAI()

def creer_document_test(position: str = "milieu") -> str:
    debut = "La Tour Eiffel est un monument parisien construit en 1889. " * 20
    fait_cle = "Le mot de passe secret est BANANE42. "
    fin = "Le Louvre est le plus grand musée du monde. " * 20

    if position == "debut":
        return fait_cle + debut + fin
    elif position == "fin":
        return debut + fin + fait_cle
    else:
        return debut + fait_cle + fin

for position in ["debut", "milieu", "fin"]:
    doc = creer_document_test(position)
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": f"Document : {doc}"},
            {"role": "user", "content": "Quel est le mot de passe secret mentionné ?"}
        ]
    )
    print(f"Position '{position}': {response.choices[0].message.content[:80]}")

Vous observerez que le modèle trouve facilement le mot de passe en début ou fin, mais hésite quand il est enfoui au milieu du document.


Prompt caching : latence et coûts réduits

Anthropic et OpenAI proposent le prompt caching : les préfixes de prompt identiques sont mis en cache côté serveur. Les appels suivants avec le même préfixe sont jusqu'à 10x plus rapides et ~90% moins chers pour la partie cachée.

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": "Tu es un expert juridique. " + open("code_civil.txt").read(),
        "cache_control": {"type": "ephemeral"}  # Cache ce préfixe
    }],
    messages=[{"role": "user", "content": "Que dit l'article 1134 ?"}]
)
print(response.usage)  # cache_read_input_tokens indique les tokens cachés

Long context vs RAG : tableau décisionnel

CritèreLong ContextRAG
Taille du corpus< 500 pagesIllimité
Coût par requêteÉlevéFaible
Précision sur fait précisBonneTrès bonne
Cohérence globale du docExcellenteRisque de manquer des liens
LatenceÉlevéeFaible
Mise à jour du corpusImmédiateRé-indexation nécessaire

Règle pratique : Long context pour des documents uniques où la cohérence globale compte (contrats, rapports). RAG pour des bases de connaissances volumineuses où vous cherchez des faits précis.

Specialiste IA — Master Intelligence Artificielle

Diplome d'un Master en Intelligence Artificielle, je travaille au quotidien sur des projets IA en entreprise. J'ai cree IwanttolearnAI pour rendre l'apprentissage de l'IA accessible a tous, gratuitement.