Комментарии 4
Для юридического домена граф поверх RAG выглядит особенно уместно не потому, что он «умнее» в вакууме, а потому что там почти всегда важна проверяемая цепочка: норма, исключение, связанный термин, актуальная редакция, судебная практика. В обычном векторном поиске эти связи часто распадаются на похожие куски текста, и модель потом склеивает их уже на своей стороне.
Я бы в такой системе мерил не только точность ответа, а ещё качество маршрута к ответу. Например: сколько обязательных сущностей из вопроса попало в подграф, нашлись ли связи между ними, есть ли конфликтующие нормы, может ли система показать минимальную цепочку источников, на которой держится вывод. Тогда становится видно, где граф реально помогает, а где просто добавляет красивую визуализацию вокруг того же retrieval.
Для пользователя разница, кажется, именно в доверии: «ответ похож на правду» против «вот почему этот ответ следует из этих документов». Во многих юридических задачах второе ценнее даже при той же формальной accuracy.
Приветствую!
Вы затронули очень интересные аспекты, постарался ответить развернуто:
Для юридического домена граф поверх RAG выглядит особенно уместно не потому, что он «умнее» в вакууме, а потому что там почти всегда важна проверяемая цепочка ...
Граф, в отличие от многомерных векторов, нелинейная структура организации данных, в этом его "сила" и поэтому он может улавливать сложные цепочки = связи между точками данных, которые недоступны простому векторному поиску.
Аналитически юридическую область знаний можно представить как постоянно меняющуюся систему сложных взаимосвязей между иерархически организованными сущностями: законами, подзаконными актами, статьями, судами, конкретными персонами и прочими категориями, терминами, понятиями и иными сущностями, которые могут быть описаны как объекты (узлы) графа.
Однако нужно сделать оговорку в защиту векторного поиска: тонко настроенный под домен векторный поиск решает многие задачи в юридическом домене не хуже, а часто быстрее и дешевле. Я довольно подробно разбирал это в статье - Графы знаний в юридическом домене: как не потерять сложность при построении RAG-системы.
граф поверх RAG
Небольшое уточнение (возможно, из статей явно не следует): граф строится не "поверх", а как часть RAG: например, в режиме mix графовый и векторный поиск работают одновременно и сливаются в единый контекст ещё до генерации.
Это можно увидеть прямо в output, задав параметр only_need_context :
params = QueryParam(
mode="mix",
top_k=70,
chunk_top_k=25,
max_total_tokens=200000,
enable_rerank=False,
user_prompt=sys_instruction,
only_need_context=True
)
await rag.aquery(question, param=params)В таком случае вместо ответа вы получите весь контекст, который будет состоять из трех частей: Knowledge Graph Data (Entity), Knowledge Graph Data (Relationship) и Document Chunks.
Кстати, логи LightRAG весьма информативны, например для вопроса - Является ли торговый павильон недвижимостью?:
Логи для вопроса - Является ли торговый павильон недвижимостью?:
INFO: Embedding func: 8 new workers initialized (Timeouts: Func: 30s, Worker: 60s, Health Check: 75s)
INFO: Query nodes: торговый павильон, недвижимость (top_k:70, cosine:0.2)
INFO: Local query: 70 entites, 73 relations
INFO: Query edges: торговый павильон, недвижимость (top_k:70, cosine:0.2)
INFO: Global query: 95 entites, 70 relations
INFO: Naive query: 25 chunks (chunk_top_k:25 cosine:0.2)
INFO: Raw search results: 144 entities, 120 relations, 25 vector chunks
INFO: After truncation: 24 entities, 120 relations
INFO: Selecting 60 from 527 entity-related chunks by vector similarity
INFO: Find 47 additional chunks in 44 relations (deduplicated 26)
WARNING: Vector similarity chunk selection: found 46 but expecting 47
WARNING: No relation-related chunks selected by vector similarity, falling back to WEIGHT method
INFO: Selecting 47 from 47 relation-related chunks by weighted polling
INFO: Round-robin merged chunks: 131 -> 107 (deduplicated 24)
INFO: Final context: 24 entities, 120 relations, 25 chunks
INFO: Final chunks S+F/O: E2/1 R2/2 E1/2 R3/3 E2/3 R4/4 E2/4 R1/5 E1/5 R1/6 E1/6 R2/7 E1/7 R1/8 R1/29 E1/8 R2/9 E1/9 R1/10 E1/10 R1/11 E1/11 R2/12 E1/12 R2/13Из логов видно, что фрагменты приходят разными путями (через сущности, через отношения, через векторы) и сводятся вместе.
При этом граф у нас неориентированный (таковы настройки фреймворка), поэтому однозначно задать маршрут на уровне настроек не получится. Поэтому, кстати, выявление противоречий между нормами я бы выносил уже на агентный уровень, а не пытался уложить в настройки ретривера.
Я бы в такой системе мерил не только точность ответа, а ещё качество маршрута к ответу.
Да, было бы здорово оценивать качество маршрута, поскольку это имеет отношение именно к качеству извлечения, то есть работе самого retrieval.
1. Сейчас активно ведутся исследования в этом направлении, например, свежая статья, посвященная специальному бенчмарку — GraphRAG‑Bench, который позволяет оценить:
качество самого графа - Graph Quality: по сути, то, что описано мной в части анализа топологии;
retrieval и
генерацию.
Однако оценка качества retrieval в этом бенчмарке не предполагает именно оценки маршрута по графу (попали ли нужные сущности, связаны ли они, какая цепочка ведёт к выводу): бенчмарк предполагает оценку, скорее, рассуждения, а не сам процесс обхода графа.
При этом, GraphRAG-Bench не подходит для юридического домена, в любом случае: он построен на художественных и медицинских текстах.
Таким образом, на текущий момент отсутствуют как сам готовый инструмент оценки (например, RAGAS для векторного поиска), так и адекватный домену юридический бенчмарк.
В таких условиях пришлось бы создавать юридический бенчмарк самому + прописывать логику оценки модуля поиска на разных задачах.
2. Если оценивать "сколько обязательных сущностей попало в подграф", кто-то должен сначала определить, какие сущности обязательны для каждого вопроса. А это ручная работа эксперта-юриста по каждому запросу. Это нужно учитывать.
Измерять "минимальную цепочку источников" в неориентированном графе, на мой взгляд, нецелесообразно хотя бы потому, что она не может быть строго не определена: путей между сущностями может быть много, да и в праве правильное обоснование обычно не единственно (к одному выводу можно прийти через разные нормы, и все ответы могут быть корректны). Поэтому честнее измерять не "совпала ли цепочка с эталонной", а набор и связность: попал ли обязательный набор сущностей в подграф и образуют ли они связную структуру.
Для пользователя разница, кажется, именно в доверии: «ответ похож на правду» против «вот почему этот ответ следует из этих документов». Во многих юридических задачах второе ценнее даже при той же формальной accuracy.
Здесь согласен полностью: прослеживаемое обоснование ответа в домене не менее важно, чем сам ответ.
Учитывая, что LightRAG дает простой доступ к логам и контексту для задачи повышения интерпретируемости можно добавить отдельный анализатор поверх логов и контекста, такой post-hoc xAI. На основе парсинга логов и контекста можно настроить отдельную логику анализа retrieval, включая визуализацию подграфа / подграфов конкретного ответа.
Другое дело, что таким образом мы интерпретируем именно стадию извлечения, а не саму генерацию: такой анализатор покажет, что было в контексте и как оно связано, но, строго говоря, не доказывает, что вывод модели держится именно на этом (доступность фрагмента ≠ обоснованность вывода на нем).
P.S. Отдельно отмечу аналитическую ценность хорошо построенного графа именно самого по себе. Топология графа и свойства узлов могут сказать многое об устройстве домена + показать связи / кластеры, иногда неочевидные даже специалисту из предметной области, особенно, если граф строится на крупном корпусе.
Сильный разбор, особенно про разрыв между «граф визуально убедителен» и реальной топологией. Глаз тут врёт всегда. Честный сигнал это распределение степеней и доля вершин со степенью <=1, мы как раз гейтим сборку графа по этой доле, до того как доверять поиску.
Про автоматизацию дедупа подтверждаю вашу боль. Двуязычное расщепление и сокращения рвут связность тише всего, а чисто символьный матч (Левенштейн, rapidfuzz) их пропускает, потому что алиас семантический. У нас лучше зашло так. Кластеризация по эмбеддингам, а LLM зовём только на спорные пары у границы. Ручной MAPPING_DICT не тянет тысячи актов, но и полный обучаемый NER с дорогой разметкой нужен не сразу.
Про маршрутизатор в планах. Мы это гоняем, и вывод ровно ваш. Вопросы про цепочку связей уходят в граф, точечный лукап в вектор. Дешёвый классификатор на входе решает куда, а честный отказ при пустом поиске на практике важнее идеального выбора хранилища.

Графы знаний в юридическом домене: эксперимент с LightRAG (продолжение)