wiki_embedding
Семантический поиск по страницам Яндекс Вики через pgvector + OpenAI embeddings.
Что делает
- Обходит раздел «Управление Аналитики» Яндекс Вики через API и Playwright
- Сохраняет содержимое страниц в Supabase (PostgreSQL)
- Генерирует векторные embeddings через OpenAI
text-embedding-3-small - Позволяет делать семантический поиск по ~700 страницам на русском и английском
Стек
| Компонент | Технология |
|---|---|
| Хранилище | Supabase (PostgreSQL 17) |
| Векторный поиск | pgvector, cosine similarity (<=>) |
| Embeddings | OpenAI text-embedding-3-small (1536 dims) |
| Wiki API | Яндекс Вики API v1 (api.wiki.yandex.net/v1) |
| Браузерный краулер | Playwright + Chromium headless |
| Язык | Python 3.12 |
Структура файлов
wiki_embedding/
├── wiki_sync.py # Главный скрипт синхронизации (API → Supabase → embeddings)
├── wiki_embeddings.py # Генерация embeddings и семантический поиск
├── yandex_wiki.py # Краулер через Яндекс Вики API v1
├── wiki_tree_crawler.py # Playwright-краулер для страниц с {% tree %}
├── wiki_check_slugs.py # Проверка покрытия ROOT_SLUGS
├── wiki_auth.py # Сохранение браузерной сессии для Playwright
├── supabase.py # SupabaseManager — подключение и операции с БД
├── requirements.txt # Зависимости
└── .env # Credentials (не коммитить)
Настройка
1. Установить зависимости
pip install -r requirements.txt
playwright install chromium
2. Создать .env
# Яндекс OAuth-токен (работает для Трекера и Вики)
YT=y0_...
ORG_ID=7405124
# Supabase
SUPABASE_HOST=aws-1-eu-north-1.pooler.supabase.com
SUPABASE_PORT=5432
SUPABASE_USER=postgres.xeakxxnriopsmaxdioke
SUPABASE_PASSWORD=...
SUPABASE_DB=postgres
# OpenAI
OPENAI_API_KEY=sk-...
3. Сохранить браузерную сессию (один раз)
python wiki_auth.py
Откроется браузер — залогинься в wiki.yandex.ru, нажми Enter.
Запуск
Полная синхронизация
python wiki_sync.py
Обходит все 642 slug-а из ROOT_SLUGS, обновляет wiki_pages, генерирует embeddings.
Обнаружить новые страницы через Playwright
python wiki_tree_crawler.py
Открывает страницы с {% tree %} в headless-браузере, находит дочерние slug-и которых нет в базе.
Проверить покрытие
python wiki_check_slugs.py
Показывает какие {% tree %} страницы не покрыты ROOT_SLUGS.
Семантический поиск (из кода)
import sys
sys.path.insert(0, '/Users/at/code/wiki_embedding')
from supabase import SupabaseManager
from wiki_embeddings import search
db = SupabaseManager()
db.connect()
results = search(db, 'твой запрос', limit=5)
for r in results:
print(r['similarity'], r['title'])
print(r['content_text'][:500])
db.close()
Similarity > 0.5 — хорошее совпадение.
Cron (ежедневная синхронизация)
0 3 * * * cd /Users/at/code/wiki_embedding && /usr/bin/python3 wiki_sync.py >> logs/wiki_sync.log 2>&1
Как устроен поиск
- При индексировании каждая страница → вектор через OpenAI (title + content)
- При поиске запрос → вектор тем же способом
- pgvector находит страницы с минимальным косинусным расстоянием (
<=>) - Возвращается
1 - distanceкак similarity (0..1)
Точный поиск без индекса (IVFFlat не используется — при < 10k векторов даёт плохие результаты).
Схема БД
-- Содержимое страниц
wiki_pages (id, slug, title, page_type, modified_at, content_hash, value JSONB)
-- Векторные embeddings
wiki_embeddings (id, slug, title, content_text, content_hash, embedding vector(1536))
Description
Languages
Python
100%