Разработка AI-ассистента для ERP аналитика прогнозы рекомендации

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-ассистента для ERP аналитика прогнозы рекомендации
Сложная
~2-4 недели
Часто задаваемые вопросы
Направления 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-ассистента для ERP: аналитика, прогнозы, рекомендации

ERP-системы содержат огромный массив данных о бизнесе, но работа с ними требует SQL-знаний или специальных навыков BI-инструментов. AI-ассистент для ERP позволяет руководителям получать аналитику на естественном языке: "Какой отдел превысил бюджет в этом квартале?" или "Когда закончатся запасы компонента А при текущем потреблении?"

Архитектура ERP-ассистента

from anthropic import Anthropic
import psycopg2
import json
from typing import Any
from pydantic import BaseModel

client = Anthropic()

class ERPQueryResult(BaseModel):
    sql: str
    data: list[dict]
    interpretation: str
    recommendations: list[str]
    alerts: list[str]

class ERPAssistant:

    def __init__(self, db_connection_string: str, erp_schema: dict):
        self.conn = psycopg2.connect(db_connection_string)
        self.schema = erp_schema  # Описание таблиц и связей ERP

        self.tools = [
            {
                "name": "execute_query",
                "description": "Выполнить SQL запрос к ERP базе данных",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "sql": {"type": "string", "description": "SELECT запрос"},
                        "description": {"type": "string", "description": "Что запрос делает"}
                    },
                    "required": ["sql"]
                }
            },
            {
                "name": "get_kpi_metrics",
                "description": "Получить предрасчитанные KPI метрики",
                "input_schema": {
                    "type": "object",
                    "properties": {
                        "metric_type": {
                            "type": "string",
                            "enum": ["revenue", "inventory", "expenses", "headcount", "orders"]
                        },
                        "period": {"type": "string", "description": "Период: week/month/quarter/year"}
                    },
                    "required": ["metric_type", "period"]
                }
            },
        ]

    def execute_query(self, sql: str) -> list[dict]:
        """Безопасное выполнение только SELECT запросов"""
        if not sql.strip().upper().startswith("SELECT"):
            raise ValueError("Только SELECT запросы разрешены")

        with self.conn.cursor() as cur:
            cur.execute(sql)
            columns = [d[0] for d in cur.description]
            rows = cur.fetchall()
            return [dict(zip(columns, row)) for row in rows[:100]]

    def get_kpi_metrics(self, metric_type: str, period: str) -> dict:
        """Возвращает предрасчитанные метрики"""
        # В реальной системе — запросы к таблицам ERP
        # Здесь упрощённый пример
        period_sql = {
            "week": "AND date >= CURRENT_DATE - INTERVAL '7 days'",
            "month": "AND date >= DATE_TRUNC('month', CURRENT_DATE)",
            "quarter": "AND date >= DATE_TRUNC('quarter', CURRENT_DATE)",
            "year": "AND date >= DATE_TRUNC('year', CURRENT_DATE)",
        }
        date_filter = period_sql.get(period, period_sql["month"])

        if metric_type == "revenue":
            sql = f"SELECT SUM(amount) as total, COUNT(*) as orders FROM sales WHERE 1=1 {date_filter}"
            return self.execute_query(sql)[0] if self.execute_query(sql) else {}
        # ... остальные метрики
        return {}

    def dispatch_tool(self, tool_name: str, tool_input: dict) -> Any:
        if tool_name == "execute_query":
            return self.execute_query(tool_input["sql"])
        elif tool_name == "get_kpi_metrics":
            return self.get_kpi_metrics(tool_input["metric_type"], tool_input["period"])
        raise ValueError(f"Unknown tool: {tool_name}")

    def answer(self, question: str, user_role: str = "manager") -> ERPQueryResult:
        """Отвечает на аналитический вопрос"""

        messages = [{
            "role": "user",
            "content": f"""Вопрос: {question}
Роль пользователя: {user_role}

Схема ERP базы:
{json.dumps(self.schema, ensure_ascii=False, indent=2)[:2000]}

Используй инструменты для получения данных, затем:
1. Проинтерпретируй результаты
2. Дай рекомендации если применимо
3. Укажи алерты если данные требуют внимания"""
        }]

        sql_queries = []
        all_data = []

        while True:
            response = client.messages.create(
                model="claude-sonnet-4-5",
                max_tokens=4096,
                system=f"""Ты — бизнес-аналитик по ERP системе компании.
Анализируй данные точно, приводи конкретные цифры.
Давай практические рекомендации руководству.""",
                tools=self.tools,
                messages=messages,
            )

            if response.stop_reason == "end_turn":
                final_text = next(
                    (b.text for b in response.content if hasattr(b, "text")), ""
                )
                return ERPQueryResult(
                    sql="; ".join(sql_queries),
                    data=all_data[:10],
                    interpretation=final_text,
                    recommendations=self._extract_list(final_text, "Рекомендации"),
                    alerts=self._extract_list(final_text, "Алерты"),
                )

            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    result = self.dispatch_tool(block.name, block.input)
                    if isinstance(result, list):
                        all_data.extend(result)
                    if block.name == "execute_query":
                        sql_queries.append(block.input.get("sql", ""))

                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": json.dumps(result, ensure_ascii=False, default=str),
                    })

            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})

    def _extract_list(self, text: str, section: str) -> list[str]:
        """Извлекает пункты из секции текста"""
        import re
        if section not in text:
            return []
        section_text = text.split(section)[1].split("\n\n")[0]
        return [
            line.strip("- •*").strip()
            for line in section_text.splitlines()
            if line.strip() and line.strip().startswith(("-", "•", "*", "1", "2"))
        ]

