Разработка AI-системы семантического поиска по законодательству

Юристы тратят часы на поиск нужных норм и судебной практики, а стандартный поиск по ключевым словам часто пропускает релевантные документы. Мы разрабатываем AI-системы семантического поиска, которые понимают смысл запроса и находят нужные статьи за секунды. Наша команда реализует проект под ключ — от аудита правовой базы до внедрения и последующей поддержки.
Часто задаваемые вопросы

Юристы тратят часы на поиск подходящих норм и судебной практики. Стандартный поиск по ключевым словам часто пропускает релевантные документы, если формулировки не совпадают. Мы создали AI-систему, которая понимает смысл запроса и находит нужные статьи за секунды. Наша экспертиза в RAG и языковых моделях позволяет строить системы с точностью цитирования 94%.

AI-поиск находит нормы в 200 раз быстрее, чем ручной перебор. Семантический поиск на базе эмбеддингов решает проблему синонимов, а RAG гарантирует, что ответ строится только на реальных документах. В результате время поиска сокращается в 200 раз, а точность цитирования в 2 раза выше, чем у стандартных решений.

Как AI-поиск по законодательству экономит время юристов?

Правовой поиск — одна из сильнейших применений RAG: корпус законодательства стабилен (нормы меняются, но не исчезают), документы структурированы (статьи, части, пункты), и точность цитирования критически важна. AI не интерпретирует право — он ищет, структурирует и подбирает релевантные нормы для конкретного вопроса.

from anthropic import Anthropic
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from pydantic import BaseModel
from typing import Optional
import json

client = Anthropic()

class LegalDocument(BaseModel):
    doc_id: str
    title: str
    doc_type: str  # "федеральный_закон", "постановление", "определение_вс"
    number: str  # "149-ФЗ", "А40-12345/2023"
    date: str
    content: str
    articles: list[dict] = []  # [{"article": "ст. 10", "text": "..."}]
    tags: list[str] = []

class LegalSearchResult(BaseModel):
    document: LegalDocument
    relevant_excerpt: str
    article_reference: str  # "Статья 10, ч. 2"
    relevance_score: float
    reasoning: str

class LegalSearchEngine:
    def __init__(self, db_path: str = "./legal_db"):
        self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
        self.vectorstore = Chroma(
            collection_name="legal_docs",
            embedding_function=self.embeddings,
            persist_directory=db_path,
        )
        self.splitter = RecursiveCharacterTextSplitter(
            chunk_size=1000,
            chunk_overlap=200,
            separators=["\nСтатья ", "\n\n", "\n", " "],
        )

    def index_document(self, doc: LegalDocument):
        """Индексирует правовой документ"""
        # Разбиваем по статьям для точного цитирования
        chunks = []
        metadatas = []
        for article in doc.articles:
            # Каждая статья = отдельный чанк
            chunk_text = f"{doc.title}\n{article['article']}\n{article['text']}"
            chunks.append(chunk_text)
            metadatas.append({
                "doc_id": doc.doc_id,
                "doc_type": doc.doc_type,
                "title": doc.title,
                "number": doc.number,
                "date": doc.date,
                "article": article["article"],
            })
        if not chunks and doc.content:
            # Если нет разбивки по статьям — делим по тексту
            splits = self.splitter.split_text(doc.content)
            for i, split in enumerate(splits):
                chunks.append(split)
                metadatas.append({
                    "doc_id": doc.doc_id,
                    "doc_type": doc.doc_type,
                    "title": doc.title,
                    "number": doc.number,
                    "date": doc.date,
                    "article": f"часть_{i}",
                })
        self.vectorstore.add_texts(texts=chunks, metadatas=metadatas)

    def search(self, query: str, k: int = 10, filters: dict = None) -> list[dict]:
        """Семантический поиск по правовой базе"""
        where_filter = {}
        if filters:
            if filters.get("doc_type"):
                where_filter["doc_type"] = filters["doc_type"]
            if filters.get("date_from"):
                where_filter["date"] = {"$gte": filters["date_from"]}
        results = self.vectorstore.similarity_search_with_score(
            query,
            k=k,
            filter=where_filter if where_filter else None,
        )
        return [{
            "content": doc.page_content,
            "metadata": doc.metadata,
            "score": score,
        } for doc, score in results]

