FR ▾
Obtenir votre clé API

Fenêtre de contexte 100k en pratique : suite, résumé, segmentation, budget

Une fenêtre de contexte de 100 000 tokens semble large, mais on découvre vite : un roman entier ne rentre pas, et un document de plusieurs dizaines de pages plus la sortie atteint la limite. Gérons le contexte comme un budget : estimer les tokens, réserver la sortie, segmenter les longs documents, et utiliser une fenêtre glissante avec un plan évolutif pour les romans. Code Python, applicable à tout langage.

Mis à jour le

Points clés

  • 100 000 est la somme du prompt et de la completion, pas une limite d'entrée seule.
  • Le nombre de tokens chinois est une estimation : environ 1 à 1,5 token par caractère. La valeur exacte figure dans usage de la réponse.
  • Résumé de longs documents par segmentation et fusion ; suite de roman par les derniers chapitres et un résumé dynamique.
  • max_tokens vaut 2048 par défaut et 16 000 au maximum. Calculez votre budget avant de générer du contenu long.

Calculer d'abord la limite

Trois chiffres déterminent tout :

  • Fenêtre de contexte totale de 100 000 tokens, prompt et completion confondus.
  • max_tokens vaut 2048 par défaut, avec un maximum de 16 000 par requête.
  • Le corps de la requête ne dépasse pas 8 Mo. Cette limite est rarement atteinte pour du texte pur ; ce sont les tokens qui bloquent en premier.

La formule du budget est simple : prompt disponible = 100000 - max_tokens. Si vous prévoyez de faire générer 4000 tokens au modèle en une seule fois, il ne restera plus que 60 000 tokens pour le prompt. Au-delà, l'API renvoie une erreur 400 et ne tronque pas automatiquement. Dire « on met tout dedans et on verra » n'est donc pas une stratégie, mais un pari.

Autre idée reçue : plus max_tokens est élevé, plus c'est sûr. En réalité, c'est un espace réservé pour la sortie. Fixer 16 000 signifie que le prompt ne peut faire que 48 000 tokens. Réglez selon vos besoins, ne mettez pas au maximum par défaut.

Prenons un exemple concret : vous avez un texte d'interview de 300 000 caractères à résumer. En estimant grossièrement 1,3 token par caractère, cela représente environ 390 000 tokens, soit plus de six fois la limite. Impossible de tout envoyer en une seule fois. Si la sortie de résumé nécessite 800 tokens, la limite d'entrée par bloc est de 63 000 tokens. En prévoyant une marge de sécurité de 10 %, vous disposez d'environ 55 000 tokens. Ce n'est pas la solution optimale : lorsque les blocs sont trop grands, le modèle accorde moins d'attention au milieu du texte. Il vaut donc mieux diviser les blocs et effectuer plusieurs appels.

Estimation des tokens : algorithme approximatif

Sans tokeniseur local, utilisez ces valeurs pour une estimation. Ces valeurs sont approximatives, pas exactes, avec une variation de 10 à 20 % selon le texte :

Type de texteConversion approximative
Texte chinoisEnviron 1 à 1,5 token par caractère
AnglaisEnviron 1 token pour 4 caractères, ou 1,3 token par mot
Code, JSON, texte dense en symbolesPlus consommateur de tokens que le texte standard. Utilisez une estimation haute et prudente.

Voici une fonction d'estimation suffisante, incluant le calcul budgétaire avec marge :

CONTEXT = 100000

def est_tokens(text: str) -> int:
    """粗估:中文按每字 1.3 token,其余字符按每 4 个字符 1 token。仅为近似。"""
    zh = sum(1 for c in text if "\u4e00" <= c <= "\u9fff")
    other = len(text) - zh
    return int(zh * 1.3 + other / 4) + 1

def max_prompt_budget(max_tokens: int, margin: float = 0.1) -> int:
    """给定计划的 max_tokens,返回 prompt 最多能用多少 token(留 margin 余量)。"""
    return int((CONTEXT - max_tokens) * (1 - margin))

# 例:计划让模型写 3000 token,prompt 预算
print(max_prompt_budget(3000))   # 54900

