AI Engineering Academy · Lekcja

Pamięć podsumowań i skracanie uwzględniające tokeny

Uczestnicy użyją ConversationSummaryMemory do automatycznego podsumowywania starszych tur rozmowy, zachowując jej zwięzłość i najważniejsze fakty podane wcześniej przez użytkownika.

Lekcja 3 z 413 kroki

Pamięć podsumowań i skracanie uwzględniające tokeny to bezpłatna lekcja AI Engineering Academy na CoddyKit. To lekcja 3 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.

Koszt tokenów pełnej historii

Conversation Buffer Memory przechowuje każdą kiedykolwiek wymienioną wiadomość, przez co szybko zużywa okno kontekstu. Rozmowa obejmująca 100 wymian może wymagać 20 000 tokenów wyłącznie na historię, pozostawiając niewiele miejsca na właściwą odpowiedź. Summary Memory rozwiązuje ten problem, zastępując starsze wymiany skompresowanym podsumowaniem.

Jak działa pamięć podsumowująca

Gdy łączna liczba tokenów przekroczy próg, ConversationSummaryMemory przekazuje najstarsze wymiany rozmowy do LLM i prosi o podsumowanie najważniejszych punktów. Pełne wymiany są usuwane i zastępowane zwięzłym podsumowaniem. Kolejne wymiany są dopisywane do podsumowania.

  • Stare wymiany: zastępowane podsumowaniem
  • Najnowsze wymiany: zachowywane bez zmian
  • Wynik: znacząca kompresja przy minimalnej utracie informacji

LangChain ConversationSummaryMemory

LangChain udostępnia ConversationSummaryMemory, które automatycznie tworzy podsumowanie, gdy bufor staje się zbyt duży. Do obiektu pamięci należy przekazać LLM, aby mógł wywoływać model na żądanie w celu generowania podsumowań.

from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model='gpt-4o-mini')

memory = ConversationSummaryMemory(
    llm=llm,
    return_messages=True
)

# Add messages manually
memory.save_context(
    {'input': 'My name is Alice and I am building a RAG system.'},
    {'output': 'Great, I can help you build a RAG system, Alice.'}
)

print(memory.load_memory_variables({}))

Summary Buffer Memory: najlepsze cechy obu podejść

ConversationSummaryBufferMemory to podejście hybrydowe: zachowuje najnowsze wymiany bez zmian, aby zapewnić dokładność, a podsumowuje tylko starsze wymiany przekraczające limit max_token_limit. Zapewnia to dokładne odtwarzanie najnowszego kontekstu oraz skompresowane odtwarzanie starszego kontekstu.

from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model='gpt-4o-mini')

memory = ConversationSummaryBufferMemory(
    llm=llm,
    max_token_limit=500,  # Summarize when older turns exceed 500 tokens
    return_messages=True
)

# As the conversation grows, old turns get summarized automatically
print('Moving summary:', memory.moving_summary_buffer)

Zliczanie tokenów przed skróceniem

Aby podejmować trafne decyzje dotyczące skracania, trzeba wiedzieć, ile tokenów zajmują wiadomości. Biblioteka tiktoken umożliwia zliczanie tokenów dla dowolnego modelu OpenAI. Dzięki temu można zaimplementować skracanie uwzględniające tokeny, które ściśle mieści się w określonym budżecie.

import tiktoken

def count_tokens(messages: list, model: str = 'gpt-4o') -> int:
    encoding = tiktoken.encoding_for_model(model)
    total = 0
    for msg in messages:
        # Each message has overhead tokens for role framing
        total += 4
        total += len(encoding.encode(msg.get('content', '')))
    total += 2  # Reply primer
    return total

messages = [
    {'role': 'user', 'content': 'Explain RAG to me.'},
    {'role': 'assistant', 'content': 'RAG stands for Retrieval-Augmented Generation...'}
]
print('Token count:', count_tokens(messages))

Ręczne skracanie z uwzględnieniem tokenów

Czasami potrzebna jest pełna kontrola nad skracaniem bez korzystania z klas pamięci LangChain. Proste podejście polega na zachowaniu wszystkich wiadomości, a następnie usuwaniu po jednej najstarszych wiadomości niebędących systemowymi, aż łączna liczba tokenów zmieści się w budżecie.

def truncate_to_budget(messages: list, budget: int, model: str = 'gpt-4o') -> list:
    '''Remove oldest non-system messages until under budget.'''
    import tiktoken
    encoding = tiktoken.encoding_for_model(model)

    def token_count(msgs):
        total = 2
        for m in msgs:
            total += 4 + len(encoding.encode(m.get('content', '')))
        return total

    result = list(messages)
    while token_count(result) > budget and len(result) > 1:
        # Never remove the system prompt at index 0
        if result[0]['role'] == 'system':
            del result[1]
        else:
            del result[0]
    return result

Tworzenie promptu podsumowującego

Tworząc własną pamięć podsumowującą, należy przygotować prompt z prośbą o wyodrębnienie najważniejszych faktów. Prompt powinien instruować model, aby uwzględnił preferencje użytkownika, nazwane encje oraz nierozstrzygnięte pytania — fakty, które z największym prawdopodobieństwem będą istotne w kolejnych wymianach.

from openai import OpenAI

client = OpenAI()

