Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Build a small retrieval-augmented generation (RAG) app by embedding your documents with Gemini, storing the vectors and source text in ChromaDB, retrieving the most relevant passages for each question, and giving those passages to Gemini to answer. The key is to use compatible embedding settings for documents and queries, keep source metadata, and test retrieval independently from answer quality.

How this Python RAG example works

RAG combines two jobs: retrieval finds passages related to a question, and generation uses those passages to produce an answer. For this app, the data flow is:

  1. Load and split a small text corpus into chunks.
  2. Generate a Gemini embedding for each chunk.
  3. Store each chunk, its vector, a stable ID, and useful metadata in ChromaDB.
  4. Embed a user’s question with compatible settings and retrieve matching chunks from ChromaDB.
  5. Send the question and retrieved passages to Gemini, asking it to answer from that context.

Google describes embeddings as a way to retrieve relevant information for use in model context. Chroma stores embeddings with documents and metadata and supports similarity search. See Google’s Gemini embeddings guide and Chroma’s getting-started guide.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose how ChromaDB gets embeddings

Chroma can embed text through a collection embedding function, or you can generate vectors with Gemini and pass them to Chroma. For this tutorial, explicit Gemini vectors make the model and task formatting visible and controllable.

#1 Best Overall
GMKtec AI Mini PC Ryzen Al Max+ 395 (up to 5.1GHz) Mini Gaming Computers
  • EVOLUTION AMD RYZEN AI MAX+ 395 MINI PC - GMKtec EVO-X2 is the next evolution in AI mini PC Ryzen Strix Halo series. Thanks to AMD Simultaneous Multithreading (SMT) the core-count is effectively doubled, to 32 threads. Ryzen AI Max+ 395 has 64 MB of L3 cache and can boost up to 5.1 GHz, depending on the workload. The Ryzen AI Max+ 395 is currently rated as the "most powerful x86 APU" on the market for AI computing.
  • AI NPU with XDNA 2 ARCHITECTURE - Powered by 16 “Zen 5” CPU cores, 50+ peak AI TOPS XDNA 2 NPU and a truly massive integrated GPU driven by 40 AMD RDNA 3.5 CUs, the Ryzen AI MAX+ 395 is a transformative upgrade and delivers a significant performance boost over the competition. The Ryzen AI Max+ 395 excels in consumer AI workloads like the llama.cpp-powered application: LM Studio. Shaping up to be the must-have app for client LLM workloads, LM Studio allows users to locally run the latest language model without any technical knowledge required and unleash their creativity and productivity.
  • AMD RADEON 8090S iGPU GAMING PC - The AMD Radeon RX 8060S offers all 40 CUs with up to 2.9 GHz graphics clock and uses the new RDNA 3.5 architecture. The powerful iGPU is positioned between an RTX 4060 and 4070 laptop GPU and therefore enables gaming in FHD at maximum details in most demanding games. The 8060S can also utilize the full 128GB pool, which is perfect for running LLMs such as Deepseek 70B Q8, which runs comfortably on this machine.
  • EIGHT CHANNEL LPDDR5X - LPDDR5X is a new ground breaking memory small form factor installed on-board. With blazing speeds up to to 8000MT/s, it runs 1.5x faster than the DDR5 SODIMMs; 90% better performance over DDR5 SODIMMs in video conferencing and photo editing; 30% better performance in productivity apps; 12% better performance in digital content workloads.
  • QUAD SCREEN 8K DISPLAY SUPPORT - EVO-X2 AI Mini PC support 4-screen 4K/8K output via HDMI 2.1 (8K@60Hz), DisplayPort 1.4 (4K@60Hz), and dual USB 4 40Gbps Transfer speed (supporting PD3.0/DP1.4/DATA). Ideal for gaming, video editing, and multitasking, it provides expansive and crisp multi-display support.
Approach Setup Control and responsibility
Chroma embedding function Pass document text and query text; the collection’s compatible embedding function creates vectors. Simpler when the chosen function suits the application. The document and query routes must still use compatible embedding behavior.
Explicit Gemini embeddings Call Gemini to embed each document chunk and question, then pass vectors to Chroma. Gives direct control over Gemini model and task formatting; your code must keep model, dimensions, and formatting consistent.

Do not mix vectors from one embedding setup with a different collection setup. Chroma requires query-vector dimensions to match the collection vectors, and Gemini notes that the spaces for its Embedding 1 and Embedding 2 models are incompatible. Sources: Chroma’s add-data guide, Chroma’s query guide, and Google’s embeddings guide.

Set up Python and persistent storage

Install the two packages in a virtual environment and configure a Gemini API key through your environment or secret manager rather than committing it to source control.

