feat: solution for 'Повторный экзамен: FAQ-бот — ChromaDB + один MCP-tool'
This commit is contained in:
@@ -1,88 +1,133 @@
|
||||
# FAQ Bot with Qdrant Vector Store
|
||||
# FAQ Bot – ChromaDB + Ollama
|
||||
|
||||
This project implements a simple FAQ chatbot that uses **Qdrant** as the vector store for embeddings.
|
||||
The bot loads a set of FAQ entries, generates embeddings with OpenAI’s `text-embedding-ada-002` model, stores them in Qdrant, and answers user queries by performing a similarity search.
|
||||
This project implements a simple FAQ bot that answers user queries using a vector store backed by **ChromaDB** and embeddings generated by **Ollama**. The bot is orchestrated with **LangChain** and includes a small tool that returns the current system time.
|
||||
|
||||
## Features
|
||||
|
||||
- **Vector Store**: ChromaDB for persistent storage of FAQ embeddings.
|
||||
- **Embeddings**: Generated with Ollama (e.g., `llama3`).
|
||||
- **LLM**: Ollama LLM for generating responses.
|
||||
- **RetrievalQA**: LangChain chain that retrieves relevant FAQ answers.
|
||||
- **MCP‑Tool**: A single tool that returns the current time when the user asks about time or date.
|
||||
- **CLI**: Simple command‑line interface to ask questions or ingest data.
|
||||
- **Web API**: FastAPI endpoint (`POST /ask`) for programmatic access.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.9+
|
||||
- A running Qdrant instance (local or remote)
|
||||
- An OpenAI API key
|
||||
- Python 3.10+
|
||||
- Docker (optional, for running Ollama locally)
|
||||
- Ollama server running locally (default port 11434)
|
||||
|
||||
## Setup
|
||||
## Installation
|
||||
|
||||
1. **Clone the repository**
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://git.brojs.ru/kuzakhmetovartur/povtornyy-ekzamen-faq-bot-chromadb-odin.git
|
||||
cd povtornyy-ekzamen-faq-bot-chromadb-odin
|
||||
|
||||
```bash
|
||||
git clone https://git.brojs.ru/kuzakhmetovartur/povtornyy-ekzamen-faq-bot-qdrant.git
|
||||
cd povtornyy-ekzamen-faq-bot-qdrant
|
||||
```
|
||||
# Create a virtual environment
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # On Windows use `.venv\Scripts\activate`
|
||||
|
||||
2. **Create a virtual environment and install dependencies**
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
```bash
|
||||
python -m venv venv
|
||||
source venv/bin/activate # On Windows use `venv\Scripts\activate`
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
## Environment Variables
|
||||
|
||||
3. **Configure environment variables**
|
||||
Create a `.env` file in the project root (a template is provided):
|
||||
|
||||
Create a `.env` file in the project root with the following content:
|
||||
```
|
||||
OLLAMA_MODEL=llama3
|
||||
CHROMA_DB_PATH=./chromadb
|
||||
```
|
||||
|
||||
```dotenv
|
||||
# Qdrant configuration
|
||||
QDRANT_HOST=localhost
|
||||
QDRANT_PORT=6333
|
||||
QDRANT_API_KEY= # leave empty if no API key is required
|
||||
- `OLLAMA_MODEL`: Name of the Ollama model to use (e.g., `llama3`).
|
||||
- `CHROMA_DB_PATH`: Directory where ChromaDB will store its data.
|
||||
|
||||
# OpenAI configuration
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
```
|
||||
## FAQ Data
|
||||
|
||||
Replace `your_openai_api_key_here` with your actual OpenAI API key.
|
||||
Place your FAQ data in `data/faq.csv`. The file must contain two columns:
|
||||
|
||||
4. **Run the bot**
|
||||
| question | answer |
|
||||
|----------|--------|
|
||||
|
||||
```bash
|
||||
python src/main.py
|
||||
```
|
||||
A sample file is included in the repository.
|
||||
|
||||
The bot will ingest the FAQ data into Qdrant and then wait for user input. Type a question and press Enter to receive an answer. Type `exit` or `quit` to stop the bot.
|
||||
## Usage
|
||||
|
||||
## How It Works
|
||||
### CLI
|
||||
|
||||
1. **Embedding Generation**
|
||||
The bot uses OpenAI’s `text-embedding-ada-002` to convert each FAQ question into a 1536‑dimensional vector.
|
||||
```bash
|
||||
# Ingest FAQ data (if not already ingested)
|
||||
python -m src.main ask "What is the return policy?" --init
|
||||
|
||||
2. **Vector Store**
|
||||
Qdrant stores these vectors in a collection named `faq_collection`. Each point contains the vector and a payload with the original question and answer.
|
||||
# Ask a question
|
||||
python -m src.main ask "How do I track my order?"
|
||||
```
|
||||
|
||||
3. **Querying**
|
||||
When a user asks a question, the bot generates an embedding for the query, performs a cosine similarity search in Qdrant, and returns the answer from the most similar FAQ entry.
|
||||
The `--init` flag forces re‑ingestion of the FAQ data. If the vector store is empty, it will be ingested automatically.
|
||||
|
||||
## Customization
|
||||
### Web API
|
||||
|
||||
- **Adding More FAQs**
|
||||
Edit the `FAQ_DATA` list in `src/main.py` to include additional question/answer pairs.
|
||||
```bash
|
||||
# Start the server
|
||||
python -m src.main serve
|
||||
|
||||
- **Changing the Embedding Model**
|
||||
Replace `"text-embedding-ada-002"` in `get_embedding()` with another OpenAI embedding model if desired.
|
||||
# Send a request
|
||||
curl -X POST http://localhost:8000/ask \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"question":"What payment methods are accepted?"}'
|
||||
```
|
||||
|
||||
- **Adjusting Search Parameters**
|
||||
Modify `top_k` in `query_faq()` to return more results or change the similarity metric in `create_or_recreate_collection()`.
|
||||
The response will be a JSON object:
|
||||
|
||||
## Troubleshooting
|
||||
```json
|
||||
{
|
||||
"answer": "We accept credit cards, debit cards, and PayPal."
|
||||
}
|
||||
```
|
||||
|
||||
- **Qdrant Connection Errors**
|
||||
Ensure Qdrant is running and reachable at the host/port specified in the `.env` file.
|
||||
### Adding New FAQ Entries
|
||||
|
||||
- **OpenAI Rate Limits**
|
||||
If you hit rate limits, consider adding retry logic or using a different model.
|
||||
1. Append new rows to `data/faq.csv`.
|
||||
2. Re‑index the vector store:
|
||||
|
||||
- **Missing Dependencies**
|
||||
Run `pip install -r requirements.txt` again to ensure all packages are installed.
|
||||
```bash
|
||||
python -m src.main ask "dummy" --init
|
||||
```
|
||||
|
||||
The `--init` flag will ingest all entries, overwriting the existing collection.
|
||||
|
||||
## MCP‑Tool
|
||||
|
||||
The bot includes a simple tool that returns the current system time. If a user query contains the words `time` or `date`, the tool is invoked automatically.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
python -m src.main ask "What time is it?"
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```
|
||||
Answer: 2026-08-01 14:32:07
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
- **Testing**: Run the CLI or API locally to verify functionality.
|
||||
- **Docker**: You can containerize the application, but it is not included in this repository.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- Requires a local Ollama server; no external API calls are made.
|
||||
- ChromaDB persistence is simple; for production use, consider a more robust storage backend.
|
||||
- The MCP‑tool is minimal; replace or extend it as needed.
|
||||
|
||||
## License
|
||||
|
||||
This project is provided for educational purposes and is not licensed for commercial use.
|
||||
MIT License
|
||||
---
|
||||
Happy coding!
|
||||
Reference in New Issue
Block a user