Von Dima Kramskoy — Senior Cloud Architect bei DoiT International
Warum es diesen Beitrag gibt
Die meisten Tutorials zur Bedrock Knowledge Base folgen demselben Drehbuch: PDF in S3 hochladen, Knowledge Base anlegen, Frage stellen. Fertig. Blogbeitrag geschrieben.
Für eine Demo reicht das. Im Produktivbetrieb taugt es nichts.
Ich habe kürzlich für ein FinTech in LATAM ein Policy-Audit-System gebaut, das Ausgaben per KI in Echtzeit gegen interne Richtlinien prüft. Es verarbeitet rund 500 Anfragen pro Tag über 100+ Policy-Dokumente in zwei Sprachen. Es läuft produktiv. Spesenabrechnungen von Mitarbeitenden werden auf Basis seiner Antworten genehmigt oder abgelehnt.
Hier ist, was ich dabei tatsächlich gelernt habe — die Architekturentscheidungen, die Chunking-Fehler, die Kostenüberraschungen und die Stolperfallen, vor denen keine AWS-Dokumentation warnt.
Ihre erste Bedrock Knowledge Base (5 Minuten)
Bevor ich in die Tiefe gehe: Stellen wir sicher, dass die Grundlagen sitzen. Wenn Sie bereits eine KB aufgebaut haben, springen Sie zum nächsten Abschnitt. Falls nicht, hier der schnellste Weg zum "es läuft":
Schritt 1: S3-Bucket mit Ihren Dokumenten anlegen
aws s3 mb s3://my-kb-source-docsaws s3 cp ./policies/ s3://my-kb-source-docs/ --recursiveSchritt 2: Knowledge Base anlegen (Konsole)
- In Amazon Bedrock → Knowledge Bases → Create
- Namen vergeben, Embedding-Modell wählen (Titan Embeddings v2 ist der Standard — für den Anfang völlig in Ordnung)
- Auf Ihren S3-Bucket verweisen
- Als Vector Store S3 Vectors wählen (serverless, keine Konfiguration) oder automatisch anlegen lassen
- Auf Create klicken → 2–3 Minuten auf die Synchronisierung warten
Schritt 3: Abfragen
import boto3
client = boto3.client('bedrock-agent-runtime')
response = client.retrieve_and_generate( input={'text': 'What is our policy on travel expenses?'}, retrieveAndGenerateConfiguration={ 'type': 'KNOWLEDGE_BASE', 'knowledgeBaseConfiguration': { 'knowledgeBaseId': 'YOUR_KB_ID', 'modelArn': 'arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-pro-v1:0' } })print(response['output']['text'])Das war's. Sie haben ein funktionierendes RAG-System, das Fragen aus Ihren Dokumenten beantwortet.
Aber jetzt der entscheidende Punkt: Damit haben Sie 60 % des Wegs hinter sich. Die restlichen 40 % — dort, wo produktive Qualität entsteht — sind das eigentliche Thema dieses Beitrags: Chunking-Strategie, Kostenkontrolle, Latenz, Transformations-Pipeline und die Stolperfallen, die Sie bei wachsender Skalierung einholen werden.
Der Anwendungsfall
Der Kunde hatte ein Problem, das früher oder später jedes wachsende Unternehmen einholt: komplexe interne Richtlinien, die niemand liest, uneinheitlich angewandt, über mehrere Länder und Sprachen hinweg.
Konkret: Ein Unternehmen mit 100+ internen Policy-Dokumenten (Englisch und Spanisch) brauchte eine KI, die Mitarbeiterausgaben in Echtzeit gegen diese Richtlinien prüft. Nicht "nach einer Richtlinie suchen" — sondern tatsächlich entscheiden, ob eine Ausgabe konform ist, die einschlägige Regel zitieren und die Entscheidung begründen.
Die Anforderungen waren klar:
- Entscheidungslatenz unter 3 Sekunden
- Jede Entscheidung muss auf einen konkreten Policy-Absatz rückführbar sein
- Freigabe durch einen Menschen bei Policy-Änderungen (rechtliche Haftung)
- Mehrsprachigkeit (Englisch/Spanisch)
- Wirtschaftlich skalierbar (~500 Anfragen/Tag, Tendenz steigend)
Architektur-Überblick
So sieht der Ablauf auf hoher Ebene aus:
Pfad für Transaktionsbewertung:
API Gateway → SQS → Step Functions → Bedrock Nova Pro (Belegvalidierung)→ Bedrock AgentCore (Policy-Entscheidung via KB) → Aurora MySQL (Entscheidung persistieren)Pfad für Policy-Ingestion:
S3-Upload → Step Functions (Freigabe durch Menschen via Task Token)→ LLM-Transformation (Policy umstrukturieren, Ausgaben extrahieren, neue Sicht aufbauen)→ Transformierte Chunks in S3 ablegen (Übergangszustand)→ API stellt Chunks zur Prüfung bereit → Freigabe durch Menschen→ Aufnahme in die Bedrock Knowledge BaseZwei klar getrennte Pfade. Einer für Echtzeit-Entscheidungen, einer für das Policy-Lifecycle-Management. Step Functions orchestriert beide — und das ist kein Zufall. State Machines liefern genau die Sichtbarkeit und Retry-Semantik, die Sie brauchen, sobald rechtliche Compliance im Spiel ist.
Warum S3 Vectors (und nicht OpenSearch)
An dieser Stelle erspare ich Ihnen Wochen des Abwägens.
Als ich das Projekt startete, war der Standard-Vector-Store für Bedrock KB OpenSearch Serverless. Funktioniert. Ist erprobt. Ist aber für einen Bestand unter 10K Dokumenten auch maßlos überdimensioniert.
S3 Vectors kam als schlankere Alternative auf den Markt — und für unseren Anwendungsfall war die Wahl offensichtlich:
| Faktor | OpenSearch Serverless | S3 Vectors |
|---|---|---|
| Monatlicher Grundpreis | ~700 $+ (mindestens 2 OCUs) | Pay-per-Query |
| Betriebsaufwand | Index-Management, Skalierung | Keiner |
| Einrichtungsaufwand | Mittel | Minimal |
| Abfragelatenz (p50) | ~200 ms | ~350 ms |
| Sweet Spot | 10K+ Dokumente, komplexe Queries | <10K Dokumente, einfaches Retrieval |
Die Entscheidungsregel ist einfach: Liegt Ihr Dokumentenkorpus unter 10K Dokumenten und brauchen Sie weder komplexes Filtering noch Hybrid Search, spart S3 Vectors Geld und Betriebsaufwand. Brauchen Sie Latenzen unter 200 ms oder haben Sie zehntausende Dokumente mit komplexen Metadaten-Queries, dann greifen Sie zu OpenSearch.
Bei unseren ~100 Policy-Dokumenten war S3 Vectors eine Selbstverständlichkeit. Wir zahlen Cent-Beträge pro Tag statt mindestens 700 $/Monat. Die zusätzlichen ~150 ms Latenz fallen in einem Workflow, der ohnehin LLM-Inferenz enthält, überhaupt nicht ins Gewicht.
Chunking-Strategien, die wirklich zählen
Bevor ich teile, was bei uns funktioniert hat, hier zunächst der Überblick — denn die meisten Guides zeigen nur ein, zwei Optionen:
| Strategie | Funktionsweise | Geeignet für | Vorsicht |
|---|---|---|---|
| Feste Größe (Standard) | Teilt alle N Zeichen/Tokens | Schneller Einstieg, generische Dokumente | Teilt mitten im Satz oder mitten in einer Regel — führt zu halluzinierten Antworten |
| Satzbasiert | Teilt an Satzgrenzen | Einfache Dokumente, FAQs | Ignoriert logische Abschnitte; eine Policy-Regel kann sich über 5+ Sätze erstrecken |
| Semantisch / abschnittsbasiert | Teilt an der Dokumentstruktur (Überschriften, Abschnitte) | Strukturierte Dokumente mit klarer Hierarchie | Erfordert Parsing der Dokumentstruktur; Chunk-Größen variieren |
| Hierarchisch (Parent-Child) | Eltern-Chunks (ganzer Abschnitt) + Kind-Chunks (Absätze) | Beste Retrieval-Qualität — Match auf Kind, Rückgabe des Elternteils für Kontext | Komplexer, höherer Speicherbedarf, langsameres Indizieren |
| LLM-gestützt | LLM restrukturiert das Dokument VOR dem Chunking | Dokumente mit hoher Tragweite, bei denen falsches Retrieval = falsche Entscheidung | Erhöht Kosten und Latenz bei der Ingestion; lohnt sich, sobald Genauigkeit zählt |
Unsere Wahl: LLM-gestützt. Bei Policy-Dokumenten, bei denen ein falsches Retrieval direkt eine falsche Ausgabenentscheidung bedeutet, amortisieren sich die Vorabkosten der LLM-Transformation sofort. Mehr dazu weiter unten im Pipeline-Abschnitt.
Aber zuerst zeige ich Ihnen den Fehlermodus, der uns dorthin geführt hat:
Hier habe ich am Anfang meinen teuersten Fehler gemacht.
Was nicht funktioniert hat: Standard-Chunking
Das Standard-Chunking der Bedrock KB teilt Dokumente nach Zeichenzahl mit Überlappung. Bei generischen Dokumenten passt das. Bei Policy-Dokumenten ist es katastrophal.
Warum: Eine Policy-Regel könnte lauten "Mahlzeiten über 75 $ erfordern die Genehmigung der Führungskraft, außer bei Kundenreisen, bei denen das Limit 150 $ beträgt." Das Standard-Chunking kann diesen Satz mittendrin aufteilen. Das Retrieval liefert dann "Mahlzeiten über 75 $ erfordern die Genehmigung der Führungskraft" — ohne die Ausnahme. Der Agent lehnt ein legitimes 100-$-Kundenessen ab. Ihre Nutzer verlieren am ersten Tag das Vertrauen in das System.
Was funktioniert hat: Chunking an semantischen Grenzen
Wir verarbeiten Dokumente vor der Ingestion und teilen sie nach Policy-Abschnitt — jede Regel oder Unterregel wird zu einem eigenen Chunk mit vollem Kontext.
import refrom dataclasses import dataclass
@dataclassclass PolicyChunk: content: str metadata: dict
def chunk_policy_document(text: str, doc_id: str, language: str) -> list[PolicyChunk]: """Chunk policy documents by semantic boundaries (section headers)."""
# Split on policy section patterns (numbered rules, headers) section_pattern = r'\n(?=\d+\.\s|\#{1,3}\s|Article\s+\d+|Artículo\s+\d+)' sections = re.split(section_pattern, text)
chunks = [] for i, section in enumerate(sections): section = section.strip() if len(section) < 50: # Skip trivial sections continue
# Keep chunks between 200-1500 chars for optimal retrieval if len(section) > 1500: # Sub-chunk by paragraph, preserving section header header = section.split('\n')[0] paragraphs = section.split('\n\n') for j, para in enumerate(paragraphs[1:], 1): chunks.append(PolicyChunk( content=f"{header}\n\n{para}", metadata={ "doc_id": doc_id, "section_index": i, "sub_index": j, "language": language, "chunk_type": "policy_rule" } )) else: chunks.append(PolicyChunk( content=section, metadata={ "doc_id": doc_id, "section_index": i, "sub_index": 0, "language": language, "chunk_type": "policy_rule" } ))
return chunksPraxis-Hinweise
- Optimale Chunk-Größe: 200–1500 Zeichen für Policy-Dokumente. Kleinere Chunks erhöhen die Präzision, größere bewahren Kontext. Finden Sie Ihre Balance.
- Überlappung: Wenn Sie unbedingt zeichenbasiert chunken müssen, dann mit mindestens 20 % Überlappung. Aber im Ernst: chunken Sie an semantischen Grenzen.
- Metadaten sind Retrieval: Versehen Sie jeden Chunk mit
language,policy_type,effective_dateunddepartment. Sie werden später danach filtern — das ist nicht optional.
Die Ingestion-Pipeline
Policy-Dokumente sind keine Blogbeiträge. Sie können sie nicht einfach in einen Vector Store kippen und auf das Beste hoffen. Eine falsche Policy-Interpretation hat rechtliche Konsequenzen.
So sieht die Pipeline aus:
Das Muster: LLM-Transformation + Human-in-the-Loop
Die zentrale Design-Erkenntnis: Transformieren VOR der Freigabe. Der Ablauf:
S3-Upload (rohes Policy-PDF) ↓LLM-Transformation (umstrukturieren, Ausgabenregeln extrahieren, in die gewünschte Sicht überführen) ↓Transformierte Chunks in S3 ablegen (Übergangszustand — für Wiederverwendung gecacht) ↓API stellt strukturierte Chunks zur Prüfung bereit ↓Prüfer gibt frei / lehnt ab (ein Klick) ↓Freigegebene Chunks werden in die Bedrock Knowledge Base aufgenommenDas ist ein logisches Freigabe-Gate, keine schwergewichtige Orchestrierung. Das LLM erledigt die harte Arbeit vorab — mehrseitige PDFs parsen, einzelne Ausgabenregeln extrahieren und konsistent strukturieren. Wenn der Prüfer das Ergebnis sieht, blickt er auf saubere, strukturierte Chunks — nicht auf Rohdokumente.
Warum das im Produktivbetrieb zählt:
- Re-Ingestion ist schnell — die Transformation ist in S3 gecacht. Policy-Updates erfordern keine vollständige Neuverarbeitung.
- Prüfer sehen Qualitäts-Output — sie geben strukturierte Regeln frei, keine PDF-Textwüsten.
- Weniger Fehler beim Retrieval — da das LLM den Inhalt vorstrukturiert, erhält die KB jedes Mal konsistent formatierte Chunks.
Warum Human-in-the-Loop wichtig ist
Ich habe Teams gesehen, die das Freigabe-Gate weglassen, weil "wir unserem Policy-Team vertrauen". Dann lädt jemand einen Entwurf hoch, das Dokument wird eingebettet, und die KI beginnt, Entwurfsregeln durchzusetzen. Ein einziger solcher Vorfall — und das Vertrauen der Organisation in das System ist dahin.
Anti-Muster: Automatische Ingestion beim S3-Upload. Bei compliance-relevanten Dokumenten ein No-Go.
Muster: Upload → LLM transformiert & strukturiert die Policy → transformierte Chunks in S3 gecacht → API stellt Chunks zur Prüfung bereit → Mensch gibt frei / lehnt ab → dann in die KB aufnehmen. So ist die Re-Ingestion schnell (die Transformation ist bereits erledigt und gecacht), und die Genehmiger sehen sauberen, strukturierten Output — keine rohen PDFs.
Retrieval-Latenz & Kosten
Echte Zahlen aus dem Produktivbetrieb (Workload mit 500 Anfragen/Tag):
Latenz (S3 Vectors)
p50 = mediane Antwortzeit (typische Erfahrung). p99 = 99. Perzentil (Worst Case ohne Extremausreißer).
- p50: 340 ms (nur Retrieval, ohne LLM-Inferenz)
- p99: 890 ms
- End-to-End-Entscheidung (inkl. AgentCore): p50 ~2,1 s, p99 ~4,8 s
Monatliche Kostenaufschlüsselung
| Komponente | Monatliche Kosten |
|---|---|
| S3 Vectors (Speicher + Abfragen) | ~12 $ |
| Bedrock-KB-API-Aufrufe | ~8 $ |
| Titan Embeddings (Ingestion) | ~3 $ |
| Nova Pro (Belegvalidierung) | ~45 $ |
| AgentCore (Policy-Entscheidungen) | ~120 $ |
| Step Functions | ~5 $ |
| Aurora MySQL (Persistenz) | ~65 $ |
| Gesamt | ~258 $/Monat |
Im Vergleich dazu OpenSearch Serverless allein bei mindestens 700 $/Monat. Architekturentscheidungen summieren sich.
Stolperfallen, vor denen niemand warnt
Nach drei Monaten Produktivbetrieb hier meine Liste:
Sync-Verzögerung nach dem Upload. Nach dem Aufruf von
StartIngestionJobsind die neuen Inhalte in der KB nicht sofort abfragbar. Rechnen Sie bei kleinen Updates mit 30–90 Sekunden. Berücksichtigen Sie das in Ihrer UX — zeigen Sie Status wie "Policy-Update wird verarbeitet".Metadaten-Filterung nur als Exact-Match (S3 Vectors). Range-Queries oder Teil-Matches auf Metadaten sind nicht möglich. Entwerfen Sie Ihr Metadaten-Schema entlang von Gleichheits-Filtern. Wenn Sie "alle Policies, die nach Januar 2025 aktualisiert wurden" brauchen, müssen Sie einen anderen Weg gehen.
Die Wahl des Embedding-Modells ist endgültig. Wer eine KB einmal mit Titan Embeddings v2 angelegt hat, kann nicht ohne kompletten Neuaufbau der Knowledge Base auf Cohere wechseln. Wählen Sie vorab sorgfältig. (Wir haben uns für Titan v2 entschieden — gute Balance aus Kosten und Qualität bei zweisprachigen Inhalten.)
Mehrsprachiges Retrieval ist keine Magie. Eine Anfrage auf Spanisch findet spanische Chunks gut, aber sprachübergreifendes Retrieval (spanische Anfrage → englische Policy) ist unzuverlässig. Wir haben das gelöst, indem wir parallele Chunks in beiden Sprachen pflegen und nach der erkannten Sprache der Anfrage filtern.
Kostenexplosion beim Re-Indexing. Wer seine gesamte KB häufig synchronisiert (statt inkrementeller Updates), erlebt eine Kostenexplosion bei den Embeddings. Ein vollständiges Re-Indexing von 100 Dokumenten kostet ~2 $. Versehentlich stündlich ausgeführt, verbrennen Sie 1.400 $/Monat allein für Embeddings.
KB-Quotas sind erstaunlich niedrig. Standardmäßig: 1 paralleler Ingestion-Job. Standard-Dokumentgröße: 50 MB. Beantragen Sie Quota-Erhöhungen, bevor Sie produktiven Maßstab erreichen.
Das Problem der "selbstbewussten falschen Antwort". Wenn der Agent einen Chunk findet, der nah dran, aber nicht richtig ist, wendet er die falsche Regel mit voller Überzeugung an. Begrenzen Sie das, indem Sie einen Schwellwert für den Similarity-Score setzen (wir nutzen 0,7) und Retrievals mit niedrigem Confidence-Wert in die manuelle Prüfung leiten.
So legen Sie los
Fünf Schritte zu Ihrer ersten produktiven Bedrock-KB-Implementierung:
Starten Sie mit 10 Dokumenten, nicht mit 100. Bringen Sie Ihre Chunking-Strategie an einem kleinen Set zum Laufen. Validieren Sie die Retrieval-Qualität manuell, bevor Sie skalieren.
Wählen Sie S3 Vectors, wenn nichts dagegen spricht. Für die meisten Knowledge-Base-Anwendungsfälle unter 10K Dokumenten ist es günstiger und einfacher. Wechseln Sie zu OpenSearch, wenn Sie es wirklich brauchen.
Investieren Sie zuerst in das Chunking. Standard-Chunking ist eine Falle bei strukturierten Dokumenten. Investieren Sie eine Woche in Ihre Chunking-Strategie — das ist die Arbeit mit der größten Hebelwirkung.
Bauen Sie die Freigabe-Pipeline von Tag eins an. Auch wenn Sie heute kein Human-in-the-Loop brauchen — sobald die Einsätze steigen, werden Sie es brauchen. Mit dem Task-Token-Muster in Step Functions lässt sich das später trivial ergänzen, aber teuer nachrüsten.
Instrumentieren Sie alles. Loggen Sie Retrieval-Scores, Chunk-IDs und Entscheidungs-Confidence. Sie können nicht verbessern, was Sie nicht messen. Wenn die Retrieval-Qualität nachlässt (und das wird sie, sobald Ihr Korpus wächst), brauchen Sie Daten zur Diagnose.
Fazit
Bedrock Knowledge Base ist tatsächlich solide Infrastruktur für produktive RAG-Systeme. Aber die Lücke zwischen "Demo" und "Produktion" ist genau der Ort, an dem alle interessanten Engineering-Entscheidungen fallen — Chunking-Strategien, Ingestion-Pipelines, Kostenoptimierung, Evidenz-Ketten, Fehlermodi.
S3 Vectors hat dieses Projekt in einem Maßstab wirtschaftlich tragfähig gemacht, in dem OpenSearch überdimensioniert gewesen wäre. Step Functions hat uns die Orchestrierungs-Garantien geliefert, die Compliance verlangt. Und AgentCore hat aus Retrieval strukturierte, auditierbare Entscheidungen gemacht.
Der Stack funktioniert. Das Schwierige waren nie die AWS-Services — sondern das Data Engineering drumherum.
Bauen Sie es gleich beim ersten Mal richtig. Ihr zukünftiges Ich (und das Legal-Team Ihres Kunden) wird es Ihnen danken.
Dima Kramskoy ist Senior Cloud Architect bei DoiT International mit über 20 Jahren Erfahrung im Software Engineering, 10 AWS-Zertifizierungen und AWS Community Builder (2026). Er unterstützt Unternehmen beim Aufbau produktiver AI/ML-Systeme auf AWS.