Iteratives Abrufmuster (Iterative Retrieval Pattern)
Löst das „Kontextproblem“ in Multi-Agent-Workflows, bei dem Subagenten erst während ihrer Arbeit erkennen, welchen Kontext sie benötigen.
Wann aktivieren
- Beim Erzeugen von Subagenten, die Codebase-Kontext benötigen, den sie nicht vorhersagen können
- Beim Aufbau von Multi-Agent-Workflows, bei denen der Kontext schrittweise verfeinert wird
- Bei Fehlern wie „Kontext zu groß“ oder „fehlender Kontext“ in Agentenaufgaben
- Beim Entwurf von RAG-ähnlichen Abrufpipelines für die Code-Exploration
- Zur Optimierung der Token-Nutzung bei der Agenten-Orchestrierung
Das Problem
Subagenten werden mit begrenztem Kontext erzeugt. Sie wissen nicht:
- Welche Dateien relevanten Code enthalten
- Welche Muster in der Codebase existieren
- Welche Terminologie das Projekt verwendet
Standardansätze scheitern:
- Alles senden: Überschreitet Kontextgrenzen
- Nichts senden: Dem Agenten fehlen kritische Informationen
- Raten, was benötigt wird: Oft falsch
Die Lösung: Iteratives Abrufen (Iterative Retrieval)
Eine 4-Phasen-Schleife, die den Kontext schrittweise verfeinert:
┌─────────────────────────────────────────────┐
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ DISPATCH │─────│ EVALUATE │ │
│ └──────────┘ └──────────┘ │
│ ▲ │ │
│ │ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ LOOP │─────│ REFINE │ │
│ └──────────┘ └──────────┘ │
│ │
│ Max 3 Zyklen, dann fortfahren │
└─────────────────────────────────────────────┘
Phase 1: DISPATCH
Erste breite Abfrage zur Sammlung von Kandidatendateien:
// Beginnen Sie mit der übergeordneten Absicht
const initialQuery = {
patterns: ['src/**/*.ts', 'lib/**/*.ts'],
keywords: ['authentication', 'user', 'session'],
excludes: ['*.test.ts', '*.spec.ts']
};
// An den Abrufagenten senden
const candidates = await retrieveFiles(initialQuery);
Phase 2: EVALUATE
Bewertung des abgerufenen Inhalts auf Relevanz:
function evaluateRelevance(files, task) {
return files.map(file => ({
path: file.path,
relevance: scoreRelevance(file.content, task),
reason: explainRelevance(file.content, task),
missingContext: identifyGaps(file.content, task)
}));
}
Bewertungskriterien:
- Hoch (0,8-1,0): Implementiert direkt die Zielfunktionalität
- Mittel (0,5-0,7): Enthält verwandte Muster oder Typen
- Niedrig (0,2-0,4): Nur indirekt verwandt
- Keine (0-0,2): Nicht relevant, ausschließen
Phase 3: REFINE
Aktualisieren der Suchkriterien basierend auf der Bewertung:
function refineQuery(evaluation, previousQuery) {
return {
// Neue Muster hinzufügen, die in hochrelevanten Dateien gefunden wurden
patterns: [...previousQuery.patterns, ...extractPatterns(evaluation)],
// Terminologie aus der Codebase hinzufügen
keywords: [...previousQuery.keywords, ...extractKeywords(evaluation)],
// Bestätigte irrelevante Pfade ausschließen
excludes: [...previousQuery.excludes, ...evaluation
.filter(e => e.relevance < 0.2)
.map(e => e.path)
],
// Auf spezifische Lücken fokussieren
focusAreas: evaluation
.flatMap(e => e.missingContext)
.filter(unique)
};
}
Phase 4: LOOP
Wiederholung mit verfeinerten Kriterien (maximal 3 Zyklen):
async function iterativeRetrieve(task, maxCycles = 3) {
let query = createInitialQuery(task);
let bestContext = [];
for (let cycle = 0; cycle < maxCycles; cycle++) {
const candidates = await retrieveFiles(query);
const evaluation = evaluateRelevance(candidates, task);
// Prüfen, ob ausreichend Kontext vorhanden ist
const highRelevance = evaluation.filter(e => e.relevance >= 0.7);
if (highRelevance.length >= 3 && !hasCriticalGaps(evaluation)) {
return highRelevance;
}
// Verfeinern und fortsetzen
query = refineQuery(evaluation, query);
bestContext = mergeContext(bestContext, highRelevance);
}
return bestContext;
}
Praktische Beispiele
Beispiel 1: Kontext für Fehlerbehebung
Aufgabe: "Behebe den Authentifizierungs-Token-Ablauffehler"
Zyklus 1:
DISPATCH: Suche nach "token", "auth", "expiry" in src/**
EVALUATE: Gefunden auth.ts (0.9), tokens.ts (0.8), user.ts (0.3)
REFINE: Füge "refresh", "jwt"-Schlüsselwörter hinzu; schließe user.ts aus
Zyklus 2:
DISPATCH: Suche mit verfeinerten Begriffen
EVALUATE: Gefunden session-manager.ts (0.95), jwt-utils.ts (0.85)
REFINE: Ausreichender Kontext (2 hochrelevante Dateien)
Ergebnis: auth.ts, tokens.ts, session-manager.ts, jwt-utils.ts
Beispiel 2: Feature-Implementierung
Aufgabe: "Füge Ratenbegrenzung zu API-Endpunkten hinzu"
Zyklus 1:
DISPATCH: Suche "rate", "limit", "api" in routes/**
EVALUATE: Keine Treffer – Codebase verwendet "throttle"-Terminologie
REFINE: Füge "throttle", "middleware"-Schlüsselwörter hinzu
Zyklus 2:
DISPATCH: Suche mit verfeinerten Begriffen
EVALUATE: Gefunden throttle.ts (0.9), middleware/index.ts (0.7)
REFINE: Router-Muster benötigt
Zyklus 3:
DISPATCH: Suche nach "router", "express"-Mustern
EVALUATE: Gefunden router-setup.ts (0.8)
REFINE: Ausreichender Kontext
Ergebnis: throttle.ts, middleware/index.ts, router-setup.ts
Integration mit Agenten
Verwendung in Agent-Prompts:
Beim Abrufen von Kontext für diese Aufgabe:
1. Beginne mit einer breiten Schlüsselwortsuche
2. Bewerte die Relevanz jeder Datei (Skala 0-1)
3. Identifiziere, welcher Kontext noch fehlt
4. Verfeinere die Suchkriterien und wiederhole (max. 3 Zyklen)
5. Gib Dateien mit Relevanz >= 0.7 zurück
Best Practices
- Beginnen Sie breit, verfeinern Sie schrittweise – Spezifizieren Sie anfängliche Abfragen nicht zu genau
- Lernen Sie die Terminologie der Codebase – Der erste Zyklus enthüllt oft die Namenskonventionen
- Verfolgen Sie, was fehlt – Explizite Lückenidentifikation treibt die Verfeinerung voran
- Stoppen Sie, wenn es „gut genug“ ist – 3 hochrelevante Dateien sind besser als 10 mittelmäßige
- Schließen Sie sicher aus – Dateien mit niedriger Relevanz werden nicht relevant
Verwandtes
- Der ausführliche Leitfaden – Abschnitt zur Subagenten-Orchestrierung
- Skill
continuous-learning– Für Muster, die sich im Laufe der Zeit verbessern - Agentendefinitionen, die mit ECC gebündelt sind (manueller Installationspfad:
agents/)