Интеграция с 1С через API

import requests

class OneCIntegration:
    """Интеграция с 1С:Предприятие через HTTP-сервис"""

    def __init__(self, base_url: str, username: str, password: str):
        self.base_url = base_url
        self.auth = (username, password)

    def get_sales_report(self, date_from: str, date_to: str) -> list[dict]:
        """Получает отчёт по продажам из 1С"""
        response = requests.get(
            f"{self.base_url}/hs/api/v1/sales",
            auth=self.auth,
            params={"dateFrom": date_from, "dateTo": date_to}
        )
        return response.json()

    def get_inventory_status(self) -> list[dict]:
        """Получает остатки товаров"""
        response = requests.get(
            f"{self.base_url}/hs/api/v1/inventory",
            auth=self.auth,
        )
        return response.json()

    def get_budget_execution(self, period: str) -> dict:
        """Получает исполнение бюджета"""
        response = requests.get(
            f"{self.base_url}/hs/api/v1/budget/{period}",
            auth=self.auth,
        )
        return response.json()

Автоматические отчёты и алерты

import asyncio
from datetime import datetime

class ERPAlertSystem:
    """Автоматически обнаруживает аномалии и отправляет алерты"""

    def __init__(self, assistant: ERPAssistant):
        self.assistant = assistant

    async def daily_health_check(self) -> list[str]:
        """Ежедневный аудит ключевых метрик"""
        checks = [
            "Есть ли товары с критически низким запасом (менее недели)?",
            "Превышены ли бюджеты каких-либо отделов в этом месяце?",
            "Есть ли просроченная дебиторская задолженность более 30 дней?",
            "Какие показатели значительно отличаются от прошлого месяца?",
        ]

        alerts = []
        for check in checks:
            result = self.assistant.answer(check)
            if result.alerts:
                alerts.extend(result.alerts)

        return alerts

    def generate_executive_report(self, period: str = "month") -> str:
        """Генерирует исполнительный отчёт для руководства"""
        result = self.assistant.answer(
            f"Подготовь исполнительный отчёт за {period}: ключевые метрики, тренды, риски, рекомендации",
            user_role="ceo"
        )
        return result.interpretation

Практический кейс: производственная компания

Контекст: ERP 1С:ERP, 15 пользователей-руководителей, аналитик-BI на полставки.

Типичные запросы:

  • "Когда закончатся материалы для производства X при текущем темпе?"
  • "Какой цех превышает плановые расходы?"
  • "Топ-5 клиентов по выручке за квартал с динамикой"

Результат:

  • Ad-hoc запросы к аналитику: 25/неделю → 7/неделю (-72%)
  • Время получения ответа на управленческий вопрос: 1–2 часа → 30 секунд
  • Ежедневный автоматический алерт на критические метрики

Сроки

  • Базовый Text-to-SQL для ERP: 1 неделя
  • Агентный loop с несколькими запросами: 1 неделя
  • Интеграция с 1С HTTP-сервисом: 1 неделя
  • Алерт-система + автоотчёты: 1 неделя