Перейти к содержанию

AI Search — Operational Runbook

Architecture: cascade-fts-spec.md | DocsChunks: docs-chunks-mssql-spec.md | Pipeline: ../ai/architecture/docs-pipeline-map.md

Diagnostic Decision Tree

Симптом
  │
  ├── 0 результатов docs search
  │   ├── Файл проиндексирован? → SELECT * FROM DocsChunks WHERE Path LIKE '%keyword%'
  │   ├── FTS catalog active? → SELECT FULLTEXTCATALOGPROPERTY('DocsChunksFTCatalog', 'PopulateStatus')
  │   ├── Frontmatter есть? → SELECT Frontmatter FROM DocsChunks WHERE Path = '...' AND ChunkIndex = 0
  │   ├── Tags заполнены? → SELECT Tags FROM DocsChunks WHERE Path = '...'
  │   └── Section weights дёргаются? → contextBox передан в docsSearch?
  │
  ├── 0 результатов task search
  │   ├── Parse mode? → perfLog: search_parse: mode={mode}
  │   ├── Colon notation сломан? → parseColonNotation не распарсил qualifier
  │   ├── ShowTasksFeed фильтры? → subcatIds, stateIds из parse
  │   └── Comments fallback сработал? → search_comments в perfLog
  │
  ├── Неправильный ranking (документ есть, но внизу)
  │   ├── Tags вес = 4.0. Tags есть? Правильные?
  │   ├── PageRank = 2.0. InLinks > 0? → SELECT * FROM DocsPageRank WHERE Path = '...'
  │   ├── Phase 0 demote? → press:0.3, blog:0.3, academy:0.3, website:0.5, admin-manual:0.3
  │   └── Phase 1 box weight? → contextBox = правильный box?
  │
  └── Медленный поиск (> 5s)
      ├── FTS catalog rebuilding? → PopulateStatus check
      ├── Большой result set? → CONTAINSTABLE timeout
      └── Embedding cosine? → in-memory на top-50, ~200ms normal

SQL-запросы

Проверить индексацию файла

-- Файл в DocsChunks?
SELECT ChunkIndex, Title, LEN(Body) as body_len, Tags, IndexedAt
FROM DocsChunks
WHERE Path LIKE '%keyword%'
ORDER BY Path, ChunkIndex

-- Сколько всего чанков
SELECT COUNT(*) as total_chunks, COUNT(DISTINCT Path) as total_files
FROM DocsChunks

Проверить FTS catalog

-- Статус каталога (0=idle, 1=full population, 2=incremental, 6=change tracking)
SELECT FULLTEXTCATALOGPROPERTY('DocsChunksFTCatalog', 'PopulateStatus') as Status,
       FULLTEXTCATALOGPROPERTY('DocsChunksFTCatalog', 'ItemCount') as Items

-- Тест FTS по конкретному запросу
SELECT TOP 5 dc.Path, dc.Title, ft.[RANK]
FROM CONTAINSTABLE(DocsChunks, Body, N'"keyword"') ft
JOIN DocsChunks dc ON dc.Id = ft.[KEY]
ORDER BY ft.[RANK] DESC

-- FREETEXTTABLE (morphological)
SELECT TOP 5 dc.Path, dc.Title, ft.[RANK]
FROM FREETEXTTABLE(DocsChunks, Body, N'ключевое слово') ft
JOIN DocsChunks dc ON dc.Id = ft.[KEY]
ORDER BY ft.[RANK] DESC

Проверить PageRank

-- Топ-20 по PageRank
SELECT TOP 20 Path, InLinks, PageRank, AuthScore, HubScore
FROM DocsPageRank ORDER BY PageRank DESC

-- PageRank конкретного документа
SELECT * FROM DocsPageRank WHERE Path LIKE '%keyword%'

Проверить search perfLog

-- Последние search вызовы
SELECT SUBSTRING(CAST(Content AS NVARCHAR(MAX)), 1, 500)
FROM AnfisaConversationLog
WHERE Role = 'perf_log'
  AND CAST(Content AS NVARCHAR(MAX)) LIKE '%search_%'
  AND CreatedAt > DATEADD(HOUR, -1, GETDATE())
ORDER BY Id DESC

Reindex Procedures

Incremental (обычный)

Автоматически через SS 509 при git push. Если нужно вручную:

# Local docsearch (для docs/ на маке)
~/repo/docsearch/.venv/bin/docsearch embed

# Проверка
~/repo/docsearch/.venv/bin/docsearch status
~/repo/docsearch/.venv/bin/docsearch query "test query"

Full Reindex (emergency)

-- ОСТОРОЖНО: полная переиндексация
TRUNCATE TABLE DocsChunks
-- Затем: trigger full SS 509 run
-- Или: python3 indexer_docs_mssql.py --full

FTS Catalog Rebuild

-- Если FTS catalog повреждён
ALTER FULLTEXT CATALOG DocsChunksFTCatalog REBUILD

-- Проверить статус (может занять несколько минут)
SELECT FULLTEXTCATALOGPROPERTY('DocsChunksFTCatalog', 'PopulateStatus')
-- 0 = ready, 1 = rebuilding

PageRank Rebuild

# Из директории ai-search
python3 build_pagerank.py
-- Verify
SELECT COUNT(*) as docs, AVG(PageRank) as avg_pr, MAX(PageRank) as max_pr
FROM DocsPageRank

zvec-search Container

Restart

# На сервере docs-srv
docker restart zvec-search
# Или
cd /opt/zvec-search && docker compose restart

Redeploy

cd /opt/zvec-search
git pull
docker compose build && docker compose up -d

Health Check

curl -s http://docs-srv:3005/health | jq .
curl -s http://docs-srv:3005/search -d '{"query": "test", "limit": 3}' | jq .

Performance Tuning Quick Reference

Параметр Где Default Tuning
RRF k ai-search-docs-mssql.js:34 60 Выше = smoother ranking, ниже = sharper
FREETEXT_TAGS weight ai-search-docs-mssql.js:26 4.0 Главный сигнал. Увеличить если tags-driven
PAGERANK weight ai-search-docs-mssql.js:32 2.0 Увеличить если авторитетные docs внизу
Phase 0 demote ai-search-docs-mssql.js:37 press:0.3, blog:0.3, academy:0.3, website:0.5, admin-manual:0.3 Добавить section если шумит
Phase 1 box weights ai-search-docs-mssql.js:40 per-box matrix Добавить box если context missing

Связанные