KI für DevOps-Engineers – Teil 2: KI-Anwendungen mit LangChain erstellen


Bicycle

Im ersten Teil unserer Blogserie haben wir uns mit den verschiedenen Herausforderungen von DevOps befasst und wie KI diese lösen kann. Außerdem haben wir Grundlagen der generativen KI und Large Language Models (LLMs) als transformative Tools für DevOps-Engineers vorgestellt. In diesem zweiten Teil tauchen wir tiefer in die Entwicklung unserer eigenen KI-Anwendungen mit LangChain ein, einem leistungsstarken Framework, das die Entwicklung von LLM-gestützten Lösungen vereinfacht und verbessert.

Warum Frameworks für KI-Anwendungen verwenden?

Die Entwicklung von KI-Anwendungen von Grund auf kann komplex und zeitaufwändig sein. LLM-Frameworks bieten Werkzeuge und Schnittstellen, die die Integration von Large Language Models in Anwendungen vereinfachen:

  1. Reduzierung von Boilerplate-Code: Frameworks können sich wiederholende Aufgaben wie API-Aufrufe, Fehlerbehandlung und Datenverarbeitung übernehmen, wodurch sich die Entwickler auf die Kernlogik konzentrieren können.
  2. Vereinfachung der Entwicklung: Abstrahierte Tools und Schnittstellen erleichtern das Experimentieren, die Iteration und die schnelle Erstellung von Anwendungen.
  3. Verbesserung der Wartbarkeit: Strukturierte Ansätze für Prompt-Engineering und Modellarchitektur erleichtern die Verwaltung und Skalierung von Codebasen.
  4. Erweiterte Workflows ermöglichen: Die Unterstützung von Techniken wie "few-shot learning", "Retrieval-Augmented Generation" (RAG) und die Verkettung von LLM-Interaktionen minimiert den eigenen Codingaufwand.
  5. Ökosystem-Integration: Einfache Verbindungen zu Datenbanken, Vektorspeichern und anderen Tools ermöglichen schnelle End-to-End-Lösungen.

Einführung in die LangChain

LangChain

