Учебный RAG на текстовых описаниях пакетов PyPI: TF-IDF + demo-ответ с источниками. Pipeline: данные → чанки → индекс → поиск → ответ.
Документы разработки: doc/ · Данные: doc/DATA.md · Улучшения: homework/IMPROVEMENTS.md
- Python 3.10+
- uv
# 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
Источник — PyPI: топовые пакеты (список hugovk/top-pypi-packages) + их
описания через публичный JSON API PyPI. Индексируется только текст
summary + description. Подробно: doc/DATA.md.
- Записей в
data/raw/datasets.json: 448 - Чанков после нарезки: 1920
- Матрица TF-IDF: 1920 × 15008
Пересобрать датасет (опционально, файл уже закоммичен):
uv run python scripts/prepare_datasets.py --limit 450Поиск лексический (TF-IDF) — формулируйте запрос словами из описаний (англ.).
| Вопрос | Ожидание |
|---|---|
pandas dataframe data analysis |
ответ, doc_id=267 (pandas), score ≈ 0.47 |
sqlalchemy database orm |
ответ, doc_id=6 (alembic) / snowflake-sqlalchemy |
requests http library |
ответ, doc_id=340 (requests), score ≈ 0.30 |
как приготовить борщ |
отказ (нет таких данных) |
uv run python scripts/check_generator.py:
--- Есть контекст: «pandas dataframe data analysis» ---
[1] pandas — Powerful data structures for data analysis ... doc_id=267, score=0.47
Источников: 3
--- Есть контекст: «sqlalchemy database orm» ---
[1] alembic — A database migration tool for SQLAlchemy. doc_id=6, score=0.29
[2] snowflake-sqlalchemy — Snowflake SQLAlchemy Dialect doc_id=374, score=0.27
Источников: 3
--- Есть контекст: «requests http library» ---
[1] requests — Python HTTP for Humans. doc_id=340, score=0.30
[3] urllib3 — HTTP library with thread-safe pooling... doc_id=422, score=0.23
Источников: 3
--- Negative: «как приготовить борщ» ---
Ответ: В базе не найдено релевантных фрагментов. Ответить по данным невозможно.
(top-k со score=0.0000 → отказ, без выдумок)
uv run pytest tests/ -v → 12 passed.
uv run pytest tests/ -v # тесты
uv run python scripts/check_retrieval.py # итерация 5: поиск
uv run python scripts/check_generator.py # итерация 6: ответ + отказlearn-rag/
├── app/
│ ├── config.py # пути, top_k, размер чанка
│ ├── chunker.py # нарезка текста
│ ├── retriever.py # TF-IDF + cosine top-k
│ ├── generator.py # demo-ответ + отказ
│ ├── prompts.py # правила и MIN_SCORE
│ └── main.py # Streamlit UI
├── scripts/
│ ├── prepare_datasets.py # сбор данных с PyPI
│ ├── 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/
- Поиск по словам (TF-IDF с биграммами), не по смыслу — синонимы могут не находиться.
- Demo-режим: ответ из найденных чанков, без внешней LLM.
- Индексируется только текст описаний пакетов.