Привет, Хабр. Эта статья про систему, которая читает папку научных статей и помогает разбираться в них как в связанном корпусе, а не как в наборе отдельных PDF. Материал написан на базе выпускного проекта студента курса NLP Advanced.

Исходный код проекта: [github.com/xabarov/science‑graphrag]

Идея простая: если в статье есть авторы, методы, датасеты, цитирования и утверждения, то их можно превратить в граф. Тогда вопрос «какие работы привели к появлению DETR?» становится не просто поиском похожих фраз, а проходом по связям между работами.

Проект получился не столько про красивую архитектуру, сколько про честную проверку качества. Самый полезный результат оказался неприятным: на простых проверках система выглядит почти идеально, а на проверках, похожих на реальные вопросы исследователя, качество резко падает. И это хорошо: значит, метрика наконец показывает правду.

Коротко о результате:

  • имена авторов и организаций извлекаются хорошо: F1 около 0,98 и 0,95;

  • связи цитирования восстанавливаются заметно лучше случайного уровня: F1 около 0,82;

  • ИИ‑помощник проходит основные пользовательские сценарии, но отвечает не мгновенно: около 26 секунд на медленных запросах;

  • извлечение сложных утверждений из статей пока слабое: F1 около 0,22 на перефразированных проверках.

Последняя цифра выглядит хуже остальных, но именно она самая важная. Ниже объясню почему.

Если коротко: F1 — гармоническое среднее точности и полноты, от 0 до 1. В тексте я использую его как компактную сводную оценку качества извлечения.

Зачем граф, если уже есть поиск по смыслу

Обычный поиск по смыслу хорошо отвечает на вопросы вроде:

«Найди фрагменты, где говорится про DETR».

Он ищет куски текста, похожие на запрос. Для многих задач этого достаточно.

Но научные статьи часто читают иначе. Нужно понять:

  • кто на кого ссылается;

  • какая работа развивает какую;

  • где авторы спорят друг с другом;

  • какие методы сравнивались на одних и тех же наборах данных;

  • из какой статьи взялось конкретное утверждение.

Для таких вопросов похожего текста мало. Нужна структура.

Например, вопрос:

«Какие работы образуют цепочку развития DETR?»

Это не вопрос «где встречается слово DETR». Это вопрос про историю идеи: какие статьи были раньше, какие позже, кто кого цитировал, какие методы стали промежуточными шагами.

Поэтому в SciGraph есть два способа смотреть на корпус:

  • поиск по смыслу помогает найти близкие фрагменты;

  • граф помогает пройти по связям между статьями, авторами, методами и утверждениями.

Сравнение RAG и GraphRAG: разрозненные фрагменты против связанного графа знаний
Сравнение RAG и GraphRAG: разрозненные фрагменты против связанного графа знаний

Один подход не заменяет другой. Они закрывают разные вопросы.

Как устроен SciGraph

От PDF к графу знаний, запрос с обходом по связям и ответ со сводкой и цитатами.
От PDF к графу знаний, запрос с обходом по связям и ответ со сводкой и цитатами.

На вход подаётся папка со статьями. В моих прогонах это был небольшой корпус по компьютерному зрению: YOLO, DETR, Faster R‑CNN и близкие работы.

Дальше система делает несколько шагов:

  1. переводит PDF в текст;

  2. достаёт название, авторов, организации и список литературы;

  3. находит методы, наборы данных и важные утверждения;

  4. связывает статьи цитированиями;

  5. кладёт фрагменты текста в поиск по смыслу;

  6. строит граф знаний;

  7. отвечает на вопросы через набор инструментов и обязательно показывает источники.

Внутри используются разные хранилища, но для читателя статьи это не главное. Главное разделение такое:

  • текстовые фрагменты нужны для поиска и цитат;

  • граф нужен для связей;

  • обычная база данных нужна для состояния документов и задач.

Самое важное правило: ответ без источников не считается хорошим ответом. Если система говорит, что статья A развивает статью B, нужно иметь возможность открыть фрагмент, на котором это основано.

Пример: авторство оказалось не таким простым

Сначала кажется, что авторство можно хранить просто:

статья → автор

Но этого быстро становится мало. У авторства есть порядок, организация на момент публикации, иногда разные варианты написания имени.

