Eine Suche reichte nicht
Agentische Suche heißt, dass ein Agent erneut sucht, wenn die ersten Ergebnisse die Frage nicht beantworten. Das ist wichtig, weil eine echte Frage oft zwei Blicke braucht: Der erste findet das Thema, der zweite das Detail.
Jemand fragt, wie lange er gesperrt bleibt. Die erste Suche findet die Passwortregeln, nicht die Sperrdauer. Der Agent sucht noch einmal.
Das Ziel dieser Lektion
Notiz
Ich kann einen Agenten mehr als einmal suchen lassen, mit Stoppregel und Grenze, und seine Antworten an bekannten Fragen bewerten.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Agentische Suche | eine Suche, die der Agent wiederholen und ändern darf |
| Stoppregel | die Bedingung, die die Suchschleife beendet |
| Suchgrenze | die meisten Suchen, die eine Frage nutzen darf |
| Abdeckung | der Anteil der nötigen Quellen, die gefunden wurden |
| Belegte Antwort | eine Antwort, deren Quellen wirklich abgerufen wurden |
| Gesehen | die bisher gefundenen Quellen |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Suche ist ein wiederverwendbares Werkzeug
Beim Thema Agenten wurde eine Agentenschleife mit einem Schrittbudget gebaut. Hier ist das Werkzeug die Suche. Der Agent sucht, liest, was zurückkommt, und antwortet entweder oder sucht mit einer neuen Anfrage erneut.
Zwei Dinge brauchen Sorgfalt. Die Schleife muss enden. Und die endgültige Antwort muss auf dem beruhen, was wirklich gefunden wurde.
Drei Arten zu stoppen
Man stoppt, wenn der Agent antwortet. Man stoppt, wenn eine Suche nichts Neues bringt, denn dieselben Wörter nochmals zu suchen hilft nicht. Man stoppt an einer Grenze für Suchen, gesetzt nach Kosten und Zeit.
Halten Sie fest, warum die Schleife stoppte: beantwortet, gestoppt, Grenze oder keine Antwort. Der Grund zeigt, was zu beheben ist.
Durchgerechnetes Beispiel: drei Durchläufe derselben Frage
| Durchlauf | Suchen | Endet mit | Belegt |
|---|---|---|---|
| Gut | 2 | beantwortet | ja |
| Festgefahren | 2 | Stopp, nichts Neues | nein |
| Grenze von 1 | 1 | Stopp, Grenze | nein |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Prüfen Sie, dass die Antwort Quellen hat
Eine Antwort nennt ihre Quellen. Sie ist belegt nur, wenn jede Quelle unter den Seiten ist, die die Suchen geliefert haben. Eine Quelle, die der Agent nie sah, ist erfunden.
Messen Sie auch die Abdeckung: Von den Seiten, die eine Frage braucht, wie viele haben die Suchen gefunden? Bewerten Sie beides an Fragen mit bekannten Quellen.
Ein häufiger Fehler
Warnung
Viele glauben, ein Agent, der eine Quelle nennt, habe sie genutzt. Eine Nennung ist nur Text. Prüfen Sie, dass jede genannte ID von einer Suche dieses Durchlaufs geliefert wurde, sonst geht eine erfundene Quelle als echte durch.
Den Modell-Helfer schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const basis = process.env.AI_URL || \"http://ai:4000\";' '// Die Token einer Antwort oder null, wenn sie keine nennt.' 'function zaehlen(daten, name) {' ' return daten.usage && typeof daten.usage[name] === \"number\" ? daten.usage[name] : null;' '}' > model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Den Modell-Helfer schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function fragen(nachrichten, probe, max) {' ' try {' ' const res = await fetch(basis + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: nachrichten, max_tokens: max || 100 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"Status \" + res.status);' ' const d = await res.json();' ' return { text: d.choices[0].message.content, eingabe: zaehlen(d, \"prompt_tokens\"), ausgabe: zaehlen(d, \"completion_tokens\"), aufgezeichnet: false };' ' } catch (fehler) {' ' console.log(\"Aufgezeichnete Probe: Kein Modell hat geantwortet (\" + fehler.message + \").\");' ' return { text: probe, eingabe: null, ausgabe: null, aufgezeichnet: true };' ' }' '}' 'module.exports = { fragen };' >> model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Suchschleife schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { fragen } = require(\"./model\");' 'const index = {' ' \"Passwortregeln\": [\"p2\", \"p1\"],' ' \"Sperrdauer\": [\"p3\"],' ' \"Passwort zurücksetzen\": [\"p1\"],' '};' 'const dok = { p1: \"Setzen Sie Ihr Passwort über die Anmeldeseite zurück.\", p2: \"Ein Passwort hat zehn Zeichen.\", p3: \"Nach fünf falschen Passwörtern wird das Konto fünfzehn Minuten gesperrt.\" };' > agentisch1.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Suchschleife schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function laufen(schritte, max) {' ' const gesehen = [];' ' let n = 0;' ' for (const s of schritte) {' ' if (\"antwort\" in s) {' ' const ok = s.quellen.length > 0 && s.quellen.every(function (p) { return gesehen.includes(p); });' ' return \"beantwortet, belegt: \" + (ok ? \"ja\" : \"nein\");' ' }' ' if (n === max) return \"Stopp: Grenze von \" + max + \" Suche(n)\";' ' n++;' ' const treffer = index[s.suche] || [];' ' const neu = treffer.filter(function (p) { return gesehen.includes(p) === false; });' ' neu.forEach(function (p) { gesehen.push(p); });' ' console.log(\" Suche \" + n + \": \" + s.suche + \" -> \" + (treffer.join(\" \") || \"nichts\") + \", neu \" + neu.length);' ' if (neu.length === 0) return \"Stopp: nichts Neues\";' ' }' ' return \"keine Antwort\";' '}' >> agentisch1.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Suchschleife schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const gut = [{ suche: \"Passwortregeln\" }, { suche: \"Sperrdauer\" }, { antwort: \"Fünfzehn Minuten.\", quellen: [\"p3\"] }];' 'const fest = [{ suche: \"Passwort zurücksetzen\" }, { suche: \"Passwort zurücksetzen\" }, { antwort: \"Unsicher.\", quellen: [\"p1\"] }];' 'console.log(\"guter Durchlauf:\"); console.log(laufen(gut, 3));' 'console.log(\"festgefahrener Durchlauf:\"); console.log(laufen(fest, 3));' 'console.log(\"Durchlauf mit Grenze:\"); console.log(laufen(gut, 1));' 'async function main() {' ' const text = \"Frage: wie lange bin ich gesperrt. Die erste Suche fand: \" + dok.p2 + \" Schreiben Sie eine bessere Suchanfrage mit höchstens 5 Wörtern. Antworten Sie nur mit der Anfrage.\";' ' const antwort = await fragen([{ role: \"user\", content: text }], \"Sperrdauer des Kontos\", 20);' ' console.log(\"ein Modell schlägt vor:\", antwort.text.trim());' '}' 'main();' >> agentisch1.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die drei Schleifen starten
docker exec -w /home/node/project agent node agentisch1.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Das ist ein Platzhalter
Die Schleife folgt aufgezeichneten Schritten, also sieht jede Person dieselben drei Durchläufe. Ein echter Agent wählt seine Schritte selbst, und der Modellaufruf schlägt hier nur eine Anfrage vor, die der Run ausgibt, ohne ihr zu folgen.
Der Index hat drei Einträge. Ein echter ist die hybride Suche, die Sie gebaut haben, mit dem Filter aus Lektion 5.
Was der Run ausgibt
| Durchlauf | Letzte Zeile |
|---|---|
| guter Durchlauf | beantwortet, belegt: ja |
| festgefahrener Durchlauf | Stopp: nichts Neues |
| Durchlauf mit Grenze | Stopp: Grenze von 1 Suche(n) |
| Vorschlag des Modells | Eine mögliche Ausgabe: Sperrdauer des Kontos |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.