Перейти к контенту

DSPy: замена хрупкого промпт-инжиниринга скомпилированными конвейерами LLM

· 7 мин чтения
Mike Thrift
Mike Thrift
Marketing Manager

Я постоянно натыкаюсь на одну и ту же стену, когда думаю о конвейерах ИИ для финансов: вы можете построить что-то, что прекрасно работает на ваших тестовых случаях, а затем наблюдать, как оно тихо разваливается, когда поставщик меняет формат инвойса или появляется новый тип транзакции. Хрупкость почти всегда заключается в промптах — написанных вручную строках, к которым никто не хочет прикасаться. DSPy, представленный Хаттабом и др. из Стэнфорда и опубликованный на ICLR 2024, предлагает фундаментально иной способ построения конвейеров LLM, который заслуживает пристального внимания любого, кто пытается автоматизировать бухгалтерскую работу.

Статья

2026-05-11-dspy-compiling-declarative-language-model-calls-self-improving-pipelines

DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines (Khattab, Singhvi, Maheshwari et al., ICLR 2024) переосмысливает создание конвейеров LLM как задачу программирования, а не задачу промпт-инжиниринга. Основное наблюдение заключается в том, что современные приложения на базе LLM обычно строятся как наборы жестко закодированных строк промптов — то, что авторы называют «шаблонами промптов», — склеенных вместе с помощью потока управления Python. Когда модель меняется или смещается распределение задач, кому-то приходится переписывать эти строки вручную.

DSPy заменяет шаблоны промптов двумя абстракциями: сигнатурами и модулями. Сигнатура — это типизированная декларативная спецификация того, что должен делать вызов языковой модели (LM), записанная компактно как question -> answer или с явным описанием полей в классе Python. Модуль оборачивает сигнатуру стратегией рассуждения — ChainOfThought, ReAct, ProgramOfThought, MultiChainComparison и так далее. Критически важным дополнением является компилятор (в статье он называется teleprompter), который берет программу DSPy, небольшой размеченный набор данных и метрику валидации, а затем автоматически генерирует демонстрации для few-shot обучения, выбирает среди них лучшие и создает промпты, оптимизированные для этой метрики. Компилятору не нужны метки на каждом промежуточном этапе — он может самостоятельно создавать демонстрации (bootstrap), запуская «учительскую» программу на неразмеченных входных данных и фильтруя трассировки, которые приводят к правильным конечным результатам.

Ключевые идеи

  • Сигнатуры отделяют намерение от реализации. Записи question, context -> answer достаточно, чтобы DSPy понял, как сконструировать, вызвать и оптимизировать соответствующий вызов LM. Разработчик никогда не пишет строку промпта.
  • Компиляция — это бутстрэппинг на основе метрик. Оптимизатор BootstrapFewShot запускает программу на обучающих примерах, собирает трассировки входных и выходных данных там, где конвейер добился успеха, и использует их в качестве демонстраций — участие человека для аннотирования промежуточных шагов рассуждения не требуется.
  • Компилятор открывает возможности малых моделей. На наборе данных GSM8K (математические текстовые задачи) базовая Llama2-13b набирает 9,4% при использовании zero-shot промптов. После компиляции DSPy с использованием модулей рефлексии и ансамблей точность достигает 46,9%. T5-Large (770 млн параметров), модель, которую многие списали со счетов для сложных рассуждений, достигает 39,3% точного совпадения ответов на HotPotQA, используя всего 200 размеченных примеров.
  • Экспертные промпты — это не предел. На GSM8K GPT-3.5 с обычными few-shot промптами достигает 25,2%. Созданная экспертами цепочка рассуждений (chain-of-thought) доводит этот показатель примерно до 72–73%. Скомпилированный конвейер рефлексии и ансамблей DSPy поднимает его до 81,6% — без написания промптов человеком.
  • Программы композируемы. Конвейер многоэтапного поиска ответов на вопросы (multi-hop retrieval QA) в DSPy занимает около 12 строк на Python. Аналогичный конвейер в LangChain, как отмечают авторы, содержит 50 строк, превышающих 1000 символов написанного вручную контента промптов.
  • Три этапа компиляции. Оптимизатор работает как: генерация кандидатов (бутстрэппинг трассировок), оптимизация параметров (случайный поиск или Optuna по гиперпараметрам) и оптимизация высшего порядка (ансамбли, динамический поток управления).

