На одном хорошем примере показываю как можно использовать встроенный инструмент OpenAI Code interpreter в 1С

Для этого нам понадобится Библиотека искусственного интеллекта для 1С. Это свободно распространяемый продукт. Его используют для создания решений на основе технологий искусственного интеллекта в 1С. Скачать можно здесь https://t.me/braingurd или здесь  https://t.me/AI_LIB_1C_bot

В 37 версии библиотеки появилась поддержка Code interpreter от OpenAI. Это так называемый "встроенный инструмент". Он не просто пишет код, он его еще и отлаживает, т.е. пытается выполнить и, при наличии ошибки, переписывает. Готовый рабочий код выполняется, а пользователю выдается результат. В общем, ваш персональный и почти бесплатный разработчик.

Как его можно использовать для решения бизнес-задач рассмотрим на простом примере. Самый распространенный вопрос в бизнесе: "мы в плюсе или в минусе". Для того, чтобы дать на него ответ считают прибыль. Более грамотно говорить "маржу" или "маржинальную прибыль", но первый вариант тоже довольно часто используется.

Пусть у нас будет торговая деятельность. Создадим два файла: purchases.csv и sales.csv. Например, такие:

дата,товар,количество,сумма
01.07.25,Ботинки,100,1000
06.07.25,Валенки,10,50
10.07.25,Ботинки,50,600
22.07.25,Валенки,20,120

дата,товар,количество,сумма
01.08.25,Ботинки,10,220
06.08.25,Валенки,4,36
10.08.25,Ботинки,60,1800
22.08.25,Валенки,8,80
11.08.25,Ботинки,60,2400

Библиотека искусственного интеллекта для 1С представляет собой коллекцию методов доступа к большим языковым моделям разных провайдеров через API. Но здесь есть и "песочница". Перейдем в нее и загрузим наши файлы в хранилище. Каждому файлу будет присвоен id. Эти id нам скоро понадобятся.

Откроем список инструментов. Первым в списке будет code_interpreter.

Откроем его и на вкладке JSON схема вставим наши id

Вот теперь все готово для того, чтобы получать ответы на вопросы с помощью code intrerpreter. Попросим посчитать прибыль по методу FIFO. Не забудем указать инструмент code_interpreter и нажмем копку Response API. Response API это новый api OpenAI. Нужно использовать именно его, чтобы задействовать встроенные инструменты

Можете убедиться, что прибыль действительно рассчитывается по методу FIFO

Здесь важно то, что файлы могут быть практически в любом формате (например, PDF). Содержимое файлов может быть структурировано произвольным способом. Может содержать посторонний текст. Это делу не помешает. LLM разберется. Сами задачи тоже могут быть любыми. Да, бывают действительно сложные задачи. Но это в науке, а в бизнесе практически все задачи LLM «по зубам».

Когда‑то появление электронных таблиц типа Excel произвело настоящую революцию. Электронной таблицей мог пользоваться любой и миллионы пользовались и продолжают пользоваться сейчас.

Похоже, что в описанном мною случае мы имеем дело с "новым Excel", причем еще более простым в использовании.