Если это потерять, система уже не ответит на вопросы вроде:

  1. «В каких работах автор менял организацию?»

  2. «Кто был первым автором в серии статей по методу?»

  3. «Какая группа развивала этот подход дальше?»

Поэтому авторство в графе хранится как отдельная сущность. Это маленькая деталь, но именно такие детали делают граф полезным, а не декоративным.

Главная инженерная грабля: процесс завис на три часа

Однажды я запустил обработку корпуса примерно из 35 статей и ушёл пить кофе. Через 20 минут всё выглядело нормально: система дошла до 16-го файла. Через час она всё ещё была на 16-м файле. Потом ещё час.

Причина оказалась прозаичной: сетевое соединение к внешнему сервису зависло в полузакрытом состоянии. Процесс не падал, но и не двигался дальше. Он просто молча ждал.

После этого в проекте появились правила, без которых я теперь не запускаю длинные задачи:

  • перед стартом проверять ключи, доступность сервисов и настройки;

  • писать в лог регулярный сигнал «я жив»;

  • ставить ограничение по времени на обработку одного файла;

  • сохранять промежуточное состояние, чтобы можно было продолжить, а не начинать заново.

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

Почему красивые метрики могут обманывать

Самая важная часть проекта — оценка качества.

Первую проверку я сделал слишком удобной. Брал утверждение из статьи почти дословно и проверял, извлечёт ли его система.

Например, в статье есть фраза про скорость метода. В проверке написано почти то же самое. Система находит эту фразу, метрика получается почти идеальной.

На бумаге всё отлично. В реальности это проверяет только то, умеем ли мы находить похожие слова рядом с источником.

Но исследователь спрашивает иначе. Он не повторяет текст статьи дословно. Он формулирует смысл своими словами:

«Почему DETR может обходиться без ручного подавления лишних рамок?»

Чтобы ответить, нужно собрать смысл из нескольких частей: как устроено сопоставление объектов, почему предсказания уникальны, как это связано с отказом от отдельного шага фильтрации.

Когда я переписал эталон своими словами, качество резко упало: F1 около 0,22.

Разрыв между удобными метриками и честной проверкой на перефразированных утверждениях
Разрыв между удобными метриками и честной проверкой на перефразированных утверждениях

Это неприятная цифра. Но она честная. Она показывает, что система уже работает как конвейер, но ещё плохо понимает сложные научные утверждения.

Почему F1 = 0,22 не провал

В машинном обучении легко получить красивую цифру, если проверять то, что удобно проверять. Вопрос в том, что эта цифра говорит о реальности.

Для меня F1 около 0,22 на перефразированных утверждениях означает три вещи:

  1. Система не просто сломана: она что‑то находит и иногда попадает в смысл.

  2. Текущего качества недостаточно, чтобы слепо доверять извлечённым утверждениям.

  3. Проверка достаточно жёсткая, чтобы отличать настоящее улучшение от косметики.

После небольшой правки инструкции для модели качество выросло совсем немного: примерно с 0,217 до 0,224 на одном наборе. Потом добавилась очистка повторов, и стало около 0,249.

Это не революция. Но в честной проверке маленький прирост лучше большой победы на удобном тесте.

История про граф, который нашёл слишком много

Ещё одна показательная ошибка случилась при обходе графа.

Я спросил систему про родословную DETR. Граф честно пошёл по связям и вернул 94 работы‑кандидата.

Нужных среди них было две. Остальное — шум.

Почему так произошло? Потому что в плотном графе «возьми соседей соседей» очень быстро превращается в лавину. Каждая статья связана с несколькими другими, те — ещё с несколькими, и через пару шагов граф приносит почти всё подряд.

Графовый обход без смысловой фильтрации: 94 кандидата превращаются в 2 релевантные работы
Графовый обход без смысловой фильтрации: 94 кандидата превращаются в 2 релевантные работы

Вывод простой: граф хорошо даёт кандидатов, но ему нужен второй этап отфильтровать найденное по смыслу вопроса. Иначе графовый поиск превращается в пожарный шланг.

ИИ‑помощник: полезно, но дорого

ИИ‑помощник: полезно, но дорого

В системе есть ИИ‑помощник, который сам выбирает, что сделать:

  • найти похожие фрагменты;

  • открыть карточку статьи;

  • пройти по связям графа;

  • найти цитату;

  • собрать финальный ответ.