Почему RAG подходит для юридических документов

RAG (Retrieval-Augmented Generation) решает ключевую проблему LLM — галлюцинации. Вместо того чтобы генерировать ответ из памяти модели, система сначала находит релевантные фрагменты в индексированной базе, а затем передает их модели для анализа. Это даёт точные цитаты и снижает риск выдуманных норм. Например, статья 81 ТК РФ четко определяет прогул — система найдет её даже по описанию ситуации.

Мы используем гибридный поиск: семантический (embeddings) дополняется булевыми фильтрами по типу документа, дате, номеру статьи. Векторная база Chroma или Qdrant хранит эмбеддинги размерностью 1536, а RecursiveCharacterTextSplitter делит документы по границам статей.

Параметр Традиционный keyword search AI-семантический поиск
Понимание смысла Нет, только точное совпадение Да, синонимы и контекст
Обработка синонимов Нет Да (через эмбеддинги)
Точность цитирования Высокая 94% (на наши тестах)
Время поиска по 1000 доков 10-15 минут 2-5 секунд
Масштабируемость Ограничена Горизонтальное масштабирование

Как семантический поиск превосходит традиционный?

Семантический поиск не просто находит точные совпадения — он понимает контекст. Например, запрос «увольнение за прогул» найдёт все статьи ТК РФ об увольнении по инициативе работодателя, даже если формулировка отличается. Это достигается за счёт эмбеддингов, которые представляют текст в виде векторов (1536-мерных). Близкие по смыслу документы оказываются рядом в векторном пространстве. Результат: скорость поиска в 200 раз выше, точность цитирования — 94%.

AI-аналитик правовых запросов

class LegalAnalyst:
    def __init__(self, search_engine: LegalSearchEngine):
        self.search = search_engine

    def analyze_question(self, question: str, jurisdiction: str = "РФ") -> dict:
        """Анализирует правовой вопрос и находит релевантные нормы"""
        # Шаг 1: Определяем правовые концепции в вопросе
        concepts = self._extract_legal_concepts(question)

        # Шаг 2: Ищем релевантные нормы
        all_results = []
        for concept in concepts:
            results = self.search.search(concept, k=5)
            all_results.extend(results)

        # Дедупликация
        seen = set()
        unique_results = []
        for r in all_results:
            key = f"{r['metadata']['doc_id']}_{r['metadata']['article']}"
            if key not in seen:
                seen.add(key)
                unique_results.append(r)

        # Шаг 3: AI анализирует и структурирует ответ
        return self._synthesize_answer(question, unique_results[:10], jurisdiction)

    def _extract_legal_concepts(self, question: str) -> list[str]:
        """Извлекает ключевые правовые концепции для поиска"""
        response = client.messages.create(
            model="claude-haiku-4-5",
            max_tokens=512,
            messages=[{
                "role": "user",
                "content": f"""Извлеки 3-5 ключевых правовых концепций/терминов из вопроса для поиска в правовой базе.
Вопрос: {question}
Верни JSON: {{"concepts": ["концепция 1", "концепция 2", ...]}}
Концепции должны быть юридическими терминами, точными для поиска."""
            }]
        )
        text = response.content[0].text
        data = json.loads(text[text.find("{"):text.rfind("}") + 1])
        return data.get("concepts", [question])

    def _synthesize_answer(self, question: str, results: list[dict], jurisdiction: str) -> dict:
        """Синтезирует ответ из найденных правовых норм"""
        context = "\n\n".join([
            f"[{r['metadata']['title']}, {r['metadata']['article']}]\n{r['content']}"
            for r in results
        ])
        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=4096,
            system=f"""Ты — правовой аналитик по законодательству {jurisdiction}.
КРИТИЧЕСКИ ВАЖНО:
- Цитируй ТОЛЬКО нормы из предоставленных документов
- Всегда указывай источник: закон + статья + часть
- Не интерпретируй расширительно — только то, что написано в законе
- Если норма не найдена — прямо сообщай об этом
- Различай: закон устанавливает / суд практикует / доктрина считает
Структура ответа:
1. Применимые нормы (с цитатами и ссылками)
2. Судебная практика (если есть)
3. Вывод
4. Что не покрыто найденными нормами""",
            messages=[{
                "role": "user",
                "content": f"""Вопрос: {question}
Найденные правовые нормы: {context}
Дай структурированный правовой анализ."""
            }]
        )
        return {
            "question": question,
            "answer": response.content[0].text,
            "sources": [
                {
                    "title": r["metadata"]["title"],
                    "number": r["metadata"]["number"],
                    "article": r["metadata"]["article"],
                    "date": r["metadata"]["date"],
                }
                for r in results[:5]
            ],
        }

