Zum Inhalt springen

Erstellen Sie einen Multi-Turn-LLM-Chat mit Gesprächshistorie in Jitterbit Studio

Einführung

Ein Multi-Turn-Gespräch erfordert mehr als das Senden einer einzelnen Benutzer-Nachricht an ein LLM: Das Modell benötigt die vollständige Austauschhistorie, um kohärent auf Folgefragen zu antworten und den Kontext über die Runden hinweg aufrechtzuerhalten. Dieser Leitfaden behandelt das Low-Level-Muster zum Erstellen und Speichern eines Gesprächshistorien-Arrays in Studio, wobei Cloud Datastore als Sitzungsstore und SumCSV verwendet wird, um Nachrichten zwischen den Ausführungen zu sammeln.

Dieser Leitfaden unterscheidet sich von Wie man einen kontextuellen KI-Agenten erstellt, der die gesamte Agentenarchitektur behandelt. Der Fokus liegt hier auf den Skript- und Transformationsmustern, die das messages-Array konstruieren: wie man jede Nachricht als CSV-Zeile formatiert, wie man die vollständige Historie zwischen den Ausführungen speichert und abruft und wie man optionale Felder wie tool_call_id behandelt, wenn man die Gesprächshistorie mit Funktionsaufrufen kombiniert.

Dieser Leitfaden baut auf:

Hinweis

Dieser Leitfaden verwaltet die Gesprächshistorie explizit, was erforderlich ist, wenn Sie das LLM über den HTTP v2-Connector aufrufen. Wenn Sie stattdessen Eingabeaufforderungen über einen nativen LLM-Connector senden, kann der Connector den Chat-Kontext für Sie beibehalten: Die OpenAI, Azure OpenAI und Amazon Bedrock Connectoren verfügen über eine Einstellung Chat-Kontext über Operationen hinweg speichern, die die Historie zwischen Operationen beibehält, die dasselbe chatId in Cloud-Agentengruppen teilen, und private Agenten behalten den Chat-Kontext automatisch im Speicher.

Designmuster

Das Gesprächsverlauf-Muster fügt zwei Schritte um einen standardmäßigen LLM-Aufruf hinzu: einen Schritt zur Abrufung des Verlaufs vor der Anfrage und einen Schritt zur Aktualisierung des Verlaufs nach der Antwort.

