Skip to content

alexmasyukov/rag-code-search

Repository files navigation

Code Search — семантический поиск по коду

RAG-система для поиска по TypeScript/React кодовой базе на русском и английском языке.

Стек

Компонент Технология Где Порт
Векторная БД Qdrant (Docker) локально 6333
Реляционная БД PostgreSQL 17 (Docker) локально 15433
Embedding (индексация) Qwen3-Embedding-4B OpenRouter (облако)
Embedding (поиск) Qwen3-Embedding-4B (MLX, 4-bit DWQ) локально (mlx-lm) 7445
Reranker Qwen3-VL-Reranker-2B (MLX) локально 7444
LLM-описания GLM-4.7-flash / Qwen3-Coder-Next (выбор в меню) OpenRouter
Search API + Web UI Python HTTP локально 7333
AST Chunker ts-morph (Node.js) локально

Проекты

Пути к индексируемым проектам задаются в .env через переменные PROJECT_<NAME>=<path>. Имя после PROJECT_ приводится к нижнему регистру и используется как id проекта в CLI/UI. Порядок объявления в .env сохраняется в меню. Пример:

PROJECT_NETWORK=~/arenadata-network/packages/network
PROJECT_ADSW=~/arenadata-adsw/packages/adsw

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

cp .env.example .env   # заполнить API-ключи и MODELS_DIR
python start.py

Интерактивное меню со стрелками — выбор действия и проекта без ввода текста.

Пайплайн индексации

AST Chunker → PostgreSQL → GLM описания (облако) → Qwen3-4B эмбеддинги (облако) → Qdrant
  1. AST Chunker — нарезает код на компоненты, функции, хуки, типы, SCSS (~2с)
  2. PostgreSQL — сохраняет чанки, сравнивает хеши с предыдущей индексацией
  3. LLM описания — генерирует описание каждого чанка на RU+EN (sliding-window concurrency, по умолчанию 50 параллельных запросов, флаг --concurrency, OpenRouter). Модель выбирается в меню (GLM-4.7-flash по умолчанию, или Qwen3-Coder-Next). Только для новых/изменённых чанков (кеш по content_hash)
  4. Qwen3-Embedding-4B — каждый чанк (описание + код) → вектор 2560-dim (OpenRouter). Инкрементально — только новые чанки
  5. Qdrant — сохраняет векторы с content_hash как point_id

Два режима индексации

  • Полная переиндексация — чистит БД, всё с нуля
  • Обновление — только новые/изменённые чанки, остальное из кеша

Пайплайн поиска

Запрос → Qwen3-4B эмбеддинг (локально) → Qdrant (15 кандидатов) → VL-Reranker-2B (локально) → top-5

Поиск полностью локальный, без интернета. ~2с на запрос.

Web UI: http://localhost:7333

CLI:

python search.py --project network "загрузка файлов"
python search.py --project network "список курсов" --no-rerank

API:

GET http://localhost:7333/search?q=загрузка+файлов&project=network

Структура

.
├── start.py                # Интерактивное меню
├── start-services.sh       # Запуск всех сервисов
├── stop.sh                 # Остановка всех сервисов
├── docker-compose.yml      # Qdrant + PostgreSQL
├── chunker/                # AST-парсер (ts-morph)
│   └── src/index.ts
├── python/
│   ├── ingest.py           # Полный пайплайн индексации
│   ├── search.py           # CLI поиск
│   ├── search_server.py    # HTTP API + Web UI (порт 7333)
│   ├── embed_server.py     # Локальный embedding-сервер (порт 7445)
│   ├── reranker_server.py  # Reranker-сервер (порт 7444)
│   ├── describe.py         # Описания через GLM/OpenRouter
│   ├── embed.py            # Утилиты embedding (облако + локально)
│   ├── db.py               # PostgreSQL операции
│   ├── test_describe.py    # Тест описаний (сравнение моделей)
│   ├── test_embedding.py   # Тест эмбеддингов (бенчмарк моделей)
│   └── static/index.html   # Web UI (тёмная тема)
├── .env.example            # Шаблон для .env
├── .env                    # OPENAI_API_KEY + OPENROUTER_TOKEN + MODELS_DIR (gitignored)
├── qdrant_data/            # Данные Qdrant (Docker volume)
└── pg_data/                # Данные PostgreSQL (Docker volume)

AST Chunker

Парсит TypeScript/React через ts-morph, извлекает:

  • Компоненты (функции с JSX)
  • Функции и хуки (use*)
  • Типы, интерфейсы, enum'ы, классы
  • Конфиги и константы
  • SCSS-файлы (целиком)
  • Ведущие комментарии (JSDoc, //)

Большие функции (>80 строк) разбиваются на: тело + внутренние функции + JSX return.

Модели (результаты бенчмарков)

Описания (LLM)

Модель Hit@1 Скорость Где
GLM-4.7-flash лучшее качество 0.27 с/чанк (200 парал.) OpenRouter
Qwen3-Coder-Next альтернатива OpenRouter
gpt-4.1-nano хорошее 0.1 с/чанк (30 парал.) OpenAI

Эмбеддинги

Модель Hit@1 Hit@5 MRR Dim
Qwen3-Embedding-4B 68% 100% 0.824 2560
Jina v5 small 68% 96% 0.797 1024
OpenAI 3-small 72% 92% 0.788 1536
Qwen3-Embedding-0.6B 60% 92% 0.735 1024

Реранкеры

Модель Качество Скорость (15 doc)
Qwen3-VL-Reranker-2B лучшее ~2с
Qwen3-Reranker-0.6B хорошее ~0.8с

Конфигурация

  • .env (создать копией из .env.example):
    • OPENAI_API_KEY — для OpenAI-моделей в бенчмарках/описаниях
    • OPENROUTER_TOKEN — для GLM-4.7-flash и Qwen3-Coder-Next
    • MODELS_DIR — путь к локальным MLX/GGUF моделям (по умолчанию ~/.lmstudio/models)
    • PROJECT_<NAME>=<path> — индексируемые проекты (минимум один, см. раздел «Проекты»)
  • Embedding: 2560 dimensions, cosine distance
  • Search defaults: candidates=15, top_k=5

Остановка

bash stop.sh

Или: python start.py → "Остановить всё"

About

Local RAG-powered semantic code search for TypeScript/React codebases (RU+EN) via Qwen3 + Qdrant

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors