TL;DR
FlashScript — набор указаний, по которым кодинг-агент превращает один удачный прогон повторяющейся задачи в нейро-символическую программу (NSP). Это скрипт, где действия и вычисления написаны кодом, значения конкретного запуска вынесены в параметры, а модель вызывается только там, где нужно суждение. Каждый такой вызов типизирован: llm возвращает строку, да/нет или выбор из списка. Он стоит в фиксированной точке кода.
Обычный агент каждый раз заново выдумывает путь. Одну и ту же задачу он решает то с лишним графиком, то с другим названием колонки. Даже «навык» (skill, текстовая инструкция из прошлого прогона) снижает разброс, но не убирает его: модель по-прежнему интерпретирует инструкцию и считает «в голове». Когда в один запрос склеили до десяти подзадач, агент с навыком путал их между собой. Точность упала до 23%, а он добавлял графики, которых никто не просил.
Метод работает в три шага. Сначала код пишется по плану: определить переменные шаблона и решить, что можно записать правилом. Затем каждое место, где нужна модель, относят к одному из трёх слоёв: ввод, вычисление или вывод. И наконец вызовы модели сокращают тремя приёмами: кэшировать, превращать суждения в правила, объединять вопросы в один вызов. Результат в тесте: 100% точности, одинаковые вызовы инструментов в каждом прогоне, примерно в 70 раз меньше входных токенов и втрое быстрее.
Схема метода
ШАГ 0: Один раз пройти задачу с агентом до результата, который тебя устраивает (обычный чат/агент)
ШАГ 1: ПЛАН → какие значения меняются от запуска к запуску (параметры),
какие решения можно записать правилом, где нужен ИИ
ШАГ 2: РАЗМЕТКА ВЫЗОВОВ ПО СЛОЯМ:
• ВВОД (текст → типизированное значение: «LA» → лист «Los Angeles»)
• ВЫЧИСЛЕНИЕ (смысловое решение: «это мошенник?»)
• ВЫВОД (красивая формулировка уже посчитанного кодом)
ШАГ 3: СОКРАЩЕНИЕ вызовов моделью:
• кэш с проверкой (guard) → вызов только если проверка не прошла
• кодификация → суждение становится правилом (regex, пороги)
• объединение → независимые вопросы в один вызов
ШАГ 4: Код пишется кодинг-агентом одним запросом: шаблон запроса + траектория + описание инструментов
ШАГ 5: Проверка раздельно: код — обычными тестами, вызовы LLM — повторными прогонами и контрактами
Пример применения
Задача: Менеджер по маркетплейсам каждый понедельник просит агента разобрать выгрузку отзывов магазина на Ozon. Нужно посчитать средний рейтинг по каждому артикулу, отметить отзывы про брак и возврат, а потом написать сводку для собственника. Один раз он довёл это с агентом до нужного результата: поправил формат таблицы, объяснил, что считать «браком». Теперь хочет, чтобы каждую неделю выходило один в один, и без оплаты тысяч токенов за пересказ одного и того же.
Промпт (отдаётся Claude Code вместе с файлом траектории):
Ты — инженер, который превращает успешный запуск агента в повторяемую программу.
Нужна Python-программа, где действия и вычисления — это код, а модель вызывается
только для суждений, через llm(вопрос, данные) -> T.
Разбери выгрузку отзывов {файл_csv} за неделю {дата_начала}–{дата_конца}.
Посчитай средний рейтинг по каждому артикулу, отметь отзывы про брак или возврат,
напиши сводку для собственника магазина {название_магазина}.
Файл reviews_run.md — полный лог удачного прогона: рассуждения, действия, мои правки.
Читать CSV через pandas; писать Excel через openpyxl; вызывать модель через функцию llm.
Сначала составь план, код пиши после него:
1. Перечисли, что меняется от запуска к запуску → параметры.
2. Перечисли решения из прогона. Для каждого реши: правило, кэш или вызов модели.
3. Найди в прогоне сокращения пути и случайные допущения. Не переноси их в программу,
если они не следуют из шаблона запроса.
Расставь вызовы llm по слоям:
- Ввод: превращение свободного текста в типизированное значение
(какой столбец — «рейтинг», даже если он назван «Оценка»).
- Вычисление: смысловые решения, которые нельзя записать правилом (отзыв про брак?).
- Вывод: словесная сводка по цифрам, которые уже посчитал код.
- Кэш: значения из прогона храни в словаре; llm вызывай, только если проверка не прошла.
- Кодификация: всё, что повторяется, превращай в правило (ключевые слова, пороги).
Модель не должна считать и суммировать.
- Объединение: независимые вопросы по одному отзыву — в один вызов.
Результат: Агент сначала выдаст план: параметры, решения прогона и их судьба (правило, кэш, вызов). Затем напишет скрипт, где расчёт рейтингов и форматирование таблицы идут кодом. Модель вызывается в нескольких точках: сопоставить названия колонок, решить спорные отзывы, не попавшие под правила, и написать сводку по уже посчитанным цифрам. Дополнительно вернётся таблица всех вызовов LLM по слоям и набор тестов. Повторный запуск на новой неделе даёт тот же формат и те же шаги, меняется только формулировка текстовой сводки.
Почему это работает
Слабость LLM. Когда агент каждый раз решает задачу с нуля, он заново выбирает путь, а на температуре выше нуля путь плавает. Модель плохо считает «в голове»: в статье она складывала дневные значения в рассуждении и ошибалась. «Навык» из прошлого прогона не помогает до конца. Модель по-прежнему сама решает, как его исполнять. Он может унаследовать и случайный shortcut из образцового прогона. Например, сравнивались суммы вместо процентов, оба способа дали верный ответ, и навык закрепил неверный.
Сильная сторона LLM. Модель хорошо делает узкие смысловые задачи: понять, что «LA» значит Los Angeles, решить, подозрительно ли объявление, красиво изложить факты. Кодинг-агент ещё и неплохо переписывает прогон в код. Поэтому метод отдаёт модели ровно эти задачи, а остальное оставляет коду.
Как метод использует это. Все действия фиксируются в коде, и разброс остаётся только внутри типизированных вызовов. Тип ответа (да/нет, выбор) ограничивает свободу модели. Три приёма (кэш, правило, объединение) сокращают число обращений к ней, а значит и случайность.
Рычаги управления: - Что отдаёшь агенту на вход. Только шаблон запроса уже даёт хорошее обобщение. Шаблон плюс траектория даёт меньше вызовов и позволяет проверить решения прогона. Одна траектория без шаблона слишком специфична. - Что сдвигать в код. Чем больше решений записано правилом, тем стабильнее и дешевле, но тем меньше вариантов входа программа переварит. Чем больше решений у модели, тем гибче, но разбросаннее. - Параметры для пользователя. Критерий («что считать браком») можно вынести в текстовое поле и подставлять в вызов LLM. - Планирование. Без требования «сначала план, потом код» точность в тестах была 0.88–0.96, и программы ломались на переформулированных запросах. С ним — 1.00.
Шаблон промпта
В тексте статьи самих инструкций нет, они лежат в приложении авторов. Ниже шаблон, собранный по описанию в статье: план, правила, слои, приёмы сокращения, тип llm.
Ты — инженер, который превращает успешный запуск агента в повторяемую
нейро-символическую программу: действия и вычисления — код, а модель вызывается
только для суждений через llm(вопрос, данные) -> T, где T — тип ответа
(строка, Boolean, выбор из списка).
{шаблон_запроса_с_переменными}
{траектория_успешного_прогона}
{описание_инструментов_и_API}
Сначала напиши план, код — после:
1. Какие значения меняются от запуска к запуску → параметры программы.
2. Какие решения принимались в прогоне. Для каждого: правило / кэш / вызов llm.
3. Какие шаги прогона — случайные допущения или сокращения пути.
Не переноси их, если они не следуют из шаблона запроса.
4. Какие варианты входа возможны (другие формулировки, граничные случаи).
Каждый вызов llm отнеси к одному слою:
- INPUT: свободный текст → типизированное значение.
- COMPUTATION: смысловое решение, которое трудно записать правилом.
- OUTPUT: словесное изложение результата, посчитанного кодом.
Вызов вставляй в фиксированной точке кода. Ответ проверяй на соответствие типу T.
- CACHING: значение, замеченное в прогоне, храни в словаре. Перед использованием
проверяй условие. Модель вызывай, только если проверка не прошла.
- CODIFYING: повторяющееся суждение запиши правилом (regex, порог, словарь).
Модель не должна принимать решение, выполняя вычисления в рассуждении.
- CLUBBING: независимые вопросы объединяй в один вызов.
Подставляй: {шаблон_запроса_с_переменными} — твой типовой запрос с пропусками вместо меняющихся значений («за {неделя}», «для города {город}»). {траектория_успешного_прогона} — экспорт или лог чата с удачным прогоном. {описание_инструментов_и_API} — чем агент читает данные и пишет результат.
🚀 Быстрый старт — вставь в чат (лучше в Claude Code или другой кодинг-агент):
Вот шаблон FlashScript. Адаптируй под мою задачу: [опиши, что за повторяющаяся задача].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, какие значения в запросе меняются от раза к разу, какие решения ты принимал вручную в удачном прогоне и какие инструменты доступны. Это нужно, чтобы отделить параметры от жёстких шагов и понять, что можно записать правилом. Она возьмёт структуру из шаблона и соберёт план под твою задачу.
Ограничения
⚠️ Предварительные результаты: Это короткая работа с «первыми результатами». Одна небольшая модель, один бенчмарк, 12 шаблонов запросов. Цифры про 70-кратную экономию и 100% точность не стоит переносить на любую задачу.
⚠️ Нужен код и запуск: Результат — Python-скрипт с вызовами модели. Его надо где-то запускать, хранить и поддерживать. В обычном чате метод не заработает, нужен кодинг-агент и доступ к API модели.
⚠️ Полные инструкции авторов не в тексте: Они вынесены в приложение. Шаблон выше — реконструкция по описанию принципов, а не копия оригинала.
⚠️ Узкий тип задач: Проверяли на аналитике с чёткими правильными ответами: прочитать данные, посчитать, сравнить с порогом, построить график. На творческих, размытых, исследовательских задачах, где каждый раз иной путь, метод не проверен.
⚠️ Не убирает случайность: Метод только запирает её внутри типизированных вызовов. Формулировки ответов и спорные суждения всё равно могут плавать.
⚠️ Ошибки образцового прогона переезжают в программу: Если в удачном прогоне был shortcut, который случайно дал верный ответ, он попадёт в код. Помогает требование плана, но проверять код всё равно нужно.
⚠️ Только траектория вредит: Если дать агенту один прогон без шаблона запроса, программа слишком привязана к конкретному случаю. На новых экземплярах задачи точность падала, часть запусков падала с ошибкой.
Как исследовали
Команда взяла бенчмарк WorkBench: 12 шаблонов аналитических задач, по десять вариантов каждого, всего 120 задач. Пример: «если число активных пользователей больше чем на 10% ниже, чем 24 ноября, построй график». Работали на небольшой модели Claude Haiku 4.5 при температуре 1. Все пробовали три раза, чтобы увидеть разброс, а не только правильность. Для каждого шаблона лучший прогон обычного агента превращали в «навык» и в NSP. Оба писал кодинг-агент.
Результаты сравнивали с обычным агентом и агентом с навыком. Обычный агент в 82% повторов приходил к тому же состоянию, что и в первый раз. Навык поднял цифру до 99%, но не до 100%. Затем авторы склеили до десяти независимых запросов в один. И тут проявился главный сюрприз: агент с навыком, получив все нужные навыки, сбился до 23% точности, добавлял лишние графики и забывал нужные. NSP в тех же условиях оставался правильным и абсолютно одинаковым. На 108 новых вариантах задач программы тоже решили всё, а навык справился с 96%.
Самый практичный результат — эксперимент с инструкциями для генерации. Простое «напиши программу по шаблону» давало 0.96 по шаблону и 0.88 по траектории. Но программы ломались на переформулировках. Добавление требования «сначала план, решения запиши правилами, вызовы расставь по слоям» подняло точность до 1.00. Из сравнения шаблон / прогон / оба вытекает: правильность даёт шаблон и план, а прогон добавляет экономию (меньше вызовов, 1.5 против 1.8 на запуск) и возможность проверить решения прогона.
Адаптации и экстраполяции
🔧 Техника: вынести критерий суждения в параметр → пользователь управляет решением, не трогая код
Авторы предлагают делать суждение настраиваемым: выбор из меню или текстовое поле. В сценарии с отзывами это выглядит так:
В программе сделай параметр {критерий_брака} (текстовое поле, значение по умолчанию —
«жалоба на дефект, поломку или несоответствие описанию»).
Подставляй его в вызов llm на слое COMPUTATION.
Теперь менеджер меняет определение «брака» одной строкой и сразу видит, как меняется результат.
Экстраполяция: правило «когда компилировать» в файле инструкций агента (моя идея, в статье не проверялась):
Если пользователь просит в третий раз выполнить задачу с тем же шаблоном запроса,
предложи превратить успешный прогон в программу: составь план, найди параметры,
реши, что станет правилом, а где нужен вызов llm. Не запускай без подтверждения.
Такое правило в CLAUDE.md или AGENTS.md превращает «разовую удачу» в накапливаемый актив.
Ресурсы
- FlashScript: Compiling Recurring Agent Workflows into Reusable Neuro-Symbolic Programs — Sadra Sabouri, Shreya Sinha, Souti Chattopadhyay (University of Southern California); Hosein Hasanbeig, Adam Sage, Cale Darling, Ashish Tiwari, Katie Garms, Sumit Gulwani (Microsoft).
- Инструкции авторов для генерации NSP: https://figshare.com/s/c812d719d2d43bae034c
- Бенчмарк WorkBench (Styles et al., 2024), arXiv:2405.00823.
- Смежные работы по компиляции траекторий: SKILL-DISCO, TraceCompiler, Agent Workflow Memory.