Поиск судебной практики

class CaseLawSearchEngine:
    """Специализированный поиск по судебным решениям"""

    def find_precedents(
        self,
        legal_issue: str,
        court_level: str = "all",  # "верховный", "арбитражный", "общей_юрисдикции"
        outcome_filter: str = None,  # "удовлетворено", "отказано"
    ) -> list[dict]:
        """Ищет релевантные судебные прецеденты"""
        response = client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=2048,
            system="""Ты анализируешь судебные решения для поиска прецедентов.
Структурируй информацию: суть спора, правовая позиция суда, ссылки на нормы, исход.
ВАЖНО: Не придумывай реквизиты дел. Работай только с предоставленными документами.""",
            messages=[{
                "role": "user",
                "content": f"""Найди прецеденты по вопросу: {legal_issue}
Параметры поиска:
- Уровень суда: {court_level}
- Исход: {outcome_filter or "любой"}
На основе найденных дел в базе данных покажи:
1. Дела с аналогичным правовым вопросом
2. Правовую позицию суда по каждому делу
3. Тенденции в судебной практике
4. Ключевые аргументы, принятые судом"""
            }]
        )
        return {"analysis": response.content[0].text}

Практический кейс: юридический департамент корпорации

Контекст: юридический отдел производственного холдинга (12 юристов). Основные задачи: проверка контрактов, трудовые споры, налоговые вопросы. Правовая база: ГК РФ, ТК РФ, НК РФ, 200+ ФЗ, практика ВС и ВАС.

Внедрение:

  • Индексирование 1800 документов (законы + ключевые постановления ВС)
  • Интерфейс в корпоративном Confluence
  • Автоответчик на типовые юридические вопросы по HR и контрактам

Метрики:

  • Время поиска применимых норм: 45 мин → 8 мин (первичный поиск)
  • Точность ссылок на нормы: 94% (6% требовали ручной проверки)
  • Типовые вопросы (командировки, больничные, НДС): 70% решаются без участия юриста
  • Экономия времени юристов: ~40%

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

Окупаемость инвестиций в среднем за 4-6 месяцев, а снижение операционных расходов на юридические исследования достигает 30%. Наша команда имеет более 10 лет опыта в AI и MLOps, выполнила более 50 проектов по внедрению интеллектуальных систем поиска.

Свяжитесь с нами для расчета стоимости проекта под ваши задачи.

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

Что входит в работу

Наша команда предоставляет:

  • Аудит и подготовку правовых документов (очистка, структуризация)
  • Индексирование и построение векторной базы
  • Настройку AI-аналитика под предметную область (включая fine-tuning юридических моделей)
  • Разработку интерфейса (веб, интеграция с Confluence/SharePoint)
  • Обучение пользователей и документацию
  • Техническую поддержку после внедрения

Процесс работы

  1. Аналитика: изучаем вашу базу документов, выделяем типовые запросы, определяем метрики точности.
  2. Проектирование: выбираем стек (Chroma/Qdrant, LLM, embedding-модель), проектируем схему метаданных.
  3. Индексирование: загружаем документы, настраиваем разбивку по статьям, создаём эмбеддинги.
  4. Настройка AI: калибруем промпты, few-shot примеры, тестируем на реальных вопросах.
  5. Интеграция: встраиваем систему в ваш рабочий процесс (Confluence, Telegram, веб-интерфейс).
  6. Тестирование: замеряем точность, время ответа, покрытие.
  7. Деплой: развёртывание на вашей инфраструктуре или в облаке.

Сроки ориентировочно

Этап Длительность
Индексирование правовой базы + базовый поиск 1 неделя
AI-аналитик с синтезом ответа 1 неделя
Поиск судебной практики 1–2 недели
Корпоративный интерфейс + права доступа 1–2 недели

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

Направления AI-разработки

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1543
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1374
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    816
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142