Разработка AI-цифрового бухгалтера (AI Accountant)

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1Все 1566 услуг
Разработка AI-цифрового бухгалтера (AI Accountant)
Сложный
от 2 недель до 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 Бухгалтер — цифровой сотрудник для финансового учёта

AI Бухгалтер автоматизирует рутинные учётные операции: обработку первичных документов (счёт-фактуры, акты, накладные), сверку данных, подготовку проводок, формирование отчётных форм, мониторинг дебиторской задолженности. Не заменяет главного бухгалтера, но снимает с него до 60–70% операционной нагрузки.

Обработка первичных документов

import anthropic
import base64
from pathlib import Path
from pydantic import BaseModel
from typing import Optional, Literal

client = anthropic.Anthropic()

class InvoiceData(BaseModel):
    document_type: Literal["invoice", "act", "waybill", "upd"]  # УПД
    vendor_name: str
    vendor_inn: Optional[str]
    vendor_kpp: Optional[str]
    document_number: str
    document_date: str
    amount_without_vat: float
    vat_rate: Optional[float]        # 20, 10, 0, None (без НДС)
    vat_amount: Optional[float]
    total_amount: float
    items: list[dict]                 # Строки документа
    payment_purpose: Optional[str]   # Назначение платежа
    contract_reference: Optional[str]

def extract_document_data(file_path: str) -> InvoiceData:
    """Извлечение данных из скана/PDF документа через Claude Vision"""

    with open(file_path, "rb") as f:
        file_content = base64.standard_b64encode(f.read()).decode("utf-8")

    ext = Path(file_path).suffix.lower()
    media_type = "application/pdf" if ext == ".pdf" else "image/jpeg"

    response = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=2000,
        messages=[{
            "role": "user",
            "content": [
                {
                    "type": "document" if ext == ".pdf" else "image",
                    "source": {
                        "type": "base64",
                        "media_type": media_type,
                        "data": file_content,
                    },
                },
                {
                    "type": "text",
                    "text": """Извлеки все реквизиты финансового документа.
Для российских документов: ИНН, КПП, номер документа, дату, суммы с НДС и без.
Верни JSON согласно схеме InvoiceData. Если поле отсутствует — null.""",
                },
            ],
        }],
    )

    return InvoiceData.model_validate_json(response.content[0].text)

Верификация и сопоставление с договорами

class DocumentVerifier:

    async def verify_invoice(
        self,
        invoice: InvoiceData,
        contract_id: str,
    ) -> dict:
        """Проверяет счёт против договора и справочников"""

        # Параллельная проверка
        contract_task = contracts_db.get(contract_id)
        vendor_task = vendor_db.get_by_inn(invoice.vendor_inn)
        previous_invoices_task = invoices_db.get_for_contract(contract_id)

        contract, vendor, previous = await asyncio.gather(
            contract_task, vendor_task, previous_invoices_task
        )

        issues = []

        # Проверка ИНН поставщика
        if vendor and vendor.inn != invoice.vendor_inn:
            issues.append(f"ИНН поставщика не совпадает: документ={invoice.vendor_inn}, справочник={vendor.inn}")

        # Проверка суммы против договора
        total_paid = sum(p.amount for p in previous if p.status == "approved")
        if total_paid + invoice.total_amount > contract.max_amount * 1.05:  # 5% допуск
            issues.append(f"Превышение суммы договора: оплачено {total_paid}, новый счёт {invoice.total_amount}, лимит {contract.max_amount}")

        # Проверка НДС
        if invoice.vat_amount and invoice.vat_rate:
            expected_vat = invoice.amount_without_vat * invoice.vat_rate / 100
            if abs(expected_vat - invoice.vat_amount) > 1:  # Допуск 1 руб
                issues.append(f"Ошибка расчёта НДС: ожидается {expected_vat:.2f}, в документе {invoice.vat_amount:.2f}")

        # Дубликат?
        duplicate = next(
            (p for p in previous if p.document_number == invoice.document_number and p.vendor_inn == invoice.vendor_inn),
            None,
        )
        if duplicate:
            issues.append(f"Дубликат документа: номер {invoice.document_number} уже обработан {duplicate.processed_date}")

        return {
            "valid": len(issues) == 0,
            "issues": issues,
            "requires_manual_review": len(issues) > 0,
            "vendor_verified": vendor is not None,
        }

Формирование проводок (1С-интеграция)

