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

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1Все 1564 услуг
Разработка AI-системы семантического поиска по законодательству
Средний
~1-2 недели
Часто задаваемые вопросы

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

Этапы разработки AI-решения

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

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1361
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    957
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1189
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    646
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    929

Юристы тратят часы на поиск подходящих норм и судебной практики. Стандартный поиск по ключевым словам часто пропускает релевантные документы, если формулировки не совпадают. Мы создали 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 дня. Свяжитесь с нами, чтобы обсудить детали.

Практический разбор LLM: fine-tuning, RAG, агенты, деплой

Модель GPT‑4 или Claude 3.5 Sonnet через публичное API — не решение, а просто инструмент. Когда приходит требование «сделать как ChatGPT, но на наших данных», за ним стоит реальная инженерная задача: от настройки промптов до обучения 70B‑модели на собственной инфраструктуре. Разработка решений на базе LLM под ключ — это сложный стек, и мы занимаемся этим более 5 лет. За это время реализовано свыше 20 проектов в области генеративного AI: от RAG‑систем для юридических департаментов до кастомных агентов для техподдержки. Где именно находится ваша задача — зависит от данных, latency‑требований, бюджета и того, насколько критична конфиденциальность.

Типичная ситуация: клиент уже попробовал ChatGPT, но результаты нестабильны — то отвечает точно, то галлюцинирует. Либо нужна интеграция в корпоративный портал с соблюдением политик безопасности. Разберём каждый слой стека в деталях — от RAG до production‑деплоя.

Почему RAG‑системы ломаются и как это исправить?

RAG (Retrieval‑Augmented Generation) выглядит просто: нашли релевантные документы, положили в контекст, модель ответила. На практике сбоит в нескольких местах.

Chunking без перекрытия. Классическая ошибка: chunk_size=512, overlap=0. Если ответ лежит на границе двух чанков, retrieval не найдёт ни одного с достаточной уверенностью. Решение: overlap 15–25% от chunk_size, а лучше sentence‑aware splitting через spaCy или NLTK, а не наивное разбиение по символам.

Плохой embedder. Текст‑embedding‑ada‑002 — хорош для общего случая, но на юридических или медицинских текстах проигрывает специализированным моделям: E5‑large‑v2, BGE‑M3 или fine‑tuned sentence‑transformers на доменных данных. Разница в Recall@5 может составлять 15–25%.

Отсутствие re‑ranking. Векторный поиск оптимизирован по скорости, не по релевантности. Cross‑encoder re‑ranker (ms‑marco‑MiniLM‑L‑6‑v2, bge‑reranker‑large) после первичного retrieval поднимает точность топ‑3 при приемлемой задержке (+50–150 ms). Это часто важнее улучшения embedding‑модели.

Гибридный поиск. Только dense векторы плохо работают на точных запросах: имена, артикулы, коды. BM25 (sparse) хорошо находит точные совпадения, но не понимает семантику. Гибрид через RRF (Reciprocal Rank Fusion) — оптимальный компромисс. Qdrant, Weaviate и pgvector 0.7+ поддерживают гибридный поиск нативно.

Типичная production‑архитектура корпоративного knowledge base
  1. Документы → preprocessing (PyMuPDF, Unstructured)
  2. Chunking → embedding (BGE‑M3)
  3. Qdrant (гибридный dense+sparse)
  4. Cross‑encoder re‑ranking
  5. Контекст → LLM (vLLM или OpenAI API)
  6. Ответ с источниками (RAGAS для оценки качества)

Когда стоит fine‑tune, а не промпт‑инжиниринг?

Промпт‑инжиниринг решает ~70% задач адаптации LLM под домен. Оставшиеся 30% требуют дообучения. Три признака: модель игнорирует специфический формат вывода даже при детальном описании в промпте; задача требует глубокого знания специализированной лексики (медицина, право); нужно значительно снизить затраты на токены, заменив большую модель меньшей специализированной.

LoRA и QLoRA — стандарт для SFT. LoRA добавляет trainable low‑rank матрицы к attention‑слоям. Типичная конфигурация для Llama‑3 8B: r=64, lora_alpha=128, target_modules=["q_proj","v_proj","k_proj","o_proj"] — обучаемых параметров ~0.8%, обучение на одной A100 40GB. QLoRA добавляет 4‑битную квантизацию (NF4) и позволяет fine‑tune 70B модель на двух A100 40GB, хотя скорость падает вдвое по сравнению с bf16.

