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

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-агента для юридического анализа документов
Сложная
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

AI-агент для анализа юридических документов

Юрист тратит 60–70% времени на анализ документов: чтение договоров, выявление рисковых условий, проверку соответствия шаблонам, сравнение версий. AI-агент не заменяет юридическую экспертизу, но делает черновую аналитическую работу за минуты вместо часов: находит отклонения от стандарта, выявляет отсутствующие обязательные условия и формирует структурированный отчёт с конкретными ссылками на пункты.

Архитектура юридического агента

from langchain_openai import ChatOpenAI
from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader
from langchain_core.tools import tool
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator
import json

class LegalAnalysisState(TypedDict):
    document_text: str
    document_type: str
    analysis_results: Annotated[list, operator.add]
    risk_flags: Annotated[list, operator.add]
    missing_clauses: list[str]
    final_report: str

@tool
def check_mandatory_clauses(document_text: str, doc_type: str) -> str:
    """Проверяет наличие обязательных условий для типа договора"""
    mandatory_map = {
        "договор_поставки": [
            "предмет договора", "цена товара", "порядок оплаты",
            "срок поставки", "качество товара", "ответственность сторон",
            "порядок разрешения споров", "срок действия договора"
        ],
        "трудовой_договор": [
            "место работы", "трудовая функция", "дата начала работы",
            "условия оплаты труда", "режим рабочего времени",
            "гарантии и компенсации", "условия труда на рабочем месте"
        ],
        "аренда": [
            "объект аренды", "арендная плата", "срок аренды",
            "права и обязанности арендатора", "права и обязанности арендодателя",
            "порядок возврата имущества"
        ]
    }

    required = mandatory_map.get(doc_type, [])
    text_lower = document_text.lower()

    missing = []
    present = []
    for clause in required:
        # Fuzzy matching — не точное совпадение слов
        if any(word in text_lower for word in clause.split()):
            present.append(clause)
        else:
            missing.append(clause)

    return json.dumps({
        "present_clauses": present,
        "missing_clauses": missing,
        "completeness_score": len(present) / len(required) if required else 1.0
    })

@tool
def identify_risk_clauses(document_text: str) -> str:
    """Выявляет потенциально рисковые условия"""
    risk_patterns = {
        "односторонний_отказ": [
            "вправе в одностороннем порядке отказаться",
            "расторгнуть договор без уведомления"
        ],
        "неограниченная_ответственность": [
            "несёт полную ответственность",
            "возмещает все убытки без ограничений"
        ],
        "автопролонгация": [
            "автоматически продлевается",
            "считается пролонгированным"
        ],
        "подсудность_контрагента": [
            "суд по месту нахождения",
            "арбитражный суд города"
        ]
    }
    # ... анализ паттернов
    return json.dumps({"risks_found": []})

Сравнение с шаблонным договором

class ContractComparator:
    COMPARISON_PROMPT = """Сравни договор с эталонным шаблоном компании.

Шаблонный договор:
{template}

Полученный договор от контрагента:
{received}

Выяви:
1. **Отклонения в пользу контрагента** (они получили лучшие условия)
2. **Отклонения против нашей компании** (мы несём повышенные риски)
3. **Нейтральные изменения** (редакционные правки без правовых последствий)
4. **Отсутствующие условия** (есть в шаблоне, нет в полученном)

Для каждого отклонения:
- Пункт шаблона vs пункт договора (цитата)
- Правовые последствия изменения
- Рекомендация: принять / настоять на шаблоне / допустимый компромисс

Формат: Markdown таблица + комментарии."""

    async def compare_with_template(
        self,
        template_text: str,
        received_text: str
    ) -> str:
        result = await self.llm.ainvoke(
            self.COMPARISON_PROMPT.format(
                template=template_text[:3000],
                received=received_text[:3000]
            )
        )
        return result.content

Граф анализа (LangGraph)

def build_legal_agent_graph():
    llm = ChatOpenAI(model="gpt-4o", temperature=0)

    tools = [
        check_mandatory_clauses,
        identify_risk_clauses,
    ]

    def analyze_node(state: LegalAnalysisState) -> LegalAnalysisState:
        # Шаг 1: определение типа документа
        doc_type_result = llm.invoke(
            f"Определи тип документа (1-2 слова): {state['document_text'][:500]}"
        )
        state["document_type"] = doc_type_result.content.strip()

        # Шаг 2: проверка обязательных условий
        mandatory_check = check_mandatory_clauses.invoke({
            "document_text": state["document_text"],
            "doc_type": state["document_type"]
        })
        state["analysis_results"].append(json.loads(mandatory_check))

        # Шаг 3: выявление рисков
        risk_check = identify_risk_clauses.invoke({
            "document_text": state["document_text"]
        })
        risks = json.loads(risk_check)
        state["risk_flags"].extend(risks.get("risks_found", []))

        return state

    def generate_report_node(state: LegalAnalysisState) -> LegalAnalysisState:
        prompt = f"""Создай структурированный отчёт по анализу документа для юриста.

Тип документа: {state['document_type']}
Результаты проверки условий: {json.dumps(state['analysis_results'], ensure_ascii=False)}
Выявленные риски: {json.dumps(state['risk_flags'], ensure_ascii=False)}

Структура отчёта:
## Общая оценка
## Критические риски (требуют немедленного внимания)
## Отсутствующие обязательные условия
## Рекомендации по доработке
## Итог: рекомендовать к подписанию / требует доработки / отказать"""

        state["final_report"] = llm.invoke(prompt).content
        return state

    graph = StateGraph(LegalAnalysisState)
    graph.add_node("analyze", analyze_node)
    graph.add_node("report", generate_report_node)
    graph.add_edge("analyze", "report")
    graph.add_edge("report", END)
    graph.set_entry_point("analyze")

    return graph.compile()

Интеграция с правовыми базами

class LegalDatabaseIntegration:
    async def check_counterparty(self, inn: str) -> dict:
        """Проверяет контрагента в ЕГРЮЛ и базах рисков"""
        egrul_data = await self.egrul_client.get_company(inn)
        risk_score = await self.risk_service.evaluate(inn)

        return {
            "company_name": egrul_data.get("name"),
            "status": egrul_data.get("status"),  # действующее / ликвидировано
            "registration_date": egrul_data.get("ogrn_date"),
            "risk_score": risk_score,              # 0-100, выше = рискованнее
            "bankruptcy_flag": egrul_data.get("bankruptcy", False),
            "tax_debt_flag": risk_score > 60
        }

Кейс: юридический департамент холдинга, 200 договоров в месяц от контрагентов. До внедрения: каждый договор прочитывался юристом полностью (~45 мин на договор). После: AI-агент за 90 секунд создаёт отчёт с выявленными отклонениями, юрист читает отчёт и проверяет только флаги (~10 мин). Продуктивность: 200 договоров в месяц → 380 договоров при той же команде. Выявляемость критических рисков: +23% (AI видит паттерны, которые человек пропускает при усталости).

Сроки: базовый агент с проверкой условий: 3–4 недели; сравнение с шаблоном и интеграция с ЕГРЮЛ: 6–8 недель.