Skip to content

Источники (Sources)

Source — это способность получать информацию. Векторный поиск — одна из стратегий, не единственная: файловая система, CSV и веб (WebSource) уже такие же первоклассные, а эмбеддинги не обязательны. Протокол Source (reactifact/sources.py) специально маленький, чтобы этот список рос добавлением реализаций, а не изменением абстракции — прямой API, поиск по ключевым словам и SQL-источники в роадмапе, но ещё не реализованы (см. roadmap); не рассчитывайте на них, пока не появятся. Источники живут в Context.resources.sources.

from reactifact import Context, RuntimeResources
from reactifact.sources import CSVSource, EmbeddingSource, FileSystemSource, WebSource

ctx = Context(
    resources=RuntimeResources(
        sources={
            "docs": FileSystemSource("./docs", embedder=embedder),  # опционально
            "catalog": CSVSource("data/price.csv", key="sku", columns=...),
            "web": WebSource(...),
        }
    )
)

SourceRef

Общий результат любого поиска — SourceRef: ранжированный, скоупированный указатель:

class SourceRef(BaseModel):
    source_id: str      # какой источник его произвёл
    payload: str        # маленький превью/тестовый фрагмент
    uid: str            # стабильный uid документа внутри источника
    score: float | None # ранг/оценка совпадения, если источник скорирует
    query: str | None   # запрос, который его нашёл
    metadata: dict      # owner_id-скоуп, дополнительный контекст

SourceRef.stable_id() позволяет строить детерминированные id артефактов (ref:{stable_id}:{owner_id} в fan_out_sources), так что повторные поиски идемпотентны.

Четыре встроенных источника

Источник Назначение Примечания
FileSystemSource поиск по ключевым словам (и, опционально, эмбединг) по локальным файлам embedder опционален; скорирует совпадения
EmbeddingSource векторный поиск по подготовленному корпусу нужен EmbeddingProvider
CSVSource запрос к каталогу/таблице, возвращает структурированные строки детерминированно, без эмбеддингов
WebSource живой веб: поиск + ленивое разрешение страниц тянет обещанные документы по требованию

Ленивая материализация

WebSource (и удалённые источники вообще) возвращают ссылки, а не содержимое. Разрешение документа — явное и ленивое: демо research тянет только те страницы, которые решило использовать, и связывает полученный документ с референсом:

SourceRef --materialized_from--> TypedDoc

Рецепт materialize_doc кодирует ровно этот поток.

Типовые стадии поиска в демо

query ──► fan_out_sources ──► SourceRefs (ранжированные, скоуп на владельца)
                                   ▼  (выбор релевантных + ленивое разрешение для web)
                              TypedDoc / строки
                            Evidence (извлечённое, со скоупом)

Пример: CSVSource для детерминированных чисел

Цены каталога никогда не идут через LLM. CSV-источник возвращает точные строки; стадия оценки в примере repair умножает количества на цены из каталога детерминированно:

catalog = CSVSource("data/price.csv", key="name")
rows = await catalog.asearch("штукатурка", limit=20)

Можно указывать CSVSource на любую структурированную таблицу и искать по ключевым словам, получая нужные строки для вычислений.