How to Build an AI Agent
How to Build an AI Agent
s06

Compact

Gedächtnisverwaltung

Three-Layer Compression

205 LOC5 Toolsmicro-compact + auto-compact + archival
Context will fill up; three-layer compression strategy enables infinite sessions

s01 > s02 > s03 > s04 > s05 > [ s06 ] | s07 > s08 > s09 > s10 > s11 > s12

"Kontext wird sich füllen; Sie brauchen eine Möglichkeit, Platz zu schaffen" -- Drei-Schichten-Kompressionsstrategie für unendliche Sitzungen.

Problem

Das Kontext-Fenster ist endlich. Ein einzelnes read_file auf einer 1000-Zeilen-Datei kostet ~4000 Tokens. Nach dem Lesen von 30 Dateien und dem Ausführen von 20 bash-Befehlen erreichen Sie 100.000+ Tokens. Der Agent kann nicht auf großen Codebasen ohne Komprimierung arbeiten.

Lösung

Drei Schichten, zunehmend in der Aggressivität:

Jeder Zug:
+------------------+
| Tool call result |
+------------------+
        |
        v
[Schicht 1: micro_compact]        (still, jeder Zug)
  Ersetze tool_result > 3 Züge alt
  mit "[Previous: used {tool_name}]"
        |
        v
[Check: tokens > 50000?]
   |               |
   nein             ja
   |               |
   v               v
weiter      [Schicht 2: auto_compact]
              Speichere Transcript in .transcripts/
              LLM fasst Konversation zusammen.
              Ersetze alle Nachrichten mit [summary].
                    |
                    v
            [Schicht 3: compact tool]
              Modell ruft compact explizit auf.
              Gleiche Zusammenfassung wie auto_compact.

Wie es funktioniert

  1. Schicht 1 -- micro_compact: Vor jedem LLM-Aufruf, ersetze alte Tool-Ergebnisse mit Platzhaltern.
def micro_compact(messages: list) -> list:
    tool_results = []
    for i, msg in enumerate(messages):
        if msg["role"] == "user" and isinstance(msg.get("content"), list):
            for j, part in enumerate(msg["content"]):
                if isinstance(part, dict) and part.get("type") == "tool_result":
                    tool_results.append((i, j, part))
    if len(tool_results) <= KEEP_RECENT:
        return messages
    for _, _, part in tool_results[:-KEEP_RECENT]:
        if len(part.get("content", "")) > 100:
            part["content"] = f"[Previous: used {tool_name}]"
    return messages
  1. Schicht 2 -- auto_compact: Wenn Tokens den Schwellenwert überschreiten, speichere vollständiges Transcript auf Disk, dann bitte das LLM zusammenzufassen.
def auto_compact(messages: list) -> list:
    # Save transcript for recovery
    transcript_path = TRANSCRIPT_DIR / f"transcript_{int(time.time())}.jsonl"
    with open(transcript_path, "w") as f:
        for msg in messages:
            f.write(json.dumps(msg, default=str) + "\n")
    # LLM summarizes
    response = client.messages.create(
        model=MODEL,
        messages=[{"role": "user", "content":
            "Summarize this conversation for continuity..."
            + json.dumps(messages, default=str)[:80000]}],
        max_tokens=2000,
    )
    return [
        {"role": "user", "content": f"[Compressed]\n\n{response.content[0].text}"},
        {"role": "assistant", "content": "Understood. Continuing."},
    ]
  1. Schicht 3 -- manuell compact: Das compact Tool löst bei Bedarf die gleiche Zusammenfassung aus.

  2. Die Schleife integriert alle drei:

def agent_loop(messages: list):
    while True:
        micro_compact(messages)                        # Schicht 1
        if estimate_tokens(messages) > THRESHOLD:
            messages[:] = auto_compact(messages)       # Schicht 2
        response = client.messages.create(...)
        # ... tool execution ...
        if manual_compact:
            messages[:] = auto_compact(messages)       # Schicht 3

Transcripts bewahren vollständige Historie auf Disk. Nichts geht wirklich verloren -- nur aus dem aktiven Kontext verschoben.

Was sich von s05 geändert hat

KomponenteVorher (s05)Nachher (s06)
Tools55 (base + compact)
Kontext-VerwaltungNoneDrei-Schichten-Kompression
Micro-compactNoneAlte Ergebnisse -> Platzhalter
Auto-compactNoneToken-Schwellenwert-Auslöser
TranscriptsNoneGespeichert in .transcripts/

Ausprobieren

python agents/s06_context_compact.py
  1. Lesen Sie jede Python-Datei im agents/ Verzeichnis nacheinander (beobachten Sie micro-compact ersetzt alte Ergebnisse)
  2. Lesen Sie weiter Dateien, bis die Komprimierung automatisch ausgelöst wird
  3. Verwenden Sie das compact Tool, um die Konversation manuell zu komprimieren