paint-brush
Verwenden von MinIO zum Erstellen einer Retrieval Augmented Generation Chat-Anwendungvon@minio
5,705 Lesungen
5,705 Lesungen

Verwenden von MinIO zum Erstellen einer Retrieval Augmented Generation Chat-Anwendung

von MinIO21m2024/09/18
Read on Terminal Reader

Zu lang; Lesen

Zum Erstellen einer produktionsreifen RAG-Anwendung ist eine geeignete Dateninfrastruktur zum Speichern, Versionieren, Verarbeiten, Auswerten und Abfragen der Datenblöcke erforderlich, aus denen Ihr proprietäres Korpus besteht.
featured image - Verwenden von MinIO zum Erstellen einer Retrieval Augmented Generation Chat-Anwendung
MinIO HackerNoon profile picture
0-item


Es wird oft gesagt, dass im Zeitalter der KI Daten Ihr Schutzgraben sind. Zu diesem Zweck erfordert die Erstellung einer produktionstauglichen RAG-Anwendung eine geeignete Dateninfrastruktur zum Speichern, Versionieren, Verarbeiten, Auswerten und Abfragen von Datenblöcken, aus denen Ihr proprietäres Korpus besteht. Da MinIO einen datenorientierten Ansatz für KI verfolgt, besteht unsere standardmäßige anfängliche Infrastrukturempfehlung für ein Projekt dieser Art darin, einen Modern Data Lake (MinIO) und eine Vektordatenbank einzurichten. Während im Laufe der Zeit möglicherweise andere Zusatztools eingebunden werden müssen, sind diese beiden Infrastruktureinheiten grundlegend. Sie dienen als Schwerpunkt für fast alle Aufgaben, die später bei der Einführung Ihrer RAG-Anwendung in die Produktion anfallen.


Aber Sie stecken in einem Dilemma. Sie haben die Begriffe LLM und RAG schon einmal gehört, aber darüber hinaus haben Sie sich wegen des Unbekannten nicht viel gewagt. Aber wäre es nicht schön, wenn es eine „Hallo Welt“- oder Boilerplate-App gäbe, die Ihnen den Einstieg erleichtern könnte?


Keine Sorge, ich war im selben Boot. In diesem Blog zeigen wir Ihnen, wie Sie mit MinIO eine auf Retrieval Augmented Generation (RAG) basierende Chat-Anwendung mit handelsüblicher Hardware erstellen können.


  • Verwenden Sie MinIO, um alle Dokumente, verarbeiteten Blöcke und Einbettungen mithilfe der Vektordatenbank zu speichern.


  • Verwenden Sie die Bucket-Benachrichtigungsfunktion von MinIO, um Ereignisse auszulösen, wenn Sie Dokumente zu einem Bucket hinzufügen oder daraus entfernen.


  • Webhook, der das Ereignis nutzt, die Dokumente mithilfe von Langchain verarbeitet und die Metadaten und die in Blöcken zusammengefassten Dokumente in einem Metadaten-Bucket speichert


  • Lösen Sie MinIO-Bucket-Benachrichtigungsereignisse für neu hinzugefügte oder entfernte Chunk-Dokumente aus


  • Ein Webhook, der die Ereignisse nutzt, Einbettungen generiert und sie in der Vector-Datenbank (LanceDB) speichert, die in MinIO gespeichert ist.


Wichtige verwendete Tools

  • MinIO - Objektspeicher zum Speichern aller Daten
  • LanceDB – Serverlose Open-Source-Vektordatenbank, die Daten im Objektspeicher speichert
  • Ollama – Zum lokalen Ausführen von LLM und Einbettungsmodell (OpenAI API-kompatibel)
  • Gradio - Schnittstelle zur Interaktion mit der RAG-Anwendung
  • FastAPI - Server für die Webhooks, der Bucket-Benachrichtigungen von MinIO empfängt und die Gradio-App verfügbar macht
  • LangChain & Unstructured – Um nützlichen Text aus unseren Dokumenten zu extrahieren und ihn zum Einbetten aufzuteilen


Verwendete Modelle

  • LLM – Phi-3-128K (3,8 Milliarden Parameter)
  • Einbettungen – Nomic Embed Text v1.5 ( Matrjoschka-Einbettungen / 768 Dim, 8K-Kontext)

MinIO-Server starten

Sie können die Binärdatei hier herunterladen, falls Sie sie noch nicht haben.


 # Run MinIO detached !minio server ~/dev/data --console-address :9090 &