Méthode de calibration : envoyez une requête avec un exemple typique d'entrée, lisez la valeur usage.prompt_tokens dans la réponse, comparez-la à votre estimation et calculez le facteur de conversion réel pour vos données. Ajustez ensuite le coefficient en fonction de cette mesure. L'estimation sert uniquement à décider « s'il faut diviser en blocs », pas à la vérification ; pour la vérification, consultez l'usage.

Résumé de longs documents : segmentation et fusion

Si le document dépasse le budget, utilisez map-reduce : segmentez pour résumer chaque partie, puis fusionnez les résumés. Attention aux détails suivants :

  1. Coupez aux limites des paragraphes, pas par nombre de caractères fixe, pour éviter de couper les phrases en deux.
  2. Réservez un budget suffisant par bloc. Il est conseillé de ne pas dépasser le tiers de la limite pour laisser de la place aux instructions et à la sortie.
  3. Les résumés partiels doivent conserver les noms, chiffres et événements clés, sinon l'information est perdue lors de la fusion.
  4. Si le résumé des résumés est encore trop long, appliquez une autre couche de récursivité.
import os
from openai import OpenAI

client = OpenAI(base_url="https://api.wushenchaapi.com/v1", api_key=os.environ["API_KEY"])

def split_paragraphs(text, budget):
    """按段落切块,每块估算不超过 budget token。"""
    chunks, cur, used = [], [], 0
    for p in text.split("\n"):
        t = int(len(p) * 1.3) + 1          # 中文粗估
        if used + t > budget and cur:
            chunks.append("\n".join(cur))
            cur, used = [], 0
        cur.append(p)
        used += t
    if cur:
        chunks.append("\n".join(cur))
    return chunks

def ask(prompt, max_tokens=800):
    r = client.chat.completions.create(
        model="uncensored",
        temperature=0.3,
        max_tokens=max_tokens,
        messages=[{"role": "user", "content": prompt}],
    )
    return r.choices[0].message.content

def summarize_long(text, budget=12000):
    parts = split_paragraphs(text, budget)
    partial = [ask("用不超过 200 字概括下面这段,保留人名和关键事件:\n\n" + p) for p in parts]
    merged = "\n".join(f"第{i+1}部分:{s}" for i, s in enumerate(partial))
    return ask("下面是分段摘要,请合并成一份 400 字以内的整体摘要:\n\n" + merged, max_tokens=900)

Ici, temperature est à 0,3 pour la stabilité. Les appels sont indépendants et peuvent être en parallèle. Attention à la limite de 300 requêtes par minute et par clé ; pour un document de quelques dizaines de segments, vous ne l'atteindrez pas.

La taille des blocs n'a pas de réponse unique. En pratique, 10 000 à 15 000 tokens par bloc offrent un bon équilibre entre conservation des détails et nombre d'appels. Testez un échantillon avec des blocs de 5000, 12000 et 25000 tokens, puis comparez le nombre de faits clés manquants dans les résumés pour choisir la taille adaptée. Pour les contrats ou documents techniques denses, utilisez des blocs plus petits ; pour les dialogues redondants, des blocs plus grands sont acceptables.

Suite de roman : fenêtre glissante et résumé dynamique

Vers le dixième chapitre, le texte entier ne tient plus et n'a pas besoin de tenir. Mémoire à deux niveaux :

  • Proximité : les deux ou trois derniers chapitres originaux pour assurer la cohérence du style, du rythme des dialogues et des détails de scène.
  • Contexte lointain : Les chapitres antérieurs sont compressés en un plan, conservant les relations, les indices et les intrigues non résolues.

Après chaque chapitre, demandez au modèle d'ajouter un résumé de trois à cinq lignes au plan. Si le plan dépasse 3 000 tokens, compressez-le globalement.

def continue_story(chapters, outline, new_hint, keep_last=3):
    """chapters: 已写章节列表。只带最近 keep_last 章原文,更早的用 outline(滚动大纲)代替。"""
    recent = "\n\n".join(chapters[-keep_last:])
    prompt = (
        f"【全书大纲(早期章节摘要)】\n{outline}\n\n"
        f"【最近章节原文】\n{recent}\n\n"
        f"【下一章要求】\n{new_hint}\n\n请写下一章,约 2000 字。"
    )
    return ask(prompt, max_tokens=4000)

