Checkpoints und Fortsetzen von Aufgaben
Speichern Sie den Agentenstatus nach jedem abgeschlossenen Schritt, damit eine lang laufende Aufgabe nach einem Fehler am letzten erfolgreichen Checkpoint fortgesetzt werden kann, statt von Grund auf neu zu beginnen.
Checkpoints und Fortsetzen von Aufgaben ist eine kostenlose AI Engineering Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Engineering Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.
Das Problem mit langlebigen Agents
Ein Agent, der eine Rechercheaufgabe mit 50 Schritten ausführt, kann 30 Minuten laufen. Wenn er in Schritt 47 aufgrund eines API-Timeouts oder eines Neustarts des Servers fehlschlägt, gehen beim Neustart von Anfang an alle bisherigen Arbeiten verloren und es entstehen zusätzliche Tokenkosten. Checkpointing speichert den Zustand des Agents nach jedem abgeschlossenen Schritt, sodass die Aufgabe am letzten erfolgreichen Punkt statt am Anfang fortgesetzt werden kann. Dies ist für jede Agent-Aufgabe unerlässlich, die länger als einige Minuten dauert.
Welchen Agent-Zustand Sie speichern sollten
Der Zustand eines Agents besteht aus: der Aufgabendefinition, den abgeschlossenen Schritten mit ihren Tool-Aufrufen und Beobachtungen, dem Index des aktuellen Schritts, allen gesammelten Ergebnissen (geschriebenen Dateien, erfassten Daten) sowie Metadaten wie Startzeit und gesamtem Tokenverbrauch. Speichern Sie all dies nach Abschluss jedes Schritts. Der Zustand muss serialisierbar sein – bevorzugen Sie aus Gründen der Portabilität JSON gegenüber Python-Objekten.
from dataclasses import dataclass, field
from typing import List, Any, Optional
@dataclass
class AgentStep:
step_index: int
thought: str
tool_name: str
tool_args: dict
observation: str
tokens_used: int
completed_at: str
@dataclass
class AgentCheckpoint:
task_id: str
task_description: str
status: str # 'running', 'completed', 'failed'
current_step: int
completed_steps: List[AgentStep] = field(default_factory=list)
accumulated_results: dict = field(default_factory=dict)
total_tokens: int = 0
final_answer: Optional[str] = NoneCheckpoints nach jedem Schritt speichern
Serialisieren Sie nach jedem erfolgreichen Schritt den Checkpoint und schreiben Sie ihn in einen persistenten Speicher. Verwenden Sie eine Datenbank oder einen Objektspeicher (S3, Redis) statt einer lokalen Festplatte, damit der Checkpoint einen Serverneustart übersteht. Fügen Sie den task_id in den Schlüssel ein, damit Sie den Checkpoint einer bestimmten Aufgabe abrufen können. Schreiben Sie außerdem für jeden Schritt einen Eintrag in ein Schrittprotokoll, um auch dann eine Prüfspur zu erhalten, wenn die Checkpoint-Datei beschädigt wird.
import json
import redis
from dataclasses import asdict
redis_client = redis.Redis()
def save_checkpoint(checkpoint: AgentCheckpoint):
key = f'agent:checkpoint:{checkpoint.task_id}'
data = json.dumps(asdict(checkpoint), default=str)
redis_client.set(key, data, ex=86400) # 24h TTL
# Also append to step log
log_key = f'agent:log:{checkpoint.task_id}'
if checkpoint.completed_steps:
last = checkpoint.completed_steps[-1]
redis_client.rpush(log_key, json.dumps(asdict(last), default=str))
def load_checkpoint(task_id: str) -> AgentCheckpoint | None:
key = f'agent:checkpoint:{task_id}'
data = redis_client.get(key)
if data:
return AgentCheckpoint(**json.loads(data))
return NoneAus einem Checkpoint fortsetzen
Laden Sie beim Fortsetzen einer Aufgabe den Checkpoint und rekonstruieren Sie den Nachrichtenverlauf des Agents anhand der abgeschlossenen Schritte. Starten Sie die Ausführungsschleife beim Index des nächsten nicht abgeschlossenen Schritts. Das Modell erhält seine vorherigen Gedanken und Beobachtungen im Nachrichtenverlauf und damit den vollständigen Kontext der bisherigen Arbeit, sodass es fortfahren kann, ohne bereits erledigte Arbeit zu wiederholen.
async def resume_or_start(task_id: str, task_description: str) -> str:
checkpoint = load_checkpoint(task_id)
if checkpoint and checkpoint.status == 'running':
print(f'Resuming task {task_id} from step {checkpoint.current_step}')
messages = rebuild_history(checkpoint)
start_step = checkpoint.current_step
else:
print(f'Starting new task {task_id}')
checkpoint = AgentCheckpoint(task_id=task_id, task_description=task_description, status='running', current_step=0)
messages = [{'role': 'user', 'content': task_description}]
start_step = 0
save_checkpoint(checkpoint)
return await run_agent_from(checkpoint, messages, start_step)Den Nachrichtenverlauf aus Schritten rekonstruieren
Der Schlüssel zum Fortsetzen liegt in der getreuen Rekonstruktion des Nachrichtenverlaufs aus den gespeicherten Schritten. Jeder abgeschlossene Schritt entspricht einer Assistant-Nachricht (Gedanke plus Tool-Aufruf) und einer Tool-Nachricht (Beobachtung). Spielen Sie alle abgeschlossenen Schritte als Nachrichten erneut ab, bevor Sie fortfahren, damit das Modell denselben Kontext wie vor der Unterbrechung erhält.
def rebuild_history(checkpoint: AgentCheckpoint) -> list:
messages = [{'role': 'user', 'content': checkpoint.task_description}]
for step in checkpoint.completed_steps:
# Reconstruct the agent's reasoning message
messages.append({
'role': 'assistant',
'content': f'Thought: {step.thought}\nAction: {step.tool_name}({step.tool_args})'
})
# Reconstruct the tool observation
messages.append({
'role': 'user',
'content': f'Observation: {step.observation}'
})
return messagesIdempotente Tool-Aufrufe
Wenn ein Schritt vor einem Absturz nur teilweise abgeschlossen wurde (das Tool wurde aufgerufen, aber die Beobachtung nicht gespeichert), ruft die Fortsetzung das Tool möglicherweise erneut auf. Entwerfen Sie Tools idempotent: Zweimalige Aufrufe mit denselben Argumenten müssen dasselbe Ergebnis liefern wie ein einmaliger Aufruf. Verwenden Sie bei Schreibvorgängen (dem Erstellen von Dateien, dem Senden von E-Mails) Deduplizierungsschlüssel, um doppelte Auswirkungen zu verhindern, selbst wenn das Tool mehrfach aufgerufen wird.
async def idempotent_write_file(content: str, path: str, task_id: str, step: int) -> str:
dedup_key = f'{task_id}:step_{step}:write:{path}'
if redis_client.exists(dedup_key):
return f'File {path} already written (dedup key present)'
with open(path, 'w') as f:
f.write(content)
redis_client.set(dedup_key, '1', ex=3600)
return f'Successfully wrote {len(content)} chars to {path}'Bereinigung und Aufbewahrung von Checkpoints
Checkpoints belegen Speicherplatz und sollten sich nicht unbegrenzt ansammeln. Legen Sie eine Aufbewahrungsrichtlinie fest: Löschen Sie abgeschlossene Checkpoints nach 24 Stunden, fehlgeschlagene Checkpoints nach 7 Tagen (für die nachträgliche Analyse) und laufende Checkpoints niemals automatisch. Implementieren Sie einen Hintergrundbereinigungsjob, der stündlich ausgeführt wird und abgelaufene Checkpoints gemäß der Richtlinie entfernt.
from datetime import datetime, timedelta
RETENTION = {
'completed': timedelta(hours=24),
'failed': timedelta(days=7),
'running': None # never auto-delete
}
def cleanup_expired_checkpoints():
now = datetime.utcnow()
for key in redis_client.scan_iter('agent:checkpoint:*'):
data = json.loads(redis_client.get(key))
status = data.get('status', 'running')
retention = RETENTION.get(status)
if retention is None:
continue
started = datetime.fromisoformat(data.get('started_at', str(now)))
if now - started > retention:
redis_client.delete(key)Checkpointing in LangGraph
LangGraph bietet über die Klassen MemorySaver und SqliteSaver native Unterstützung für Checkpointing. Verknüpfen Sie einen Checkpointer mit Ihrem Graphen, damit jede Knotenausführung automatisch gespeichert wird. Rufen Sie zum Fortsetzen graph.invoke mit derselben thread_id auf. LangGraph übernimmt die Rekonstruktion des Verlaufs und die Nachverfolgung der Schritte, sodass Sie die Checkpointing-Logik nicht selbst implementieren müssen.
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.graph import StateGraph
# Create graph with persistent checkpointer
checkpointer = SqliteSaver.from_conn_string('/tmp/agent_state.db')
graph = StateGraph(AgentState)
graph.add_node('reason', reason_node)
graph.add_node('act', act_node)
# ... add edges ...
app = graph.compile(checkpointer=checkpointer)
# Run with thread_id - LangGraph auto-checkpoints
config = {'configurable': {'thread_id': 'task_abc123'}}
result = await app.ainvoke({'task': 'Research climate change'}, config)
# Resume same thread - LangGraph loads from checkpoint
result = await app.ainvoke({'task': 'Continue'}, config)Verteiltes Checkpointing für parallele Agents
Wenn mehrere Agents parallel an Teilaufgaben arbeiten, benötigt jeder Agent einen eigenen Checkpoint-Namensraum. Verwenden Sie eine hierarchische Schlüsselstruktur: parent_task_id:sub_task_id. Der Checkpoint des übergeordneten Agents vermerkt, welche Teilaufgaben abgeschlossen wurden, und enthält deren Ergebnisse. Beim Fortsetzen verwendet der übergeordnete Agent die abgeschlossenen Ergebnisse der Teilaufgaben aus dem Checkpoint, statt sie erneut auszuführen.
async def parallel_with_checkpoints(parent_id: str, subtasks: list) -> list:
results = []
for i, subtask in enumerate(subtasks):
sub_id = f'{parent_id}:sub_{i}'
# Check if subtask already completed
existing = load_checkpoint(sub_id)
if existing and existing.status == 'completed':
print(f'Sub-task {i} already done, using cached result')
results.append(existing.final_answer)
else:
result = await run_agent(sub_id, subtask)
results.append(result)
return resultsDas Verhalten beim Fortsetzen testen
Schreiben Sie Integrationstests, die den Agent absichtlich während einer Aufgabe abstürzen lassen, und überprüfen Sie, ob das Fortsetzen zum korrekten Endergebnis führt. Simulieren Sie einen Absturz, indem Sie bei einem bestimmten Schrittindex eine Exception auslösen. Prüfen Sie nach dem Fortsetzen, dass nur die Schritte nach dem Absturz erneut ausgeführt werden, nicht die davor. Testen Sie außerdem, dass idempotente Tool-Aufrufe beim erneuten Abspielen eines Schritts keine doppelten Auswirkungen erzeugen.
import pytest
@pytest.mark.asyncio
async def test_resumption_from_step_3():
task_id = 'test_resume_001'
# Run until step 3, then crash
with pytest.raises(SimulatedCrash):
await run_agent_crashing_at(task_id, 'Research AI trends', crash_at_step=3)
checkpoint = load_checkpoint(task_id)
assert checkpoint.current_step == 3
assert len(checkpoint.completed_steps) == 3
# Resume and complete
result = await resume_or_start(task_id, 'Research AI trends')
assert result is not None
# Verify only steps 4+ were re-executed
assert checkpoint_step_was_not_replayed(task_id, step=0)Checkpoint-Versionierung bei Schemaänderungen
Wenn Sie das Schema von AgentCheckpoint ändern (etwa durch das Hinzufügen oder Umbenennen von Feldern), sind ältere gespeicherte Checkpoints nicht mehr kompatibel. Behandeln Sie dies mit einer Checkpoint-Versionierung: Fügen Sie ein Feld checkpoint_version hinzu und schreiben Sie Migrationsfunktionen, die alte Checkpoints beim Laden auf das neue Schema aktualisieren. Dadurch werden Abstürze verhindert, wenn Agents nach einem Deployment mit geändertem Checkpoint-Format fortgesetzt werden.
def load_and_migrate_checkpoint(task_id: str) -> AgentCheckpoint:
raw = json.loads(redis_client.get(f'agent:checkpoint:{task_id}'))
version = raw.get('checkpoint_version', '1.0')
if version == '1.0':
# Migrate: add new fields added in v2.0
raw['checkpoint_version'] = '2.0'
raw['accumulated_results'] = raw.get('accumulated_results', {})
raw['total_tokens'] = raw.get('total_tokens', 0)
return AgentCheckpoint(**raw)Kurzer Check
Testen Sie Ihr Verständnis von Checkpointing und der Wiederaufnahme von Aufgaben in Agents.
Zusammenfassung der Lektion
In dieser Lektion haben Sie gelernt: Checkpointing serialisiert den Zustand des Agents nach jedem Schritt, sodass langlebige Aufgaben Fehler überstehen, ohne von Anfang an neu gestartet werden zu müssen. Das Rekonstruieren des Nachrichtenverlaufs aus gespeicherten Schritten gibt dem Modell beim Fortsetzen den vollständigen Kontext, und idempotente Tools mit Deduplizierungsschlüsseln verhindern doppelte Auswirkungen, wenn Schritte erneut abgespielt werden. Als Nächstes entwerfen wir Auslöser für die Eskalation an Menschen.
Häufig gestellte Fragen
Ist die Lektion „Checkpoints und Fortsetzen von Aufgaben“ kostenlos?
Ja — der vollständige Text von „Checkpoints und Fortsetzen von Aufgaben“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Engineering Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Engineering Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Checkpoints und Fortsetzen von Aufgaben“?
Speichern Sie den Agentenstatus nach jedem abgeschlossenen Schritt, damit eine lang laufende Aufgabe nach einem Fehler am letzten erfolgreichen Checkpoint fortgesetzt werden kann, statt von Grund auf… Du übst AI Engineering Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um AI Engineering Academy zu starten?
Keine Vorkenntnisse erforderlich. AI Engineering Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Checkpoints und Fortsetzen von Aufgaben“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser AI Engineering Academy-Lektion Code schreiben und ausführen?
Ja. Jede AI Engineering Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Fehlermodi von Agenten klassifizieren
- Selbstkorrektur und reflektierendes Prompting
- Checkpoints und Fortsetzen von Aufgaben
- Eskalation mit Human-in-the-Loop