Chroma DB stores document embeddings and their source text in collections so applications can retrieve semantically related documents. It fits local development and small-scale projects, while larger deployments may require more robust vector-database options. section 6.2.2 section 6.3.2
A practical Chroma DB workflow has four layers:
- Prepare documents by splitting source content into semantic chunks and converting each chunk into an embedding vector. section 6.3.2
- Create or load a collection, then add embeddings, document text, and unique identifiers; avoid re-adding vectors when the collection already contains them. section 6.2.2 section 6.3.2
- Embed each query and request the nearest documents with collection.query(), using the returned identifiers, distances, and texts. section 6.2.2
- Treat returned scores as distances rather than similarities: cosine distance ranges from 0 for most-similar items to 2 for semantically opposite items. section 6.2.2
A persistent script-search collection
A RAG agent chunks a movie script, creates OpenAI embeddings, opens a persistent Chroma DB path, and retrieves matching chunks through a search tool. Grounding instructions then require answers to use the retrieved context rather than unsupported model knowledge. section 6.3.2
Listing 6.5 document_query_chromadb.py (relevant code sections)
embeddings = [get_embedding(doc) for doc in documents] #1
ids = [f"id{i}" for i in range(len(documents))] #2
chroma_client = chromadb.Client() #2
collection = chroma_client.create_collection( #2
name="documents") #2
collection.add( #3
embeddings=embeddings,
documents=documents,
ids=ids
)
def query_chromadb(query, top_n=2): #4
query_embedding = get_embedding(query)
results = collection.query(
query_embeddings=[query_embedding],
n_results=top_n
)
return [(id, score, text) for id, score, text in
zip(results['ids'][0],
results['distances'][0],
results['documents'][0])]
while True: #5
query = input("Enter a search query (or 'exit' to stop): ")
if query.lower() == 'exit':
break
top_n = int(input("How many top matches do you want to see? "))
search_results = query_chromadb(query, top_n)
print("Top Matched Documents:")
for id, score, text in search_results:
print(f"""
ID:{id} TEXT: {text} SCORE: {round(score, 2)}
""") #5
print("\n")
###Output
Enter a search query (or 'exit' to stop): dogs are lazy
How many top matches do you want to see? 3
Top Matched Documents:
ID:id7 TEXT: The dog is lazy but the brown fox is quick! SCORE: 0.24
ID:id5 TEXT: The brown fox is quick and the blue dog is lazy! SCORE: 0.28
ID:id2 TEXT: The quick brown fox jumps over the lazy dog. SCORE: 0.29
Inspect the smallest working pattern: create a collection, add embeddings with documents and IDs, embed a query, and return ranked results. section 6.2.2






