Розробка 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,
        }

Генерування проводок

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]:
        """Генерує записи в журналі"""

        # 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:
        """Завантажує записи через API"""
        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:
                # Масштабування до CFO
                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
  • Автоматична верифікація постачальника
  • Відповідність контрактам
  • Генерування проводок (завантаження XML)
  • Щотижневий звіт AR

Результати:

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

Примітка щодо відповідності: потрібна інтеграція з реєстром постачальників, системами податкової верифікації та дотримання стандартів фінансових документів.

Часова шкала

  • OCR + вилучення документів: 2–3 тижні
  • Логіка верифікації та довідники: 1–2 тижні
  • Генератор записів + класифікатор видатків: 2 тижні
  • Інтеграція системи: 2–3 тижні
  • Моніторинг AR та комунікації: 1–2 тижні
  • Разом: 8–12 тижнів