0.22.0
Итерация 18 плана аудита: память — hybrid search (BM25 + vector) и RAG-параметры.
Added
- Миграция
024_hybrid_search(sqlite + pg, up/down): - SQLite: FTS5 виртуальные таблицы
memory_facts_ftsиmemory_chunks_fts(content-sync mode, не дублирует данные). Триггерыtrg_facts_fts_ins/del/updиtrg_chunks_fts_ins/del/updдля синхронизации с основными таблицами. Начальное заполнение черезINSERT INTO ... VALUES ('rebuild'). - PostgreSQL:
content_tsvector tsvector GENERATED ALWAYS AS (to_tsvector('simple', content)) STOREDвmemory_factsиmemory_chunks. GIN-индексыidx_memory_facts_tsvectorиidx_memory_chunks_tsvector. - Store-методы
SearchFactsFTS(ctx, agentID, userID, query, topK)иSearchChunksFTS(ctx, agentID, userID, query, topK)— полнотекстовый поиск. SQLite: FTS5MATCH+bm25()+ JOIN для фильтрации agentID/userID. PostgreSQL:tsvector @@ plainto_tsquery('simple', ...)+ts_rank(). Реализованы для SQLite, Postgres, DualStore. RRFMerge(lists, topK, k)вinternal/store/vectors.go— Reciprocal Rank Fusion: объединяет несколько отсортированных списков в один с корректным скорингом1/(k+rank). k=60 (стандарт). Перекрывающиеся документы получают повышенный score.- Hybrid search в
ContextBuilder.buildMemoryContext: vector top-30 + FTS top-30 →RRFMerge→ top-30 → MMR (15/10) → reranker → dynamic top-K. - Обновлённые параметры RAG:
- Retrieval: top-K 30 (было 30), threshold 0.45 (было 0.6).
- Final top-K: динамический по бюджету — facts 3-7, chunks 1-4 (было фиксировано 5/3). Функция
dynamicRAGTopK(ragBudget)масштабирует пропорционально budget.RAG. TouchFacts(ctx, factIDs)— батчевый UPDATE вместо N индивидуальныхTouchFact. Вызывается один раз в концеbuildMemoryContext. SQLite: transaction + prepared statement. PostgreSQL:pgx.Batch.POST /memory/searchhandler: использует hybrid search (vector + FTS + RRF) + reranker (передан вNewMemoryHandler). Порог по умолчанию 0.45 (было 0.7).- 21 юнит-тест:
internal/store/rrf_test.go(6 тестов): BasicMerge, EmptyLists, SingleList, TopK, OverlappingBoostsScore, DefaultK.internal/store/fts_test.go(8 тестов): SearchFactsFTS_Basic, UserIsolation, EmptyQuery, SearchChunksFTS_Basic, TouchFacts_Batch, TouchFacts_Empty, HybridSearch_RRF, Migrations_UpTo024.internal/agent/context_test.go(1 тест): DynamicRAGTopK (6 кейсов по бюджету).- Все тесты проходят с
-race.
Changed
NewMemoryHandlerтеперь принимаетreranker.RerankerProviderвторым аргументом (послеstore.Store).buildMemoryContextвызываетTouchFactsбатчем вместо поочерёдногоTouchFact.