def summarize_history(old_summary: str, new_turns: list) -> str:
    turns_text = '\n'.join(
        f'{m["role"].capitalize()}: {m["content"]}' for m in new_turns
    )
    prompt = f'''Current summary:\n{old_summary}\n\nNew conversation turns:\n{turns_text}\n\nWrite an updated summary that captures key facts, user preferences, and open questions.'''

    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return resp.choices[0].message.content

Integracja podsumowania z promptem systemowym

Po utworzeniu podsumowania należy wstrzyknąć je do promptu systemowego, aby LLM zawsze miał kontekst dotyczący historii rozmowy. Podsumowanie należy umieścić jako krótki blok kontekstu przed głównymi instrukcjami definiującymi osobowość.

def build_messages_with_summary(summary: str, recent_turns: list, user_input: str) -> list:
    system_content = (
        'You are a helpful AI assistant.'
        + ('\n\n[Conversation summary]\n' + summary if summary else '')
    )

    messages = [{'role': 'system', 'content': system_content}]
    messages.extend(recent_turns)
    messages.append({'role': 'user', 'content': user_input})
    return messages

Automatyczne wywoływanie podsumowania

Często stosowany wzorzec polega na wywołaniu podsumowania po przekroczeniu przez rozmowę określonego progu tokenów — na przykład gdy bieżąca historia przekroczy 2000 tokenów. Wtedy należy podsumować wszystkie wymiany poza dwiema ostatnimi i zastąpić je podsumowaniem.

class SummaryBufferChat:
    def __init__(self, max_tokens=2000):
        self.summary = ''
        self.recent_turns = []
        self.max_tokens = max_tokens

    def chat(self, user_message: str) -> str:
        from openai import OpenAI
        client = OpenAI()

        messages = build_messages_with_summary(self.summary, self.recent_turns, user_message)
        resp = client.chat.completions.create(model='gpt-4o', messages=messages)
        reply = resp.choices[0].message.content

        self.recent_turns.append({'role': 'user', 'content': user_message})
        self.recent_turns.append({'role': 'assistant', 'content': reply})

        if count_tokens(self.recent_turns) > self.max_tokens:
            to_summarize = self.recent_turns[:-2]
            self.recent_turns = self.recent_turns[-2:]
            self.summary = summarize_history(self.summary, to_summarize)

        return reply

Zachowywanie nazwanych encji w podsumowaniach

Jakość podsumowania w dużej mierze zależy od promptu podsumowującego. Jeśli użytkownicy wspominają o swoim imieniu, miejscu zamieszkania, preferencjach lub terminach, prompt musi wyraźnie instruować model, aby uwzględnił te fakty. Ogólne podsumowania często pomijają nazwy własne, które mają największe znaczenie dla personalizacji.

  • Uwzględnij: imiona i nazwy, daty, podjęte decyzje techniczne, otwarte pytania
  • Pomiń: wymiany bez treści, potwierdzenia, powtarzające się uprzejmości

Kompromisy: pamięć podsumowująca a okienkowa

Wybór między pamięcią podsumowującą a okienkową zależy od przypadku użycia. Pamięć okienkowa zachowuje dokładne brzmienie wypowiedzi, co ma znaczenie przy precyzyjnym odtwarzaniu, ale zużywa tokeny na nieistotny kontekst. Pamięć podsumowująca zapewnia intensywną kompresję, lecz wymaga dodatkowego wywołania LLM i może utracić szczegóły nietypowych przypadków. Większość chatbotów produkcyjnych korzysta z rozwiązania hybrydowego: najnowsze wymiany w oryginalnej postaci oraz starsze objęte narastającym podsumowaniem.

Szybki test

Sprawdź swoją wiedzę na temat pamięci podsumowującej i koncepcji skracania z uwzględnieniem tokenów.

Podsumowanie lekcji

W tej lekcji nauczyłeś się, że: pamięć podsumowująca kompresuje starsze wymiany za pomocą wywołania LLM; ConversationSummaryBufferMemory łączy dokładne najnowsze wymiany z podsumowanymi starszymi; a tiktoken umożliwia skracanie z uwzględnieniem tokenów, aby utrzymać rozmowy w ramach budżetu. W następnej części omówimy trwałe przechowywanie historii czatu w Redis i PostgreSQL.

Bezpłatny start

Ucz się Python dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
30
Lekcje
120

Często zadawane pytania

Czy lekcja „Pamięć podsumowań i skracanie uwzględniające tokeny” jest bezpłatna?

Tak — pełny tekst „Pamięć podsumowań i skracanie uwzględniające tokeny” 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 „Pamięć podsumowań i skracanie uwzględniające tokeny”?

Uczestnicy użyją ConversationSummaryMemory do automatycznego podsumowywania starszych tur rozmowy, zachowując jej zwięzłość i najważniejsze fakty podane wcześniej przez użytkownika. Ć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 3 z 4.

Ile czasu zajmuje lekcja „Pamięć podsumowań i skracanie uwzględniające tokeny”?

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

  1. Dlaczego bezstanowe LLM-y potrzebują pamięci zewnętrznej
  2. Pamięć buforowa i okno kontekstu
  3. Pamięć podsumowań i skracanie uwzględniające tokeny
  4. Trwałe przechowywanie historii czatu w Redis i PostgreSQL
← Powrót do AI Engineering Academy