Warum ein Chatbot Ihren Namen vergisst
Ein Chatbot speichert die Nachrichten eines Gesprächs und schickt sie mit jeder neuen Frage erneut mit. Das ist wichtig, weil ein Aufruf an ein Sprachmodell kein eigenes Gedächtnis hat.
Ein Kunde erzählt dem Chatbot eines Busunternehmens, dass er sein Ticket verloren hat. Dann fragt er „und für meinen Bruder?“. Der Bot versteht das nur, wenn die früheren Nachrichten mitreisen.
Am Ende dieser Lektion
Notiz
Ich kann ein Gespräch über mehrere Anfragen hinweg behalten.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Sitzung | das Gespräch einer Person mit dem Chatbot | |
| Sitzungs-ID | ein Etikett, das eine Sitzung benennt | lena |
| Zustand | was das Programm zwischen Anfragen behält | |
| Speicher | der Ort, an dem alle Sitzungen liegen | |
| Nachrichtenliste | die Nachrichten, die mit jedem Aufruf gehen |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Jeder Aufruf beginnt bei null
Jeder Aufruf an ein Modell beginnt von vorn. Das Modell kennt nur die Nachrichten, die Sie in diesem Aufruf schicken.
Für ein Gespräch speichert Ihr Programm alle Nachrichten. Es schickt jedes Mal die ganze Liste, mit der neuen Frage am Ende. Diese Liste ist der Zustand des Chats.
Beispiel: drei Anfragen
| Anfrage | Gesendete Nachrichten | Was das Modell sehen kann |
|---|---|---|
| 1 | system, user | Nur die Regel und „Ich heiße Lena.“ |
| 2 | system, user, assistant, user | Den ersten Austausch und „Wie heiße ich?“ |
| 3 | system, user, assistant, user, assistant, user | Alles bisher und die neueste Frage |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Jede Person hat ihre eigene Sitzung
Ein Chatbot spricht mit vielen Menschen gleichzeitig. Darum ist der Speicher nach Sitzungs-ID geordnet: eine Liste je Gespräch. Eine neue ID eröffnet eine neue Liste. Eine bekannte ID ergänzt ihre Liste.
Der Speicher kann eine Variable sein, solange das Programm läuft. Eine kleine JSON-Datei im Projektordner bewahrt ihn auf, wenn das Programm endet.
Wem gehört der Zustand?
Der Zustand gehört Ihrem Programm, nicht dem Modell. Darum entscheiden Sie, was gespeichert wird und wie lange.
Speichern Sie keine Passwörter, keine Kartennummern und nichts, was der Chatbot nicht braucht. Geben Sie den Menschen eine Möglichkeit, eine Sitzung zu löschen. Das Löschen einer Sitzung entfernt die ganze Liste.
Ein häufiger Fehler
Warnung
Viele glauben, das Modell erinnere sich daran, wer spricht. Das stimmt nicht. Teilen zwei Personen eine Liste, sieht jede die Worte der anderen. Führen Sie eine Liste je Sitzungs-ID.
Die Modellhilfe schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const basis = process.env.AI_URL || \"http://ai:4000\";' '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 || 200 }),' ' signal: AbortSignal.timeout(30000),' ' });' ' if (res.ok === false) throw new Error(\"Status \" + res.status);' ' return (await res.json()).choices[0].message.content;' > 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 Modellhilfe schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' ' } catch (fehler) {' ' console.log(\"Aufgezeichnete Probe: Kein Modell hat geantwortet (\" + fehler.message + \").\");' ' const liste = [].concat(probe);' ' const runde = nachrichten.filter(function (m) { return m.role === \"assistant\"; }).length;' ' return liste[Math.min(runde, liste.length - 1)];' ' }' '}' '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.
Den Sitzungsspeicher schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const { fragen } = require(\"./model\");' 'const DATEI = \"sitzungen.json\"; // der Speicher liegt im Projektordner' 'const REGEL = \"Sie sind ein freundlicher Assistent. Antworten Sie in einem kurzen Satz.\";' '' 'function laden() {' ' try { return JSON.parse(fs.readFileSync(DATEI, \"utf8\")); } catch (fehler) { return {}; }' '}' 'function speichern(speicher) { fs.writeFileSync(DATEI, JSON.stringify(speicher, null, 1)); }' > chat1.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 Sitzungsspeicher schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function sagen(speicher, id, text, proben) {' ' if (speicher[id] === undefined) speicher[id] = [{ role: \"system\", content: REGEL }];' ' speicher[id].push({ role: \"user\", content: text });' ' const antwort = await fragen(speicher[id], proben, 40);' ' speicher[id].push({ role: \"assistant\", content: antwort });' ' speichern(speicher);' ' return antwort;' '}' >> chat1.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 Sitzungsspeicher schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const speicher = {};' ' // Aufgezeichnete Proben, nur benutzt, wenn kein Modell antwortet.' ' const lenaProben = [\"Freut mich, Lena.\", \"Sie heißen Lena.\"];' ' const jonasProben = [\"Ihren Namen kenne ich noch nicht.\"];' ' console.log(\"Lena:\", await sagen(speicher, \"lena\", \"Ich heiße Lena. Merken Sie sich das.\", lenaProben));' ' console.log(\"Lena:\", await sagen(speicher, \"lena\", \"Wie heiße ich?\", lenaProben));' ' console.log(\"Jonas:\", await sagen(speicher, \"jonas\", \"Wie heiße ich?\", jonasProben));' ' const gelesen = laden();' ' console.log(\"Gespeichert: lena hat \" + gelesen.lena.length + \" Nachrichten, jonas hat \" + gelesen.jonas.length);' '}' 'main();' >> chat1.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.
Zwei Gespräche ausführen
docker exec -w /home/node/project agent node chat1.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Eine mögliche Ausgabe
| Zeile | Was sie zeigen kann |
|---|---|
| Lena (erste) | Ein kurzer Gruß, der den Namen Lena benutzen kann |
| Lena (zweite) | Eine Antwort, die den Namen nennen kann, weil ihr die früheren Nachrichten geschickt wurden |
| Jonas | Eine Antwort, die Lenas Namen nicht kennen kann, weil Jonas eine eigene Liste hat |
| Gespeichert | lena hat 5 Nachrichten, jonas hat 3 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.