Авторская колонка

Векторный поиск против Графа знаний: сколько на самом деле стоит построить и удержать GraphRAG

Векторный RAG решает задачу поиска похожих фрагментов («найди, где упоминался X»), тогда как граф знаний необходим для многошаговых вопросов о связях и обобщения корпуса («кто и какими инструментами делал проект X за полтора года»). Отказ от поштучного вызова CLI с системным промптом на 117 000 токенов в пользу пакетного извлечения субагентами внутри одной сессии снизил стоимость построения графа по 10 019 записям с расчётных $1 500 до единиц долларов. Главная цена графа кроется в эксплуатации: канонизация 2 542 сырых вариантов названий инструментов и 1 213 написаний проектов (сжатых до 81 реального проекта) требует регулярной чистки дублей и защиты от взрыва автолинковки.

Векторный поиск против Графа знаний: сколько на самом деле стоит построить и удержать GraphRAG
Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
Главный редактор
Исходный корпус и размер графа10 019 карточек знаний, развёрнутых в 5 237 узлов и 19 803 ребра (файл SQLite 15 МБ)
Экономия на этапе построенияснижение стоимости экстракции с расчётных $1 500 (при 117K токенов префикса на вызов) до нескольких долларов
Сжатие сущностей канон-словарём1 213 вариантов написания проектов схлопнулись в 81 канонический проект (в 15 раз)
Скорость гибридного контура13 мс на ранжированную выдачу FTS5 по 538 956 сообщениям и 87 мс на двухшаговый графовый JOIN
  • Исходный корпус и размер графа: 10 019 карточек знаний, развёрнутых в 5 237 узлов и 19 803 ребра (файл SQLite 15 МБ)
  • Экономия на этапе построения: снижение стоимости экстракции с расчётных $1 500 (при 117K токенов префикса на вызов) до нескольких долларов
  • Сжатие сущностей канон-словарём: 1 213 вариантов написания проектов схлопнулись в 81 канонический проект (в 15 раз)
  • Скорость гибридного контура: 13 мс на ранжированную выдачу FTS5 по 538 956 сообщениям и 87 мс на двухшаговый графовый JOIN

За год эксплуатации собственной системы памяти я сформулировал разницу между двумя подходами в одну фразу: векторный поиск отвечает на вопрос «найди мне цитату про X», а граф отвечает на вопрос «расскажи, как устроен X и кто с ним связан». Когда вы спрашиваете «какими инструментами мы пользовались в проекте за полтора года и кто в нём участвовал», правильного ответа нет ни в одном текстовом чанке целиком — векторный поиск вернёт три случайных фрагмента, а недостающие 80% картины модель уверенно досочиняет.

Часто цитируемая работа Microsoft Research (`arXiv:2404.16130`), обещающая победу GraphRAG в 72–83% попарных сравнений по полноте ответа, верна, но имеет жёсткие граничные условия. Замер проводился на задаче глобального обобщения корпуса (`query-focused summarization` на 1,0–1,7 млн токенов), причём в вилку 72–83% авторы включили и конфигурацию `TS`, которая вообще не использует граф, а делает `map-reduce` по исходным текстам.

Как не сжечь $1 500 на системном промпте при извлечении сущностей из

10 019 записей?

Когда я сел строить граф поверх 10 019 карточек знаний (5 658 заметок обучения, 2 657 фрагментов кода, 1 209 обсуждений и 155 разборов ошибок), первая наивная реализация чуть не разорила проект. Казалось естественным нарезать корпус на пачки по 200 записей и запускать консольный агент подпроцессом на каждый батч. Первый же пробный вызов стоил 15 центов: CLI-клиент при каждом старте заново подгружал системный промпт, правила и описания скиллов — 117 000 токенов служебного префикса. На 49 батчах это давало больше $7 холостого хода, а при поштучном разборе 10 019 записей счёт перевалил бы за $1 500.

Мы перестроили пайплайн: предварительно отсеяли 287 мусорных записей и запустили волны из 5–7 параллельных субагентов внутри одной живой родительской сессии, где префикс уже закэширован. Попытка поднять сразу 20 воркеров упёрлась в серверный троттлинг после 411 задач из 672, поэтому мы зафиксировали оптимум: стабильные ID батчей в манифесте и волна до 6–8 параллельных агентов.

Почему эксплуатация графа дороже его сборки и как канон-словарь

сжимает проекты в 15 раз?

Каждая новая волна извлечения сущностей приносит десятки вариантов написания одних и тех же имён и брендов. Если складывать их в базу как есть, через месяц вместо одного проекта в графе оказывается пятнадцать изолированных островов. Единственное лекарство — детерминированный канон-словарь (`_MAPS`) перед записью в базу:

```python def canon(entity_kind: str, raw_name: str) -> str: # Приводит сырое имя сущности к каноническому или отбрасывает шум (пустая строка) cleaned = (str(raw_name) if raw_name is not None else "").strip() return _MAPS.get(entity_kind, {}).get(cleaned, cleaned) ```

