Юристи витрачають години на пошук відповідних норм і судової практики. Стандартний пошук за ключовими словами часто пропускає релевантні документи, якщо формулювання не збігаються. Ми створили 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)
- Навчання користувачів і документацію
- Технічну підтримку після впровадження
Процес роботи
- Аналітика: вивчаємо вашу базу документів, виділяємо типові запити, визначаємо метрики точності.
- Проектування: обираємо стек (Chroma/Qdrant, LLM, embedding-модель), проектуємо схему метаданих.
- Індексування: завантажуємо документи, налаштовуємо розбивку за статтями, створюємо ембеддинги.
- Налаштування AI: калібруємо промпти, few-shot приклади, тестуємо на реальних питаннях.
- Інтеграція: вбудовуємо систему у ваш робочий процес (Confluence, Telegram, веб-інтерфейс).
- Тестування: заміряємо точність, час відповіді, покриття.
- Деплой: розгортання на вашій інфраструктурі або в хмарі.
Терміни орієнтовно
| Етап | Тривалість |
|---|---|
| Індексування правової бази + базовий пошук | 1 тиждень |
| AI-аналітик із синтезом відповіді | 1 тиждень |
| Пошук судової практики | 1–2 тижні |
| Корпоративний інтерфейс + права доступу | 1–2 тижні |
Гарантуємо точність цитування та конфіденційність даних. Отримайте консультацію — оцінимо ваш проєкт за 2 дні. Зв'яжіться з нами, щоб обговорити деталі.







