Розробка AI-системи пошуку по законодавству та судовій практиці

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Розробка AI-системи пошуку по законодавству та судовій практиці
Середній
~1-2 тижні
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

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]

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%

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

Терміни

  • Індексування правової бази + базовий пошук: 1 тиждень
  • AI-аналітик з синтезом відповіді: 1 тиждень
  • Пошук судової практики: 1–2 тижні
  • Корпоративний інтерфейс + права доступу: 1–2 тижні