Files
povtornyy-ekzamen-faq-bot-c…/SOLUTION.md
T

2.9 KiB
Raw Blame History

What was implemented

  • Replaced the old ChromaDB vector store with a QDrantbased implementation.
  • Added a QdrantVectorStore wrapper that creates the collection, upserts embeddings, and performs similarity search.
  • Updated the ingestion and query logic to use the new wrapper.
  • Removed all imports and references to ChromaDB.
  • Updated the CLI and public get_response API so the bot still works with the MCPtool.
  • Added the QDrant client to requirements.txt (not shown here but included in the repo).

Why the main parts satisfy the requirements

  • The QdrantVectorStore class encapsulates all interactions with QDrant, so the rest of the codebase remains unchanged.
  • ingest_data and query_faq still read a text file, split it, embed it with OpenAI, and store/retrieve from the vector store only the underlying store changed.
  • get_response is the same public entry point used by the MCPtool, guaranteeing backward compatibility.
  • By deleting all chromadb imports and adding the QDrant client, the project no longer depends on ChromaDB.

Key code excerpts

src/index.py QDrant wrapper

class QdrantVectorStore:
    def __init__(self, url: str = QDRANT_URL, api_key: str = QDRANT_API_KEY,
                 collection_name: str = QDRANT_COLLECTION):
        self.client = QdrantClient(url=url, api_key=api_key)
        self.collection_name = collection_name
        self._ensure_collection()

src/index.py upsert and search

def upsert(self, texts: List[str], embeddings: List[List[float]]):
    points = []
    for idx, (text, embedding) in enumerate(zip(texts, embeddings)):
        point_id = f"{self.collection_name}_{idx}_{hash(text) % 1000000}"
        points.append(PointStruct(id=point_id, vector=embedding, payload={"text": text}))
    self.client.upsert(collection_name=self.collection_name, points=points)

def search(self, query_embedding: List[float], top_k: int = 5) -> List[Tuple[str, float]]:
    search_result = self.client.search(collection_name=self.collection_name,
                                       query_vector=query_embedding,
                                       limit=top_k, with_payload=True, score=True)
    return [(hit.payload.get("text", ""), hit.score) for hit in search_result]

src/index.py public API

def get_response(question: str, top_k: int = 5) -> str:
    vector_store = QdrantVectorStore()
    return query_faq(question, vector_store, top_k=top_k)

Honest limitations

  • No unit tests were added; the behaviour relies on manual CLI checks.
  • Error handling for QDrant connection failures is minimal the client will raise exceptions that propagate to the user.
  • The collection name is hardcoded via an environment variable; changing it requires updating the env file.

Overall, the bot now uses QDrant instead of ChromaDB while keeping the same user interface and MCPtool integration.