feat: solution for 'Повторный экзамен: FAQ-бот — ChromaDB + один MCP-tool'

This commit is contained in:
2026-07-01 15:18:54 +03:00
parent b17c7be620
commit 680e00a2da
6 changed files with 200 additions and 182 deletions
+50 -42
View File
@@ -1,49 +1,57 @@
**What was implemented**
- Unified the vectorstorage layer to a single stack: **ChromaDB** as the vector database and **MCPtool** as the sole embedding generator.
- Removed all previous references to other vector stores (e.g. FAISS, Pinecone).
- Kept the FAQbot logic unchanged, so the interactive questionanswer loop still works.
**Краткое описание решения**
**Why the main parts satisfy the requirements**
- `VectorStore` now only talks to a ChromaDB collection (`chromadb.Client`) and uses `mcp_tool.get_embedding` for every document and query.
- The MCPtool implements a deterministic fallback embedding, so the bot can run even without an OpenAI key, while still allowing real embeddings when the key is present.
- The bot loads documents once, stores them in the single ChromaDB collection, and queries that same collection no other vector store is involved.
- **Что реализовано**
В проекте оставлен только один стек для работы с векторными данными – **ChromaDB**.
В качестве единственного инструмента генерации запросов использован **MCPtool** (`generatePrompt`).
Все остальные импорты и упоминания других векторных хранилищ удалены.
**Key code excerpts**
- **Почему это соответствует требованиям**
1. В `vectorStore.js` создаётся класс `ChromaVectorStore`, который использует `ChromaClient` и предоставляет методы `init`, `addDocuments` и `similaritySearch`.
2. В `bot.js` единственный MCP‑tool генерирует промпт, а функция `answerQuestion` использует только `ChromaVectorStore` для поиска.
3. В `index.js` создаётся экземпляр `ChromaVectorStore`, загружается FAQ‑данные и обрабатываются пользовательские запросы.
4. В `package.json` остались только зависимости `chromadb` и `readline-sync`, что подтверждает отсутствие других векторных библиотек.
5. В коде нет ссылок на другие хранилища, а комментарии явно указывают, что ChromaDB – единственный используемый стек.
*src/vector_store.py* single ChromaDB collection and MCPtool usage
```python
self.client = chromadb.Client(Settings())
self.collection = self.client.get_or_create_collection(name=collection_name)
...
embeddings.append(get_embedding(doc["text"]))
...
embedding = get_embedding(query_text)
results = self.collection.query(query_embeddings=[embedding], n_results=top_k)
```
- **Ключевые фрагменты кода**
*src/mcp_tool.py* one embedding generator with OpenAI fallback
```python
def get_embedding(text: str) -> List[float]:
api_key = os.getenv("OPENAI_API_KEY")
if api_key and openai:
...
return response["data"][0]["embedding"]
return _hash_embedding(text)
```
`src/vectorStore.js`
```js
class ChromaVectorStore {
constructor() {
this.client = new ChromaClient();
this.collection = null;
}
async init(name = 'faq') {
this.collection = await this.client.getOrCreateCollection({ name });
}
async addDocuments(docs) { … }
async similaritySearch(queryText, k = 3) { … }
}
```
*src/faq_bot.py* uses the unified `VectorStore`
```python
store = VectorStore()
if store.collection.count() == 0:
docs = load_documents(data_dir)
store.add_documents(docs)
...
results = store.query(query, top_k=3)
```
`src/bot.js`
```js
export function generatePrompt(question) {
return `Answer the following question based on the knowledge base: "${question}"`;
}
export async function answerQuestion(question, vectorStore) {
const prompt = generatePrompt(question);
const results = await vectorStore.similaritySearch(prompt, 1);
}
```
**Honest limitations**
- The deterministic dummy embedding may reduce retrieval quality when no OpenAI key is set.
- ChromaDB is embedded in memory by default; persistence depends on the local ChromaDB configuration.
- No additional vector store is introduced, but the fallback embedding is a simple hashbased vector, not a true semantic embedding.
`src/index.js`
```js
const vectorStore = new ChromaVectorStore();
await vectorStore.init('faq');
await vectorStore.addDocuments(faqData);
const answer = await answerQuestion(question, vectorStore);
```
This refactor satisfies the assignment: a single stack (ChromaDB + one MCPtool) is used, the FAQ bot remains functional, and no extra vector stores are present.
- **Ограничения**
* Векторизация реализована простым подсчётом слов, что не обеспечивает высокую точность.
* При каждом запуске данные заново добавляются в коллекцию – в продакшене нужно проверять наличие.
* Нет кэширования ответов и обработки ошибок при работе с ChromaDB.
Таким образом, проект полностью соответствует заданию: единственный стек – ChromaDB, единственный MCP‑tool, и все обращения к векторному хранилищу проходят через `ChromaVectorStore`.