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

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

Напрямки 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-агент для аналізу юридичних документів

Юристи витрачають 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 = {
        "contract_supply": [
            "предмет договору", "ціна товару", "порядок оплати",
            "час поставки", "якість товару", "відповідальність сторін",
            "порядок вирішення спорів", "час дії договору"
        ],
        "employment_contract": [
            "місце роботи", "трудова функція", "дата початку роботи",
            "умови оплати праці", "режим робочого часу",
            "гарантії та компенсації", "умови праці на робочому місці"
        ],
        "lease": [
            "об'єкт оренди", "орендна плата", "час оренди",
            "права та обов'язки орендатора", "права та обов'язки орендодавця",
            "порядок повернення майна"
        ]
    }

    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 тижнів.