Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions IMPROVEMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Улучшения

## Реализованные (для оценки "Отлично")

| Улучшение | Описание | Статус |
|-----------|----------|--------|
| 🟢🟡🔴 Цветные индикаторы | Зеленый (score ≥ 0.3), желтый (score ≥ 0.15), красный (score < 0.15) | ✅ Реализовано |
| 🇷🇺 Русскоязычный интерфейс | Полная локализация | ✅ Реализовано |
| 📊 Большой датасет | 1297 документов (вместо 9) | ✅ Реализовано |

## Планируемые улучшения
1. Векторная база (ChromaDB)
2. Фильтрация по дате
3. Подключение LLM
101 changes: 23 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,39 @@
# RAG Tutorial
# RAG Tutorial: Поиск по Википедии

Учебный RAG на текстовых описаниях: TF-IDF + demo-ответ с источниками.
Pipeline: данные → чанки → индекс → поиск → ответ.

**Документы разработки:** [doc/tasklist.md](doc/tasklist.md) · **Данные:** [doc/DATA.md](doc/DATA.md) · **Домашнее задание:** [homework/README.md](homework/README.md) · **Слайды:** [Seminar_Big_data.pdf](Seminar_Big_data.pdf) · **Kaggle:** [Consumer Complaint Database](https://www.kaggle.com/datasets/datasnaek/consumer-complaint-database)

## Требования

- Python 3.10+
- [uv](https://docs.astral.sh/uv/)
Учебный RAG на TF-IDF: данные → чанки → индекс → поиск → ответ.

## Быстрый старт

```bash
# 1. Окружение
uv venv
uv sync

# 2. Сборка индекса (ingest + chunk + TF-IDF)
uv run python scripts/build_index.py

# 3. Запуск UI
uv run streamlit run app/main.py
```
Данные

Откройте в браузере: http://localhost:8501

## Demo-вопросы

В sidebar приложения или в поле ввода:

| Вопрос | Ожидание |
|--------|----------|
| **Ипотека - закрытие ипотечной сделки** | ответ, doc_id=2, score > 0.4 |
| Какие переменные в датасете про безработицу? | отказ (нет таких данных) |
| За какой период данные об инфляции? | отказ |
| Как приготовить борщ? | отказ |

Другие рабочие запросы: `студенческий кредит`, `Capital One`, `Wells Fargo закрытие счёта`.

## Проверка из консоли

```bash
# Тесты
uv run pytest tests/ -v

# Поиск (итерация 5)
uv run python scripts/check_retrieval.py

# Demo-ответ (итерация 6)
uv run python scripts/check_generator.py
```

## Структура проекта
Источник: Русская Википедия
Объем: 1297 документов (1617 чанков)
Демо-вопросы

```
rag-tutorial/
├── app/
│ ├── config.py # пути, top_k, размер чанка
│ ├── chunker.py # нарезка текста
│ ├── retriever.py # TF-IDF + cosine top-k
│ ├── generator.py # demo-ответ
│ ├── prompts.py # правила и отказы
│ └── main.py # Streamlit UI
├── scripts/
│ ├── ingest.py
│ ├── build_index.py
│ ├── check_retrieval.py
│ └── check_generator.py
├── data/
│ ├── raw/datasets.json
│ ├── processed/ # documents.jsonl, chunks.jsonl (генерируются)
│ └── index/ # vectorizer.pkl, matrix.npz (генерируются)
├── tests/
└── doc/
```

## Пересборка индекса
Вопрос Ожидание
Космос ответ + источник
Животные ответ + источник
Наука ответ + источник
Как приготовить борщ? отказ
Улучшения

После изменения `data/raw/datasets.json`:
🟢/🟡/🔴 Цветные индикаторы
🇷🇺 Русскоязычный интерфейс
## Скриншоты работы

```bash
uv run python scripts/build_index.py
```
### Поиск "Космос"
![Космос](screenshots/1.png)

## Ограничения MVP
### Поиск "Елена"
![Животные](screenshots/2.png)

- Поиск по **словам** (TF-IDF), не по смыслу — синонимы могут не находиться.
- Demo-режим: ответ из найденных чанков, без внешней LLM.
- Индексируется только текст описаний, CSV не используется.
### Поиск "Крутая Джорджия"
![Наука](screenshots/3.png)

## Контакты
Подписывайтесь на канал: @Marat_notes
### Negative-запрос "Шоколадка" (отказ)
![Отказ](screenshots/4.png)
22 changes: 17 additions & 5 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from app.retriever import Retriever

DEMO_QUESTIONS = [
"Ипотека - закрытие ипотечной сделки",
"Какие переменные в датасете про безработицу?",
"За какой период данные об инфляции?",
"Космос",
"Животные",
"Наука",
"Как приготовить борщ?",
]

Expand All @@ -24,8 +24,20 @@ def load_retriever() -> Retriever:
return Retriever()


def _get_score_emoji(score: float) -> str:
"""Возвращает эмодзи в зависимости от оценки релевантности."""
if score >= 0.3:
return "🟢"
elif score >= 0.15:
return "🟡"
else:
return "🔴"


def render_chunk(i: int, src: dict, expanded: bool = True) -> None:
label = f"[{i}] doc_id={src['doc_id']} · score={src['score']:.4f}"
score = src['score']
emoji = _get_score_emoji(score)
label = f"{emoji} [{i}] doc_id={src['doc_id']} · score={score:.4f}"
with st.expander(label, expanded=expanded):
st.markdown(f"**{src['name']}**")
st.text(src["text"])
Expand Down Expand Up @@ -85,4 +97,4 @@ def main() -> None:


if __name__ == "__main__":
main()
main()
Loading