Раньше система работала так. Горничная фотографировала чек и отправляла в WhatsApp. Бот видел фото, передавал его GPT-4o Vision, а та смотрела на изображение, видела слово "payment" или "transfer" или "счёт" — и отправляла запись в категорию "нераспознанное". Категория "нераспознанное" быстро стала мусорным ведром: туда падало 40-50% всех чеков, ни один из которых нельзя было автоматически включить в финансовый отчёт.
Управлять финансами 16 вилл — это десятки чеков в день. Электричество PLN, вода PDAM, покупки для уборки, ремонт кондиционера, обеды для рабочих, традиционные балийские подношения. У каждой категории свои исполнители, свои бюджеты, своя аналитика. Если половина чеков в "нераспознанном" — ни аналитики, ни контроля.
13 апреля я сел и переписал систему распознавания. После — бот смотрит на фото из столовой и пишет "обед". Без моего участия.
В чём была проблема с первой версией
Первая версия промпта была слишком абстрактной. Я давал GPT-4o такую инструкцию: "Посмотри на чек и определи категорию расходов". Без словарей, без контекста, без специфики Бали.
Модель смотрела на индонезийский чек, видела английские слова-шаблоны типа "bill", "payment", "total", "receipt", "transfer" — и добросовестно их возвращала как "категорию". Технически она была права: на чеке написано "payment". Но "payment" — это описание типа документа, а не категория расхода. Как если бы бухгалтер, когда его спросили "что это за расход?", ответил: "это платёж".
Плюс Бали — специфический контекст. Большая часть платёжных документов здесь выглядит не как привычный европейский чек, а как рукописная записка, квитанция на индонезийском или скриншот банковского перевода. Универсальная модель без специфики региона с этим справляется плохо.
Ошибка при настройке AI-систем для финансов: давать модели общее задание без контекста. "Определи категорию" работает в учебниках. В реальности нужны конкретные словари для конкретного региона.
Чёрный список пустых слов
Первое улучшение — добавить в промпт список слов, которые ничего не значат как категории. Явный запрет: "Если на чеке видишь слова payment, transfer, receipt, bill, total, invoice, счёт, платёж, оплата, итого — это NOT категории расходов. Это описание типа документа. Игнорируй их и смотри на содержание."
Это сразу убрало самые частые ошибки. Бот перестал возвращать "payment" как категорию — теперь он знал, что это слово нужно проигнорировать и искать дальше.
Словари категорий: PLN это электричество
Второе улучшение — добавить конкретные словари для балийского контекста. Список синонимов и узнаваемых маркеров для каждой категории:
- Электричество: PLN, listrik, kwh, meter listrik, tagihan listrik
- Вода: PDAM, air, tagihan air, meter air
- Транспорт: Grab, Gojek, GoRide, GoCar, bensin, BBM, parkir
- Уборка и товары для виллы: Indomaret, Alfamart, sabun, detergen, sapu, pel
- Питание/обед для персонала: warung, makan, nasi, mie, makanan, minuman, kopi
- Ремонт и материалы: cat, semen, besi, pipa, keramik, tukang, servis AC
- Традиционные церемонии: offerings, canang, sesajen, banten, pura, upacara
- Интернет: Telkomsel, Indosat, XL, wifi, internet, paket data
Теперь промпт говорит явно: "Если видишь PLN или слова 'listrik', 'kwh' — это электричество. Если видишь PDAM или 'tagihan air' — это вода. Если 'Grab' или 'GoRide' — это транспорт."
После этого добавления точность распознавания резко выросла. Большинство балийских расходов теперь попадало в правильные категории автоматически.
Работа с рукописными чеками
Отдельная история — рукописные квитанции. На Бали это норма: небольшая мастерская, локальный тукан (мастер), уличный рынок — никакого кассового аппарата, просто лист бумаги с суммой и подписью.
GPT-4o Vision справляется с рукописным текстом значительно лучше, чем специализированные OCR-решения. Особенно с индонезийским рукописным — потому что модель понимает контекст, а не просто сканирует пиксели. Если написано неразборчиво "srvis AC" — модель понимает, что это "servis AC" (ремонт кондиционера), категория "ремонт".
Для рукописных документов я добавил инструкцию: "Если текст неразборчив, попробуй прочитать по контексту. Укажи уверенность в распознавании от 0 до 1. Если уверенность ниже 0.6 — помечай запись как 'требует проверки', не пропускай в основной отчёт автоматически."
Это важно: лучше честное "не уверен" с флагом для проверки, чем уверенная неправильная категория в финансовом отчёте.
Структура промпта для распознавания чека
После нескольких итераций промпт для финансового бота выглядит примерно так. Упрощённая версия:
Блок 1 — контекст: "Ты финансовый ассистент для управляющей компании вилл на Бали. Анализируешь платёжные документы — чеки, квитанции, скриншоты банковских переводов."
Блок 2 — что игнорировать: "Слова payment, transfer, receipt, total, tagihan, faktur — это тип документа, не категория. Игнорируй их при определении категории."
Блок 3 — словари категорий: Полный список с синонимами как выше.
Блок 4 — что извлечь: "Из документа извлеки: 1) категория расхода (из словаря), 2) сумма в рупиях, 3) дата если видна, 4) название объекта/поставщика, 5) краткое описание одной фразой, 6) уверенность распознавания от 0 до 1."
Блок 5 — формат ответа: JSON с фиксированными полями. Без JSON нельзя автоматически записать в базу данных.
Автоматические 39 мёртвых групп
В тот же день — 13 апреля — параллельно с работой над финансовым ботом система сделала кое-что интересное без моего участия.
Рассыльщик по Telegram-группам тихо отключил 39 групп из 103 активных. Не я принял такое решение — бот сам. Он несколько недель собирал статистику по каждой группе: сколько успешных отправок, сколько ошибок. У 39 групп показатель был такой: 3 и более ошибок подряд, ноль успешных за последние 7 дней.
Причины разные. Где-то бота выкинули из админов. Где-то группа стала закрытой. Где-то запретили прикреплять медиафайлы. Технически отправка "происходила" — бот пытался — но всегда получал ошибку.
Система пометила такие группы как "auto: деактивирована по статистике ошибок" и остановила отправку. Успешность рассылок сразу выросла: теперь считались только группы, где отправка реально работает. Метрики стали честными.
Это то, о чём я писал в статье про тихие отказы: мониторь результаты, а не только статус. Бот "работал" и в мёртвых группах — он пытался. Но результата не было. Только мониторинг реальных результатов позволяет отделить настоящую работу от имитации активности.
Куда это ведёт: финансы без ручного труда
Сейчас пайплайн работает так. Горничная фотографирует чек прямо после покупки и отправляет в WhatsApp. Бот получает фото, прогоняет через GPT-4o Vision с полным промптом, получает JSON с категорией, суммой, описанием. Если уверенность выше 0.7 — запись автоматически попадает в базу данных расходов с привязкой к нужной вилле. Если уверенность ниже 0.7 — запись помечается для ручной проверки и попадает в отдельную очередь.
В конце недели финансовый бот собирает все записи, группирует по категориям и виллам, считает суммы и формирует отчёт. Без единого Excel, без ручного ввода, без категоризации.
Мой следующий шаг — сравнивать расходы с историческими нормами. Если PLN по вилле в апреле на 40% больше, чем в марте — это флаг: что-то не так? Кондиционер сломан и работает вхолостую? Счётчик скрутили? Жильцы живут с открытыми дверями? Без автоматического сравнения с нормой такие отклонения видны только когда платишь счёт и удивляешься сумме. С автоматическим — видишь аномалию в реальном времени.
Это большой шаг к тому, о чём я давно думаю: финансы как живой поток данных, а не ежемесячная отчётность задним числом. Сейчас это уже почти реально. О том как автоматизируются финансы вилл в целом — отдельная история.
Принцип, который стал яснее
Пока разбирался с чеками, пришло понимание, которое хочу записать отдельно. Я уже несколько месяцев думаю о том, как настраивать AI-агентов — через детальные инструкции или через принципы.
С первой версией промпта для чеков у меня был детальный сценарий: "если видишь то, делай это, если видишь то, делай другое". Каждый тип чека — отдельная ветка инструкций. Это работало, пока чеки были похожи на то, что я предусмотрел. Когда появлялся новый тип — инструкции не справлялись.
Вторая версия работает через принципы: "ты финансовый ассистент, твоя цель — понять что за расход, вот словари для ориентира, вот что игнорировать, вот как оценивать уверенность". Модель сама разбирается с новыми форматами — потому что она понимает цель, а не следует сценарию.
Разница особенно видна на рукописных чеках. Детальные инструкции с ними не справлялись — каждый рукописный документ непохож на другой. Модель с принципиальным промптом справляется — потому что понимает что от неё хотят, и применяет контекст.
Этот же принцип я начал применять к настройке всех AI-агентов: передавай принципы и границы, а не сценарии. Модели становятся умнее каждый квартал — жёсткие инструкции устаревают, принципы остаются.
Сколько это реально стоит и сколько экономит
GPT-4o Vision на один чек — примерно $0.005-0.015 в зависимости от качества изображения и длины промпта. При 30-40 чеках в день на 16 вилл — около $0.20-0.60 в день, $6-18 в месяц.
Что стоит ручная категоризация? Бухгалтер или ассистент, который разбирает чеки вручную — минимум $300-500 в месяц. Плюс задержка: ручная категоризация обычно происходит раз в неделю или раз в месяц, потому что делать это ежедневно трудозатратно. Автоматическая — в реальном времени, каждый чек немедленно.
Соотношение очевидное. Но важнее не экономия, а качество данных. Когда категоризация происходит сразу — данные актуальные. Когда раз в месяц задним числом — к тому времени половина деталей теряется, а аномалии уже неустранимы.
День, когда система работала без меня
13 апреля примечателен ещё одним. Пока я работал над финансовым ботом и документировал всё в коде, несколько параллельных процессов шли без моего участия.
Сторожевой процесс для Facebook Messenger поймал бесконечный цикл ошибок, подождал 30 минут, насчитал 5 ошибок без единого успеха и перезапустил сервис сам. Без моего участия, без уведомления. Я узнал об этом только из логов вечером.
Рассыльщик деактивировал 39 мёртвых групп по статистике ошибок. Без моего участия.
Финансовый бот с утра обработал 23 чека от горничных. Без моего участия.
Три разные системы, три разные задачи — все выполнены до того, как я к ним прикоснулся. К вечеру я обнаружил в логах, что день прошёл нормально, ничего не сломалось, несколько вещей даже само починились. Это и есть конечная цель: не когда автоматизация помогает тебе делать работу, а когда работа выполняется, пока ты занят другим.