Ollama-Server starten + LLM und Embedding-Modell herunterladen

Laden Sie Ollama hier herunter


 # Start the Server !ollama serve


 # Download Phi-3 LLM !ollama pull phi3:3.8b-mini-128k-instruct-q8_0


 # Download Nomic Embed Text v1.5 !ollama pull nomic-embed-text:v1.5


 # List All the Models !ollama ls


Erstellen Sie eine einfache Gradio-App mit FastAPI, um das Modell zu testen

 LLM_MODEL = "phi3:3.8b-mini-128k-instruct-q8_0" EMBEDDING_MODEL = "nomic-embed-text:v1.5" LLM_ENDPOINT = "http://localhost:11434/api/chat" CHAT_API_PATH = "/chat" def llm_chat(user_question, history): history = history or [] user_message = f"**You**: {user_question}" llm_resp = requests.post(LLM_ENDPOINT, json={"model": LLM_MODEL, "keep_alive": "48h", # Keep the model in-memory for 48 hours "messages": [ {"role": "user", "content": user_question } ]}, stream=True) bot_response = "**AI:** " for resp in llm_resp.iter_lines(): json_data = json.loads(resp) bot_response += json_data["message"]["content"] yield bot_response


 import json import gradio as gr import requests from fastapi import FastAPI, Request, BackgroundTasks from pydantic import BaseModel import uvicorn import nest_asyncio app = FastAPI() with gr.Blocks(gr.themes.Soft()) as demo: gr.Markdown("## RAG with MinIO") ch_interface = gr.ChatInterface(llm_chat, undo_btn=None, clear_btn="Clear") ch_interface.chatbot.show_label = False ch_interface.chatbot.height = 600 demo.queue() if __name__ == "__main__": nest_asyncio.apply() app = gr.mount_gradio_app(app, demo, path=CHAT_API_PATH) uvicorn.run(app, host="0.0.0.0", port=8808)

Test-Einbettungsmodell

 import numpy as np EMBEDDING_ENDPOINT = "http://localhost:11434/api/embeddings" EMBEDDINGS_DIM = 768 def get_embedding(text): resp = requests.post(EMBEDDING_ENDPOINT, json={"model": EMBEDDING_MODEL, "prompt": text}) return np.array(resp.json()["embedding"][:EMBEDDINGS_DIM], dtype=np.float16)


 ## Test with sample text get_embedding("What is MinIO?")


Übersicht über die Aufnahmepipeline

MinIO-Buckets erstellen

Verwenden Sie den Befehl mc oder führen Sie es über die Benutzeroberfläche aus

  • custom-corpus - Zur Speicherung aller Dokumente
  • Warehouse - Zum Speichern aller Metadaten, Chunks und Vektoreinbettungen


 !mc alias set 'myminio' 'http://localhost:9000' 'minioadmin' 'minioadmin'


 !mc mb myminio/custom-corpus !mc mb myminio/warehouse

Erstellen Sie einen Webhook, der Bucket-Benachrichtigungen aus einem benutzerdefinierten Corpus-Bucket nutzt.

 import json import gradio as gr import requests from fastapi import FastAPI, Request from pydantic import BaseModel import uvicorn import nest_asyncio app = FastAPI() @app.post("/api/v1/document/notification") async def receive_webhook(request: Request): json_data = await request.json() print(json.dumps(json_data, indent=2)) with gr.Blocks(gr.themes.Soft()) as demo: gr.Markdown("## RAG with MinIO") ch_interface = gr.ChatInterface(llm_chat, undo_btn=None, clear_btn="Clear") ch_interface.chatbot.show_label = False demo.queue() if __name__ == "__main__": nest_asyncio.apply() app = gr.mount_gradio_app(app, demo, path=CHAT_API_PATH) uvicorn.run(app, host="0.0.0.0", port=8808)


 ## Test with sample text get_embedding("What is MinIO?")


Erstellen Sie MinIO-Ereignisbenachrichtigungen und verknüpfen Sie sie mit dem benutzerdefinierten Korpus-Bucket

Webhook-Ereignis erstellen

Gehen Sie in der Konsole zu Ereignisse -> Ereignisziel hinzufügen -> Webhook


Füllen Sie die Felder mit den folgenden Werten aus und klicken Sie auf „Speichern“


Kennung - doc-webhook


Endpunkthttp://localhost:8808/api/v1/document/notification


Klicken Sie oben auf „MinIO neu starten“, wenn Sie dazu aufgefordert werden.


( Hinweis : Sie können hierfür auch mc verwenden.)

Verknüpfen Sie das Webhook-Ereignis mit benutzerdefinierten Korpus-Bucket-Ereignissen

Gehen Sie in der Konsole zu Buckets (Administrator) -> benutzerdefiniertes Corpus -> Ereignisse


Füllen Sie die Felder mit den folgenden Werten aus und klicken Sie auf „Speichern“


ARN - Wählen Sie den Doc-Webhook aus der Dropdown-Liste


Ereignisse auswählen - PUT und DELETE aktivieren


( Hinweis : Sie können hierfür auch mc verwenden.)


Wir haben unser erstes Webhook-Setup

Testen Sie nun, indem Sie ein Objekt hinzufügen und entfernen

Extrahieren Sie Daten aus den Dokumenten und Chunks

Wir werden Langchain und Unstructured verwenden, um ein Objekt aus MinIO zu lesen und Dokumente in mehrere Blöcke aufzuteilen.


 from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_community.document_loaders import S3FileLoader MINIO_ENDPOINT = "http://localhost:9000" MINIO_ACCESS_KEY = "minioadmin" MINIO_SECRET_KEY = "minioadmin" # Split Text from a given document using chunk_size number of characters text_splitter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=64, length_function=len) def split_doc_by_chunks(bucket_name, object_key): loader = S3FileLoader(bucket_name, object_key, endpoint_url=MINIO_ENDPOINT, aws_access_key_id=MINIO_ACCESS_KEY, aws_secret_access_key=MINIO_SECRET_KEY) docs = loader.load() doc_splits = text_splitter.split_documents(docs) return doc_splits


 # test the chunking split_doc_by_chunks("custom-corpus", "The-Enterprise-Object-Store-Feature-Set.pdf")

Fügen Sie die Chunking-Logik zu Webhook hinzu

Fügen Sie die Chunk-Logik zum Webhook hinzu und speichern Sie die Metadaten und Chunks im Warehouse-Bucket


 import urllib.parse import s3fs METADATA_PREFIX = "metadata" # Using s3fs to save and delete objects from MinIO s3 = s3fs.S3FileSystem() # Split the documents and save the metadata to warehouse bucket def create_object_task(json_data): for record in json_data["Records"]: bucket_name = record["s3"]["bucket"]["name"] object_key = urllib.parse.unquote(record["s3"]["object"]["key"]) print(record["s3"]["bucket"]["name"], record["s3"]["object"]["key"]) doc_splits = split_doc_by_chunks(bucket_name, object_key) for i, chunk in enumerate(doc_splits): source = f"warehouse/{METADATA_PREFIX}/{bucket_name}/{object_key}/chunk_{i:05d}.json" with s3.open(source, "w") as f: f.write(chunk.json()) return "Task completed!" def delete_object_task(json_data): for record in json_data["Records"]: bucket_name = record["s3"]["bucket"]["name"] object_key = urllib.parse.unquote(record["s3"]["object"]["key"]) s3.delete(f"warehouse/{METADATA_PREFIX}/{bucket_name}/{object_key}", recursive=True) return "Task completed!"

Aktualisieren Sie den FastAPI-Server mit der neuen Logik

 import json import gradio as gr import requests from fastapi import FastAPI, Request, BackgroundTasks from pydantic import BaseModel import uvicorn import nest_asyncio app = FastAPI() @app.post("/api/v1/document/notification") async def receive_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() if json_data["EventName"] == "s3:ObjectCreated:Put": print("New object created!") background_tasks.add_task(create_object_task, json_data) if json_data["EventName"] == "s3:ObjectRemoved:Delete": print("Object deleted!") background_tasks.add_task(delete_object_task, json_data) return {"status": "success"} with gr.Blocks(gr.themes.Soft()) as demo: gr.Markdown("## RAG with MinIO") ch_interface = gr.ChatInterface(llm_chat, undo_btn=None, clear_btn="Clear") ch_interface.chatbot.show_label = False demo.queue() if __name__ == "__main__": nest_asyncio.apply() app = gr.mount_gradio_app(app, demo, path=CHAT_API_PATH) uvicorn.run(app, host="0.0.0.0", port=8808)

Neuen Webhook hinzufügen, um Dokumentmetadaten/-blöcke zu verarbeiten

Nachdem wir nun den ersten funktionierenden Webhook haben, besteht der nächste Schritt darin, alle Blöcke mit Metadaten abzurufen, die Embeddings zu generieren und in der Vektordatenbank zu speichern.



 import json import gradio as gr import requests from fastapi import FastAPI, Request, BackgroundTasks from pydantic import BaseModel import uvicorn import nest_asyncio app = FastAPI() @app.post("/api/v1/metadata/notification") async def receive_metadata_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() print(json.dumps(json_data, indent=2)) @app.post("/api/v1/document/notification") async def receive_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() if json_data["EventName"] == "s3:ObjectCreated:Put": print("New object created!") background_tasks.add_task(create_object_task, json_data) if json_data["EventName"] == "s3:ObjectRemoved:Delete": print("Object deleted!") background_tasks.add_task(delete_object_task, json_data) return {"status": "success"} with gr.Blocks(gr.themes.Soft()) as demo: gr.Markdown("## RAG with MinIO") ch_interface = gr.ChatInterface(llm_chat, undo_btn=None, clear_btn="Clear") ch_interface.chatbot.show_label = False demo.queue() if __name__ == "__main__": nest_asyncio.apply() app = gr.mount_gradio_app(app, demo, path=CHAT_API_PATH) uvicorn.run(app, host="0.0.0.0", port=8808)


Erstellen Sie MinIO-Ereignisbenachrichtigungen und verknüpfen Sie sie mit dem Warehouse-Bucket

Webhook-Ereignis erstellen

Gehen Sie in der Konsole zu Ereignisse -> Ereignisziel hinzufügen -> Webhook


Füllen Sie die Felder mit den folgenden Werten aus und klicken Sie auf „Speichern“


Kennung - Metadaten-Webhook


Endpunkthttp://localhost:8808/api/v1/metadata/notification


Klicken Sie oben auf „MinIO neu starten“, wenn Sie dazu aufgefordert werden.


( Hinweis : Sie können hierfür auch mc verwenden.)

Verknüpfen Sie das Webhook-Ereignis mit benutzerdefinierten Korpus-Bucket-Ereignissen

Gehen Sie in der Konsole zu Buckets (Administrator) -> Lager -> Ereignisse


Füllen Sie die Felder mit den folgenden Werten aus und klicken Sie auf „Speichern“


ARN - Wählen Sie den Metadaten-Webhook aus der Dropdown-Liste aus


Präfix - Metadaten/


Suffix – .json


Ereignisse auswählen - PUT und DELETE aktivieren


( Hinweis : Sie können hierfür auch mc verwenden.)


Wir haben unser erstes Webhook-Setup

Testen Sie nun, indem Sie ein Objekt im benutzerdefinierten Korpus hinzufügen und entfernen, und prüfen Sie, ob dieser Webhook ausgelöst wird

Erstellen Sie eine LanceDB-Vektordatenbank in MinIO

Nachdem wir nun den grundlegenden Webhook zum Laufen gebracht haben, richten wir die LanceDB-Vektordatenbank im MinIO-Warehouse-Bucket ein, in dem wir alle Einbettungen und zusätzlichen Metadatenfelder speichern werden.


 import os import lancedb # Set these environment variables for the lanceDB to connect to MinIO os.environ["AWS_DEFAULT_REGION"] = "us-east-1" os.environ["AWS_ACCESS_KEY_ID"] = MINIO_ACCESS_KEY os.environ["AWS_SECRET_ACCESS_KEY"] = MINIO_SECRET_KEY os.environ["AWS_ENDPOINT"] = MINIO_ENDPOINT os.environ["ALLOW_HTTP"] = "True" db = lancedb.connect("s3://warehouse/v-db/")


 # list existing tables db.table_names()


 # Create a new table with pydantic schema from lancedb.pydantic import LanceModel, Vector import pyarrow as pa DOCS_TABLE = "docs" EMBEDDINGS_DIM = 768 table = None class DocsModel(LanceModel): parent_source: str # Actual object/document source source: str # Chunk/Metadata source text: str # Chunked text vector: Vector(EMBEDDINGS_DIM, pa.float16()) # Vector to be stored def get_or_create_table(): global table if table is None and DOCS_TABLE not in list(db.table_names()): return db.create_table(DOCS_TABLE, schema=DocsModel) if table is None: table = db.open_table(DOCS_TABLE) return table


 # Check if that worked get_or_create_table()


 # list existing tables db.table_names()

Speichern/Entfernen von Daten aus LanceDB zum Metadaten-Webhook hinzufügen

 import multiprocessing EMBEDDING_DOCUMENT_PREFIX = "search_document" # Add queue that keeps the processed meteadata in memory add_data_queue = multiprocessing.Queue() delete_data_queue = multiprocessing.Queue() def create_metadata_task(json_data): for record in json_data["Records"]: bucket_name = record["s3"]["bucket"]["name"] object_key = urllib.parse.unquote(record["s3"]["object"]["key"]) print(bucket_name, object_key) with s3.open(f"{bucket_name}/{object_key}", "r") as f: data = f.read() chunk_json = json.loads(data) embeddings = get_embedding(f"{EMBEDDING_DOCUMENT_PREFIX}: {chunk_json['page_content']}") add_data_queue.put({ "text": chunk_json["page_content"], "parent_source": chunk_json.get("metadata", "").get("source", ""), "source": f"{bucket_name}/{object_key}", "vector": embeddings }) return "Metadata Create Task Completed!" def delete_metadata_task(json_data): for record in json_data["Records"]: bucket_name = record["s3"]["bucket"]["name"] object_key = urllib.parse.unquote(record["s3"]["object"]["key"]) delete_data_queue.put(f"{bucket_name}/{object_key}") return "Metadata Delete Task completed!"

Fügen Sie einen Scheduler hinzu, der Daten aus Warteschlangen verarbeitet

 from apscheduler.schedulers.background import BackgroundScheduler import pandas as pd def add_vector_job(): data = [] table = get_or_create_table() while not add_data_queue.empty(): item = add_data_queue.get() data.append(item) if len(data) > 0: df = pd.DataFrame(data) table.add(df) table.compact_files() print(len(table.to_pandas())) def delete_vector_job(): table = get_or_create_table() source_data = [] while not delete_data_queue.empty(): item = delete_data_queue.get() source_data.append(item) if len(source_data) > 0: filter_data = ", ".join([f'"{d}"' for d in source_data]) table.delete(f'source IN ({filter_data})') table.compact_files() table.cleanup_old_versions() print(len(table.to_pandas())) scheduler = BackgroundScheduler() scheduler.add_job(add_vector_job, 'interval', seconds=10) scheduler.add_job(delete_vector_job, 'interval', seconds=10)

Aktualisieren Sie FastAPI mit den Änderungen bei der Vektoreinbettung

 import json import gradio as gr import requests from fastapi import FastAPI, Request, BackgroundTasks from pydantic import BaseModel import uvicorn import nest_asyncio app = FastAPI() @app.on_event("startup") async def startup_event(): get_or_create_table() if not scheduler.running: scheduler.start() @app.on_event("shutdown") async def shutdown_event(): scheduler.shutdown() @app.post("/api/v1/metadata/notification") async def receive_metadata_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() if json_data["EventName"] == "s3:ObjectCreated:Put": print("New Metadata created!") background_tasks.add_task(create_metadata_task, json_data) if json_data["EventName"] == "s3:ObjectRemoved:Delete": print("Metadata deleted!") background_tasks.add_task(delete_metadata_task, json_data) return {"status": "success"} @app.post("/api/v1/document/notification") async def receive_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() if json_data["EventName"] == "s3:ObjectCreated:Put": print("New object created!") background_tasks.add_task(create_object_task, json_data) if json_data["EventName"] == "s3:ObjectRemoved:Delete": print("Object deleted!") background_tasks.add_task(delete_object_task, json_data) return {"status": "success"} with gr.Blocks(gr.themes.Soft()) as demo: gr.Markdown("## RAG with MinIO") ch_interface = gr.ChatInterface(llm_chat, undo_btn=None, clear_btn="Clear") ch_interface.chatbot.show_label = False ch_interface.chatbot.height = 600 demo.queue() if __name__ == "__main__": nest_asyncio.apply() app = gr.mount_gradio_app(app, demo, path=CHAT_API_PATH) uvicorn.run(app, host="0.0.0.0", port=8808) 




Nachdem die Ingestion-Pipeline nun funktioniert, integrieren wir die endgültige RAG-Pipeline.

Vektorsuchfunktion hinzufügen

Nachdem wir das Dokument nun in die lanceDB aufgenommen haben, fügen wir die Suchfunktion hinzu


 EMBEDDING_QUERY_PREFIX = "search_query" def search(query, limit=5): query_embedding = get_embedding(f"{EMBEDDING_QUERY_PREFIX}: {query}") res = get_or_create_table().search(query_embedding).metric("cosine").limit(limit) return res


 # Lets test to see if it works res = search("What is MinIO Enterprise Object Store Lite?") res.to_list()

Aufforderung an LLM, die relevanten Dokumente zu verwenden

 RAG_PROMPT = """ DOCUMENT: {documents} QUESTION: {user_question} INSTRUCTIONS: Answer in detail the user's QUESTION using the DOCUMENT text above. Keep your answer ground in the facts of the DOCUMENT. Do not use sentence like "The document states" citing the document. If the DOCUMENT doesn't contain the facts to answer the QUESTION only Respond with "Sorry! I Don't know" """


 context_df = [] def llm_chat(user_question, history): history = history or [] global context_df # Search for relevant document chunks res = search(user_question) documents = " ".join([d["text"].strip() for d in res.to_list()]) # Pass the chunks to LLM for grounded response llm_resp = requests.post(LLM_ENDPOINT, json={"model": LLM_MODEL, "messages": [ {"role": "user", "content": RAG_PROMPT.format(user_question=user_question, documents=documents) } ], "options": { # "temperature": 0, "top_p": 0.90, }}, stream=True) bot_response = "**AI:** " for resp in llm_resp.iter_lines(): json_data = json.loads(resp) bot_response += json_data["message"]["content"] yield bot_response context_df = res.to_pandas() context_df = context_df.drop(columns=['source', 'vector']) def clear_events(): global context_df context_df = [] return context_df

Aktualisieren Sie den FastAPI-Chat-Endpunkt, um RAG zu verwenden

 import json import gradio as gr import requests from fastapi import FastAPI, Request, BackgroundTasks from pydantic import BaseModel import uvicorn import nest_asyncio app = FastAPI() @app.on_event("startup") async def startup_event(): get_or_create_table() if not scheduler.running: scheduler.start() @app.on_event("shutdown") async def shutdown_event(): scheduler.shutdown() @app.post("/api/v1/metadata/notification") async def receive_metadata_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() if json_data["EventName"] == "s3:ObjectCreated:Put": print("New Metadata created!") background_tasks.add_task(create_metadata_task, json_data) if json_data["EventName"] == "s3:ObjectRemoved:Delete": print("Metadata deleted!") background_tasks.add_task(delete_metadata_task, json_data) return {"status": "success"} @app.post("/api/v1/document/notification") async def receive_webhook(request: Request, background_tasks: BackgroundTasks): json_data = await request.json() if json_data["EventName"] == "s3:ObjectCreated:Put": print("New object created!") background_tasks.add_task(create_object_task, json_data) if json_data["EventName"] == "s3:ObjectRemoved:Delete": print("Object deleted!") background_tasks.add_task(delete_object_task, json_data) return {"status": "success"} with gr.Blocks(gr.themes.Soft()) as demo: gr.Markdown("## RAG with MinIO") ch_interface = gr.ChatInterface(llm_chat, undo_btn=None, clear_btn="Clear") ch_interface.chatbot.show_label = False ch_interface.chatbot.height = 600 gr.Markdown("### Context Supplied") context_dataframe = gr.DataFrame(headers=["parent_source", "text", "_distance"], wrap=True) ch_interface.clear_btn.click(clear_events, [], context_dataframe) @gr.on(ch_interface.output_components, inputs=[ch_interface.chatbot], outputs=[context_dataframe]) def update_chat_context_df(text): global context_df if context_df is not None: return context_df return "" demo.queue() if __name__ == "__main__": nest_asyncio.apply() app = gr.mount_gradio_app(app, demo, path=CHAT_API_PATH) uvicorn.run(app, host="0.0.0.0", port=8808)


Konnten Sie den RAG-basierten Chat mit MinIO als Data Lake-Backend implementieren? Wir werden in Kürze ein Webinar zu diesem Thema abhalten, in dem wir Ihnen eine Live-Demo geben, während wir diese RAG-basierte Chat-Anwendung erstellen.

RAGs-R-Us

Als Entwickler mit Schwerpunkt auf KI-Integration bei MinIO erforsche ich ständig, wie unsere Tools nahtlos in moderne KI-Architekturen integriert werden können, um Effizienz und Skalierbarkeit zu verbessern. In diesem Artikel haben wir Ihnen gezeigt, wie Sie MinIO mit Retrieval-Augmented Generation (RAG) integrieren, um eine Chat-Anwendung zu erstellen. Dies ist nur die Spitze des Eisbergs, um Ihnen bei Ihrem Vorhaben, einzigartigere Anwendungsfälle für RAG und MinIO zu entwickeln, einen Anstoß zu geben. Jetzt haben Sie die Bausteine dafür. Los geht‘s!


Wenn Sie Fragen zur MinIO RAG-Integration haben, wenden Sie sich bitte an uns unter Locker !