flowchart LR A["Abfrage Cloud Datastore
Verlauf nach Sitzungs-ID abrufen"] --> B["Skript
Nachrichten-CSV erstellen"] --> C["Transformation
CSV in JSON konvertieren
LLM aufrufen"] --> D["Skript
Benutzer + Assistent anhängen
CDS aktualisieren"]

Jede Benutzer-Nachricht und jede Assistenten-Antwort wird im Cloud Datastore als Zeile in einem CSV-String gespeichert, der durch einen Sitzungsbezeichner (typischerweise eine Slack-Kanal-ID oder Benutzer-ID) gekennzeichnet ist. Vor jedem LLM-Aufruf wird der vollständige Verlauf abgerufen und in das messages-Array zusammengefügt. Nachdem das LLM geantwortet hat, werden die aktuelle Benutzer-Nachricht und die Antwort des Assistenten beide zum Verlauf hinzugefügt, und der aktualisierte String wird zurück in den Cloud Datastore geschrieben.

Teil 1: Cloud Datastore-Speicher einrichten

Erstellen Sie einen Schlüssel-Speicher mit einem Feld ConversationHistory, um den CSV-Verlauf-String für jede Sitzung zu halten. Folgen Sie Speichern und Abrufen des Sitzungsstatus mit Cloud Datastore für die vollständigen Einrichtungsschritte. Um Felder hinzuzufügen, navigieren Sie im Harmony-Portal zu Harmony-Portal-Menü > Management Console > Cloud Datastore, öffnen Sie den Schlüssel-Speicher und fügen Sie ein Feld mit dem Namen ConversationHistory vom Typ Big Text hinzu. Die integrierten Felder Key, Alternative Key und Value sind immer vorhanden und müssen nicht hinzugefügt werden.

Hinweis

Big Text-Felder unterstützen bis zu 25.000 Bytes pro Element. Für langanhaltende Gespräche implementieren Sie eine Truncationsstrategie: Behalten Sie nur die letzten N Austausche bei, bevor Sie zurück in den Cloud Datastore schreiben, oder fassen Sie frühere Wendungen mithilfe des LLM selbst zusammen, bevor Sie speichern.

Teil 2: Verlauf abrufen und das Nachrichten-Array erstellen

Verlauf abrufen

Der erste Schritt in der Operation fragt den Cloud Datastore nach dem Sitzungsdatensatz ab, wobei der Sitzungsbezeichner (zum Beispiel eine Slack-Kanal-ID) als Schlüssel-Filter verwendet wird. Nach der Aktivität "Abfrageelemente" lesen Sie das Ergebnis in einem Skript-Schritt:

<trans>
$historyMessages = "";
if(Source.json.pagination.totalItems > 0,
    $historyMessages = Source.json.items.item[0].ConversationHistory
);
</trans>

Dies setzt historyMessages auf den gespeicherten CSV-String oder auf einen leeren String, wenn dies die erste Runde in der Sitzung ist.

Nachrichtenarray erstellen

Im nächsten Skriptschritt wird das vollständige Nachrichtenarray als CSV-String unter Verwendung von SumCSV zusammengestellt. Jeder Aufruf von SumCSV erzeugt eine CSV-Zeile aus einem Array von Feldwerten:

<trans>
// System message (always first, not stored in history)
message = Array();
message[0] = "system";
message[1] = $systemPrompt;
$messages = SumCSV(message);

// Append stored conversation history (all prior user/assistant pairs)
if(length(trim($historyMessages)) > 0,
    $messages = $messages + "\n" + $historyMessages
);

// Append the current user message
message[0] = "user";
message[1] = $userInput;
$messages = $messages + "\n" + SumCSV(message);
</trans>

messages enthält jetzt einen CSV-String mit einer Zeile pro Nachricht. Die Systemnachricht steht immer an erster Stelle; die gespeicherte Historie folgt in der Reihenfolge, in der sie angesammelt wurde; die aktuelle Benutzernachricht steht zuletzt.

Tipp

Speichern Sie den Sitzungsschlüssel in einer globalen Variablen vor diesem Vorgang, damit das Cloud Datastore-Update in Teil 4 denselben Schlüssel verwendet.

Teil 3: Konvertieren Sie das Nachrichtenarray in JSON und rufen Sie das LLM auf

Konfigurieren Sie das Quellschema der Transformation

Fügen Sie eine Transformation zur Operation hinzu und setzen Sie die Quelldaten auf die Variable messages, die als CSV geparst ist. Definieren Sie ein zweispaltiges CSV-Quellschema:

  • role (string)
  • content (string)

Ordnen Sie das Nachrichtenarray der LLM-Anforderungsstelle zu

Ordnen Sie die CSV-Spalten dem Anforderungstextkörper von OpenAI Chat Completions zu. Der Zielpfad für jeden Nachrichten-Eintrag ist json/messages/item:

  • json/messages/item/role → Quellspalte role
  • json/messages/item/content → Quellspalte content

Wenn die Operation auch die Ergebnisse von Toolaufrufen zur Historie hinzufügt (zur Verwendung mit dem Muster des Toolaufrufs), kann die CSV zusätzliche Spalten enthalten. Verwenden Sie Unmap im Zielskriptfeld, um das Feld wegzulassen, wenn die Spalte leer ist, anstatt einen Null- oder leeren String-Wert zu senden:

// Im Zielskript für json/messages/item/tool_call_id
if(length(trim(tool_call_id)) == 0, Unmap(), tool_call_id)

Wenden Sie dasselbe Muster auf name an, wenn Sie eine tool_name-Spalte einfügen:

// In dem Zielskript für json/messages/item/name
if(length(trim(tool_name)) == 0, Unmap(), tool_name)

Dies stellt sicher, dass das Feld im serialisierten JSON-Objekt fehlt, wenn es leer ist. Die OpenAI-API erfordert, dass tool_call_id und name abwesend (nicht null oder leer) sind für standardmäßige user- und assistant-Nachrichten.

Mit dem LLM-Endpunkt verbinden

Platzieren Sie die HTTP v2 POST-Aktivität, die auf den OpenAI Chat Completions-Endpunkt abzielt, nach der Transformation. Für die Verbindung und Authentifizierung siehe OpenAI zur Verarbeitung von Daten in einer Studio-Operation verwenden.

Teil 4: Die Antwort anhängen und Cloud Datastore aktualisieren

Nach dem LLM-Aufruf extrahiert ein Skriptschritt die Antwort des Assistenten, fügt sowohl die Benutzer-Nachricht als auch die Antwort des Assistenten zur gespeicherten Historie hinzu und schreibt die aktualisierte Zeichenfolge zurück in den Cloud Datastore.

Die aktualisierte Historie-Zeichenfolge erstellen

<trans>
// Extract the assistant response
$assistantReply = TrimChars(GetJSONString($jitterbit.response, "/choices/0/message/content"), "\"");

// Build the two new rows to append
userMessage = Array();
userMessage[0] = "user";
userMessage[1] = $userInput;

assistantMessage = Array();
assistantMessage[0] = "assistant";
assistantMessage[1] = $assistantReply;

newExchange = SumCSV(userMessage) + "\n" + SumCSV(assistantMessage);

// Combine prior history with the new exchange
$updatedHistory = trim($historyMessages);
if(length($updatedHistory) > 0,
    $updatedHistory = $updatedHistory + "\n"
);
$updatedHistory = $updatedHistory + newExchange;
</trans>

updatedHistory enthält alle vorherigen Austausche sowie die aktuelle Benutzer-Nachricht und die Antwort des Assistenten. Die Systemnachricht ist nicht enthalten: Sie wird dynamisch zu Beginn jeder Runde in Teil 2 vorangestellt und muss nicht gespeichert werden.

Die aktualisierte Historie in den Cloud Datastore schreiben

Verwenden Sie das Abfrage-Einfügen-Aktualisieren-Muster aus Sitzungsstatus mit Cloud Datastore speichern und abrufen, um updatedHistory in das Feld ConversationHistory zu schreiben, das mit demselben Sitzungsbezeichner versehen ist, der in Teil 2 verwendet wurde.

Hinweis

Die Update Items-Aktivität vergleicht den Datensatz, der aktualisiert werden soll, anhand seines Key-Felds. Wenn das Abfrageergebnis aus Teil 2 totalItems = 0 zurückgegeben hat, muss stattdessen die Einfügeoperation ausgeführt werden. Strukturieren Sie die Post-Update-Kette so, dass sie dem Muster im Cloud Datastore-Leitfaden entspricht.

Alternative Ansatz: GetInstance()

Die GetInstance Funktion bietet eine alternative Möglichkeit, Nachrichtenrollen zuzuweisen, wenn Nachrichten bereits als strukturiertes Array gespeichert sind (zum Beispiel aus einem JSON-Array oder einer Datenbanktabelle mit einer Zeile pro Nachricht abgerufen). In einer Transformation, die über Nachrichteninstanzen iteriert, verwenden Sie TargetInstanceCount, um den aktuellen Zeilenindex zu erhalten und Rollen basierend auf gerader/ungerader Position zuzuweisen:

<trans>
// Assign alternating user/assistant roles based on row position (1-based)
$role = if(TargetInstanceCount() % 2 == 1, "user", "assistant");
</trans>

Ordnen Sie role zu json/messages/item/role. Dieser Ansatz funktioniert, wenn alle Wendungen mit ihren Inhaltswerten in chronologischer Reihenfolge gespeichert sind und die Rollenzuweisung allein aus der Position abgeleitet werden kann. Er unterstützt keine Systemnachricht als distinct ersten Eintrag oder per-Nachricht Rollenmetadaten.

Der SumCSV Ansatz in Teil 2 ist flexibler für das Muster des Konversationsagenten: Er unterstützt eine explizite Systemnachricht, erlaubt jede Rolle pro Zeile und speichert die gesamte Historie als ein einzelnes Cloud Datastore-Feld, ohne ein separates Zeile-pro-Nachricht-Schema zu erfordern.

Überprüfen Sie die Integration

  1. Bereitstellen und ausführen Sie die Operation mit einem Sitzungsschlüssel, der noch nicht im Speicher existiert. Geben Sie eine anfängliche Benutzer-Nachricht an.

  2. Bestätigen Sie in den Betriebsprotokollen, dass das Abfrageergebnis totalItems = 0 zeigt und dass die Einfügeoperation ausgeführt wurde, um den Sitzungsdatensatz zu erstellen.

  3. Öffnen Sie in Management Console > Cloud Datastore den Speicher und bestätigen Sie, dass ein Datensatz mit dem erwarteten Schlüssel existiert und dass ConversationHistory eine Benutzerzeile und eine Assistentenzeile enthält.

  4. Führen Sie die Operation erneut mit demselben Sitzungsschlüssel und einer Folgefrage aus, die sich auf den ersten Austausch bezieht.

  5. Bestätigen Sie, dass die LLM-Antwort den vorherigen Kontext widerspiegelt. Bestätigen Sie im Cloud Datastore, dass ConversationHistory jetzt zwei Benutzer/Assistenten-Paare enthält.

  6. Wenn die LLM-Antwort den vorherigen Kontext ignoriert, verwenden Sie WriteToOperationLog, um messages vor der Transformation zu protokollieren und zu bestätigen, dass vorherige Wendungen im CSV-String erscheinen.

  7. Wenn die Transformation einen Schema-Mismatch-Fehler auslöst, bestätigen Sie, dass die Spaltenanzahl des CSV-Quellschemas mit der Anzahl der Werte übereinstimmt, die an jeden SumCSV-Aufruf übergeben werden. Alle Zeilen müssen die gleiche Anzahl von Spalten haben.