DPO вместо RLHF. Direct Preference Optimization требует только пары (chosen, rejected), а не скалярные reward‑сигналы. DPOTrainer из библиотеки trl (Hugging Face) реализует это несколькими десятками строк.

Типичная ошибка. Датасет из 500 примеров, 5 эпох, validation loss 0.8 — кажется норм. Но на тесте модель деградировала на общих инструкциях. Причина: catastrophic forgetting. Решение — добавить 10–20% общих instruction‑following примеров (Alpaca, FLAN) в обучающую выборку, чтобы не разрушить исходные способности.

Как выбрать базовую модель: 8B или 70B?

Модель Параметры Сильные стороны Контекст
Llama‑3.1 8B 8B Баланс качество/скорость 128k
Llama‑3.1 70B 70B Сложные рассуждения 128k
Mistral 7B / Mixtral 8x7B 7B / 47B Эффективность на размер 32k
Qwen2.5 72B 72B Код, мультиязычность 128k
Gemma 2 27B 27B Открытая лицензия 8k

Для большинства задач fine‑tuning 8B модели достаточно. 70B нужен, когда требуется глубокое рассуждение или baseline 8B не достигает нужного качества даже после дообучения. Стоимость инференса Llama‑3 8B через vLLM на A100 — около $0.001/1K токенов, что в 15 раз дешевле GPT‑4.

Что даёт PagedAttention в production?

vLLM — первый выбор для serving open‑source моделей. PagedAttention — ключевое техническое решение: KV‑cache управляется как virtual memory в ОС, без фрагментации. Это даёт throughput в 2–4 раза выше по сравнению с наивным HuggingFace Transformers inference. Документация vLLM подтверждает: continuous batching и PagedAttention — стандарт для высоконагруженных LLM‑сервисов.

Типичные числа на A100 80GB для Llama‑3 8B (bf16): 400–600 req/s, P50 latency 200–400ms, P99 latency 600–900ms при concurrency 64. Для 70B на двух A100 с tensor parallelism: 80–120 req/s, P99 latency 1.5–2.5s. Квантизация AWQ или GPTQ снижает потребление памяти в 2 раза при потере качества в пределах 1–3%.

Мультиагентные системы

Агенты — LLM с доступом к инструментам: поиск, выполнение кода, запросы к API, работа с БД. Основные паттерны:

  • ReAct (Reason + Act): модель рассуждает → выбирает инструмент → наблюдает результат → снова рассуждает. LangChain и LlamaIndex реализуют из коробки.
  • Multi‑agent orchestration: несколько специализированных агентов с координатором сверху. Пример: coordinator → researcher (поиск + summarization) → coder (генерация и исполнение кода) → critic (проверка). Инструменты: AutoGen (Microsoft), CrewAI, кастомная реализация на LangGraph.

В продакшене агентные системы недетерминированы. Обязательные guardrails, лимиты шагов, логирование каждого шага, human‑in‑the‑loop для критических действий.

Как мы работаем: этапы, сроки, результат

Этап Длительность Что получаете
Аудит и сбор данных 1–2 нед. Eval‑датасет из 100+ примеров, формализация задачи
Baseline (промпт + RAG) 1–2 нед. Рабочий прототип, метрики качества
Fine‑tuning (если нужно) 2–4 нед. Обученная модель, LoRA‑веса, model card
Деплой и мониторинг 1–2 нед. vLLM сервер, Grafana + Prometheus
Документация и обучение 1 нед. API‑документация, обучение команды

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

Мы передаём:

  • Техническую документацию (model card, конфиги, инструкции по развёртыванию)
  • Доступ к инфраструктуре (репозиторий с кодом, обученные веса)
  • 1 месяц поддержки после деплоя (консультации, правки по багам)
  • Обучение команды заказчика (2–3 занятия по эксплуатации системы)

Сроки: базовый RAG‑прототип — 1–2 недели. Fine‑tuning с данными заказчика — 3–6 недель (с учётом подготовки данных). Production‑система с мониторингом и переобучением — 2–4 месяца. Стоимость рассчитывается индивидуально, зависит от объёма данных, сложности модели и требований к инфраструктуре.

Хотите оценить свой проект? Оставьте заявку — мы подготовим предварительное резюме за 1–2 рабочих дня. Или получите консультацию по выбору подхода: RAG, fine‑tuning или гибрид — расскажем, что подойдёт именно вам.