Strategie mieszczące się w oknie kontekstu
Uczestnicy zaimplementują pamięć z przesuwanym oknem, podsumowywanie wiadomości i selektywne skracanie kontekstu, aby obsługiwać długie rozmowy bez przekraczania limitów tokenów.
Strategie mieszczące się w oknie kontekstu to bezpłatna lekcja AI Engineering Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Engineering Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.
Narastający problem rozmów
Każda wiadomość wymieniona w rozmowie zwiększa liczbę tokenów kolejnego wywołania API. W długiej sesji obsługi klienta lub wielogodzinnej sesji programistycznej zgromadzona historia rozmowy może z łatwością przekroczyć 20 000–50 000 tokenów — a całą tę historię trzeba wysyłać do API przy każdej kolejnej turze, wielokrotnie płacąc za wcześniej przetworzone tokeny.
Bez strategii zarządzania kontekstem aplikacja albo osiągnie limit kontekstu i ulegnie awarii, albo po cichu skróci wiadomości, przez co model straci informacje o ważnym wcześniejszym kontekście. Każda produkcyjna aplikacja LLM potrzebuje jasno określonej strategii zarządzania rozrostem kontekstu.
Strategia 1: okno przesuwne (ostatnie N wiadomości)
Najprostsza strategia polega na zachowaniu w kontekście tylko ostatnich N wiadomości i odrzuceniu starszych. Nazywa się to oknem przesuwnym. Jest łatwe do zaimplementowania, zapewnia przewidywalne koszty i wystarcza w wielu przypadkach użycia, w których nowszy kontekst jest ważniejszy niż starsze wymiany.
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 smallStrategia 2: przycinanie uwzględniające tokeny
Zamiast przycinać historię na podstawie liczby wiadomości, przycinanie uwzględniające tokeny usuwa wiadomości do momentu, aż całkowita liczba tokenów spadnie poniżej określonego progu. Jest to dokładniejsze rozwiązanie, ponieważ długość wiadomości może się znacznie różnić — limit liczby wiadomości może obejmować 10 krótkich wiadomości albo 3 bardzo długie, co oznacza zupełnie inne koszty tokenów.
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 trimmedStrategia 3: podsumowywanie rozmowy
Podsumowywanie kompresuje starsze tury rozmowy do zwięzłego podsumowania, zachowując najważniejsze fakty, decyzje i kontekst wspomniane przez użytkownika. Jest to bardziej zaawansowane rozwiązanie niż okna przesuwne, ponieważ zachowuje istotę wcześniejszych wymian, zamiast po prostu je odrzucać.
Wzorzec ten działa w następujący sposób: gdy rozmowa przekroczy określony próg, należy wysłać do modelu N najstarszych tur wraz z promptem „Podsumuj dotychczasowy przebieg tej rozmowy”, zastąpić te tury pojedynczą wiadomością systemową zawierającą podsumowanie, a następnie kontynuować rozmowę z nową, skompresowaną historią.
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: pamięć encji
Pamięć encji wydobywa i przechowuje ustrukturyzowaną reprezentację najważniejszych faktów wspomnianych w rozmowie — preferencji użytkownika, imion, szczegółów projektu i podjętych decyzji — zamiast przechowywać surową historię wiadomości. Przed każdą turą zapisane fakty są wstrzykiwane do promptu systemowego.
Rozwiązanie to jest bardziej efektywne pod względem liczby tokenów niż pełna historia, ponieważ uwzględnia tylko informacje ważne semantycznie, a nie każde słowo z każdej tury. Pamięć encji sprawdza się szczególnie dobrze w przypadku długotrwale używanych asystentów, gdy użytkownicy odwołują się do preferencji i faktów ustalonych znacznie wcześniej w rozmowie.
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))Kiedy stosować poszczególne strategie
Strategię należy wybrać na podstawie charakterystyki aplikacji:
- Okno przesuwne: proste aplikacje czatowe, w których liczy się wyłącznie najnowszy kontekst, a użytkownicy nie odwołują się do wcześniejszych wymian. Najtańsze rozwiązanie do zaimplementowania.
- Przycinanie uwzględniające tokeny: każda aplikacja produkcyjna, w której długości wiadomości znacznie się różnią. Zawsze lepsze niż przycinanie na podstawie liczby wiadomości.
- Podsumowywanie: długotrwale używani asystenci, sesje obsługi klienta i boty do zarządzania projektami. Użytkownicy oczekują, że asystent będzie pamiętał najważniejsze fakty z wymian sprzed kilku godzin.
- Pamięć encji: asystenci osobisti, chatboty uwzględniające preferencje użytkownika oraz systemy korepetycyjne, w których profil użytkownika ma znaczenie przez całą sesję.
Strategie te można również łączyć: używać pamięci encji do przechowywania najważniejszych faktów, a okna przesuwnego do obsługi najnowszej części rozmowy.
RAG jako alternatywa dla upychania kontekstu
W przypadku aplikacji opartych na dużej ilości wiedzy najlepszą strategią zarządzania kontekstem nie jest umieszczanie dokumentów w kontekście — zamiast tego należy użyć RAG (Retrieval-Augmented Generation), aby pobierać tylko konkretne fragmenty istotne dla bieżącego zapytania. Dzięki temu kontekst pozostaje skoncentrowany, koszty są niższe, a odpowiedzi często są lepsze niż w przypadku wstrzykiwania całego dokumentu.
Kluczowy wniosek jest taki, że długie okna kontekstu rozwiązują problem czy da się to zmieścić?, ale nie rozwiązują problemu czy model dobrze to wykorzysta?. Precyzyjne wyszukiwanie rozwiązuje oba problemy, dostarczając modelowi tylko informacje rzeczywiście potrzebne do udzielenia odpowiedzi na bieżące pytanie.
Prawidłowa obsługa błędów maksymalnego kontekstu
Mimo najlepszych starań w środowisku produkcyjnym mogą wystąpić błędy limitu kontekstu, szczególnie w przypadku treści tworzonych przez użytkowników, które okazują się nieoczekiwanie długie. Należy zawsze jawnie obsługiwać błąd context_length_exceeded, zamiast pozwalać, aby przedostał się do użytkownika jako nieobsłużony wyjątek.
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.'}
raiseUtrwalanie kontekstu między sesjami
W rzeczywistej aplikacji użytkownicy zamykają i ponownie otwierają aplikację. Serwer jest restartowany. Zarządzanie kontekstem musi uwzględniać utrwalanie danych między sesjami, a nie tylko w obrębie jednej sesji. Oznacza to przechowywanie historii rozmów w bazie danych i wczytywanie jej na początku każdej sesji.
Rozsądny wzorzec polega na przechowywaniu pełnej, surowej historii w PostgreSQL do celów audytu i dostrajania, ale podczas wczytywania kontekstu na potrzeby nowego wywołania API należy zastosować strategię podsumowywania lub przycinania, aby zmieścić się w budżecie tokenów. W ten sposób nie tracą Państwo danych, ale nie płacą za pełną historię przy każdym żądaniu.
Monitorowanie rozrostu kontekstu w środowisku produkcyjnym
Należy rejestrować liczbę tokenów każdego wywołania API i śledzić ją w czasie dla każdego identyfikatora rozmowy. W zdrowej rozmowie powinien być widoczny stopniowy wzrost, a następnie stabilizacja, gdy zaczyna działać podsumowywanie. Rozmowa, która rośnie bez ograniczeń aż do osiągnięcia limitu kontekstu, wskazuje, że logika przycinania nie działa prawidłowo.
Należy również monitorować średnią długość kontekstu we wszystkich rozmowach. Jeśli z czasem rośnie, może to oznaczać, że domyślny prompt systemowy się rozrasta (w wyniku dodawania funkcji), użytkownicy wklejają coraz dłuższe dane wejściowe albo RAG zwraca coraz większe fragmenty. Każda z tych przyczyn wymaga innego rozwiązania.
Łączenie strategii: wzorzec produkcyjny
Solidny produkcyjny system zarządzania kontekstem łączy wiele strategii w warstwach:
- Przed złożeniem kontekstu: sprawdź budżet tokenów i zarejestruj go
- Zastosuj ekstrakcję encji: wstrzyknij ustrukturyzowany blok pamięci z najważniejszymi faktami
- Dodaj najnowszą historię: dołącz 6–10 ostatnich wiadomości w niezmienionej formie
- Podsumuj starszą historię: jeśli istnieje starsza historia, wstrzyknij aktualizowane podsumowanie
- Kontrola ochronna: jeśli całość nadal przekracza budżet, usuń najstarsze wiadomości zachowane w niezmienionej formie
Takie warstwowe podejście zachowuje najważniejsze informacje (pamięć encji i najnowszy kontekst), a jednocześnie stopniowo upraszcza starszą historię — najpierw do podsumowań, a następnie, w ostateczności, przez jej przycinanie.
Szybki sprawdzian
Sprawdź swoją wiedzę na temat koncepcji inżynierii AI omówionych w tej lekcji.
Podsumowanie lekcji
W tej lekcji dowiedziałeś się, że: okna przesuwne i przycinanie uwzględniające tokeny to proste strategie odrzucające starszy kontekst, aby zmieścić się w limitach, podsumowywanie kompresuje starsze tury do zwartej reprezentacji zachowującej najważniejsze fakty, a także że pamięć encji wydobywa ustrukturyzowane fakty, zapewniając efektywną pod względem tokenów pamięć długoterminową w obrębie rozmowy. Następnie omówimy, jak skłonić LLM-y do zwracania niezawodnego JSON-u za pomocą trybu JSON i ustrukturyzowanych danych wyjściowych.
Często zadawane pytania
Czy lekcja „Strategie mieszczące się w oknie kontekstu” jest bezpłatna?
Tak — pełny tekst „Strategie mieszczące się w oknie kontekstu” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Engineering Academy, przejdź na CoddyKit PRO. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Strategie mieszczące się w oknie kontekstu”?
Uczestnicy zaimplementują pamięć z przesuwanym oknem, podsumowywanie wiadomości i selektywne skracanie kontekstu, aby obsługiwać długie rozmowy bez przekraczania limitów tokenów. Ćwiczysz AI Engineering Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć AI Engineering Academy?
Nie wymagamy żadnego doświadczenia. AI Engineering Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Strategie mieszczące się w oknie kontekstu”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji AI Engineering Academy?
Tak. Każda lekcja AI Engineering Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Czym jest token?
- Okna kontekstu: rozmiar i znaczenie
- Obliczanie i prognozowanie kosztów API
- Strategie mieszczące się w oknie kontekstu