RAG für Bilder: Vision models und visuelle Suche
Umfassender Leitfaden zur Integration von Bildern in Ihr RAG-System: Vision models, multimodal embeddings, Indexierung und visuelle Suche mit GPT-4V, Claude Vision und CLIP.
RAG für Bilder: Vision-Modelle und visuelle Suche
Die traditionellen RAG-Systeme beschränken sich auf Text. Dabei sind viele Unternehmensinformationen visuell: Produktfotos, Screenshots, Grafiken, technische Zeichnungen. Image RAG erlaubt es, in diesen visuellen Inhalten mit derselben Präzision wie bei einem textuellen RAG zu indexieren und zu suchen.
Warum Bilder in den RAG integrieren?
Visuelle Daten im Unternehmen
- E-Commerce: 70% der Kaufentscheidungen werden durch Produktbilder beeinflusst
- Technischer Support: Screenshots beschleunigen die Lösung von Tickets um 60%
- Dokumentation: Eine Grafik ist oft mehr wert als eine Seite Text
- Compliance: Baustellenfotos, Zustandsdokumentationen, visuelle Belege
Konkrete Anwendungsfälle
| Branche | Anwendung | Beispielanfrage |
|---|---|---|
| E-Commerce | Visuelle Suche | "Finde Kleider, die diesem Foto ähneln" |
| Immobilien | Objektanalyse | "Zeig mir moderne Einbauküchen" |
| IT-Support | Diagnose | "Was bedeutet diese Fehlermeldung?" |
| Fertigung | Qualitätskontrolle | "Weist dieses Teil einen Defekt auf?" |
Architektur eines Image RAG
Gesamtübersicht
┌─────────────────────────────────────────────────────────────┐
│ IMAGE RAG PIPELINE │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Image │───▶│ Vision │───▶│ Embedding │ │
│ │ Input │ │ Model │ │ (CLIP/SigLIP) │ │
│ └──────────┘ └──────────────┘ └──────────────────┘ │
│ │ │ │ │
│ │ ▼ ▼ │
│ │ ┌──────────────┐ ┌──────────────────┐ │
│ │ │ Description │ │ Vector Store │ │
│ │ │ textuelle │ │ (Qdrant/Pine) │ │
│ │ └──────────────┘ └──────────────────┘ │
│ │ │ │ │
│ │ ▼ ▼ │
│ │ ┌─────────────────────────────────┐ │
│ └────────▶│ Retrieval multimodal │ │
│ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────┐ │
│ │ Génération (VLM/LLM) │ │
│ └─────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Die zwei Ansätze
1. Description + RAG textuel
- Das Vision-Model beschreibt das Bild in Text
- Der Text wird klassisch indexiert
- Einfacher, verliert jedoch visuelle Informationen
2. Native multimodale Embeddings
- Das Bild wird direkt in einen Vektor konvertiert
- Bewahrt die vollständige visuelle Information
- Ermöglicht Bild-zu-Bild-Suche
Vision-Modelle für den RAG
Proprietäre Modelle
| Modell | Max. Auflösung | Kosten | Stärken |
|---|---|---|---|
| GPT-4V | 2048x2048 | $0.00765/Bild (low) | Komplexes Reasoning, exzellentes OCR |
| Claude 3.5 Sonnet Vision | 8192x8192 | $0.003/Bild | Detaillierte Analyse, Sicherheit |
| Gemini 1.5 Pro | Unbegrenzt | $0.001315/Bild | Multi-Bild, langer Kontext |
Open-Source-Modelle
| Modell | Parameter | VRAM | Anwendung |
|---|---|---|---|
| LLaVA 1.6 | 34B | 24GB | Allgemeine Beschreibung |
| CogVLM2 | 19B | 16GB | Feingranulares Verständnis |
| InternVL2 | 76B | 48GB | SOTA-Performance |
| Qwen-VL-Max | 72B | 48GB | Mehrsprachig |
Multimodale Embedding-Modelle
| Modell | Dimension | Sprachen | Open Source |
|---|---|---|---|
| CLIP (OpenAI) | 512/768 | Hauptsächlich EN | Ja |
| SigLIP | 384-1152 | Mehrsprachig | Ja |
| Jina CLIP v2 | 1024 | 89 Sprachen | Ja |
| Cohere Embed v3 | 1024 | 100+ Sprachen | Nein |
Praktische Implementierung
Schritt 1: Extraktion und Beschreibung der Bilder
DEVELOPERpythonimport base64 from openai import OpenAI def describe_image_for_rag(image_path: str, context: str = "") -> dict: """ Erzeugt eine RAG-optimierte Beschreibung eines Bildes. """ client = OpenAI() # Das Bild in base64 kodieren with open(image_path, "rb") as f: image_data = base64.b64encode(f.read()).decode("utf-8") # Den MIME-Typ bestimmen mime_type = "image/jpeg" if image_path.endswith((".jpg", ".jpeg")) else "image/png" prompt = """Analysiere dieses Bild für ein RAG-System. Liefere: 1. **Allgemeine Beschreibung** (2-3 Sätze) 2. **Schlüsselelemente** (Aufzählung der wichtigen Objekte/Konzepte) 3. **Sichtbarer Text** (jeglicher lesbarer Text im Bild) 4. **Vorgeschlagene Metadaten** (Kategorie, relevante Tags) Sei umfassend, aber prägnant. Ziel ist es, die textuelle Suche auf diesem Bild zu ermöglichen.""" if context: prompt += f"\n\nZusätzlicher Kontext: {context}" response = client.chat.completions.create( model="gpt-4o", messages=[ { "role": "user", "content": [ {"type": "text", "text": prompt}, { "type": "image_url", "image_url": { "url": f"data:{mime_type};base64,{image_data}", "detail": "high" } } ] } ], max_tokens=1000 ) description = response.choices[0].message.content return { "image_path": image_path, "description": description, "model": "gpt-4o", "tokens_used": response.usage.total_tokens }
Schritt 2: Multimodale Embeddings mit CLIP
DEVELOPERpythonimport torch from PIL import Image from transformers import CLIPProcessor, CLIPModel class MultimodalEmbedder: def __init__(self, model_name: str = "openai/clip-vit-large-patch14"): self.device = "cuda" if torch.cuda.is_available() else "cpu" self.model = CLIPModel.from_pretrained(model_name).to(self.device) self.processor = CLIPProcessor.from_pretrained(model_name) def embed_image(self, image_path: str) -> list[float]: """Erzeugt ein Embedding für ein Bild.""" image = Image.open(image_path).convert("RGB") inputs = self.processor(images=image, return_tensors="pt").to(self.device) with torch.no_grad(): embedding = self.model.get_image_features(**inputs) # Für Kosinusähnlichkeit normalisieren embedding = embedding / embedding.norm(dim=-1, keepdim=True) return embedding.cpu().squeeze().tolist() def embed_text(self, text: str) -> list[float]: """Erzeugt ein Embedding für Text (im selben Raum wie die Bilder).""" inputs = self.processor(text=[text], return_tensors="pt", padding=True).to(self.device) with torch.no_grad(): embedding = self.model.get_text_features(**inputs) embedding = embedding / embedding.norm(dim=-1, keepdim=True) return embedding.cpu().squeeze().tolist() def compute_similarity(self, image_path: str, text: str) -> float: """Berechnet die Ähnlichkeit Bild-zu-Text.""" img_emb = torch.tensor(self.embed_image(image_path)) txt_emb = torch.tensor(self.embed_text(text)) return (img_emb @ txt_emb).item()
Schritt 3: Indexierung in Qdrant
DEVELOPERpythonfrom qdrant_client import QdrantClient from qdrant_client.models import ( VectorParams, Distance, PointStruct, Filter, FieldCondition, MatchValue ) class ImageRAGIndex: def __init__(self, collection_name: str = "image_rag"): self.client = QdrantClient(url="http://localhost:6333") self.collection_name = collection_name self.embedder = MultimodalEmbedder() def create_collection(self, vector_size: int = 768): """Erstellt die Collection mit zwei Vektorräumen.""" self.client.recreate_collection( collection_name=self.collection_name, vectors_config={ # Visuelles Embedding (CLIP) "visual": VectorParams( size=vector_size, distance=Distance.COSINE ), # Textuelles Embedding (Beschreibung) "textual": VectorParams( size=1536, # Ada-002 oder ähnlich distance=Distance.COSINE ) } ) def index_image( self, image_id: str, image_path: str, description: str, text_embedding: list[float], metadata: dict = None ): """Indexiert ein Bild mit seinen beiden Embeddings.""" visual_embedding = self.embedder.embed_image(image_path) point = PointStruct( id=hash(image_id) % (2**63), vector={ "visual": visual_embedding, "textual": text_embedding }, payload={ "image_id": image_id, "image_path": image_path, "description": description, **(metadata or {}) } ) self.client.upsert( collection_name=self.collection_name, points=[point] ) def search_by_text(self, query: str, limit: int = 5) -> list[dict]: """Suche mittels textueller Anfrage.""" query_embedding = self.embedder.embed_text(query) results = self.client.search( collection_name=self.collection_name, query_vector=("visual", query_embedding), # CLIP text -> visual limit=limit ) return [ { "image_path": r.payload["image_path"], "description": r.payload["description"], "score": r.score } for r in results ] def search_by_image(self, image_path: str, limit: int = 5) -> list[dict]: """Suche nach ähnlichen Bildern.""" query_embedding = self.embedder.embed_image(image_path) results = self.client.search( collection_name=self.collection_name, query_vector=("visual", query_embedding), limit=limit ) return [ { "image_path": r.payload["image_path"], "description": r.payload["description"], "score": r.score } for r in results ]
Schritt 4: Generierung mit visuellem Kontext
DEVELOPERpythondef generate_with_images( query: str, retrieved_images: list[dict], client: OpenAI ) -> str: """ Erzeugt eine Antwort unter Verwendung der abgerufenen Bilder als Kontext. """ # Den multimodalen Inhalt vorbereiten content = [ { "type": "text", "text": f"""Du bist ein Assistent, der Fragen beantwortet, indem er die bereitgestellten Bilder als Informationsquelle nutzt. Frage des Benutzers: {query} Verfügbare Bilder:""" } ] # Jedes Bild mit seiner Beschreibung hinzufügen for i, img in enumerate(retrieved_images[:3], 1): # Max 3 Bilder with open(img["image_path"], "rb") as f: img_data = base64.b64encode(f.read()).decode("utf-8") content.append({ "type": "text", "text": f"\n**Bild {i}** (Score: {img['score']:.2f}):\n{img['description']}" }) content.append({ "type": "image_url", "image_url": { "url": f"data:image/jpeg;base64,{img_data}", "detail": "low" # Tokens sparen } }) content.append({ "type": "text", "text": "\n\nBeantworte die Frage ausschließlich auf Grundlage dieser Bilder. Falls die Bilder keine Antwort ermöglichen, sage dies klar." }) response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": content}], max_tokens=1000 ) return response.choices[0].message.content
Erweiterte Optimierungen
Chunking hochauflösender Bilder
Für sehr große Bilder (Pläne, Schaubilder) in Kacheln schneiden:
DEVELOPERpythonfrom PIL import Image def tile_large_image(image_path: str, tile_size: int = 512, overlap: int = 64): """Zerteilt ein großes Bild in überlappende Kacheln.""" img = Image.open(image_path) width, height = img.size tiles = [] for y in range(0, height - overlap, tile_size - overlap): for x in range(0, width - overlap, tile_size - overlap): box = (x, y, min(x + tile_size, width), min(y + tile_size, height)) tile = img.crop(box) tiles.append({ "tile": tile, "position": (x, y), "original_size": (width, height) }) return tiles
Hybride Suche Bild + Text
DEVELOPERpythondef hybrid_image_search( query: str, text_embedding: list[float], index: ImageRAGIndex, alpha: float = 0.7 # Gewicht visuell vs. textuell ) -> list[dict]: """Kombiniert visuelle und textuelle Suche.""" # Visuelle Suche (CLIP) visual_results = index.search_by_text(query, limit=20) # Textuelle Suche (auf den Beschreibungen) text_results = index.client.search( collection_name=index.collection_name, query_vector=("textual", text_embedding), limit=20 ) # Scores mit RRF zusammenführen combined_scores = {} for rank, r in enumerate(visual_results): img_id = r["image_path"] combined_scores[img_id] = combined_scores.get(img_id, 0) + alpha / (rank + 60) for rank, r in enumerate(text_results): img_id = r.payload["image_path"] combined_scores[img_id] = combined_scores.get(img_id, 0) + (1 - alpha) / (rank + 60) # Nach kombiniertem Score sortieren sorted_results = sorted(combined_scores.items(), key=lambda x: x[1], reverse=True) return [{"image_path": path, "score": score} for path, score in sorted_results[:5]]
Benchmarks und Kosten
Retrieval-Performance
| Methode | Precision@5 | Recall@10 | Latenz |
|---|---|---|---|
| Nur Beschreibung | 0.72 | 0.81 | 50ms |
| Nur CLIP | 0.78 | 0.85 | 30ms |
| Hybrid | 0.84 | 0.91 | 80ms |
Kosten pro indexiertem Bild
| Schritt | Geschätzte Kosten | Hinweise |
|---|---|---|
| Beschreibung GPT-4V | $0,01-0,03 | Je nach Größe und Detailgrad |
| CLIP-Embedding | $0 (lokal) | GPU empfohlen |
| Qdrant-Speicherung | ~$0,0001 | Pro Vektor/Monat |
Vergleich der Embedding-Modelle
| Modell | Zero-Shot-Genauigkeit | Mehrsprachig | Geschwindigkeit |
|---|---|---|---|
| CLIP ViT-L/14 | 75.5% | Nein | Schnell |
| SigLIP So400m | 83.1% | Ja | Mittel |
| Jina CLIP v2 | 81.2% | Ja | Schnell |
Fallstricke und Lösungen
Problem 1: Bilder mit wenig visuellem Inhalt
Symptom: Screenshots mit viel Text werden von CLIP schlecht indexiert.
Lösung: Explizites OCR + textuelle Indexierung.
DEVELOPERpythonimport pytesseract def extract_text_from_image(image_path: str) -> str: """Extrahiert Text aus einem Bild mittels OCR.""" img = Image.open(image_path) text = pytesseract.image_to_string(img, lang='fra+eng') return text.strip()
Problem 2: Visuelle Duplikate
Symptom: Mehrere nahezu identische Bilder verschmutzen die Ergebnisse.
Lösung: Deduplizierung per Ähnlichkeit.
DEVELOPERpythondef deduplicate_images(embeddings: list, threshold: float = 0.95): """Entfernt zu ähnliche Bilder.""" keep = [] for i, emb in enumerate(embeddings): is_duplicate = False for j in keep: similarity = cosine_similarity(emb, embeddings[j]) if similarity > threshold: is_duplicate = True break if not is_duplicate: keep.append(i) return keep
Problem 3: Widersprüchlicher visueller vs. textueller Kontext
Symptom: Die generierte Beschreibung widerspricht dem Bild.
Lösung: Kreuzvalidierung und Vertrauensscore.
Integration mit Ailog
Ailog unterstützt nativ die Indexierung von Bildern in euren Knowledge Bases:
- Upload: Bilder per Drag & Drop in die Oberfläche ziehen
- Automatische Analyse: Vision-Model zur Inhaltsextraktion
- Hybride Indexierung: Visuelle + textuelle Embeddings
- Vereinheitlichte Suche: Eine einzige Anfrage für Text und Bilder
Probieren Sie das Image RAG bei Ailog aus - Keine Konfiguration erforderlich.
FAQ
Verwandte Guides
Tags
Verwandte Artikel
RAG Multimodal: Bilder, PDFs und über den Text hinaus
Erweitern Sie Ihr RAG über den Text hinaus: Indexierung von Bildern, Extraktion von PDFs, Tabellen und Grafiken für einen wirklich umfassenden Assistenten.
Stand der Technik: RAG multimodal 2026
Überblick über RAG multimodal im Jahr 2026: vision-language-Modelle, multimodale Embeddings und Architekturen für die Verarbeitung von Bildern, PDFs und Dokumenten.
Diagramme und Schemata: Visuelle Informationen extrahieren
Umfassender Leitfaden zur Integration von Diagrammen, technischen Schemata und Infografiken in Ihr RAG-System: Extraktion, Interpretation und Indexierung mit den vision models.