python -m venv .venv
# Activate the environment for your operating system
python -m pip install chromadb google-genai

The examples below assume the key is available to the Google Gen AI Python SDK through its supported configuration. Check Google’s current SDK instructions if you use a different authentication setup.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use a persistent Chroma client for a local tutorial so the index survives process termination:

Rank #2
AMD Ryzen™ AI Halo - Personal AI Desktop Computer - Developer Platform - Linux OS
  • Built for Local AI Development: AMD Ryzen AI Halo is designed for local AI development and inference, featuring 128GB unified memory and support for up to 200B parameter models to build and run intensive AI workloads locally.
  • 128GB Unified Memory: Features 128GB LPDDR5x unified memory at 8000 MT/s with 256 GB/s memory bandwidth, providing a shared memory pool across the CPU, GPU, and NPU to support larger AI models.
  • AMD Ryzen AI Max+ 395 Processor: Features 16 cores, 32 threads, and Zen 5 architecture, paired with AMD Radeon 8060S integrated graphics featuring 40 RDNA 3.5 compute units and an AMD XDNA 2 NPU with up to 50 TOPS.
  • Linux AI Developer Platform: Purpose-built for Linux-based AI development with full AMD ROCm software support and preloaded tools, models, and workflows optimized for local AI development.
  • Compact, Connected Design: Includes a 2TB M.2 SSD, 10GbE LAN, Wi-Fi 7, Bluetooth 5.4, USB-C connectivity, and HDMI 2.1b.
import chromadb
from google import genai

ai = genai.Client()
chroma = chromadb.PersistentClient(path="./chroma_db")
collection = chroma.get_or_create_collection(name="knowledge")

The persistent client writes local database files under ./chroma_db. Chroma’s in-memory client is useful for a disposable demonstration, but its data is lost when the process exits. For shared or deployed applications, Chroma also documents client-server and hosted patterns; choose those when a local, single-machine index is not suitable. See Chroma’s storage and client guidance.

Prepare and embed document chunks

Keep chunks traceable

Load text from a corpus you are entitled to use, clean obvious extraction noise, and split it into chunks that preserve useful context. Store a source identifier and location such as a file name, page, or section in metadata. That lets the app show which passages informed an answer.

Assign every chunk a stable, unique string ID. Stable IDs let you rerun ingestion with upsert instead of accumulating duplicate records. Choose chunk size and overlap based on your documents and evaluation; Google’s published embedding input limits are not recommendations for chunk size.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use one embedding per chunk

Google’s current embeddings guide identifies gemini-embedding-2 as its latest Gemini API embedding model and says gemini-embedding-001 remains available for text-only use. For text-only asymmetric retrieval with Embedding 2, Google recommends task instructions in the text. A document can use a form such as title: ... | text: ...; a query can use task: question answering | query: ... or task: search result | query: .... Select the task that fits your application and apply its format consistently.

Rank #3
GMKtec EVO-X2 AI Mini PC Ryzen Al Max+ 395 Superchip 128GB LPDDR5X 2TB SSD
  • EVOLUTION RYZEN AI MAX+ 395 MINI PC - GMKtec EVO-X2 is the next evolution in AI mini PC Ryzen Strix Halo series. Thanks to AMD Simultaneous Multithreading (SMT) the core-count is effectively doubled, to 32 threads. Ryzen AI Max+ 395 has 64 MB of L3 cache and can boost up to 5.1 GHz, depending on the workload. The Ryzen AI Max+ 395 is currently rated as the "most powerful x86 APU" on the market for AI computing.
  • AI NPU with XDNA 2 ARCHITECTURE - Powered by 16 “Zen 5” CPU cores, 50+ peak AI TOPS XDNA 2 NPU and a truly massive integrated GPU driven by 40 AMD RDNA 3.5 CUs, the Ryzen AI MAX+ 395 is a transformative upgrade and delivers a significant performance boost over the competition. The Ryzen AI Max+ 395 excels in consumer AI workloads like the llama.cpp-powered application: LM Studio. Shaping up to be the must-have app for client LLM workloads, LM Studio allows users to locally run the latest language model without any technical knowledge required and unleash their creativity and productivity.
  • AMD RADEON 8090S iGPU GAMING PC - The AMD Radeon RX 8060S offers all 40 CUs with up to 2.9 GHz graphics clock and uses the new RDNA 3.5 architecture. The powerful iGPU is positioned between an RTX 4060 and 4070 laptop GPU and therefore enables gaming in FHD at maximum details in most demanding games. The 8060S can also utilize the full 128GB pool, which is perfect for running LLMs such as Deepseek 70B Q8, which runs comfortably on this machine.
  • EIGHT CHANNEL LPDDR5X - LPDDR5X is a new ground breaking memory small form factor installed on-board. With blazing speeds up to to 8000MT/s, it runs 1.5x faster than the DDR5 SODIMMs; 90% better performance over DDR5 SODIMMs in video conferencing and photo editing; 30% better performance in productivity apps; 12% better performance in digital content workloads.
  • QUAD SCREEN 8K DISPLAY SUPPORT - EVO-X2 AI Mini PC support 4-screen 4K/8K output via HDMI 2.1 (8K@60Hz), DisplayPort 1.4 (4K@60Hz), and dual USB 4 40Gbps Transfer speed (supporting PD3.0/DP1.4/DATA). Ideal for gaming, video editing, and multitasking, it provides expansive and crisp multi-display support.

