Коротко
Автор финансового приложения заменил LLM, распределявшую накопления по целям, детерминированным алгоритмом. Он работает без сети, дает повторяемые результаты и использует тот же расчет дат, что и остальная часть приложения; модель оставили для объяснений и советов.
Контекст
Автор разрабатывает приложение «Кубыш», которое планирует бюджет между получками и отображает накопления по целям-конвертам. У каждой цели есть сумма, приоритет и желаемая дата. Кнопка «Показать Кубышу» прежде обращалась к внешней LLM, чтобы предложить распределение денег.
Главное
- Внешняя LLM иногда была недоступна на мобильном интернете в России без VPN; автор также упоминает ограничения из-за белых списков.
- Повторные нажатия могли давать разные распределения, что снижало доверие к финансовому результату.
- Результаты LLM было трудно проверять обычными тестами, а названные ею даты расходились с календарным движком приложения.
- Алгоритм поддерживает два режима: ускорять достижение целей по очереди или оставлять максимум свободных денег после минимальных взносов.
- Очередность задается приоритетом и ближайшей желаемой датой внутри него.
- Минимальную сумму для срока ищут бинарным поиском с шагом 1 000 ₽; прогноз передается через функцию forecast.
- Для дат используется тот же движок, что формирует даты на карточках целей; тест-сторож должен предотвращать отдельные расчеты.
- Автор перечисляет тестовые случаи: цель без даты, выполнимый и невыполнимый срок, очередь и премия.
- LLM оставили для объяснения рассчитанных цифр, советов и тона общения; при отсутствии сети используется запасной текстовый шаблон.
Как сделано
Автор свел задачу к двум режимам: быстрее достигать целей, распределяя деньги по очереди, или выделить каждой цели минимальную сумму, достаточную для достижения желаемой даты, а остаток оставить свободным. Порядок целей совпадает с календарным движком: сначала приоритет («критичная», «важная», «хотелка»), затем ближайшая желаемая дата в пределах приоритета.
Минимум для цели ищется бинарным поиском: проверяется прогноз при разных суммах, пока интервал не станет меньше 1 000 ₽. Дата прогнозируется той же передаваемой извне функцией forecast, которая используется для карточек целей. По словам автора, отдельный тест-сторож обнаруживает появление второго независимого расчета прогноза.
Код отвечает за числа, даты и распределение. LLM используется для текстовых объяснений и советов; при отсутствии сети предусмотрен шаблонный текст.
Результаты
Распределение стало детерминированным, локальным и мгновенным. Одинаковые входные данные дают одинаковый результат, даты согласуются с прогнозом на карточках. Автор сообщает о тестах для целей без даты, выполнимых и невыполнимых сроков, очередности и премии, но не приводит метрик производительности или пользовательских измерений.
Ограничения
Не приведены результаты количественного сравнения с прежней LLM, объем тестового набора, детали календарного движка и оценка поведения на всех возможных входных данных. Бинарный поиск использует шаг 1 000 ₽, поэтому точность до рубля не предполагается. Не описаны стоимость и конкретная модель прежнего внешнего сервиса.
Что взять себе
- Если результат можно точно описать правилами и проверить тестами, расчет надежнее поручить обычному коду.
- Для финансовых цифр нужен единый источник истины: языковая модель может объяснять их, но не должна придумывать альтернативные значения.
- Сетевые AI-функции стоит дополнять офлайн-резервом, если они влияют на доступность ключевого сценария.
- Разделяйте расчет и коммуникацию: детерминированная логика считает, а модель помогает понятно подать результат.
Читать оригинал, если…
Откройте оригинал, если нужны полный Swift-фрагмент функции бинарного поиска и дополнительные детали реализации теста-сторожа.