Die Schleife hinter jedem Modell mit Werkzeugen
Ein Werkzeugaufruf ist nur die Hälfte eines Gesprächs. Das Modell bittet um einen Aufruf, Ihr Programm führt ihn aus, und das Modell muss das Ergebnis sehen, bevor es antworten kann. Der Austausch ist also eine Schleife.
Jeder Assistent mit Werkzeugen führt diese Schleife aus, und sie muss immer einen Weg haben, anzuhalten.
Am Ende dieser Lektion
Notiz
Ich kann die Schleife aus Fragen, Aufrufen, Antworten und erneutem Fragen ausführen.
Schlüsselwörter
| Begriff | Was er bedeutet |
|---|---|
| Schleife | Schritte, die das Programm bis zu einer Haltebedingung wiederholt |
| Nachrichtenverlauf | die Liste der Nachrichten, die bei jeder Frage mitgeht |
| Werkzeugergebnis | die Nachricht, die die Antwort eines Aufrufs zum Modell bringt |
| Schritt | eine Frage und ihre Antwort |
| Schrittgrenze | die höchste Zahl von Schritten einer Schleife |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die Schleife fragt nach jedem Aufruf erneut
Senden Sie die Nachrichten und die Werkzeuge an das Modell. Enthält die Antwort tool_calls, führen Sie jeden Aufruf aus, hängen die Ergebnisse an die Nachrichten an und fragen erneut. Besteht die Antwort aus Worten, ist das die Antwort, und die Schleife endet.
Das Modell behält zwischen zwei Fragen nichts. Jede Frage trägt den ganzen Verlauf.
Durchgerechnetes Beispiel: der Verlauf nach jedem Schritt
| Schritt | Was geschieht | Nachrichten, die danach gesendet werden |
|---|---|---|
| Start | Der Nutzer fragt nach einer Birne | user |
| 1 | Das Modell bittet um preis_von | user, assistant |
| 1 | Ihr Programm hängt das Ergebnis an | user, assistant, tool |
| 2 | Das Modell antwortet mit Worten | user, assistant, tool, assistant |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Einen Helfer speichern, der das Modell aufruft
docker exec -w /home/node/project agent node -e "const fragen=async(m,t,c)=>{const r=await fetch((process.env.AI_URL||'http://ai:4000')+'/v1/chat/completions',{method:'POST',headers:{'content-type':'application/json',authorization:'Bearer lab'},body:JSON.stringify({model:'lab',messages:m,tools:t,tool_choice:c,max_tokens:120})});const j=await r.json();if(r.ok)return j.choices[0].message;throw Error(r.status+' '+j.error.message)};require('fs').writeFileSync('ki.cjs','exports.fragen='+fragen+';');console.log('ki.cjs gespeichert: fragen(messages, tools) gibt die Nachricht des Modells zurück.')"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein Werkzeugergebnis trägt die Aufruf-id
Nach einem Aufruf hängen Sie eine Nachricht mit der Rolle tool an. Sie enthält die tool_call_id der Anfrage, auf die sie antwortet, und das Ergebnis als Text.
Das Modell ordnet mit der id jedes Ergebnis seiner Anfrage zu. Ohne sie könnte eine Antwort mit zwei Aufrufen nicht beide Ergebnisse erhalten.
Die Schleife mit höchstens drei Schritten ausführen
docker exec -w /home/node/project agent node -e "const{fragen}=require('./ki.cjs');const P={apfel:40,birne:45};const T=[{type:'function',function:{name:'preis_von',description:'Ein Preis.',parameters:{type:'object',properties:{artikel:{type:'string'}}}}}];let rec=0;const falsch=m=>m.at(-1).role=='tool'?{role:'assistant',content:'Preis: 45 Cent.'}:{role:'assistant',tool_calls:[{id:'c1',function:{name:'preis_von',arguments:JSON.stringify({artikel:'birne'})}}]};(async()=>{const m=[{role:'user',content:'Preis einer Birne?'}];for(let s=1;s<4;s++){let a;try{if(rec)throw 0;a=await fragen(m,T)}catch(e){rec||console.log('Fehler ('+e.message+'). Aufgezeichnetes Beispiel:');rec=1;a=falsch(m)}m.push(a);if(a.tool_calls==null){console.log('Antwort: '+a.content);return}for(const c of a.tool_calls){const v=P[JSON.parse(c.function.arguments).artikel];console.log('Schritt '+s+': '+c.function.name+' -> '+v);m.push({role:'tool',tool_call_id:c.id,content:String(v)})}}console.log('Grenze erreicht')})()"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Eine Schrittgrenze stoppt die Endlosschleife
Ein Modell kann immer wieder um einen Aufruf bitten. Jeder Schritt kostet Zeit und Guthaben, also zählen Sie die Schritte und halten an einer Grenze an. Drei ist ein guter Anfang.
Kommt die Grenze zuerst, sagt Ihr Programm das. Es tut nicht so, als hätte es eine Antwort.
Ein häufiger Fehler
Warnung
Viele glauben, das Modell erinnere sich an frühere Fragen. Das tut es nicht. Es sieht nur die Nachrichten, die Sie senden. Lassen Sie das Werkzeugergebnis weg, kann das Modell nicht wissen, was der Aufruf lieferte: behalten Sie alle Nachrichten.
Zum Weiterdenken: die Frage ändern
Ändern Sie die Frage im Lauf in Was kosten ein Apfel und eine Birne?. Führen Sie ihn dreimal aus und zählen Sie jedes Mal die Schritte.
Ändern Sie danach s<4 in s<2. Schreiben Sie auf, was das Programm ausgibt, wenn die Grenze zuerst kommt.