Это удобнее, чем один большой запрос к модели: разные вопросы требуют разных действий.

Но за это приходится платить временем. Каждый шаг такого помощника — это дополнительный вызов модели или инструмента. Поэтому сложные вопросы отвечают не мгновенно.

Я пробовал более сложную схему с несколькими «специалистами»: один отвечает за поиск, другой за граф, третий пишет финальный текст. На схеме это выглядело красиво. На практике стало медленнее и сложнее для отладки.

Главный урок: не всякое усложнение архитектуры делает систему умнее. Иногда оно просто добавляет задержку и новые места для ошибок.

То же самое оказалось верно для длинных диалогов: можно добавить память, сжатие истории и промежуточные сводки, но это нужно включать только после живых проверок. Иначе легко получить красивую архитектуру, которая хуже объясняет пользователю, что делает, и дольше отвечает.

Что получилось хорошо

В проекте есть несколько частей, которыми я доволен.

Извлечение авторов и организаций работает стабильно. Это не самая эффектная часть, но без неё нельзя строить нормальные вопросы про научные группы и вклад авторов.

Связи цитирования восстанавливаются достаточно хорошо, чтобы граф стал полезным. Он уже помогает видеть, какие работы связаны, а не просто лежат рядом в папке.

Ответы с цитатами стали обязательным правилом. Это сильно меняет ощущение от системы: можно не только прочитать вывод, но и проверить, откуда он взялся.

И главное: появилась проверка, которая не льстит проекту. Она показывает слабые места, а не только подтверждает, что всё запускается.

Что пока болит

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

Графовый поиск без дополнительной фильтрации приносит слишком много лишнего.

Многошаговый ИИ‑помощник медленный. Для исследовательского инструмента это терпимо, но для приятного продукта нужны промежуточные статусы, постепенная выдача ответа и более аккуратная работа с историей диалога.

Длинные фоновые задачи требуют дисциплины: проверок перед стартом, ограничений по времени, логов и возможности продолжить после сбоя. Без этого обработка корпуса рано или поздно зависнет в самый неудобный момент.

Что я бы сделал иначе

Я бы раньше начал с честной проверки качества. Не после того, как конвейер уже выглядит красиво, а в самом начале.

Я бы раньше добавил наблюдаемость: где модель тратит время, какие инструменты вызывает, на каком шаге ломается ответ. Без этого отладка превращается в гадание.

Я бы осторожнее относился к схемам с несколькими ИИ‑ролями. Разделение ролей полезно только тогда, когда оно уменьшает хаос. Если оно добавляет лишние решения и лишние вызовы модели, его нужно выключать, даже если диаграмма выглядит убедительно.

И я бы сразу проектировал долгую обработку корпуса как очередь задач, а не как один большой процесс «запустил и надеюсь».

Вывод

Граф поверх научных статей оправдан не потому, что это модное слово, а потому что есть вопросы, на которые обычный поиск по похожему тексту отвечает плохо:

  • как развивался метод;

  • кто на кого опирался;

  • где статьи спорят друг с другом;

  • из какого фрагмента взялось утверждение;

  • как связаны авторы, методы и наборы данных.

Но граф сам по себе не решает всё. Нужен поиск по смыслу, нужны цитаты, нужна фильтрация шума и нужна честная оценка качества.

Главный вывод проекта для меня такой: лучше неприятная метрика, которая показывает реальность, чем красивая цифра, которая проверяет только удобный сценарий.

Если коротко, три практических урока:

  1. Проверяйте систему на перефразированных вопросах, а не на дословных цитатах.

  2. Не смешивайте реальные прогоны и имитации в одной таблице качества.

  3. Для длинных задач сразу делайте таймауты, промежуточные сохранения и понятные логи.

SciGraph пока не идеален. Но теперь понятно, где он действительно работает, где обманывает сам себя и куда двигаться дальше.

Проект выполнен в рамках курса OTUS NLP Advanced, 2026.

Если вам близка тема LLM‑систем, которые не просто красиво отвечают, а умеют работать с данными, источниками и инструментами, присмотритесь к бесплатным открытым урокам:

Больше бесплатных уроков по AI, ML, разработке и архитектуре — в [календаре открытых уроков].

А чтобы не пропускать новые материалы, разборы и анонсы, подписывайтесь на канал OTUS в MAX.