После прогона карт нормализации 1 213 сырых написаний проектов схлопнулись в 81 реальный проект (в 15 раз!), 2 542 варианта инструментов ужались до 1 068, компании — с 1 427 до 1 115, а люди — с 783 до 590. Ещё 66 псевдо-инструментов и 11 абстрактных «компаний» («Холдинг», «Библиотека») замапили в пустую строку. Попутно мы починили две классические грабли: цикл `for t in stack` по строковому полю вместо списка, наплодивший 96 000 мусорных рёбер к отдельным буквам алфавита (вылечено проверкой `isinstance(v, list)`), и взрыв автолинковки по подстроке заголовка на 27 000 ложных связей (вылечено фильтром длины от 5 символов и условием, что ключ встречается не более чем в 4 проектах, что дало 543 точных ребра `about`).

Когда достаточно двух таблиц SQLite вместо выделенного графового сервера?

Первая версия нашего графа жила на сервере в базе FalkorDB (поверх Redis и GraphBLAS). Там выяснилось, что диалект Cypher не поддерживает регулярки `=~` и ненаправленный `shortestPath()`, а из-за выключенного MCP-коннектора и необходимости поднимать SSH-туннель граф с 4 743 узлами простоял 7 недель полностью отключённым от агентов.

Мы перенесли весь граф в локальный SQLite-файл размером 15 МБ из двух таблиц (`nodes` и `edges`). На масштабе 5 237 узлов и 19 803 ребра обычный SQL-запрос с двумя `JOIN` находит топ проектов по числу инструментов и сессий (лидер — 277 сессий и 285 инструментов) за 87 мс, а полнотекстовый FTS5 по полумиллиону сообщений отвечает за 13 мс.

Такой гибридный поиск без лишних демонов заложен в архитектуру [Nomad AI](https://nomadnet.ai) и облачной платформы [agent.nomadnet.ai](https://agent.nomadnet.ai). Научиться собирать промышленные RAG и графы знаний можно в [Hamidun Academy](https://academy.hamidun.com) (открыт 72-часовой триал), а скрипты канонизации доступны в [Vibe Club](https://hamidun.com/club).

Сюжет

Вопросы и ответы по материалу

Как не сжечь $1 500 на системном промпте при извлечении сущностей из 10 019 записей?

Когда я сел строить граф поверх 10 019 карточек знаний (5 658 заметок обучения, 2 657 фрагментов кода, 1 209 обсуждений и 155 разборов ошибок), первая наивная реализация чуть не разорила проект. Казалось естественным нарезать корпус на пачки по 200 записей и запускать консольный агент подпроцессом на каждый батч. Первый же пробный вызов стоил 15 центов: CLI-клиент при каждом старте заново подгружал системный промпт, правила и описания скиллов — 117 000 токенов служебного префикса. На 49 батчах это давало больше $7 холостого хода, а при поштучном разборе 10 019 записей счёт

Почему эксплуатация графа дороже его сборки и как канон-словарь сжимает проекты в 15 раз?

Каждая новая волна извлечения сущностей приносит десятки вариантов написания одних и тех же имён и брендов. Если складывать их в базу как есть, через месяц вместо одного проекта в графе оказывается пятнадцать изолированных островов. Единственное лекарство — детерминированный канон-словарь (`_MAPS`) перед записью в базу: ```python def canon(entity_kind: str, raw_name: str) -> str: # Приводит сырое имя сущности к каноническому или отбрасывает шум (пустая строка) cleaned = (str(raw_name) if raw_name is not None else "").strip() return _MAPS.get(entity_kind, {}).get(cleaned, cl

Когда достаточно двух таблиц SQLite вместо выделенного графового сервера?

Первая версия нашего графа жила на сервере в базе FalkorDB (поверх Redis и GraphBLAS). Там выяснилось, что диалект Cypher не поддерживает регулярки `=~` и ненаправленный `shortestPath()`, а из-за выключенного MCP-коннектора и необходимости поднимать SSH-туннель граф с 4 743 узлами простоял 7 недель полностью отключённым от агентов. Мы перенесли весь граф в локальный SQLite-файл размером 15 МБ из двух таблиц (`nodes` и `edges`). На масштабе 5 237 узлов и 19 803 ребра обычный SQL-запрос с двумя `JOIN` находит топ проектов по числу инструментов и сессий (лидер — 277 сессий и 2

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Практика · Hamidun Academy

Соберите рабочего ИИ-агента или сервис своими руками без ручного кода

В Академии Жемала Хамидуна (academy.hamidun.com) открыт бесплатный 72-часовой тест-драйв: интерактивные скетч-уроки по Claude Code и Cursor, живой Tech Radar и готовые шаблоны агентов.

Открыть 72ч бесплатный доступ →Интенсив по Вайб-кодингу
Что вы думаете?
Загружаем комментарии…