Heim > Artikel > Backend-Entwicklung > Anleitung: So erstellen Sie einen KI-Agenten für SRE-Teams
Das Engineering-Team von Aptible AI hat die letzten ca. 4 Monate damit verbracht, einen AI-Agenten zu entwickeln, der unserem SRE-Team bei der Untersuchung und Lösung von Produktionsproblemen helfen soll. Da wir mit so vielen frühen Testern und Designpartnern gesprochen haben, die gerade dabei waren, ihren eigenen Agenten für ähnliche Zwecke zu erstellen, haben wir beschlossen, einen Leitfaden zusammenzustellen, der erklärt, was wir mit unserem eigenen Agenten gemacht haben und wie Sie ihn erstellen können selbst eins.
In der folgenden Schritt-für-Schritt-Anleitung zeigen wir Ihnen, wie Sie:
Aber zuerst ein paar Überlegungen und Profi-Tipps.
? Überlegungen: Wenn Sie nichts Neues bauen müssen, sollten Sie es auch nicht tun. Es gibt so. viele. Werkzeuge auf dem Markt. Und abhängig von Ihrem spezifischen Anwendungsfall finden Sie möglicherweise eine, die für Sie geeignet ist.
Der Anstoß für die Suche von Aptible und schließlich die Entwicklung unserer eigenen Reaktion auf Vorfälle war, dass wir mit Wissenssilos zu kämpfen hatten und dazu neigten, uns jedes Mal auf drei oder vier Fachexperten zu verlassen, wenn wir auf ein Problem mit einem bestimmten System stießen.
Also haben wir mit einem Open-Source-Tool namens Danswer begonnen, um den Informationsabruf zu verbessern (ähnlich wie sein beliebter kommerzieller Konkurrent Glean). Es ließ sich direkt an Slack anschließen und konnte Antworten auf Fragen in natürlicher Sprache aus verschiedenen Informationsquellen abrufen. Das Problem bestand darin, dass es nur auf indizierte Daten beschränkt war (d. h. nur auf unsere Dokumente und unseren Chat-Verlauf).
⚒️ Was wir gebaut haben: Was wir brauchten, war ein Tool, das sich in alle unsere anderen Systeme integrieren ließ (nicht nur in Dokumente und Slack). Wir mussten Protokolle und Metriken sowie den Anwendungszustand abrufen und Berichte und Post-Mortem-Analysen erstellen, nachdem unsere Vorfälle vorüber waren. Deshalb haben wir einen KI-Agenten entwickelt, der im Wesentlichen auf einer Reihe von Integrationen basiert, die Ihnen die Verbindung sowohl mit Echtzeit- als auch mit indizierten Daten ermöglichen. Mehr dazu später!
? Profi-Tipp: Bevor Sie sich entscheiden, Ihr eigenes Produkt zu entwickeln, schauen Sie sich an, was bereits verfügbar ist. Ein guter Ausgangspunkt könnte Crowdsourcing-Ideen von Reddit sein (sehen Sie sich zum Beispiel diesen Thread an) oder sich einige der verfügbaren Open-Source-Tools ansehen (hier ist ein guter Ausgangspunkt in Github, wenn Sie speziell nach Incident-Response-Tools suchen). ). Es gibt auch eine lange Liste von Open-Source-KI-Agenten, die Sie morgen verwenden könnten.
? Überlegungen: Wie oben erwähnt, ist die wichtigste Überlegung hier: Auf welche Art von Informationen soll Ihr Agent Zugriff haben? Vielleicht könnten Sie damit davonkommen, es einfach über eine API mit Drittanbietern zu integrieren, aber wenn Sie die Integration spezifischer auf Ihre Bedürfnisse abstimmen möchten, müssen Sie bei der Funktionsweise Ihrer Integrationen sorgfältiger vorgehen.
Wenn Sie sorgfältig überlegen, was Sie integrieren müssen, bevor Sie mit dem Bau beginnen, ersparen Sie sich später einige Kopfschmerzen. Benötigen Sie, dass Ihr Agent benutzerdefinierte Skripte ausführen kann, um Ihre Datenbanken abzufragen? Benötigen Sie den Echtzeitabruf von Protokollen und Metriken, und wie werden Sie den Agent so gestalten, dass er diese Informationen abruft? Wird der Link zur Quelle zurückgegeben? Wird ein Teil der Protokollzeilen zurückgegeben, die Sie noch manuell durchsuchen müssen, oder kann daraus abgeleitet werden, wo die Anomalie liegen könnte?
⚒️ Was wir entwickelt haben: Im Kern basiert Aptible AI auf einer Reihe von Integrationen. Eine Integration ist mehr als nur eine Verbindung zu einem Drittanbieter, sie ist auch eine Sammlung von Konfigurationen, die einzigartig für die Art und Weise sind, wie unser Team diesen Anbieter nutzt. Aptible AI unterstützt beispielsweise mehrere Integrationen für denselben Anbieter, da wir diesen Anbieter möglicherweise auf unterschiedliche Weise nutzen möchten. Verschiedene Teams verwenden Datadog unterschiedlich und legen Wert auf unterschiedliche Metriken oder verwenden unterschiedliche Tags, sodass jedes Team die Integration in dasselbe Tool auf die Art und Weise nutzen kann, wie es es benötigt.
Aptible AI unterstützt eine Reihe gängiger SRE-Tools, darunter:
Die tatsächliche Implementierung dieser Integrationen passt in eine von drei Kategorien der Anpassbarkeit:
Für den Anfang verfügen Sie über eine Basisintegration, die keiner Anpassung bedarf (PagerDuty ist ein Beispiel). Da es lediglich darum geht, Daten von PagerDuty abzurufen und sie dem KI-Kontext hinzuzufügen, verwendet jedes einzelne Team, das die PagerDuty-Integration nutzt, sie auf die gleiche Weise.
Als nächstes haben wir anpassbarere Integrationen (wie das Datadog-Beispiel von zuvor), die auf einer generischen InfluxDB-Integration aufbauen, aber an die spezifischen Anwendungsfälle des Nachschlagens von Containermetriken und des Nachschlagens von Neustartaktivitäten angepasst sind.
Schließlich gibt es vollständig benutzerdefinierte Tools, die für niemanden außerhalb von Aptible wahrscheinlich keinen Sinn ergeben würden (ein Beispiel wäre hier unsere Integration, die Container für eine Anwendung abruft). Diese sind völlig spezifisch für die Art und Weise, wie wir unsere Infrastruktur betreiben, und können entweder über eine einfache PubSub-Schnittstelle oder einen Websocket-basierten „sicheren“ Proxy implementiert werden.
? Profi-Tipp:Weniger ist mehr! Wenn Sie dem Modell zu viele Werkzeuge zur Auswahl geben, kann es anfangen, falsche Werkzeuge auszuwählen und sich selbst zu verwirren. Mehr dazu im nächsten Abschnitt
? Überlegungen: Hier ist die Sache mit Modellen: Jeden Tag tauchen neue auf, und es gibt mehrere Überlegungen, die Sie bei der Auswahl eines Modells berücksichtigen sollten (hauptsächlich im Zusammenhang mit Ihren spezifischen Anwendungsfällen). Sollten Sie selbst Gastgeber sein? Soll Ihr Agent gesprächig oder aufgabenorientiert sein oder beides? Wird es einfache oder komplexe Aufgaben ausführen? Benötigen Sie Echtzeitleistung?
Wir müssen nicht alle existierenden Modelle durchgehen, da der Inhalt bereits allgegenwärtig ist (wenn Sie tiefer eintauchen möchten, ist dies eine großartige Ressource), aber wir können die Entscheidungen, die wir getroffen haben, durchgehen was beim Aufbau von Aptible AI zu tun ist und welche Optionen wir in Betracht gezogen haben.
Es ist ein kniffliger Prozess, weil man Kompromisse nicht wirklich vermeiden kann. Wenn Ihr Agent komplexe Aufgaben erledigen soll, müssen Sie Abstriche bei der Geschwindigkeit und den Kosten machen.
Größe, Leistungsfähigkeit und Architektur des Modells hängen stark davon ab, ob die Aufgaben eine einfache Klassifizierung oder hochkomplexe Argumentation und Interaktion erfordern. Wenn es einfach wäre, würde ein kleineres, leichtes Modell wie ein Entscheidungsbaum, eine Zufallsstruktur oder ein einfaches neuronales Netzwerk ausreichen. Wenn es komplexer ist, können Sie ein leistungsfähigeres Modell wie GPT-4, BERT oder eine ähnliche transformatorbasierte Architektur in Betracht ziehen.
Wenn Sie sich für das Selbsthosting entscheiden, um Sicherheitsprobleme zu vermeiden, müssen Sie wahrscheinlich auf Features und Funktionalität verzichten, da Ihre selbstgehostete Version hinter den gehosteten Optionen zurückbleibt.
Wenn Ihr Agent in domänenspezifischem Wissen geschult werden soll, müssen Sie zur Feinabstimmung Ihre eigenen Datensätze kuratieren oder erstellen. Versuchen Sie, ein vorab trainiertes Modell zu verwenden, das bereits auf große Datenmengen trainiert wurde, um das Problem der Datenqualität zu vermeiden (obwohl dies je nach den Daten, auf die Ihr Agent Zugriff haben muss, möglicherweise unmöglich ist).
⚒️ Was wir entwickelt haben: Wir verwenden derzeit GPT-4o für Aptible AI, weil wir glauben, dass es uns am wahrscheinlichsten Antworten von höchster Qualität liefert. Wir sind uns jedoch bewusst, dass Kunden, die Aptible AI verwenden, möglicherweise ihre eigenen Modelle (einschließlich selbst gehosteter Modelle) verwenden möchten. Daher berücksichtigen wir dies beim Aufbau.
? Profi-Tipp: Ihr Agent ist nur so schlau wie die Informationen, die Sie ihm geben. LLMs benötigen Hilfe, um zu verstehen, wie und wann die von Ihnen bereitgestellten Informationen verwendet werden sollen, und wenn Sie ihnen keine Anweisungen zur Interpretation der Informationen geben, erfinden sie einfach etwas. Geben Sie sich im Vorfeld große Mühe, die Informationen zu kuratieren, die Sie Ihrem LLM zuführen!
? Überlegungen: Sie könnten versucht sein, so viele Daten wie möglich abzurufen (Dokumentation, Slack-Konversationen, Code-Repositorys, Issue-Tracker usw.) und alles einer RAG-Anwendung zuzuführen*, * und stellen Sie ihm Fragen. Aber unserer Erfahrung nach wird es fast immer zu viel Lärm geben, als dass dies nützlich wäre. Hier kommt schnelles Engineering ins Spiel.
Wir haben bereits darauf hingewiesen, aber Prompt Engineering ist hier ein entscheidender Teil des Puzzles (eine tolle Übersicht über Prompt-Techniken finden Sie hier). Je besser Ihr Prompt-Engineering ist, desto besser wird Ihr Agent sein.
Für den Kontext sind hier einige, die wir (im Laufe der Zeit) bei der Entwicklung von Aptible AI berücksichtigt haben:
Zero-Shot-Eingabeaufforderung: Dies ist, was die meisten Leute tun, wenn sie mit ChatGPT sprechen; Sie stellen ihm einfach eine Frage und bekommen dann eine Antwort. Wenn die Antwort schlecht ist, stellen sie die Frage einfach anders.
Few-Shot-Eingabeaufforderung: Dies ist, was etwas erfahrenere Leute tun, wenn sie mit ChatGPT sprechen; Sie stellen ihm eine Frage und fügen Beispiele für die gewünschte Ausgabe bei. Sie könnten Zero- und/oder Few-Shot-Prompt für sehr einfache Aufgaben verwenden, die das zugrunde liegende Modell bereits ausführen kann.
Retrieval Augmented Generation (RAG): Dies ist eine Technik, die es dem Modell ermöglicht, zusätzlichen Kontext abzurufen und ihn zur Beantwortung der Frage zu verwenden. Dies ist besonders nützlich für die KI-gestützte Dokumentensuche (siehe auch: Glean und Danswer).
ReAct: Diese Technik ermöglicht es einem Agenten, auf iterative Weise „Gedanken“ zu generieren und „Aktionen“ zu ergreifen, um ein Problem zu lösen, was dem menschlichen Denken am ähnlichsten ist. ReAct eignet sich hervorragend für mäßig komplexe Probleme, wie das Navigieren in Referenzen durch Dokumentation und Tools in Echtzeit, um eine Antwort zu verfassen.
Es ist wichtig zu bedenken, dass Sie diese Techniken kombinieren und kombinieren können (wir werden uns als Nächstes mit dem Multi-Agent-Ansatz befassen). Folgendes haben wir getan...
⚒️ Was wir gebaut haben: Da Aptible AI eine Multi-Agenten-Struktur hat (dazu später mehr), haben wir je nach Komplexität der Aufgabe/Frage eine Mischung aus ReAct und RAG implementiert.
Wenn Sie der KI also eine Frage stellen, übergeben wir alle Integrationen (mit Anweisungen zu deren Verwendung) an die KI. Die KI trifft dann Entscheidungen darüber, welche Tools aufgerufen werden sollen, basierend auf den ihr zur Verfügung stehenden Informationen. Nach jedem Integrationsaufruf hat die KI die Möglichkeit zu entscheiden, dass sie über genügend Informationen verfügt, um eine Antwort zu geben, oder zu entscheiden, dass zusätzliche Integrationen relevant sind und möglicherweise zusätzliche Informationen liefern könnten.
Während des gesamten Prozesses versuchen wir, der KI dabei zu helfen, mithilfe verschiedener Mechanismen bessere Entscheidungen darüber zu treffen, welche Integrationen genutzt werden sollen:
Umfangreiches Prompt-Engineering für die Integrationen, um sicherzustellen, dass wirklich klar ist, wann und wie jede Integration verwendet werden soll und wie die Ausgabe zu interpretieren ist.
Wir haben ein Selbstbewertungssystem entwickelt, das die KI auffordert, den Wert der Antwort einer Integration selbst zu bewerten. Selbst wenn die KI beim Aufrufen einer Integration eine dumme Entscheidung trifft (oder schlechte Eingaben liefert), ist sie in der Regel in der Lage, dies im Nachhinein zu erkennen, wenn Sie sie bitten, selbst zu bewerten, ob die Ausgabe der Integration nützlich war oder nicht. Wir können dies dann nutzen, um zu beeinflussen, wie stark ein bestimmter Output in eine Reaktion einfließt. Wir können die KI auch daran hindern, fortzufahren, wenn sie ständig schlechte Entscheidungen trifft.
Wir haben Naive Bayes basierend auf früheren Erfahrungen implementiert. Wenn Sie beispielsweise die meiste Zeit Integration A und dann B aufrufen und dies zu nützlichen Ergebnissen führt, ist es wahrscheinlich sinnvoll, dies auch weiterhin zu tun. Der Agent kann auch Dinge wie den Vergleich mit früheren ähnlichen Vorfällen nutzen, um weiter einzugrenzen, welche Integrationen wann in bestimmten Szenarien nützlich sind.
? Profi-Tipp: Um unsinnige Antworten zu vermeiden, die richtig klingen, es aber nicht sind, gehen Sie einen Schritt zurück und überlegen Sie, woher Ihre nützlichsten Informationen normalerweise für die Probleme kommen, die Sie mit KI lösen möchten – und entwerfen Sie dann Ihren Agenten darauf basierend.
? Überlegungen: Multi-Agent-Ansätze werden immer beliebter, können jedoch je nach Anwendungsfall kompliziert und möglicherweise unnötig sein. Es kann sehr nützlich sein, ein Team von Agenten zu haben, die mit unterschiedlichen Techniken zusammenarbeiten, um komplexe Probleme zu lösen.
Wenn Sie Ihrem Bot beispielsweise in Slack eine Frage stellen, die nichts mit Ihrer spezifischen Infrastruktur zu tun hat (vielleicht möchten Sie einfach nur wissen, wer 1995 die World Series gewonnen hat), könnten Sie einen Agenten haben, der auf Zero-Shot basiert Aufforderung, einfach als ChatGPT zu fungieren, das in Ihr Slack integriert ist (oder wo auch immer Sie es haben).
Aber wenn Ihre Frage oder Ihr Bedarf komplex ist, wäre es nützlich, ein Team von Agenten zu haben, die im Grunde als Ihr kleines Forschungsteam fungieren und Daten aus unterschiedlichen Quellen auf intelligente Weise sammeln und analysieren.
⚒️ Was wir entwickelt haben: Aptible AI verwendet einen Multi-Agenten-Ansatz, beginnend mit einem Broker-Agenten, der bestimmt, welche Art von Frage oder Aufgabe angegangen werden muss.
? Profi-Tipp: Es ist einfacher, auf einen Multi-Agenten-Ansatz umzusteigen, als ihn zu verlassen! Stellen Sie also sicher, dass Sie es benötigen, bevor Sie mit der Erstellung Ihres Agenten auf diese Weise beginnen.
? Überlegungen: Dies ist ein Thema, das häufig zur Sprache kommt, wenn wir mit frühen Benutzern von Aptible AI chatten. Die meisten Entwicklungsteams müssen sich irgendwann mit ihrem Sicherheitsteam auseinandersetzen, wenn es um die Implementierung neuer Tools geht, und es ist von entscheidender Bedeutung, die Sicherheit der Daten zu gewährleisten (insbesondere, wenn Sie in einer stark regulierten Branche arbeiten). Als Erstes müssen Sie also die KI-Sicherheitsrichtlinien Ihres Unternehmens kennen. Anschließend können Sie einige Maßnahmen ergreifen, um sich vor potenziellen Datenlecks oder externen Bedrohungen zu schützen.
⚒️ Was wir gebaut haben: Zunächst verwenden wir ein Modell, das nicht auf unseren Daten trainiert. Wir sind immer noch dabei, herauszufinden, was Kunden in Bezug auf Sicherheit benötigen, sei es beim Selbsthosting oder etwas anderem! Bleiben Sie dran.
? Profi-Tipp: Seien Sie vorsichtig mit den Daten, auf die Sie Ihrer KI Zugriff gewähren oder die Sie in Eingabeaufforderungen einbeziehen, insbesondere wenn diese Daten nicht mit dem Endbenutzer geteilt werden sollen! Wenn Sie unvorhersehbare Daten wie Protokolle einbeziehen müssen, sollten Sie die Verwendung eines Tools wie Nightfall in Betracht ziehen, um sicherzustellen, dass die an das LLM und die Endbenutzer weitergeleiteten Daten bereinigt werden
Oh, und natürlich muss es nutzbar sein!
? Überlegungen: Wie wollen Sie Ihren Agenten einsetzen? Muss es eine Benutzeroberfläche haben? Wird es im gesamten Unternehmen verwendet?
Sie müssen wahrscheinlich keine Zeit damit verbringen, das Rad neu zu erfinden, wenn es um die UX rund um Ihren Bot geht. Frameworks wie Chainlit, Gradio und Streamlit bieten Ihnen sofort einsatzbereite Tools zum Erstellen von Benutzeroberflächen und/oder zur Integration mit Ihren anderen Workflow-Tools wie Slack. Verwenden Sie zunächst eines dieser Tools, damit Sie sich darauf konzentrieren können, gute Antworten von Ihrem Agenten zu erhalten!
⚒️ Was wir entwickelt haben: Da unser Agent speziell für die Reaktion auf Vorfälle entwickelt wurde – und weil wir Vorfälle innerhalb von Slack bearbeiten – verwenden wir hauptsächlich Slack als unsere Benutzeroberfläche. Es hat jedoch seine Grenzen, daher tun wir unser Bestes, um diese zu umgehen (d. h. anstatt zu zeigen, dass der Agent antwortet, indem er die Eingabe nachahmt, wie es in ChatGPT der Fall ist, reagiert der Bot stattdessen in Slack mit einem ?-Emoji auf die Frage). Wir haben auch eine Web-Benutzeroberfläche für Konfiguration, Berichterstellung, Prüfung und Analyse entworfen.
? Profi-Tipp: Achten Sie darauf, Ihren LLM-Code so entkoppelt wie möglich zu halten, damit Sie ihn bei Bedarf problemlos in eine andere UX umgestalten können.
Okay, lassen Sie uns mit dem theoretischen Gespräch über Modelle, Techniken und Frameworks fortfahren! Es ist Zeit, sich die Hände schmutzig zu machen und mit dem Aufbau Ihres eigenen Agenten zu beginnen.
Bevor wir uns in das endlose Kaninchenloch des Aufbaus von KI stürzen, bereiten wir uns auf den Erfolg vor, indem wir Chainlit einrichten, ein beliebtes Framework zum Aufbau von Konversationsassistenten-Schnittstellen.
Chainlit bietet einen eigenwilligen Satz von Bausteinen zur Modellierung von Gesprächsinteraktionen – wie Threads, Nachrichten und Schritte – sowie eine ChatGPT-ähnliche Benutzeroberfläche für die Interaktion mit dem LLM.
Es bietet auch sofort einsatzbereite Integrationen mit beliebten Chat-Tools wie Slack und Teams sowie Bibliotheken für die Anbindung an beliebte Tools wie React und FastAPI, sodass Sie es bei Bedarf in eine größere Anwendung einbauen können .
Kurz gesagt: Chainlit wird uns einen Großteil der Gerüst- und Grunzarbeit abnehmen, sodass wir uns auf die Entwicklung unseres KI-Assistenten und das Einholen von Feedback von unseren Benutzern konzentrieren können, anstatt mit der Benutzeroberfläche und Konfiguration herumzuspielen.
Am Ende dieser Übung verfügen Sie über eine funktionierende Chainlit-Anwendung, die einfach wiedergibt, was Sie sagen. Wir werden im nächsten Artikel auf die KI-Integration eingehen.
Bevor wir beginnen, müssen Sie einige Dinge vorbereiten:
Sobald Sie fertig sind, fahren Sie fort.
Richten Sie zunächst Ihr Projekt ein und fügen Sie Chainlit als Abhängigkeit hinzu:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
Als nächstes erstellen Sie eine app.py-Datei im Stammverzeichnis Ihres Projekts mit folgendem Inhalt:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
Der obige Code registriert die handle_message-Funktion bei Chainlit, sodass diese Funktion jedes Mal ausgeführt wird, wenn eine Nachricht empfangen wird.
Im Moment gibt unsere Funktion die Nachricht einfach mit dem Präfix „Received:“ an den Benutzer zurück.
Endlich loslegen! Sie können --watch verwenden, um Ihren Code im laufenden Betrieb neu zu laden, wenn Sie Änderungen vornehmen.
poetry run chainlit run app.py --watch
Durch die Ausführung dieses Befehls wird Ihre Chainlit-App gestartet und die Benutzeroberfläche Ihres Browsers geöffnet, wo Sie eine Nachricht senden und eine Antwort erhalten können:
Mit unserer Chainlit-App können wir sie mit einem LLM verbinden, sodass wir mit ihr sprechen und eine menschenähnliche Antwort erhalten können.
Der Einfachheit halber verwenden wir das gehostete gpt-4o-Modell von OpenAI, aber die Verwendung eines anderen Anbieters ist nur eine Frage der Syntax.
Am Ende dieses Artikels können Sie das gpt-4o-Modell aufrufen und eine Antwort erhalten, ähnlich wie bei der Interaktion mit ChatGPT. Wir stellen außerdem sicher, dass der Bot den Konversationskontext beibehält, damit Sie Folgefragen stellen können.
Bevor Sie beginnen, benötigen Sie:
Ein OpenAI-Konto und ein API-Schlüssel
Zuerst konfigurieren wir einen API-Client für die Schnittstelle mit den APIs von OpenAI. Fügen Sie den folgenden Code oben in Ihrer app.py ein:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
Als nächstes müssen wir unsere handle_message-Funktion aktualisieren, um die Nachricht des Benutzers an OpenAI zu senden und eine Antwort zu erhalten, anstatt sie nur zurückzusenden. Ersetzen Sie Ihre handle_message-Funktion durch diese:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
Wenn Sie jetzt Ihre Anwendung ausführen (oder sie mit dem Flag --watch laufen lassen), können Sie eine Frage stellen und eine Antwort erhalten.
Wenn Sie ein wenig herumgespielt und Folgefragen gestellt haben, ist Ihnen vielleicht aufgefallen, dass sich der Bot an nichts „erinnert“, worüber Sie gesprochen haben. Zum Beispiel:
Dies geschieht, weil wir jedes Mal, wenn wir eine Nachricht senden, nur diese eine Nachricht an das LLM senden, das standardmäßig keine Ahnung von der „Konversation“ hat.
Um diese Amnesie zu heilen, müssen wir jedes Mal, wenn wir eine neue senden, alle Nachrichten in der Konversation senden.
Chainlit macht uns dies einfach, indem es einen cl.chat_context.to_openai()-Helper bereitstellt, der uns alle bisher ausgetauschten Nachrichten bequem in dem Format liefert, das OpenAI (und die meisten anderen Anbieter) erwartet.
Aktualisieren Sie Ihre handle_message-Funktion, um historische Nachrichten vor der neuesten voranzustellen:
poetry run chainlit run app.py --watch
Jetzt können wir weitere Fragen stellen!
Nachdem Sie die ersten Schritte aus Teil 1 ausgeführt haben, ist Ihnen möglicherweise aufgefallen, dass es eine Verzögerung gibt, bevor Sie etwas sehen, wenn Sie Fragen stellen, die eine lange Antwort erfordern.
Dies kann zu einer schlechten Benutzererfahrung führen (insbesondere später in Teil 3, wenn wir anfangen, lang laufende Toolaufrufe hinzuzufügen), also lasst uns das beheben.
Am Ende dieses Schritts können Sie den „Typ“ Ihres Bots in Echtzeit sehen, ähnlich wie bei ChatGPT.
Um Nachrichtenaktualisierungen in Echtzeit zu erhalten, müssen wir unsere Implementierung aktualisieren, um einen „Stream“ zu verwenden. Grundsätzlich antworten wir jedes Mal, wenn wir eine Nachricht erhalten, sofort mit einer leeren Nachricht, starten einen Stream mit dem LLM und aktualisieren unsere leere Nachricht jedes Mal, wenn wir einen neuen Teil der Antwort vom Stream erhalten.
Das hört sich vielleicht kompliziert an, ist aber überraschend einfach! Aktualisieren Sie Ihre handle_message-Funktion wie folgt:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
?? Hier ist also der bisher vollständige Code:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
Wenn Sie jetzt eine Frage stellen, sollten Sie sehen, wie Ihr Bot in Echtzeit „tippt“!
Zu diesem Zeitpunkt haben wir einen einfachen Klon von ChatGPT erstellt. Das ist cool und alles, aber was wir wirklich wollen, ist ein Assistent, der uns bei der Ausführung einer bestimmten Aufgabe hilft: In diesem Fall möchten wir, dass er Vorfälle behebt, wie es ein SRE tun würde.
Um dorthin zu gelangen, wandeln wir zunächst unseren Agenten in einen benutzerdefinierten OpenAI-Assistenten um, der uns die Kontrolle über die Systemeingabeaufforderung gibt (sowie die Möglichkeit, dem LLM Zugriff auf Tools wie Dateisuche und Funktionsaufrufe zu gewähren). worauf wir später noch eingehen werden).
Am Ende dieses Schritts haben Sie Ihren Bot in einen benutzerdefinierten „Assistenten“ umgestaltet und seine Systemaufforderung angepasst, um ihm eine eigene „Persönlichkeit“ zu verleihen. Ihr Code verwendet außerdem einen „Thread“, der Nachrichten mithilfe der OpenAI-API beibehält, anstatt jedes Mal alle Nachrichten senden zu müssen, wenn wir eine neue erhalten.
Das Erstellen eines Assistenten ist unkompliziert: Wir müssen lediglich die OpenAI Assistants API aufrufen. Da wir dies jedoch nur einmal beim Start der Anwendung tun möchten, können wir diesen API-Aufruf nicht in die Funktion „handle_message“ einfügen.
Stattdessen verwenden wir einen anderen Chainlit-Hook – on_chat_start, der nur einmal beim ersten Start der Anwendung ausgeführt wird –, um unseren Assistenten einzurichten.
Fügen Sie dies zu Ihrer app.py hinzu:
poetry run chainlit run app.py --watch
Hinweis: Es ist technisch möglich, dem Assistenten eine benutzerdefinierte Systemaufforderung zu geben, indem eine erste Systemmeldung im Nachrichtenverlauf in handle_message bereitgestellt wird. Wir wandeln es jedoch in einen Assistenten mit benutzerdefinierten Anweisungen um, da dadurch mehrere andere Funktionen freigeschaltet werden, die wir in naher Zukunft nutzen werden.
Da wir nun einen Assistenten und einen Thread für die Konversation haben, können wir unseren Nachrichtenhandler umgestalten, um sie zu verwenden.
Zuerst benötigen wir einen AssistantEventHandler, der unserem neuen Assistant-Objekt mitteilt, wie es mit den verschiedenen Ereignissen umgehen soll, die während einer Konversation auftreten.
Fügen Sie Folgendes zu Ihrer app.py hinzu:
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
Jetzt müssen wir nur noch unsere handle_message-Funktion anpassen, um alle unsere neuen Spielzeuge nutzen zu können! Aktualisieren Sie Ihre handle_message-Funktion wie folgt:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[{"content": message.content, "role": "user"}], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
?? Hier ist der bisher vollständige Code:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
Da wir nun Assistenten und Threads verwenden, können wir mit der Anpassung des Verhaltens beginnen. Zunächst gewähren wir unserem Assistenten Zugriff auf einige unserer internen Dokumentationen, damit er Antworten liefern kann, die besser auf unseren Anwendungsfall zugeschnitten sind.
Am Ende dieses Abschnitts haben Sie Ihrem Bot die Möglichkeit gegeben, eine Sammlung von Dateien (z. B. Ihre SRE-Runbooks und andere interne Dokumentation) zu durchsuchen, wenn er auf Eingabeaufforderungen reagiert.
Der Einfachheit halber implementieren wir dies als einen Ordner voller Dateien, die in einen Vektorspeicher hochgeladen und unserem Assistenten bereitgestellt werden.
Als Erstes müssen wir einen Vektorspeicher erstellen und ihn unserem Assistenten zur Verfügung stellen.
Aktualisieren Sie zunächst den Anfang unserer Funktion handle_chat_start, sodass er Folgendes enthält:
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
Aktualisieren Sie als Nächstes den Aufruf von client.beta.assistants.update(), um dem Assistenten Zugriff auf den Vektorspeicher zu gewähren und das Dateisuchtool zu aktivieren.
poetry run chainlit run app.py --watch
Zuletzt müssen wir unsere Dokumentation hochladen, auf die sich unser Assistent bei der Beantwortung von Eingabeaufforderungen beziehen soll.
Zuerst müssen wir einen Ordner erstellen, in dem wir unsere Dokumente ablegen:
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
Als nächstes sammeln wir unsere Dokumentation und legen sie in diesem Ordner ab. Zu Testzwecken habe ich das folgende gefälschte Dokument zu meinem Ordner hinzugefügt:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[{"content": message.content, "role": "user"}], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
Zuletzt aktualisieren wir unsere Funktion handle_chat_start, um unsere Dokumente automatisch in den Vektorspeicher hochzuladen, den wir zuvor erstellt haben. Fügen Sie den folgenden Code direkt nach der Erstellung des Vektorspeichers hinzu:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Retrieve the response from the LLM response = await client.chat.completions.create( messages=[ # Prepend all previous messages to maintain the conversation. *cl.chat_context.to_openai(), {"content": message.content, "role": "user"} ], model="gpt-4o", ) await cl.Message(content=response.choices[0].message.content).send()
ℹ️ Hinweis: Im Moment unterstützen wir nur .md-Dateien, OpenAI unterstützt jedoch viele verschiedene Dateitypen. Sie können das Glob-Muster also jederzeit auf das aktualisieren, was für Ihren Anwendungsfall sinnvoll ist!
Dadurch werden automatisch alle Dateien im Ordner ./docs hochgeladen und unserem Vektorspeicher hinzugefügt.
Die Dateisuche kann manchmal eine Weile dauern, insbesondere bei größeren Datensätzen. In solchen Fällen möchten Sie den Benutzer wahrscheinlich wissen lassen, was los ist, damit er nicht frustriert wird.
Glücklicherweise macht Chainlit dies einfach, indem es eine Step-Klasse bereitstellt, mit der wir dem Benutzer mitteilen können, dass im Hintergrund etwas passiert. Wir können die Step-Klasse in Verbindung mit dem zuvor erstellten MessageEventHandler verwenden und bei jedem Aufruf eines Tools einen Indikator hinzufügen.
Fügen Sie Folgendes zu Ihrem MessageEventHandler hinzu:
# ... @cl.on_message async def handle_message(message: cl.Message) -> None: # Send an empty initial message that we can update with a streaming # response. message = cl.Message(content="") await message.send() # Stream the response from the LLM stream = await client.chat.completions.create( messages=[ # Prepend all previous messages to maintain the conversation. *cl.chat_context.to_openai(), {"content": message.content, "role": "user"} ], model="gpt-4o", stream=True, ) # Update the existing (initially-empty) message with new content # from each "chunk" in the stream. async for chunk in stream: if token := chunk.choices[0].delta.content: await message.stream_token(token) # Send a final update to let the message know it's complete. await message.update()
Nachdem Sie nun einige Ihrer eigenen Dokumentation hochgeladen haben, versuchen Sie, einige Fragen zu stellen, die spezifischer auf Ihren Anwendungsfall zugeschnitten sind, und sehen Sie, was Sie erhalten!
In unserem Testfall wurde bei der Frage nach einer hohen CPU-Auslastung in einer Kundendatenbank korrekt auf unser Runbook verwiesen:
?? Als Referenz hier der bisher vollständige Code:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
Unser Agent ist jetzt in der Lage, Daten aus unserer kuratierten internen Dokumentation abzurufen, was nützlich ist, wenn Sie über eine gute Dokumentation verfügen. Beim Vorfallmanagement wird jedoch oft viel Zeit damit verbracht, Dinge zu untersuchen, die nicht in den Dokumenten behandelt werden: Warnungen scannen, Protokolle lesen, Metriken interpretieren usw.
Für diese Dinge möchten wir unserem Assistenten die Möglichkeit geben, externe APIs aufzurufen – und allgemeiner gesagt von uns definierte Funktionen auszuführen –, damit er bei Bedarf mehr Kontext sammeln kann.
Dazu nutzen wir die „Funktionsaufruf“-Fähigkeiten des Modells, um von uns definierte Funktionen auszuführen.
Am Ende dieses Abschnitts haben Sie Ihrem Bot die Möglichkeit gegeben, ein externes Tool (ein gefälschtes PagerDuty-Tool) zu verwenden, um beim Beantworten von Eingabeaufforderungen Informationen abzurufen.
Zuerst fügen wir unserer app.py eine neue Funktion namens get_pagerduty_alert_details hinzu.
import chainlit as cl @cl.on_message async def handle_message(message: cl.Message) -> None: # Echo the message back to the user. await cl.Message( content=f"Received: {message.content}", ).send()
Als nächstes müssen wir dem LLM mitteilen, wie er unser Tool aufrufen soll. OpenAI erwartet Tooldefinitionen im JSONSchema-Format.
Aktualisieren Sie Ihren Aufruf von client.beta.assistants.update(), um nach dem bereits vorhandenen Tool „file_search“ eine neue Tooldefinition einzuschließen.
poetry run chainlit run app.py --watch
Unser MessageEventHandler verarbeitet derzeit hin- und hergehende Nachrichtenereignisse, das Aufrufen von Tools erfordert jedoch eine besondere Behandlung.
Bei der Beantwortung Ihrer Aufforderung entscheidet das LLM, welche Tools es aufrufen soll (falls vorhanden), und sendet Ihnen eine oder mehrere „Tool-Aufruf“-Definitionen in der Antwortnutzlast zurück und teilt Ihnen mit, dass die Antwort „eine Aktion erfordert“. Um die Funktion tatsächlich auszuführen, müssen wir diese „Handlung erforderlich“-Antworten verarbeiten.
Wir können dies tun, indem wir unsere MessageEventHandler-Klasse aktualisieren, um die on_event-Methode zusammen mit einer neuen handle_requires_action-Methode zum Ausführen unseres Funktionsaufrufs und zum Hinzufügen des Ergebnisses zum laufenden Thread zu implementieren:
import os from openai import AsyncOpenAI ## # Settings # try: OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] except KeyError as ex: raise LookupError(f"Missing required environment variable: {ex}") client = AsyncOpenAI(api_key=OPENAI_API_KEY) # ...
Es kann oft hilfreich sein, den LLM daran zu erinnern, dass er gegebenenfalls versuchen sollte, die von Ihnen bereitgestellten Tools zu verwenden. Fügen Sie am Ende Ihrer Eingabeaufforderung eine Zeile wie diese hinzu:
Verwenden Sie gegebenenfalls die bereitgestellten Tools, um zusätzlichen Kontext zum Vorfall zu sammeln.
Wenn Ihre Tools konfiguriert sind, können Sie PagerDuty-Links in Ihre Eingabeaufforderungen einfügen, und das LLM verwendet diese Tools, um den Kontext zu erfassen, bevor es antwortet:
?? Hier ist der vollständige Code:
mkdir roger cd roger poetry init --no-interaction poetry add chainlit
Jetzt sind Sie bereit, einen nützlichen KI-Agenten für Ihr SRE-Team zu erstellen! Wenn Sie Fragen zu den in diesem Leitfaden behandelten Themen haben, wenden Sie sich bitte an uns. Wir helfen Ihnen gerne weiter. Wenn Ihnen in der Zwischenzeit etwas fehlt oder Sie sonst noch etwas über den KI-Agenten erfahren möchten, lassen Sie es uns wissen!
Wenn Sie Aptible AI selbst ausprobieren möchten, anstatt Ihren eigenen Agenten zu erstellen, können Sie sich auf www.aptible.ai anmelden.
Das obige ist der detaillierte Inhalt vonAnleitung: So erstellen Sie einen KI-Agenten für SRE-Teams. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!