feat: solution for 'Повторный экзамен: FAQ-бот — ChromaDB + один MCP-tool'
This commit is contained in:
+50
-42
@@ -1,49 +1,57 @@
|
||||
**What was implemented**
|
||||
- Unified the vector‑storage layer to a single stack: **ChromaDB** as the vector database and **MCP‑tool** as the sole embedding generator.
|
||||
- Removed all previous references to other vector stores (e.g. FAISS, Pinecone).
|
||||
- Kept the FAQ‑bot logic unchanged, so the interactive question‑answer 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 MCP‑tool 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**.
|
||||
В качестве единственного инструмента генерации запросов использован **MCP‑tool** (`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 MCP‑tool 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 hash‑based 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 MCP‑tool) is used, the FAQ bot remains functional, and no extra vector stores are present.
|
||||
- **Ограничения**
|
||||
* Векторизация реализована простым подсчётом слов, что не обеспечивает высокую точность.
|
||||
* При каждом запуске данные заново добавляются в коллекцию – в продакшене нужно проверять наличие.
|
||||
* Нет кэширования ответов и обработки ошибок при работе с ChromaDB.
|
||||
|
||||
Таким образом, проект полностью соответствует заданию: единственный стек – ChromaDB, единственный MCP‑tool, и все обращения к векторному хранилищу проходят через `ChromaVectorStore`.
|
||||
Reference in New Issue
Block a user