[LangChain] (https://www.langchain.com/) ist ein Open-Source-Framework, das die Arbeit mit LLMs vereinfacht. Es zeichnet sich durch seine Fähigkeit aus, agentenbasierte Aufgaben-Workflows zu handhaben, die eine autonome Aufgabenausführung durch Verkettung mehrerer LLM-Interaktionen ermöglichen. Dies macht es ideal für die Erstellung von Anwendungen mit komplexen Arbeitsabläufen, wie zum Beispiel:

  • Retrieval-Augmented Generation (RAG)
  • Multi-step Reasoning
  • Integration mit externen Tools und APIs

Komponenten von LangChain

Das modulare Design von LangChain umfasst mehrere Schlüsselkomponenten, die zusammenarbeiten, um coole KI-Anwendungen zu erstellen:

  1. Dokumentenlader: Mit Loadern können wir Daten aus verschiedenen Quellen wie PDFs, Websites oder Datenbanken laden und verarbeiten und für die Verwendung vorbereiten.
  2. Vektor-Speicher: Einbettungen sind wichtig für die Verarbeitung und den Vergleich von Textdaten. Vektorspeicher helfen, diese Einbettungen effizient zu verwalten und abzufragen.
  3. Aufforderungen: Anweisungen oder Abfragen können gemanaged und strukturiert werden, um genaue und relevante Modellantworten zu gewährleisten.
  4. LLMs: Natürlich können wir auch jedes Sprachmodell (z. B. GPT-4, LLaMA) verwenden, egal ob cloudbasiert oder lokal.
  5. Ketten: Wir können mehrere LLM-Interaktionen verknüpfen, um komplexe Workflows zu erstellen (z. B. Abruf, Zusammenfassung und Fragen und Antworten).
  6. Agenten: Ermöglichen die autonome Erledigung von Aufgaben, indem sie Entscheidungen treffen, mit Werkzeugen interagieren und ihr Verhalten anpassen - und das alles selbstständig.

Erstellung von KI-Anwendungen mit LangChain

Lasst uns nun anhand einiger praktischer Beispiele erkunden, wie LangChain zur Erstellung von KI-Anwendungen verwendet werden kann. Wir verwenden dabei die Programmiersprache Python, da sie in der KI-Entwicklung weit verbreitet ist und sich gut in LangChain integrieren lässt.

Beispiel 1: Einfache Chat-App

Wir fangen ganz einfach mit einer einfachen Chat-Anwendung an.

 1from langchain.chains import ConversationChain
 2from langchain.memory import ConversationBufferMemory
 3from langchain_community.llms import Ollama
 4
 5# Initialisierung des LLM
 6llm = Ollama(model="llama2")
 7
 8# Speicher zum Speichern des Gesprächsverlaufs einrichten
 9memory = ConversationBufferMemory()
10
11# Eine Gesprächskette erstellen
12conversation = ConversationChain(llm=llm, memory=memory)
13
14# Chat-Schleife
15while True:
16    user_input = input("Input: ")
17    response = conversation.run(user_input)
18    print(f"AI: {response}")

Schauen wir uns den Code an:

  1. Als erstes müssen die notwendigen LangChain-Komponenten importiert werden.
  2. Dann initialisieren wir ein LLM (lokales Ollama Modell) mit dem gewünschten Modell und den Einstellungen.
  3. Ein Speicherpuffer wird eingerichtet, um den Gesprächsverlauf zu speichern, so dass die KI auf frühere Interaktionen zurückgreifen kann.
  4. Außerdem wird eine Gesprächskette erstellt, um die Interaktion zwischen dem Benutzer und der KI zu managen.
  5. Schließlich wird eine Chat-Schleife eingerichtet, in der der Benutzer Nachrichten eingeben kann, auf die die KI entsprechend antwortet.

Wir sehen, wie LangChain den Prozess der Einrichtung einer kompletten Chat-Anwendung mit einem LLM vereinfacht! Natürlich ist dieses Beispiel noch sehr einfach, da wir nur in der Konsole chatten und unser Modell ein einfacher Chatbot ist. Aber es zeigt, wie einfach es ist, mit LangChain zu beginnen.

Beispiel 2: Retrieval-Augmented Generation (RAG)

Wenn wir uns an den ersten Teil dieser Serie erinnern, ist Retrieval-Augmented Generation (RAG) eine Technik, die Informationsbeschaffung mit Sprachgenerierung kombiniert. LangChain kann verwendet werden, um RAG-Workflows zu implementieren:

 1from langchain.document_loaders import TextLoader
 2from langchain.vectorstores import Chroma
 3from langchain.embeddings import OpenAIEmbeddings
 4from langchain.chains import RetrievalQA
 5from langchain.chat_models import ChatOpenAI
 6
 7# Dokumente laden
 8loader = TextLoader("example.txt")
 9documents = loader.load()
10
11# Embeddings und Vektorspeicher erstellen
12embeddings = OpenAIEmbeddings()
13vector_store = Chroma.from_documents(documents, embeddings)
14
15# Retriever einrichten
16retriever = vector_store.as_retriever()
17
18# Initialisierung des LLM
19llm = ChatOpenAI(model="gpt-3.5-turbo")
20
21# RetrievalQA-Kette erstellen
22qa_chain = RetrievalQA(llm=llm, retriever=retriever)
23
24# Eine Frage stellen
25query = "What is the main topic of the document?"
26response = qa_chain.run(query)
27print(f"Answer: {response}")

Wir können sehen, dass in diesem Beispiel etwas mehr los ist:

  1. Natürlich müssen wir bedenken, dass wir jetzt noch mehr Komponenten wie Dokumentenlader, Vektorspeicher und Embeddings importieren müssen, um den Abrufprozess zu erledigen.
  2. Wir laden ein Dokument aus einer Datei und erstellen Embeddings dafür mit OpenAIs eigenen Embeddings. LangChain unterstützt verschiedene Abrufquellen, darunter Dateien (z. B. PDFs, CSVs), Webinhalte und Cloud-Anbieter. Embeddings sind eine Möglichkeit, Textdaten als numerische Vektoren darzustellen. Diese Vektoren erfassen die semantische Bedeutung des Textes und ermöglichen eine effektivere Verarbeitung und einen besseren Vergleich durch das Modell.
  3. Anschließend erstellen wir einen Vektorspeicher, um alle Embeddings zu verwalten, und richten einen Retriever ein, um relevante Informationen auf der Grundlage der Benutzeranfrage abzurufen.
  4. Schließlich initialisieren wir ein LLM und erstellen eine RetrievalQA-Kette, um die Interaktion zwischen der Benutzeranfrage und den abgerufenen Informationen zu verarbeiten.

Wie wir sehen, ist die grobe Struktur des Codes ähnlich wie bei der Chat-Anwendung, wir haben lediglich weitere Komponenten hinzugefügt, um den Abrufprozess zu handhaben.

Es ist zu beachten, dass wir bei der Arbeit mit Cloud-basierten Modellen wie GPT-3 einen API-Schlüssel benötigen, um auf das Modell zugreifen zu können! Man kann einen API-Schlüssel vom jeweiligen Anbieter erhalten.

Beispiel 3: Chatten mit PDF-Inhalten

Mit LangChain und Streamlit können wir interaktive Anwendungen bauen, wie etwa zum Chatten mit PDF-Inhalten erstellen.

Streamlit

Streamlit

Streamlit ist ein Open-Source-Python-Framework, mit dem sich schnell und einfach interaktive Webanwendungen erstellen lassen. Es ist bei Datenwissenschaftlern und Ingenieuren für maschinelles Lernen beliebt, weil es uns ermöglicht, mit minimalem Aufwand benutzerfreundliche Oberflächen für Modelle und Daten-Workflows zu erstellen.

  • Einfachheit: Wir können Webanwendungen mit nur ein paar Zeilen Python-Code erstellen.
  • Echtzeit-Interaktivität: Unterstützt Widgets wie Schieberegler, Texteingaben und Datei-Uploader für dynamische Nutzerinteraktionen.
  • Schnelles Prototyping: Wir können Änderungen sofort sehen, während wir den Code modifizieren.
  • Integration mit KI- und ML-Tools: Streamlit arbeitet nahtlos mit gängigen Bibliotheken wie LangChain, TensorFlow und PyTorch zusammen.
 1import streamlit as st
 2from langchain.document_loaders import PyPDFLoader
 3from langchain.vectorstores import Chroma
 4from langchain.embeddings import OpenAIEmbeddings
 5from langchain.chains import ConversationalRetrievalChain
 6from langchain.chat_models import ChatOpenAI
 7
 8# Streamlit UI
 9st.title("Chat with Your PDF")
10uploaded_file = st.file_uploader("Upload a PDF", type="pdf")
11
12if uploaded_file:
13    # PDF laden
14    loader = PyPDFLoader(uploaded_file)
15    documents = loader.load()
16
17    # Embeddings und Vektorspeicher erstellen
18    embeddings = OpenAIEmbeddings()
19    vector_store = Chroma.from_documents(documents, embeddings)
20
21    # Retriever und Konversationskette einrichten
22    retriever = vector_store.as_retriever()
23    llm = ChatOpenAI(model="gpt-3.5-turbo")
24    conversation_chain = ConversationalRetrievalChain(llm=llm, retriever=retriever)
25
26    # Chat Interface
27    if "chat_history" not in st.session_state:
28        st.session_state.chat_history = []
29
30    user_input = st.text_input("Ask a question about the PDF:")
31    if user_input:
32        response = conversation_chain.run(user_input)
33        st.session_state.chat_history.append((user_input, response))
34
35    # Chatverlauf anzeigen
36    for user_msg, ai_msg in st.session_state.chat_history:
37        st.write(f"You: {user_msg}")
38        st.write(f"AI: {ai_msg}")

Mit dieser einfachen webbasierten Spleamlit-Anwendung können Nutzer ein PDF hochladen, Fragen zu dessen Inhalt stellen und kontextbezogene Antworten erhalten. Die LangChain-Komponenten übernehmen die PDF-Verarbeitung, die Textextraktion und die LLM-Interaktionen, während Streamlit die benutzerfreundliche Schnittstelle bereitstellt. Die Struktur ist ähnlich wie in den vorherigen Beispielen, aber jetzt haben wir sie mit Streamlit integriert, um ein interaktiveres Erlebnis zu schaffen.

  1. Unsere Anwendung beginnt mit einer Streamlit-Benutzeroberfläche, die es den Nutzern ermöglicht, eine PDF-Datei hochzuladen.
  2. Wenn eine Datei hochgeladen wurde, laden wir den PDF-Inhalt mit einem PyPDFLoader.
  3. Wir erstellen Embeddings und einen Vektorspeicher, um die Textdaten aus der PDF-Datei zu verwalten.
  4. Eine Conversational Retrieval Chain wird eingerichtet, um die Interaktion zwischen den Benutzeranfragen und dem PDF-Inhalt zu handhaben.
  5. Der Nutzer kann Fragen zum PDF eingeben, und die KI antwortet entsprechend. Der Chatverlauf wird im Sitzungsstatus gespeichert und dem Nutzer angezeigt.

Qualität in KI-Anwendungen sicherstellen

Die Entwicklung von KI-Anwendungen ist eine Sache, aber ihre Qualität zu gewährleisten eine andere. KI kann unberechenbar sein, daher müssen wir sicherstellen, dass die Anwendung zuverlässig und genau ist und in realen Szenarien die erwartete Leistung erbringt. Bei Anwendungen, die auf Sprachmodellen basieren, sind Tests und Bewertungen entscheidend für die Aufrechterhaltung der Leistung oder die Identifizierung von Problemen.

In diesem Abschnitt werden wir die Bedeutung des Testens in LLM-Anwendungen, verschiedene Testansätze und die Möglichkeiten von Tools wie LangSmith zur Vereinfachung dieses Prozesses untersuchen.

Warum Tests bei LLM-Bewerbungen entscheidend sind

Das Testen von LLM-Bewerbungen zielt darauf ab, folgendes sicherzustellen:

  • Zuverlässigkeit: Die Anwendung funktioniert durchgehend wie erwartet, auch wenn Modelle oder Eingabeaufforderungen aktualisiert werden.
  • Genauigkeit: Die vom Modell erzeugten Ergebnisse stimmen mit den Erwartungen der Nutzer und den Zielen der Anwendung überein.
  • Leistungsfähigkeit: Die Anwendung ist in der Lage, reale Szenarien, einschließlich Grenzfällen, zu bewältigen, ohne abzubrechen oder irrelevante Ergebnisse zu liefern.
  • Nutzerzufriedenheit: Durch die Validierung der Ergebnisse stellen die Tests sicher, dass die Anwendung die Bedürfnisse von Nutzern erfüllt.

LLMs sind probabilistische Modelle, d. h. ihre Ergebnisse können je nach Eingabe, Aufforderung oder Kontext variieren. Diese Variabilität macht das Testen noch wichtiger, um konsistente und hochwertige Ergebnisse zu gewährleisten.

Testen in LLM-Anwendungen: Ansätze und Beispiele

Das Testen von LLM-Anwendungen umfasst mehrere Ansätze, die jeweils auf bestimmte Anwendungsfälle zugeschnitten sind. Als nächstes werden wir einige gängige Testmethoden und Beispiele untersuchen.

Definition von Evaluationsmetriken

Metriken sind wichtig, um die Leistung von LLM-Anwendungen zu beurteilen. Diese sollten mit den Zielen der Anwendung oder den Zielen des Unternehmens übereinstimmen. Zum Beispiel:

  • Genauigkeit: Wie gut stimmt die Ausgabe des Modells mit dem erwarteten Ergebnis überein.
  • Relevanz: Ob das Ergebnis kontextuell angemessen ist.
  • Kreativität: Bei Aufgaben wie der Generierung von Geschichten, wie originell und fesselnd das Ergebnis ist.
  • Kohärenz: Ob die Ausgabe logisch konsistent und gut strukturiert ist.

Testfälle mit erwarteten Ergebnissen

Eine der einfachsten Möglichkeiten, eine LLM-Anwendung zu testen, ist die Erstellung von Testfällen mit klaren Eingaben und erwarteten Ausgaben. Dieser Ansatz ist ideal für Aufgaben mit deterministischen Antworten, wie zum Beispiel die Beantwortung von Fragen oder die Übersetzung.

 1test_cases = [
 2    {"input": "Hello, how are you?", "expected_output": "Bonjour, comment ça va?"},
 3    {"input": "Goodbye", "expected_output": "Au revoir"},
 4]
 5
 6for test in test_cases:
 7    result = chain.run(text=test["input"])
 8    print(f"Input: {test['input']}")
 9    print(f"Expected: {test['expected_output']}")
10    print(f"Actual: {result.strip()}")
11    print(f"Pass: {result.strip() == test['expected_output']}\n")

Einsatz von LLMs als Richter

Bei Aufgaben mit subjektiven oder komplexen Ergebnissen (z. B. bei der Erstellung von Geschichten oder Zusammenfassungen) ist eine genaue Übereinstimmung zwischen erwarteten und tatsächlichen Ergebnissen möglicherweise nicht möglich. In solchen Fällen kann ein LLM als "Richter" fungieren, um die Qualität der eigenen oder der Ergebnisse eines anderen Modells zu bewerten.

 1# Definieren des Prompts zur Generierung einer Geschichte
 2story_prompt_template = PromptTemplate(
 3    input_variables=["theme"],
 4    template="Write a short story based on the following theme: {theme}."
 5)
 6
 7# Definieren des Prompts zur Bewertung der Geschichte
 8evaluation_prompt_template = PromptTemplate(
 9    input_variables=["story"],
10    template=(
11        "You are a judge evaluating short stories. Please rate the following story on a scale from 1 to 10 "
12        "for creativity, coherence, and grammar. Provide a brief explanation for each rating.\n\n"
13        "Story: {story}\n\n"
14        "Creativity: \nCoherence: \nGrammar: \nExplanation:"
15    )
16)
17
18# Initialisierung der LLMs
19story_generator = OpenAI(model="text-davinci-003")
20story_evaluator = OpenAI(model="text-davinci-003")
21
22# Erstellen der LLMChains
23story_chain = LLMChain(llm=story_generator, prompt=story_prompt_template)
24evaluation_chain = LLMChain(llm=story_evaluator, prompt=evaluation_prompt_template)
25
26# Eine Geschichte generieren
27theme = "adventure in a mystical forest"
28generated_story = story_chain.run(theme=theme)
29
30# Die Geschichte bewerten
31evaluation = evaluation_chain.run(story=generated_story)
32
33# Output
34print("Generated Story:\n", generated_story)
35print("\nEvaluation:\n", evaluation)

Prompt Refactoring

Das Refactoring von Prompts ist ein iterativer Prozess zur Verbesserung der Qualität von Prompts für bessere Ergebnisse. Bei diesem Ansatz werden die Ergebnisse des Modells analysiert, verbesserungswürdige Bereiche identifiziert und die Eingabeaufforderung verfeinert, um das gewünschte Ergebnis zu erzielen.

 1# Definieren des Prompts zur Verbesserung der Benutzereingabe
 2enhancement_prompt_template = PromptTemplate(
 3    input_variables=["user_input"],
 4    template=(
 5        "You are an expert in creating detailed prompts for language models. "
 6        "Given the user input: '{user_input}', generate a comprehensive prompt that includes "
 7        "specific details, context, and any relevant questions to ensure a thorough response."
 8    )
 9)
10
11# Definieren des Prompts zur Durchführung der eigentlichen Aufgabe
12task_prompt_template = PromptTemplate(
13    input_variables=["enhanced_prompt"],
14    template="{enhanced_prompt}"
15)
16
17# Initialisierung der LLMs
18enhancer_model = OpenAI(model="text-davinci-003")
19task_model = OpenAI(model="text-davinci-003")
20
21# Erstellen der LLMChains
22enhancement_chain = LLMChain(llm=enhancer_model, prompt=enhancement_prompt_template)
23task_chain = LLMChain(llm=task_model, prompt=task_prompt_template)
24
25# Beispielhafte Benutzereingabe
26user_input = "Explain the impact of the Industrial Revolution."
27
28# Step 1: Verbessern der Benutzereingabe
29enhanced_prompt = enhancement_chain.run(user_input=user_input)
30
31# Step 2: Durchführung der eigentlichen Aufgabe
32task_output = task_chain.run(enhanced_prompt=enhanced_prompt)
33
34# Output
35print("Enhanced Prompt:\n", enhanced_prompt)
36print("\nTask Output:\n", task_output)

LangSmith: LangChain's Tool zum Testen und Managen von LLM-Anwendungen

LangSmith ist ein leistungsfähiges, in das LangChain-Ökosystem integriertes Tool, das Funktionen zum Testen, Überwachen und Managen von LLM-Anwendungen bietet.

  • Tracing: LangSmith ermöglicht es Entwicklern, die Ausführung von LLM-Ketten zu visualisieren. Dadurch lassen sich Bottlenecks, Fehler und Ineffizienzen leichter erkennen. Es bietet auch Einblicke in die Token-Nutzung und Latenz, um die Leistung zu optimieren.
  • Evaluierungsdatensätze: Es ermöglicht auch die Erstellung von Datensätzen für die einheitliche Bewertung von LLM-Anwendungen. Diese Datensätze ermöglichen es Entwicklern, ihre Anwendungen systematisch zu testen und eine zuverlässige Leistung zu gewährleisten.
  • Testing: LangSmith unterstützt das automatische Testen von LLM-Ketten, um die Ergebnisse zu validieren und die Genauigkeit sicherzustellen. Außerdem können Entwickler die Leistung verschiedener Modellversionen vergleichen.
  • Überwachung: Das Tool verfolgt Leistungskennzahlen wie Latenz, Genauigkeit und Benutzerinteraktionen. Dies hilft den Entwicklern, die Leistung ihrer Anwendungen in realen Szenarien zu bewerten und Bereiche mit Verbesserungsbedarf zu ermitteln.
  • Versionskontrolle: Mit LangSmith können Entwickler auch verschiedene Versionen von Prompts, Ketten und Modellen verwalten und so Änderungen verfolgen und die Leistung vergleichen. Es unterstützt auch A/B-Tests.

LangSmith kann mit oder ohne LangChain verwendet werden.

Fazit

In diesem zweiten Teil der Blog-Reihe haben wir untersucht, wie KI-Anwendungen mit LangChain erstellt werden können, einem leistungsstarken Framework, das die Entwicklung von LLM-gestützten Lösungen vereinfacht. Von der Erstellung einfacher Chat-Anwendungen bis hin zur Implementierung fortschrittlicher Workflows wie Retrieval-Augmented Generation (RAG) und der Erstellung interaktiver Tools mit Streamlit bietet LangChain einen modularen und flexiblen Ansatz für die Arbeit mit Sprachmodellen.

Wir erwähnten auch, wie wichtig es ist, die Qualität von KI-Anwendungen durch Tests und Bewertungen sicherzustellen. Durch den Einsatz von Tools wie LangSmith können Entwickler Tests optimieren, die Leistung überwachen und Versionen effektiv verwalten, um sicherzustellen, dass ihre Anwendungen langfristig zuverlässig, genau und anpassungsfähig bleiben.

Im nächsten und letzten Teil dieser Serie werden wir uns mit dem Deployment von KI-Anwendungen befassen und uns Operations- und Sicherheitsüberlegungen für LLM-gestützte Lösungen sowie KI-Agenten ansehen. Bleiben Sie dran!

Wenn Sie noch mehr erfahren möchten, sehen Sie sich unbedingt unsere Videos unseres neuesten KI-Workshops für DevOps-Engineers auf YouTube an:

Zurück Unsere Trainings entdecken

Wir sind für Sie da

Sie interessieren sich für unsere Trainings oder haben einfach eine Frage, die beantwortet werden muss? Sie können uns jederzeit kontaktieren! Wir werden unser Bestes tun, um alle Ihre Fragen zu beantworten.

Hier kontaktieren