class AccountingEntryGenerator:

    ACCOUNT_MAPPING = {
        "materials": {"debit": "10.01", "credit": "60.01"},
        "services": {"debit": "26",     "credit": "60.01"},
        "goods": {"debit": "41.01",     "credit": "60.01"},
        "vat_input": {"debit": "19.03", "credit": "60.01"},
    }

    async def generate_entries(
        self,
        invoice: InvoiceData,
        cost_center: str,
    ) -> list[dict]:
        """Генерирует проводки для 1С"""

        # LLM классифицирует тип расхода
        classification = await client.messages.create(
            model="claude-opus-4-5",
            max_tokens=200,
            messages=[{
                "role": "user",
                "content": f"""Классифицируй расход для бухгалтерских проводок.
Поставщик: {invoice.vendor_name}
Наименования в документе: {[item['name'] for item in invoice.items[:5]]}

Верни JSON: {{"expense_type": "materials|services|goods|fixed_assets", "account": "26|44|10|08", "vat_deductible": true|false}}"""
            }],
        )

        classification_data = json.loads(classification.content[0].text)
        entries = []

        # Основная проводка
        account_map = self.ACCOUNT_MAPPING.get(classification_data["expense_type"], self.ACCOUNT_MAPPING["services"])
        entries.append({
            "debit": account_map["debit"],
            "credit": account_map["credit"],
            "amount": invoice.amount_without_vat,
            "description": f"{invoice.vendor_name} / {invoice.document_number} от {invoice.document_date}",
            "cost_center": cost_center,
            "analytic": invoice.vendor_inn,
        })

        # НДС
        if invoice.vat_amount and classification_data.get("vat_deductible"):
            entries.append({
                "debit": "19.03",
                "credit": "60.01",
                "amount": invoice.vat_amount,
                "description": f"НДС / {invoice.vendor_name} / {invoice.document_number}",
                "cost_center": cost_center,
            })

        return entries

    async def post_to_1c(self, entries: list[dict]) -> str:
        """Загружает проводки в 1С через COM-объект или API"""
        # Формируем XML для 1С
        xml_data = self.format_1c_xml(entries)
        result = await onec_api.post_document(xml_data)
        return result["document_id"]

Мониторинг дебиторской задолженности

class ReceivablesMonitor:

    async def daily_ar_check(self) -> dict:
        """Ежедневная проверка просроченной дебиторки"""

        overdue_invoices = await invoices_db.get_overdue()

        report = {
            "total_overdue": sum(i.amount for i in overdue_invoices),
            "by_aging_bucket": self.group_by_aging(overdue_invoices),
            "actions_taken": [],
        }

        for invoice in overdue_invoices:
            days_overdue = invoice.days_overdue

            if days_overdue <= 7:
                # Дружественное напоминание
                await self.send_reminder(invoice, tone="friendly")
                report["actions_taken"].append(f"Напоминание: {invoice.customer_name}")

            elif days_overdue <= 30:
                # Официальное требование
                await self.send_reminder(invoice, tone="formal")
                await crm.create_task(customer_id=invoice.customer_id, title="AR Follow-up")
                report["actions_taken"].append(f"Официальное требование: {invoice.customer_name}")

            elif days_overdue > 30:
                # Эскалация финансовому директору
                await self.escalate_to_cfo(invoice)
                report["actions_taken"].append(f"ЭСКАЛАЦИЯ: {invoice.customer_name}, {days_overdue} дней")

        return report

    async def generate_ar_reminder(self, invoice: dict, tone: str) -> str:
        response = await openai_client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[{
                "role": "system",
                "content": f"Напиши напоминание об оплате. Тон: {tone}. Официальный деловой стиль. 2-3 абзаца."
            }, {
                "role": "user",
                "content": f"Счёт №{invoice['number']} от {invoice['date']} на {invoice['amount']:,.0f} руб, просрочка {invoice['days_overdue']} дней, клиент: {invoice['customer_name']}"
            }],
        )
        return response.choices[0].message.content

Практический кейс: производственная компания, 300 документов/день

Ситуация: 4 бухгалтера обрабатывали 300 документов в день (счёт-фактуры, акты, накладные). 40% времени — ручной ввод данных и сверки.

AI Бухгалтер обрабатывал:

  • Сканы и PDF через OCR + Claude Vision
  • Автоматическая верификация ИНН через ФНС API
  • Сопоставление с договорами
  • Формирование проводок в 1С (загрузка XML)
  • Еженедельный AR-отчёт

Результаты:

  • Документов обработано без участия бухгалтера: 68%
  • Ошибки ввода данных: -94%
  • Среднее время обработки 1 документа: 12 мин → 40 сек
  • Бухгалтеры фокусируются на: сложных документах, налоговых вопросах, аудит

Требования для России: необходима интеграция с ФНС API (проверка ИНН/КПП), системой ЕГРЮЛ, соблюдение требований 402-ФЗ об ответственности за первичные документы.

Сроки

  • OCR + извлечение данных документов: 2–3 недели
  • Верификационная логика и справочники: 1–2 недели
  • Генератор проводок + классификатор расходов: 2 недели
  • Интеграция с 1С: 2–3 недели
  • AR мониторинг и коммуникации: 1–2 недели
  • Итого: 8–12 недель