add vector_store.py

This commit is contained in:
2026-05-28 09:50:55 +00:00
parent e3238fabc4
commit 77c1521bc2
+43 -33
View File
@@ -1,54 +1,64 @@
""" """
Vector store abstraction using ChromaDB. Vector store implementation using ChromaDB.
Provides methods to add documents with embeddings and perform similarity search. Provides methods to add documents and perform similarity search.
""" """
import os import os
from pathlib import Path from pathlib import Path
from typing import List, Dict, Any from typing import List, Dict
from chromadb import Client as ChromaClient from chromadb import Client as ChromadbClient
from chromadb.config import Settings from chromadb.config import Settings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_ollama import OllamaEmbeddings from langchain_ollama import OllamaEmbeddings
# Initialize global client (in-memory for simplicity) # Ensure persistent directory exists
client = ChromaClient(Settings(chroma_db_impl="duckdb+parquet", persist_directory=None)) CHROMA_DIR = Path("./chroma_db")
collection_name = "rag_collection" CHROMA_DIR.mkdir(parents=True, exist_ok=True)
# Ensure collection exists # Embedding model via Ollama
embeddings = OllamaEmbeddings(model="nomic-embed-text")
# Chroma client with persistence
client = ChromadbClient(Settings(persist_directory=str(CHROMA_DIR)))
collection_name = "knowledge"
if collection_name not in client.list_collections(): if collection_name not in client.list_collections():
client.create_collection(name=collection_name) client.create_collection(name=collection_name)
col = client.get_or_create_collection(name=collection_name) col = client.get_or_create_collection(name=collection_name)
embeddings = OllamaEmbeddings(model="nomic-embed-text") # Chunker from chunker.py
from chunker import chunker
class ChromaVectorStore: class VectorStore:
"""Wrapper around a Chroma collection.""" def add_documents(self, docs: List[str], metadatas: List[Dict]):
"""Add documents to the collection.
def __init__(self, collection): Parameters
self.collection = collection ----------
docs: list of raw text strings.
metadatas: list of metadata dicts corresponding to each doc.
"""
# Split into chunks and embed
all_chunks = []
all_metadatas = []
for doc, meta in zip(docs, metadatas):
chunks = chunker.split_text(doc)
all_chunks.extend(chunks)
all_metadatas.extend([meta] * len(chunks))
def add_documents(self, documents: List[Dict[str, Any]]): # Generate embeddings via Ollama
ids = [] embeds = embeddings.embed_documents(all_chunks)
texts = [] ids = [f"chunk_{i}" for i in range(len(all_chunks))]
metadatas = [] col.add(ids=ids, documents=all_chunks, metadatas=all_metadatas, embeddings=embeds)
for doc in documents:
ids.append(doc.get("id", os.urandom(8).hex()))
texts.append(doc["content"])
metadatas.append(doc.get("metadata", {}))
embeddings_list = embeddings.embed_documents(texts)
self.collection.add(ids=ids, documents=texts, embeddings=embeddings_list, metadatas=metadatas)
def similarity_search(self, query: str, k: int = 5) -> List[Dict[str, Any]]: def similarity_search(self, query: str, k: int = 5) -> List[Dict]:
results = self.collection.query( """Return top-k similar chunks with metadata."""
results = col.query(
query_texts=[query], query_texts=[query],
n_results=k, n_results=k,
include=['documents', 'distances', 'metadatas'], include=['documents', 'metadatas'],
) )
docs = [] # results is dict with keys documents, metadatas
for doc, dist, meta in zip(results["documents"][0], results["distances"][0], results["metadatas"][0]): docs = results["documents"][0]
docs.append({"content": doc, "distance": dist, "metadata": meta}) metas = results["metadatas"][0]
return docs return [{"content": d, "metadata": m} for d, m in zip(docs, metas)]
# Singleton instance
vector_store = ChromaVectorStore(col)