Les détails préparés en amont sont les plus faciles à perdre. Il est conseillé de créer une section « intrigues non résolues » dans le plan et d'exiger explicitement, lors de la suite, que le chapitre en traite une. Listez également les noms de personnages et de lieux dans une liste fixe placée dans le système pour éviter que le modèle ne les modifie une fois qu'ils sortent de la fenêtre de contexte.

Un autre problème souvent négligé lors de la génération continue est la dérive stylistique. Le modèle a tendance à se rapprocher du style des derniers chapitres ; si le style des chapitres précédents diffère de celui des chapitres suivants, cette divergence s'amplifie. La solution consiste à inclure dans le système un « échantillon de style » : insérez un passage de votre texte original que vous appréciez particulièrement. Cela sert d'ancrage fixe, indépendant du glissement de la fenêtre.

max_tokens et troncature

Il existe deux cas de troncature de réponse à distinguer :

  1. finish_reason vaut length : vous avez atteint votre max_tokens. Augmentez max_tokens ou demandez au modèle de générer par segments (« arrêtez ici, je dirai de continuer »).
  2. Rejet 400 : prompt + max_tokens dépasse 100 000. Réduisez l'input ou diminuez max_tokens.

Tableau de correspondance budgétaire pratique :

Tâchemax_tokens conseilléprompt disponible (approx.)
résumé, extraction80063,200
poursuite de chapitre (env. 2000 mots)400060,000
sortie longue de plusieurs milliers de mots16000 (limite)48,000

Les sorties longues sont également affectées par le temps de réponse. Il est recommandé d'utiliser le streaming pour afficher le contenu au fur et à mesure de sa génération.

Lorsque la poursuite est tronquée, ne vous contentez pas de soumettre le contenu inachevé au modèle en lui disant « continuez ». Une approche plus robuste consiste à réintégrer le contenu déjà généré en tant que message assistant dans messages, puis à ajouter un message user « écrivez à la suite de la dernière phrase, sans répétition ». Cela assure la transition la plus naturelle. Notez que cette étape allonge le prompt ; vérifiez à nouveau votre budget.

Liste de contrôle pour les longs contextes

  • Avant chaque requête, calculez le prompt avec une fonction d'estimation. Si le budget est dépassé, suivez la branche de segmentation.
  • Enregistrez l'utilisation à chaque réponse pour calibrer en continu les coefficients d'estimation.
  • Placez le system et le plan au début du contenu. Répétez les exigences clés de l'instruction à la fin.
  • Vérifiez finish_reason : s'il est égal à length, émettez une alerte ou lancez une poursuite.
  • Définissez une limite de conservation pour les conversations historiques. Si cette limite est dépassée, supprimez les messages les plus anciens plutôt que d'attendre un code 400 de l'interface.

Liés : Écriture de prompt, Manuel de dépannage des codes d'erreur, Page des tarifs.

Dernier rappel : un long contexte n'équivaut pas à une longue mémoire. Le modèle lit à nouveau à partir de zéro le contenu que vous lui fournissez à chaque requête ; il ne se souvient de rien de l'appel précédent. Pour assurer la continuité, vous devez vous-même transmettre l'historique.

Questions fréquentes

Le contexte 100k inclut-il la sortie ?

Oui. La limite est la somme du prompt et de la complétion. Plus max_tokens est élevé, moins il reste de place pour l'input.

Combien de tokens représente exactement un caractère chinois ?

On ne peut faire qu'une estimation approximative : environ 1 à 1,5 token par caractère, avec des variations selon le texte. La méthode la plus précise consiste à lire le champ usage de la réponse et à calibrer avec la valeur mesurée.

L'entrée est-elle automatiquement tronquée si la limite est dépassée ?

Non, la requête renverra 400. Segmentez ou supprimez l'ancien contenu avant l'appel.

Quelle est la longueur maximale générable en une seule fois ?

max_tokens est de 2048 par défaut, avec un maximum de 16 000. Pour du contenu plus long, générez en plusieurs fois et utilisez un plan ou un résumé pour la cohérence.

Il vous suffit de remplir le formulaire pour obtenir votre clé

Créez un compte, copiez votre clé et modifiez l'URL de base. La configuration est aussi simple que cela.