# Amazon Bedrock Knowledge Bases + OpenSearch Serverless A practical step‑by‑step guide for future you (and anyone you share this with) This README walks through the full **console-based** flow for setting up an Amazon Bedrock Knowledge Base backed by **OpenSearch Serverless** and **S3 documents**. It is written so that: * You can **recreate the whole setup from scratch** later without having to re-open the workshop. * You can **switch documents** in your knowledge base cleanly. * You **avoid the common index / dimension / field-name errors** you ran into. --- ### TLDR Tools: - S3 → document storage - Bedrock Knowledge Base → - reads S3 files - chunks + embeds them - stores embeddings in a vector database - can create the OpenSearch index for you (if using “Quick create”) - Bedrock Flow → orchestration layer that wires your question → KB retrieval → LLM answer - **(Able to create through Bedrock)** *OpenSearch Serverless → the actual vector store holding your embeddings* --- ## 0. High‑Level Mental Model Before clicking anything, anchor on this picture: * **S3 bucket** = where your raw docs live (PDFs, TXT, shareholder letters, etc.). * **Embeddings model** (Titan Text Embeddings v2) = converts each chunk of text into a 1024‑dimensional vector. * **OpenSearch Serverless collection + index** = vector database that stores: * The **original text chunk** (e.g., in a `text` field) * The **embedding vector** (in a `vector` / `Vector` field) * **Metadata** (filename, chunk IDs, etc.). * **Bedrock Knowledge Base** = the glue service that: * Reads from S3 * Chunks text * Calls the embeddings model * Writes vectors + metadata into OpenSearch * Runs **RetrieveAndGenerate** when you query it. * **Flows (optional)** = a visual orchestration that wires: * Your **question** → **Knowledge Base node** → **Prompt node** → **LLM answer**. If something breaks, it’s almost always one of: * Wrong **index name** * Wrong **vector field name** * Wrong **vector dimension** (1024 vs 1924) * Missing **permissions** from Bedrock to OpenSearch. --- ## 1. Create OpenSearch Serverless Vector Store (Workshop Path) > If you use **Bedrock “Quick create a new vector store”**, Bedrock will create the index for you. This section is for when you want to follow the **workshop’s manual OpenSearch setup**. ### 1.1 Create the Collection 1. In the AWS console, go to **Amazon OpenSearch Service**. 2. In the left menu, click **Serverless** → **Dashboard**. 3. Click **Get started** (if this is your first time) or **Create collection**. 4. Configure: * **Collection name:** `bedrock-sample-rag` * **Collection type:** `Vector Search` * **Deployment type:** `Enable redundancy` * **Security:** `Easy create` (for a workshop; in prod you’d do fine‑grained access). 5. Click **Next** → **Submit**. 6. After creation, note down: * **Collection name:** `bedrock-sample-rag` * **Collection ARN** (looks like `arn:aws:aoss:us-east-1:ACCOUNT_ID:collection/COLLECTION_ID`). ### 1.2 Create the Vector Index Still inside the same collection: 1. Go to **Indexes** and click **Create index**. 2. Set: * **Index name:** `bedrock-sample-rag-index` 3. Under **Vector fields**, click **Add vector field** and configure: * **Field name:** `Vector` (or `vector`, but be consistent) * **Engine:** `faiss` * **Precision:** `FP16` (or FP32) * **Dimensions:** `1924` (per the workshop; **NOTE:** this will *not* match Titan v2’s 1024 dims – see Gotchas section) * **Distance metric:** `Euclidean` * Advanced settings (from workshop): * **M:** `16` * **ef_construction:** `512` * **ef_search:** `512` (if exposed) 4. Add **metadata fields** (if your console supports defining them now): * `text` (type: `text`) * `text-metadata` (type: `object` / `nested`) 5. Create the index. 📌 **Remember:** * **Index name:** `bedrock-sample-rag-index` * **Vector field name:** `Vector` (or `vector`) * **Text field name:** `text` * **Metadata field name:** `text-metadata` These names must match what you later tell Bedrock. --- ## 2. Upload Documents to S3 1. In the AWS console, go to **Amazon S3**. 2. Create (or reuse) a bucket, e.g.: * `aws-bedrock-kb-workshop-aoss-fp67` (workshop example) 3. Upload your documents (e.g., Amazon shareholder letters): * `AMZN-2019-Shareholder-Letter.pdf` * `AMZN-2020-Shareholder-Letter.pdf` * `AMZN-2021-Shareholder-Letter.pdf` * `AMZN-2022-Shareholder-Letter.pdf` 4. Note the bucket path you’ll use in the Knowledge Base: * `s3://aws-bedrock-kb-workshop-aoss-fp67` You can change files later without changing the bucket. --- ## 3. Create a Knowledge Base in Amazon Bedrock You have **two modes** here: * **Mode A: Quick create a new vector store (recommended for future you).** * **Mode B: Use an existing vector store (what the workshop shows).** ### 3.1 Start Knowledge Base Creation 1. In the AWS console, go to **Amazon Bedrock**. 2. In the left menu, under **Build**, click **Knowledge Bases**. 3. Click **Create** → **Knowledge base with vector store**. 4. Step 1 – **Provide details**: * Knowledge base name: e.g. `amzn-shareholder-kb` * Service role: * For workshop: **Create and use a new service role**. * Data source type: **Amazon S3**. Click **Next**. ### 3.2 Configure Data Source (S3) 1. **S3 URI:** * Browse and select your bucket, e.g. `s3://aws-bedrock-kb-workshop-aoss-fp67`. 2. **Chunking strategy:** * Change to **Fixed-size chunking**. * **Max tokens:** `512` (per workshop; you can tweak later). 3. Parsing strategy: **Default**. 4. Data deletion policy: usually **DELETE** (means if you delete a document from S3 and re‑sync, associated vectors can be removed). Click **Next**. ### 3.3 Choose Embeddings Model 1. Under **Embeddings model**, click **Select model**. 2. Choose: * **`Titan Text Embeddings V2`** (v2.0) 3. Click **Apply**. 👉 Titan v2 produces **1024‑dimensional float vectors**. Your OpenSearch vector field must match this dimension if you are using an existing vector index. --- ## 4. Configure the Vector Store (Important Choices) This is where most errors happen. ### 4.1 Option A – Quick Create a New Vector Store (Recommended) Use this when you **don’t care about manually defining the index** and you want Bedrock to handle everything. 1. **Vector store creation method:** * Select **Quick create a new vector store – Recommended**. 2. **Vector store type:** * Choose **OpenSearch Serverless**. 3. **Collection ARN:** * Paste your collection ARN, e.g.: * `arn:aws:aoss:us-east-1:ACCOUNT_ID:collection/COLLECTION_ID` 4. Pick an index name for Bedrock to create, e.g.: * `kb-index-titan-v2-01` 5. Field mappings: * **Vector field name:** `vector` * **Text field name:** `text` * **Metadata field name:** `metadata` or `text-metadata` Bedrock will: * Create the index for you. * Set `vector` as a `knn_vector` field with dimension **1024**. * Configure `text` and `metadata` fields. ✅ **This avoids all dimension mismatch errors** and is what you should use going forward unless you have a strong reason not to. ### 4.2 Option B – Use an Existing Vector Store (Workshop Path) Use this if you **already created** the index in OpenSearch (like `bedrock-sample-rag-index`). 1. **Vector store creation method:** * Select **Use an existing vector store**. 2. **Vector store type:** * **OpenSearch Serverless**. 3. **Collection ARN:** * Same as before, e.g. `arn:aws:aoss:us-east-1:ACCOUNT_ID:collection/osz7...`. 4. **Vector index name:** * `bedrock-sample-rag-index` (from the workshop). 5. **Index field mapping:** * **Vector field name:** `Vector` or `vector` (must match the field name in that index). * **Text field name:** `text`. * **Bedrock-managed metadata field name:** `text-metadata`. ⚠️ **Gotcha:** If this index was created with **1924 dimensions** for the `Vector` field, and you’re using **Titan v2 (1024 dims)**, you will get errors like: > `Query vector has invalid dimension: 1024. Dimension should be: 1924` To avoid this, either: * Create a **new index** with a 1024‑dimensional `knn_vector` field, **or** * Use **Quick create a new vector store** so Bedrock aligns dimensions for you. --- ## 5. Finish Creating and Sync the Knowledge Base After configuring the vector store: 1. Click **Next**. 2. On **Review and create**, confirm: * Knowledge base name * S3 URI * Embeddings model: **Titan Text Embeddings V2** * Vector store details (collection ARN, index name, field names) 3. Click **Create Knowledge Base**. Once it’s created: 1. Go to Knowledge Base. 2. Open the **Data source** tab. 3. Select your S3 data source. 4. Click **Sync**. Bedrock will now: * Scan the S3 bucket * Chunk files * Embed chunks with Titan v2 * Write to your OpenSearch index If there are errors, check: * **Index not found** → index name typo or index doesn’t exist when using “existing vector store” mode. * **Invalid dimension** → mismatch between Titan v2 (1024) and your OpenSearch `knn_vector` dimension. --- ## 6. Test the Knowledge Base from the Console 1. In your Knowledge Base, look for **Test knowledge base**. 2. Click **Select model**. 3. Choose **Claude 3.5 Haiku** (or any supported model). 4. Ask a question like: * `What is Amazon doing in the field of generative AI?` 5. Click **Run**. 6. Expand **Show details** to see: * Retrieved chunks * Their source files * How they were used to answer your question. This uses the **RetrieveAndGenerate** API under the hood: Bedrock retrieves relevant docs from OpenSearch, then feeds them to the LLM to generate an answer. --- ## 7. Build a Bedrock Flow that Uses the Knowledge Base Once the Knowledge Base works, you can wire it into a **Flow** so others can use it without knowing any of the plumbing. ### 7.1 Create the Flow 1. In the Bedrock console, go to **Flows**. 2. Click **Create flow**. 3. Name it e.g. `langchain-kb-retriever`. 4. Service role: **Create and use a new service role**. 5. Click **Create Flow**. You’ll see three default nodes: * **Flow input** * **Prompt** * **Flow output** ### 7.2 Add a Knowledge Base Node 1. Add a new node of type **Knowledge base**. 2. Select the Knowledge Base you created in Section 3. 3. Make sure **Return retrieved results** is enabled. ### 7.3 Configure the Prompt Node 1. Click on the **Prompt** node. 2. Choose a model, e.g. **Nova Micro** or any LLM. 3. Use a prompt like: ```text Human: You are a financial advisor AI system, and provide answers to questions by using fact-based and statistical information when possible. Use the following pieces of information to provide a concise answer to the question enclosed in <question> tags. If you don't know the answer, just say that you don't know; don't try to make up an answer. <question> {{question}} </question> The response should be specific and use statistics or numbers when possible. Context: {{context}} A: ``` 4. In **Prompt settings → Inputs**, change the **context** parameter’s data type to **Array**, because the Knowledge Base returns an array of retrieved results. ### 7.4 Wire the Nodes Together Connect the nodes so that: * **Flow input → Prompt input** * Map `question` on Flow input → `question` on Prompt. * **Flow input → Knowledge base input** * Map `question` on Flow input → `retrieval query` (or equivalent) on KB node. * **Knowledge base output → Prompt input** * Map retrieved results → `context` input on the Prompt. * **Prompt output → Flow output** * Map `completion` (or `text`) → Flow output. Click **Save**. ### 7.5 Test the Flow 1. Open the **Test panel** (icon on the right side of the Flow editor). 2. Enter a question, e.g.: * `What is Amazon doing in the field of generative AI?` 3. Run the flow. 4. Inspect the trace for: * **Knowledge Base node** → what chunks were retrieved. * **Prompt node** → how the context and question were combined. * **Flow output** → final answer. --- ## 8. Updating Documents Later If you just want to change which documents are used **without touching the OpenSearch index or KB wiring**: ### 8.1 Replace Docs, Same Bucket 1. Upload new documents into the **same S3 bucket**. 2. Optionally remove old documents if you don’t want them included. 3. In Bedrock → Knowledge Bases → your KB → **Data sources**: * Select your S3 data source. * Click **Sync**. Bedrock will re‑index the bucket contents and update the embeddings in your vector store. ### 8.2 Fully Reset the Knowledge Base If you want to wipe the KB logic but **keep the bucket**: 1. Delete the **Knowledge Base** in Bedrock. 2. Leave the **S3 bucket** and documents unchanged. 3. Create a **new Knowledge Base** pointing to the same S3 bucket. 4. Prefer **Quick create a new vector store** for fewer errors. You can reuse the same S3 path; the KB is what you are resetting. --- ## What a Working Screenshot Looks Like ![image](https://hackmd.io/_uploads/ByopPW3eWe.png) ![image](https://hackmd.io/_uploads/SymRvbhgbl.png) One of our knowledgebase sources: https://www.blackrock.com/corporate/literature/whitepaper/bii-global-outlook-in-charts.pdf --- ## 9. Common Errors and How to Decode Them ### 9.1 `no such index [name]` **Meaning:** * Bedrock was told to use an index (e.g. `bedrock-kb-index-01`) that **doesn’t exist** in your collection, *and* you chose **Use an existing vector store**. **Fix:** * Either **create that index** manually in OpenSearch, or * Switch to **Quick create a new vector store** and let Bedrock build it. ### 9.2 `Field 'vector' is not knn_vector type` **Meaning:** * Bedrock expects the field you named `vector` to be a **knn_vector**, but in the index it’s some other type (e.g. `float`, `text`, or not present). **Fix:** * Ensure that in your index mapping, the field is defined as: ```json "vector": { "type": "knn_vector", "dimension": 1024 } ``` * Or again, let Bedrock **quick-create** the vector store so it defines this correctly. ### 9.3 `Query vector has invalid dimension: 1024. Dimension should be: 1924` **Meaning:** * Your embedding model produces 1024‑dim vectors (Titan v2), but your OpenSearch `knn_vector` field was defined with dimension 1924. **Fix:** * Create a **new index** whose vector field has **dimension 1024**, and point Bedrock to that. * Or use **Quick create** so Bedrock sets the dimension correctly. ### 9.4 Access / permissions errors (403 / dependency failure) **Meaning:** * The **Data Access Policy** for your OpenSearch collection does not allow the Bedrock execution role to read/write the index. **Fix:** * Add the Bedrock KB role (`AmazonBedrockExecutionRoleForKnowledgeBase_*`) to the collection’s data policy with permissions like: ```json { "Rules": [ { "ResourceType": "index", "Resource": [ "index/bedrock-sample-rag/*" ], "Permission": [ "aoss:CreateIndex", "aoss:UpdateIndex", "aoss:ReadDocument", "aoss:WriteDocument" ] } ], "Principal": [ "arn:aws:iam::ACCOUNT_ID:role/AmazonBedrockExecutionRoleForKnowledgeBase_*" ] } ``` --- ## 10. Cheat Sheet / TL;DR for Future Reference When in doubt, follow this minimal happy path: 1. **Docs** → Put PDFs/TXT in `s3://your-bucket/path`. 2. **OpenSearch** → Create a **vector collection** (`Vector Search`). 3. In Bedrock → **Knowledge Bases** → Create: * S3 data source → your bucket * Embeddings → **Titan Text Embeddings V2** * **Vector store creation method → Quick create a new vector store** 4. Let Bedrock create the index and all field mappings. 5. After creation → **Sync** the data source. 6. Test the KB with **Test knowledge base**. 7. (Optional) Build a **Flow** with: * Flow input → KB node → Prompt node → Flow output. If you stick to **Quick create** and keep S3 docs tidy, you’ll: * Avoid 95% of the dimension and index errors. * Be able to swap / add docs just by **re‑syncing** the KB. You can now safely forget the workshop page and use this README as your canonical guide.