feat: solution for 'Экзамен: RAG-агент с ChromaDB и веб-поиском'
This commit is contained in:
+28
-39
@@ -1,54 +1,43 @@
|
||||
**What was implemented**
|
||||
The script `src/index.py` now uses **ChromaDB** as the persistent vector store instead of Qdrant.
|
||||
It loads documents from a folder, splits them into chunks, embeds them with OpenAI embeddings, and stores the vectors in a Chroma collection.
|
||||
A Retrieval‑QA chain is built with LangChain’s `RetrievalQA` and OpenAI’s GPT model, and a lightweight web‑search tool (`DuckDuckGoSearchRun`) is kept for quick queries.
|
||||
- Replaced the previous Qdrant‑based vector store with a lightweight wrapper around **ChromaDB** (`src/vector_store.py`).
|
||||
- Updated the `RAGAgent` to work exclusively with the new `ChromaVectorStore`.
|
||||
- Kept the FastAPI endpoints (`/ingest`, `/query`, `/websearch`) unchanged, so the public API and web‑search logic remain intact.
|
||||
- Removed every import and reference to Qdrant, ensuring the stack now matches the assignment.
|
||||
|
||||
**Why the main parts satisfy the assignment**
|
||||
* The vector database is explicitly ChromaDB – the `initialize_vectorstore()` function creates a `chromadb.PersistentClient` and wraps it with LangChain’s `Chroma` wrapper.
|
||||
* All required stack components are present: `chromadb`, `langchain`, `openai`, and `python-dotenv`.
|
||||
* The agent can ingest, query, and perform web search, matching the functional requirements of the exam task.
|
||||
**Why the main parts satisfy the requirements**
|
||||
- `ChromaVectorStore` creates a Chroma client and a collection, then exposes `add_documents` and `similarity_search` that match the original Qdrant interface.
|
||||
- `RAGAgent` uses this store for ingestion and querying, and still relies on OpenAI embeddings, so the RAG workflow is preserved.
|
||||
- The FastAPI app simply forwards requests to the agent; no Qdrant code is touched, so the vector database is now exclusively ChromaDB.
|
||||
- Web‑search utilities (`src/web_search.py`) are untouched, so the search‑to‑ingest pipeline continues to work.
|
||||
|
||||
**Key code excerpts**
|
||||
|
||||
`src/index.py` – imports and vector store initialization
|
||||
`src/vector_store.py` – Chroma client and collection creation
|
||||
```python
|
||||
import chromadb
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.vectorstores import Chroma
|
||||
...
|
||||
def initialize_vectorstore() -> Chroma:
|
||||
client = chromadb.PersistentClient(path=CHROMA_DB_PATH)
|
||||
client.get_or_create_collection(name=COLLECTION_NAME)
|
||||
vectorstore = Chroma(
|
||||
client=client,
|
||||
collection_name=COLLECTION_NAME,
|
||||
embedding_function=OpenAIEmbeddings(model=EMBEDDING_MODEL),
|
||||
)
|
||||
return vectorstore
|
||||
self.client = chromadb.Client()
|
||||
self.collection = self.client.get_or_create_collection(name=collection_name)
|
||||
```
|
||||
|
||||
`src/index.py` – ingesting documents into Chroma
|
||||
`src/rag_agent.py` – ingestion uses the new store
|
||||
```python
|
||||
def ingest_documents(folder_path: str, vectorstore: Chroma) -> None:
|
||||
raw_texts = load_documents_from_folder(folder_path)
|
||||
chunks = split_text(raw_texts)
|
||||
vectorstore.add_texts(chunks)
|
||||
print(f"Ingested {len(chunks)} chunks into collection '{COLLECTION_NAME}'.")
|
||||
self.vector_store.add_documents(docs_with_embeddings)
|
||||
```
|
||||
|
||||
`src/index.py` – web‑search helper
|
||||
`src/main.py` – FastAPI endpoint that calls the agent
|
||||
```python
|
||||
def perform_web_search(query: str) -> List[Dict[str, str]]:
|
||||
search_tool = DuckDuckGoSearchRun()
|
||||
results = search_tool.run(query)
|
||||
if isinstance(results, list):
|
||||
return results
|
||||
return [{"title": "Search Result", "url": "", "body": results}]
|
||||
@app.post("/ingest")
|
||||
def ingest(request: IngestRequest):
|
||||
docs = [doc.dict() for doc in request.documents]
|
||||
rag_agent.ingest(docs)
|
||||
```
|
||||
|
||||
**Limitations**
|
||||
* No unit tests are included.
|
||||
* Error handling is minimal (e.g., missing environment variables or empty folders).
|
||||
* The script is single‑threaded and may not scale for very large corpora without further optimization.
|
||||
`src/web_search.py` – still feeds results into the agent
|
||||
```python
|
||||
agent.ingest(docs_to_ingest)
|
||||
```
|
||||
|
||||
Overall, the implementation now adheres to the required stack and fulfills the RAG agent functionality described in the assignment.
|
||||
**Honest limitations**
|
||||
- ChromaDB is used in its default in‑memory mode; data will not persist across server restarts unless a persistent storage path is configured.
|
||||
- No additional error handling for Chroma connection failures has been added beyond the basic try/except in the API routes.
|
||||
|
||||
Overall, the project now uses only ChromaDB for vector storage, keeps all existing functionality, and respects the assignment constraints.
|
||||
Reference in New Issue
Block a user