Комментарии (4)


  1. climateka
    25.08.2025 22:19

    А 1с то здесь зачем? Оно не выполняет ровным счетом ничего, закиньте также эти файлы в условный гигачат, и будет то же самое, если он умеет файлы читать)


    1. exwill Автор
      25.08.2025 22:19

      У гигачат нет code interpreter


  1. nafa2017
    25.08.2025 22:19

    Я так понял, что она должна была написать код, потом показать результат его выполнения. Можно посмотреть код, который был создан в данном случае ?


    1. exwill Автор
      25.08.2025 22:19

      import pandas as pd
      from pathlib import Path
      from collections import defaultdict, deque
      
      def read_csv_smart(path):
          for enc in ["utf-8", "utf-8-sig", "cp1251", "latin1"]:
              try:
                  return pd.read_csv(path, encoding=enc)
              except Exception:
                  continue
          # fallback
          return pd.read_csv(path, encoding="latin1", errors="ignore")
      
      # Load
      purchases = read_csv_smart("/mnt/data/file-7hqUPaq8LxdUaPjygcVFrh-purchases.csv")
      sales = read_csv_smart("/mnt/data/file-Q1Zn1817nakCUSQTtTxs25-sales.csv")
      
      # Normalize column names
      purchases.columns = [c.strip().lower() for c in purchases.columns]
      sales.columns = [c.strip().lower() for c in sales.columns]
      
      # Map Russian columns
      # дата, товар, количество, сумма
      req_cols = ["дата", "товар", "количество", "сумма"]
      for df_name, df in [("Закупки", purchases), ("Продажи", sales)]:
          missing = [c for c in req_cols if c not in df.columns]
          if missing:
              raise ValueError(f"{df_name}: отсутствуют столбцы {missing}. Найдены: {list(df.columns)}")
      
      # Prepare dataframes
      p_df = purchases[["дата", "товар", "количество", "сумма"]].copy()
      s_df = sales[["дата", "товар", "количество", "сумма"]].copy()
      
      # Parse dates (dd.mm.yy)
      for df in (p_df, s_df):
          df["дата"] = pd.to_datetime(df["дата"], format="%d.%m.%y", errors="coerce")
          df["количество"] = pd.to_numeric(df["количество"], errors="coerce")
          df["сумма"] = pd.to_numeric(df["сумма"], errors="coerce")
      
      # Drop bad rows
      p_df = p_df.dropna(subset=["дата", "товар", "количество", "сумма"])
      s_df = s_df.dropna(subset=["дата", "товар", "количество", "сумма"])
      
      # Compute unit cost for purchases
      p_df = p_df[p_df["количество"] > 0]
      p_df["unit_cost"] = p_df["сумма"] / p_df["количество"]
      
      # For sales, revenue is given as total "сумма"
      s_df = s_df[s_df["количество"] > 0]
      s_df["revenue"] = s_df["сумма"]
      
      # Sort
      p_df = p_df.sort_values(["товар", "дата"]).reset_index(drop=True)
      s_df = s_df.sort_values(["товар", "дата"]).reset_index(drop=True)
      
      # Build FIFO queues per product
      purchase_queues = defaultdict(deque)
      for prod, grp in p_df.groupby("товар", sort=False):
          for _, r in grp.iterrows():
              purchase_queues[prod].append([float(r["количество"]), float(r["unit_cost"]), r["дата"]])
      
      # Process sales
      rows = []
      shortages = defaultdict(float)
      
      for prod, grp in s_df.groupby("товар", sort=False):
          for _, r in grp.iterrows():
              qty = float(r["количество"])
              revenue = float(r["revenue"])
              remaining = qty
              cogs = 0.0
              pq = purchase_queues[prod]
              while remaining > 0 and pq:
                  lot_qty, lot_cost, lot_date = pq[0]
                  use = min(remaining, lot_qty)
                  cogs += use * lot_cost
                  lot_qty -= use
                  remaining -= use
                  if lot_qty == 0:
                      pq.popleft()
                  else:
                      pq[0][0] = lot_qty
              if remaining > 0:
                  shortages[prod] += remaining
              rows.append({
                  "date": r["дата"],
                  "product": prod,
                  "qty_sold": qty,
                  "revenue": revenue,
                  "cogs_fifo_known": cogs,
                  "gross_profit_known": revenue - cogs,
                  "uncosted_qty_due_to_shortage": max(0.0, remaining)
              })
      
      res_df = pd.DataFrame(rows)
      
      # Aggregate per product
      agg = res_df.groupby("product", as_index=False).agg(
          revenue=("revenue", "sum"),
          cogs_fifo_known=("cogs_fifo_known", "sum"),
          gross_profit=("gross_profit_known", "sum"),
          qty_sold=("qty_sold", "sum"),
          uncosted_qty=("uncosted_qty_due_to_shortage", "sum")
      ).sort_values("gross_profit", ascending=False)
      
      # Display results
      display(agg)
      
      # Totals
      totals = pd.DataFrame({
          "product": ["ИТОГО"],
          "revenue": [agg["revenue"].sum()],
          "cogs_fifo_known": [agg["cogs_fifo_known"].sum()],
          "gross_profit": [agg["gross_profit"].sum()],
          "qty_sold": [agg["qty_sold"].sum()],
          "uncosted_qty": [agg["uncosted_qty"].sum()],
      })
      display(totals)
      
      # If shortages, show brief note
      if (agg["uncosted_qty"] > 0).any():
          display({"Примечание": "Обнаружены продажи без достаточного запаса на момент продажи. COGS рассчитан только для доступной части. Проверьте последовательность дат закупок/продаж."})