Автоматизировать юридическую экспертизу сложно. Здесь нужно не просто описать ситуацию, но и грамотно трактовать законы, учитывать контекст и судебную практику, понимать интересы клиента.
Поэтому Legal Tech — одна из самых быстрорастущих отраслей в мире, а теперь она набирает обороты и в России. Однако не все так просто.
В других отраслях, таких как финансы и техподдержка, искусственный интеллект (ИИ) давно помогает снижать издержки, избегать рисков и повышать эффективность, в то время как юридические задачи в России чаще всего по-прежнему выполняют люди.
Почему так? Причины две:
-
В российском праве многое зависит от формулировок текста, конкретных обстоятельств дела, роли участников, а также от судебной практики, которая отличается в разных регионах. К тому же даже самые современные языковые модели с трудом понимают термины и сложные конструкции в юридических текстах.
-
Современные ИИ чаще всего обучаются на англоязычных юридических данных. Из-за этого сложно их внедрять в российскую юридическую практику — нужна адаптация.
Как решить эти проблемы и как создать надежных ИИ-консультантов — обсудим сегодня.
1. Зачем нужен ИИ-консультант в сфере права
Юристы много времени тратят на работу с типовыми формами и структурированной информацией: например, ищут конкретную норму или как ее адаптировать под клиента, потом готовят документы. Все эти задачи можно автоматизировать, передав часть обязанностей юридическому консультанту. Такой ассистент может отвечать на ваши вопросы и искать необходимые нормы, интерпретировать их и готовить черновики документов. При этом все результаты запроса будут индивидуальными, адаптированными под конкретный юридический кейс.
Предположим, сотрудник уволился с работы по собственному желанию и обратился к ИИ-консультанту с просьбой разъяснить ситуацию с работодателем:
«Уволился по собственному. Работал 8 месяцев, но отпуск не брал. Должны ли выплатить компенсацию?»
Обычный поиск по Трудовому кодексу даст только конкретный ответ и укажет на ст. 127 ТК РФ: «При увольнении работнику выплачивается денежная компенсация за неиспользованные отпуска». Но ИИ-консультант учтет, сколько времени работал сотрудник, и поймет, что тот не брал отпуск и имеет право на компенсацию. Более того, ИИ укажет, сколько точно дней оплачиваемого отпуска должны компенсировать, поэтому ответ будет выглядеть так: «Да, вам должны выплатить компенсацию за неиспользованные 18 дней отпуска. Это предусмотрено ст. 127 ТК РФ».
Другой пример запроса:
«Соседи шумят по ночам, невозможно спать. Куда жаловаться и есть ли смысл?»
Обычный поиск сошлется на санитарные нормы, КоАП и так далее. Возможно, предложит несколько статей. ИИ-консультант же распознает, что речь идет о нарушении тишины в ночное время в многоквартирном доме, и ответит примерно так:
«Вы можете обратиться с жалобой в управляющую компанию, Роспотребнадзор или полицию. Нарушение тишины с 23:00 до 7:00 может повлечь штраф по ст. 6.3 КоАП. Зафиксируйте шум (например, аудиозаписью)».
Теперь посмотрим, как это работает на примере закона РФ «О защите прав потребителей». Предположим, пользователь задает ассистенту вопрос:
«Купил смартфон. Стал глючить через 10 дней после покупки, хочу вернуть. Что делать?».
Обычный справочник сослался бы на раздел статьи 18 «Права потребителя при обнаружении в товаре недостатков». ИИ-ассистент же должен понять:
-
что речь идет о технически сложном товаре,
-
что после покупки прошло 10 дней,
-
с какой проблемой столкнулся пользователь,
-
что автор запроса планирует товар вернуть.
В итоге ответ должен выглядеть примерно так: «Если смартфон имеет существенный недостаток, вы вправе требовать возврат денег в течение 15 дней с момента покупки (ст. 18 ЗоЗПП). После 15 дней — только при наличии экспертизы, подтверждающей дефект». Это уже не просто ответ, а на мини-консультация!
Именно такого юридического помощника — собственного ИИ-консультанта — мы и попробуем сегодня создать. Он не только облегчит работу с юридической информацией, но и сможет давать короткие консультации.
2. Построение юридического ИИ-консультанта
Чтобы создать ИИ-ассистента, нужно пройти несколько этапов:
-
Сначала мы определим, какие именно функции и задачи будет выполнять наш помощник.
-
Затем подготовим данные, соберем и структурируем всю информацию.
-
И наконец, выберем подходящую модель искусственного интеллекта, которая станет «мозгом» нашего помощника.
Работать будем на платформе Google Colab — это удобный и бесплатный инструмент. Вы также можете создать продвинутую версию бота, сделав интерфейс в Telegram, Gradio или Streamlit.
Шаг 1. Постановка задачи
Основная задача ассистента — это правильно понять юридический запрос пользователя, сформулированный на естественном языке, и предоставить точный, обоснованный ответ с ссылкой на соответствующий документ.
Чтобы решить эту задачу, в качестве основного источника берем Закон о защите прав потребителей, который предварительно обрабатываем и разбиваем на отдельные части — чанки, где каждый чанк соответствует отдельной статье. При обработке запросов модель ищет релевантные статьи и на их основе формирует точный и обоснованный ответ.
Будем использовать современные подходы:
-
Загрузку документа через PyPDFLoader.
-
Векторное представление текстов с помощью HuggingFaceEmbeddings.
-
Индексацию и быстрый поиск по текстам через FAISS.
-
Построение цепочки вопрос-ответ с помощью RetrievalQA.
-
GPT модель — для генерации и понимания текста .
Приступим к работе и сначала установим и импортируем библиотеки:
!pip install -U langchain-community
!pip install pypdf
!pip install faiss-gpu-cu12
LangChain нужен для создания приложений с языковыми моделями (LLM), такими как GPT. Langchain-community содержит open-source интеграции (вроде FAISS, RAG, OpenAI и др.).
Pypdf — это библиотека для работы с PDF-документами: чтение, разбор, извлечение текста, метаданных и так далее. Полезна, если мы хотим загружать и анализировать pdf-файлы.
Faiss-gpu — это библиотека для быстрого поиска по векторным представлениям слов (например, чтобы находить похожие документы или текстовые фрагменты). Особенно полезно в системах «вопрос-ответ», чат-ботах с базой знаний и RAG (Retrieval-Augmented Generation).
import os
import re
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.schema import Document
from langchain.vectorstores.faiss import FAISS
Теперь нужно получить API key GPT :
api_key = os.environ["OPENAI_API_KEY"] = "sk-..."
Можно переходить к работе с данными.
Шаг 2. Подготовка данных
На этом этапе мы собираем и обрабатываем данные (в нашем случае — Закон), извлекаем из него основное содержимое, структурируем и векторизуем текст для дальнейшей передачи его в модель.
Для работы над ассистентом нужно собрать базу нормативных текстов. Основу возьмем из законов и подзаконных актов, дополним — пояснительными материалами, решениями судов, часто задаваемыми вопросами (FAQ) с официальных ресурсов (например, Роспотребнадзора, КонсультантПлюс или Гаранта). Собрать их можно вручную или парсить с сайтов вроде consultant.ru, garant.ru и pravo.gov.ru.
В нашем примере мы используем готовый текст Закона о защите прав потребителей, скачанный в формате PDF, подготовленный www.consultant.ru. Разберем подробнее, как его предобрабатывать: извлекать текст, разбивать на статьи и готовить к векторизации:
loader = PyPDFLoader("/content/sample_data/Zakon_consultant.pdf")
documents = loader.load()
Загружаем и извлекаем текст из всех страниц PDF. Возвращаем список объектов Document, где каждая страница — это отдельный элемент со своим текстом и метаданными. Всего должно получиться 45 страниц. Посмотрим, как выглядит первая страница:
documents[0]
Document(metadata={'producer': 'КонсультантПлюс', 'creator': 'Версия 4021.00.500 1992 - 2022 КонсультантПлюс Сборка 582435',
'creationdate': '20220912111458', 'title': 'Закон РФ от 07.02.1992 N 2300-1\n(ред. от 14.07.2022)\nО защите прав
потребителей', '/content/sample_data/consultantplus_consultant.pdf', 'total_pages': 45, 'page': 0, 'page_label': '1'},
page_content='Закон РФ от 07.02.1992 N 2300-1\n(ред. от 14.07.2022)\nО защите прав потребителей\nдокумент предоставлен
КонсультантПлюс www.consultant.ru\nДата сохранения: 12.09.2022')
Как видите, здесь много лишней информации, ее нужно удалить.
Почему удаляем:
-
Важно избавиться от неинформативного текста — например, ссылок, бесполезных символов и повторов. Такие элементы не несут смысла, но искажают векторное представление документов. Очистка позволяет FAISS точнее находить релевантные фрагменты юридических текстов.
-
Большие языковые модели (LLM), включая GPT, работают с ограниченным числом токенов на запрос. Лишний текст расходует эти токены без пользы. Это не только снижает эффективность генерации, но и увеличивает стоимость обработки — особенно при работе с платными API.
-
LLM не умеет отличать полезную информацию от служебной, для нее все это — просто текст. Если в контексте есть дубликаты, примечания вроде «абзац утратил силу» или технические вставки, модель может ошибочно включить их в ответ. Очистка делает текст логичным, непротиворечивым и понятным для модели.
Пример того, как мы можем предобработать наш документ (к коду даны краткие комментарии к каждому пункту):
def clean_text(text):
# Удаляем все URL, включая www.consultant.ru
text = re.sub(r"https?://\S+|www\.\S+", "", text)
# Удаляем технические вставки от КонсультантПлюс, ГАРАНТ и т.д.
text = re.sub(r"КонсультантПлюс.*?(\n|$)", "", text, flags=re.IGNORECASE)
text = re.sub(r"Документ предоставлен КонсультантПлюс", "", text, flags=re.IGNORECASE)
text = re.sub(r"Система ГАРАНТ\s*\d+/\d+", "", text, flags=re.IGNORECASE)
text = re.sub(r"Дата сохранения:.*?\n?", "", text, flags=re.IGNORECASE)
# Удаляем дублирующиеся заголовки законов
text = re.sub(r"Закон РФ от.*?\n", "", text)
text = re.sub(r"\(ред\. от.*?\)", "", text, flags=re.IGNORECASE)
# Удаляем редакционные и служебные примечания
text = re.sub(r"\(в ред\..*?\)", "", text, flags=re.IGNORECASE)
text = re.sub(r"\(абзац .*?\)", "", text, flags=re.IGNORECASE)
text = re.sub(r"\(часть .*?\)", "", text, flags=re.IGNORECASE)
text = re.sub(r"абзац утратил силу.*?(\n|$)", "", text, flags=re.IGNORECASE)
text = re.sub(r"часть утратила силу.*?(\n|$)", "", text, flags=re.IGNORECASE)
text = re.sub(r"- Примечание.*?(\n|$)", "", text, flags=re.IGNORECASE)
# Удаляем лишние подчеркивания, табы и многократные пробелы
text = re.sub(r"_+", "", text)
text = re.sub(r"[ \t]{2,}", " ", text)
text = re.sub(r"\s*\n\s*", " ", text)
text = re.sub(r"\s{2,}", " ", text)
return text.strip()
Применяем функцию clean_text ко всему документу:
cleaned_docs = [doc.page_content for doc in documents]
cleaned_docs = [clean_text(text) for text in cleaned_docs]
Теперь разобьем документ на чанки — небольшие фрагменты текста, чтобы дальше было удобнее его обрабатывать. Например, текст объемом 10 000 слов можно разделить на 20 чанков по 500 слов. Затем чанки векторизуем и добавим в FAISS для семантического поиска. Система будет искать не по всему документу, а по отдельным частям (в нашем случае — по отдельным статьям Закона).
Благодаря этому, RAG-система при запросе не анализирует весь закон целиком, а сразу находит подходящие статьи и передает их в модель для генерации ответа.
def split_by_articles(text):
# Паттерн для распознавания заголовков типа "Статья 23", "Статья 23.1", "Статья 7.3-1"
pattern = r'(Статья\s+\d+(?:[\.\-]\d+)*\.?)'
# Разбиваем текст по заголовкам статей, сохраняя заголовки
parts = re.split(pattern, text)
chunks = []
for i in range(1, len(parts), 2):
header = parts[i].strip()
content = parts[i + 1].strip() if (i + 1) < len(parts) else ""
chunk = f"{header} {content}".strip()
if chunk:
chunks.append(Document(page_content=chunk))
return chunks
Применяем функцию split_by_articles к предобработанному тексту:
# Объединяем весь очищенный текст в один
full_text = " ".join(cleaned_docs)
documents_by_articles = split_by_articles(full_text)
Пример того, что получаем на выходе на примере одной статьи:
documents_by_articles
[Document(metadata={}, page_content='Статья 1. Правовое регулирование отношений в области защиты прав потребителей 1.
Отношения в области защиты прав потребителей регулируются Гражданским кодексом Российской Федерации, настоящим Законом,
другими федеральными законами (далее - законы) и принимаемыми в соответствии с ними иными нормативными правовыми актами
Российской Федерации. (п. 1 в ред. Федерального закона от 21.12.2004 N 171-ФЗ)
2. Правительство Российской Федерации не вправе поручать федеральным органам исполнительной власти принимать акты,
содержащие нормы о защите прав потребителей.
Правительство Российской Федерации вправе издавать для потребителя и продавца (изготовителя, исполнителя, уполномоченной
организации или уполномоченного индивидуального предпринимателя, импортера, владельца агрегатора) правила, обязательные при
заключении и исполнении публичных договоров (договоров розничной купли-продажи, энергоснабжения, договоров о выполнении
работ и оказании услуг). (абзац введен Федеральным законом от 21.12.2004 N 171-ФЗ; в ред. Федерального закона от
24.04.2020 N 144-ФЗ)'),
Document(metadata={}, page_content='Статья 2. Международные договоры Российской Федерации 1. Если международным договором
Российской Федерации установлены иные правила о защите прав потребителей, чем те, которые предусмотрены настоящим Законом,
применяются правила международного договора. 2. Решения межгосударственных органов, принятые на основании положений
международных договоров Российской Федерации в их истолковании, противоречащем Конституции Российской Федерации,
не подлежат исполнению в Российской Федерации. Такое противоречие может быть установлено в порядке, определенном федеральным
конституционным законом. (п. 2 введен Федеральным законом от 08.12.2020 N 429-ФЗ)')
]
Теперь перейдем к индексации документов и познакомимся с моделями.
Шаг 3. Выбор модели
В нашем проекте мы будем использовать модель rubert-tiny2, созданную на основе архитектуры BERT и адаптированную для русского языка.
Плюсы этой модели:
-
ее просто использовать, потому что у нее небольшой вес,
-
для ее получения достаточно обратиться к Hugging Face,
-
она подходит для быстрого выполнения задач и имеет максимальную длину контекста 2048 токенов.
Вы можете выбрать и другую модель — например ruBERT, ruGPT или GigaChat.
Для получения эмбеддингов (числовых представлений текста) загружаем модель. Ее задача — точно передавать смысл каждого текстового фрагмента (чанка) в виде вектора.
embedding_model = HuggingFaceEmbeddings(model_name="cointegrated/rubert-tiny2")
db = FAISS.from_documents(documents_by_articles, embedding_model)
Затем инициализируем GPT, для примера мы будем использовать версию gpt-3.5-turbo, но вы можете взять любую. Указываем значение temperature=0.2, чтобы снизить уровень вариативности в ответах модели, так как нам нужны более надежные и однозначные ответы:
llm = ChatOpenAI(
model="gpt-3.5-turbo", # или "gpt-4"
temperature=0.2,
openai_api_key=api_key
)
Построим цепочку QA. Создаем связку retriever и qa_chain, чтобы реализовать подход Retrieval-Augmented Generation (RAG). Ретривер извлекает 3 наиболее релевантных фрагмента из базы (параметр k=3), а затем модель формирует ответ на основе найденного контекста.
retriever = db.as_retriever(search_kwargs={"k": 3})
qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever)
Шаг 4. Оценка качества
Теперь рассмотрим результат работы на наших запросах.
Вернемся к вопросу пользователя:
query = "Купил смартфон. Стал глючить через 10 дней после покупки, хочу вернуть. Что делать?"
response = qa_chain.invoke({"query": query})
Что получилось:
{'query': 'Купил смартфон. Стал глючить через 10 дней после покупки, хочу вернуть. Что делать?',
'result': 'Согласно статье 26.1 закона "О защите прав потребителей", вы можете отказаться от товара ненадлежащего качества
в течение семи дней после его передачи. В вашем случае, если смартфон начал глючить через 10 дней после покупки,
вы можете обратиться к продавцу с требованием о возврате товара и возврате денежной суммы, уплаченной по договору.
Продавец обязан вернуть вам деньги, за исключением расходов на доставку, не позднее чем через десять дней с дня предъявления вами требования.'}
Попробуем другие запросы:
query = "Какие документы нужно предоставить для возврата товара?"
response = qa_chain.invoke({"query": query})
Результат:
{'query': 'Какие документы нужно предоставить для возврата товара?',
'result': 'Для возврата товара надлежащего качества потребителю необходимо сохранить товарный вид, потребительские свойства товара,
а также иметь документ, подтверждающий факт и условия покупки указанного товара. Если у потребителя нет товарного или кассового чека,
он может использовать другие доказательства приобретения товара у данного продавца.'}
Еще один:
query = "Как вернуть товар, если он был куплен онлайн?"
response = qa_chain.invoke({"query": query})
Вывод:
{'query': 'Как вернуть товар, если он был куплен онлайн?',
'result': 'В случае покупки товара онлайн, потребитель вправе отказаться от товара в любое время до его передачи,
а после передачи товара - в течение семи дней. Возврат товара надлежащего качества возможен при сохранении его товарного вида,
потребительских свойств и наличии документа, подтверждающего факт и условия покупки товара.
Потребитель должен обратиться к продавцу с требованием о возврате уплаченной за товар денежной суммы.'}
Попробуем оценить, какие еще варианты ответов может предложить система. Для этого выведем топ-3 наиболее релевантных фрагмента из базы знаний и проанализируем их с точки зрения близости к исходному запросу. FAISS-индекс работает с метрикой L2 (евклидово расстояние), что позволяет измерить, насколько близко по смыслу каждый чанк находится к заданному вопросу.
from langchain.vectorstores.faiss import FAISS
similar_docs_and_scores = db.similarity_search_with_score(query, k=3)
for i, (doc, score) in enumerate(similar_docs_and_scores, 1):
print(f"\n--- Документ {i} ---")
print(f"Схожесть: {score:.4f}")
print(doc.page_content[:500])
Важно понимать, что retriever сам по себе не выбирает «правильный» ответ, его задача — извлечь k наиболее подходящих по смыслу фрагментов (документов или статей).
Затем уже LLM анализирует все переданные фрагменты и самостоятельно формирует финальный ответ. Она не выбирает один конкретный чанк, а синтезирует информацию из всех источников.
Чтобы объективно оценить качество ответов на юридические вопросы, важно привлекать экспертов, практикующих юристов. Они проверят, соответствуют ли ответы законодательству, насколько полно раскрыта тема и нет ли искажений.
Вывод
Сегодня мы разобрали, как с помощью больших языковых моделей (LLM) и инструментов RAG и FAISS можно собрать работающий прототип LegalTech-ассистента. Он умеет искать и структурировать информацию по Закону о защите прав потребителей.
На практике такой ИИ-ассистент поможет разгрузить специалистов, а людям без юридического образования — легко находить нужную информацию и ответы на вопросы.
Что дальше? Можно подключить новые нормативные акты, научить ИИ обрабатывать более сложные запросы и внедрить другие полезные возможности. В следующих статьях расскажем, как развить прототип в полноценного LegalTech-ассистента.