Что подтверждается, а что — нет

Эмпирические результаты реальны и значительны. Переход от 9,4% к 46,9% на GSM8K с Llama2-13b при использовании лишь горстки размеченных примеров — это не постепенное улучшение; это тот самый разрыв, который делает маленькие и дешевые модели пригодными для задач, ранее требовавших GPT-4. Архитектура также по-настоящему элегантна: сигнатуры легко читаются, модули композируемы, а абстракция не кажется «дырявой» для продемонстрированных задач.

Однако ограничения существуют, хотя в статье им не посвящен отдельный раздел. Самое важное: компилятор хорош лишь настолько, насколько хороша ваша метрика. Если метрика валидации неточна или не соответствует фактическому качеству выполнения задачи — что крайне часто встречается на практике — оптимизатор найдет хитрые способы максимизировать её, проваливая то, что вам действительно важно. В структурированной области, такой как бухгалтерский учет, вы можете определить метрику типа «проводка сбалансирована», но сбалансированная запись все равно может иметь совершенно неверные коды счетов. Авторы знают о существовании этой проблемы, но оставляют её на совести разработчика.

Второе ограничение: компиляция все равно требует некоторых размеченных данных. В статье утверждается, что можно использовать всего 10 примеров с BootstrapFewShot, и что нужны только входные значения (а не промежуточные метки). Это верно в лучшем случае, но на практике надежность бутстрэппинга падает, когда начальная программа не может решить ни одного обучающего примера. Если ваш финансовый агент имеет почти нулевую базовую точность — что часто бывает при создании чего-то нового — компиляция может топтаться на месте.

Третье, более тонкое: DSPy оптимизирует промпты и демонстрации, но не саму структуру программы. Если вы соединили модули способом, который фундаментально неверен для задачи, компилятор вам не поможет. Проектирование программы по-прежнему лежит на разработчике.

Почему это важно для ИИ в финансах

Проблема хрупкости промптов — пожалуй, самое большое практическое препятствие для внедрения финансовых ИИ-агентов в эксплуатацию. Конвейер, который классифицирует транзакции, сопоставляя описания с кодами счетов, будет деградировать всякий раз, когда данные о продавцах меняют формат, когда появляется новая категория расходов или когда обновляется план счетов. С DSPy вы определяете задачу абстрактно (transaction_description, chart_of_accounts -> account_code, confidence) и позволяете компилятору находить оптимальные демонстрации каждый раз, когда распределение данных меняется.

Конкретно для Beancount я вижу конвейер, состоящий из трех связанных модулей DSPy: один извлекает структурированные данные о транзакциях из необработанных банковских выгрузок, другой ищет наиболее подходящий счет в существующем плане счетов леджера, а третий проверяет полученную проводку на соответствие ограничениям двойной записи. Каждый модуль получает свою сигнатуру; вся программа компилируется с использованием метрики, которая проверяет как бухгалтерскую корректность, так и соблюдение формата. Проблема качества метрик здесь стоит наиболее остро — вам нужна метрика, которая ловит неправильные коды счетов, а не просто несбалансированные записи, — но это решаемая инженерная задача.

Более глубокий смысл: DSPy переносит работу с «написания лучших промптов» на «написание лучших метрик и сбор небольших наборов размеченных данных». Это гораздо более устойчивая инженерная практика для промышленной финансовой системы, которой необходимо развиваться по мере изменения нормативных актов, структуры плана счетов и форматов транзакций.

Что почитать дальше

  • OPRO: Large Language Models as Optimizers (Yang et al., arXiv:2309.03409) — подход Google DeepMind к оптимизации промптов через итеративное уточнение, генерируемое самой LM; полезный контраст подходу бутстрэппинга в DSPy.
  • TextGrad: Automatic "Differentiation" via Text (Yuksekgonul et al., arXiv:2406.07496) — представляет оптимизацию как обратное распространение через текстовую обратную связь, а не через бутстрэппинг на основе метрик; показывает сильные результаты в задачах программирования и научных задачах, где подход DSPy слабее.
  • DSPy Assertions: Computational Constraints for Self-Refining Language Model Pipelines (Singhvi et al., arXiv:2312.13382) — добавляет жесткие и мягкие ограничения в программы DSPy, позволяя конвейерам самокорректироваться, когда выходные данные нарушают доменные правила; напрямую применимо для обеспечения бухгалтерских инвариантов.