Google’s 2026 documentation lists an 8,192-token input limit for Embedding 2 and output dimensions from 128 to 3,072, with 768, 1,536, and 3,072 listed as recommended dimensions. These are model-specific limits and options, not chunk-size guidance or performance claims. The same documentation lists a 2,048-token input limit for Embedding 001 and the same flexible output dimension range. Verify model identifiers and API behavior against the current Gemini embeddings documentation before deploying.

Illustrative ingestion boundary:

def embed_document(text, title=""):
    content = f"title: {title} | text: {text}"
    result = ai.models.embed_content(
        model="gemini-embedding-2",
        contents=content,
        # Set the output dimension consistently if configuring it.
    )
    return result.embeddings[0].values

# For each chunk, prepare a stable ID, source metadata, and vector.
# Then write them together:
# collection.upsert(
#     ids=chunk_ids,
#     documents=chunk_texts,
#     embeddings=chunk_vectors,
#     metadatas=chunk_metadata,
# )

This is a code skeleton, not a complete loader or a tested application. Confirm the response shape and any dimension-setting parameters in the SDK version you install. For distinct embeddings from multiple inputs, Google cautions that passing multiple inputs directly with Embedding 2 can aggregate them into one embedding; use separately wrapped content objects or the Batch API when each input needs its own vector. See Google’s Embedding 2 guidance and Chroma’s add-data guide.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Retrieve passages and generate an answer

At question time, format and embed the query with the same embedding model and compatible output dimension used for the collection. Then pass that vector to Chroma’s query_embeddings argument. This is the explicit-vector path; query_texts is for text queries embedded by the collection’s embedding function.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
def embed_query(question):
    content = f"task: question answering | query: {question}"
    result = ai.models.embed_content(
        model="gemini-embedding-2",
        contents=content,
        # Use the same output dimension as document vectors.
    )
    return result.embeddings[0].values

question = "What does the handbook say about leave?"
query_vector = embed_query(question)
results = collection.query(
    query_embeddings=[query_vector],
    n_results=4,
)

passages = results["documents"][0]
sources = results["metadatas"][0]

Chroma returns 10 matches per query by default; set n_results to the amount you want to inspect. Results include associated documents and metadata, which you can use to display evidence sources. Metadata filters (where) and document filters (where_document) are also available. See Chroma’s query and get documentation.

Build the generation request with the retrieved passages and the user’s question. Tell Gemini to rely on the supplied context and acknowledge when it does not contain the answer:

context = "nn".join(passages)
prompt = f"""Answer the question using only the context below.
If the context does not contain enough information, say so.

Context:
{context}

Question: {question}
"""

response = ai.models.generate_content(
    model="YOUR_SUPPORTED_GEMINI_GENERATION_MODEL",
    contents=prompt,
)
print(response.text)

Replace the generation-model value with a currently supported identifier for your account and application. Google’s API pattern uses client.models.generate_content(model=..., contents=...); the request needs contents. Preserve the returned source metadata in your application so a reader can inspect the passages behind the response. See Google’s generate-content API reference.

Test retrieval before tuning generation

A fluent answer can still be unsupported if retrieval returned the wrong material. Evaluate the retrieval step separately before judging the final response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Try representative questions whose answers are present, and check whether the relevant passage appears in the retrieved results.
  • Try irrelevant questions and questions whose answers are absent; check whether the system abstains rather than inventing an answer.
  • Inspect source metadata and the exact retrieved text, not just the generated response.
  • Adjust chunking, the number of results, and prompt instructions based on observed failures; do not describe a configuration as accurate without evaluation.

Keep the index consistent when it changes

Keep the embedding model, output dimension, and task formatting aligned for all stored chunks and future queries. If you move an existing index from gemini-embedding-001 to gemini-embedding-2, re-embed all indexed content: Google says their embedding spaces are incompatible. Chroma also raises an exception when supplied vectors do not match the dimensionality already in a collection. A clean migration therefore means rebuilding the vectors consistently rather than querying old vectors with the new model.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.