6 часов писать паттерны вручную vs 1 минута с AI-агентом: как мы автоматизировали DSL

6 часов писать паттерны вручную vs 1 минута с AI-агентом: как мы автоматизировали DSL

Привет! Я — Лиза Плюснина, лингвист-разработчик чат-ботов в Just AI. Работаю с платформой JAICP, где создаются голосовые и текстовые боты. Одна из ключевых задач — написание паттернов на внутреннем DSL-языке. Это регулярный, монотонный процесс, отнимающий часы. Мы решили его автоматизировать с помощью AI-агента. Рассказываю, как это сделали.

Зачем нужен агент: задача и контекст

Лингвист-разработчик — специалист на стыке лингвистики и программирования. Его задача — научить бота понимать человека. Для этого используются паттерны: конструкции, описывающие возможные формулировки пользовательских реплик — от «да» до сложных фраз.

В JAICP паттерны пишутся на собственном DSL, отличном от привычных инструментов вроде регулярных выражений. Есть системный проект zb-common с базовыми паттернами, например $agree для фраз согласия. Но часто его возможностей не хватает — нужны термины заказчика, сленг, особенности бизнеса.

Тогда приходится писать паттерны вручную. Это несложно, но утомительно. Особенно — в многоязычных проектах. Например, на одном проекте мы работали с русским, турецким, немецким и английским. Пользователи говорят по-разному: «привет», «добрейшего дня», «не то пальто». А в других языках этим фразам нужны смысловые аналоги, а не дословный перевод.

Вот примеры:

Английский

Мимо кассы

Tam hedefi vurmadı.

Missed the mark.

Konu dışı.

Nicht zum Thema.

Off-topic.

Вообще не то

Tamamen yanlış.

Überhaupt nicht.

Not at all.

Iska geçti.

Fehlgriff.

Не то пальто

Hiç uymuyor.

Passt überhaupt nicht.

Not even close.

Это фиаско

Bu tam bir fiyasko.

Das ist ein Fiasko.

This is a fiasco.

Найти человека, свободно владеющего всеми этими языками и понимающего контекст, — почти невозможно. Приходится тратить время на анализ, изучение особенностей языков и ручное написание.

Даже простая группа фраз — например, 20 приветствий на русском — может занять у разработчика до часа. А еще нужны автотесты. Их можно частично автоматизировать скриптом, но и там остаётся ручная работа: нужно придумывать вариации, сленг, опечатки, и каждый раз прогонять через скрипт.

В итоге разработчик тратит время на рутину, а не на сложные задачи.

Почему не просто LLM?

Можно было бы использовать нейросеть напрямую. Но у этого подхода минусы:

  • Ограниченный контекст: каждый раз приходится заново вводить модель в курс дела.
  • Незнание DSL: языковые модели не знакомы с нашим внутренним языком.
  • Шаблонность: модели склонны к однообразным ответам.
  • Неудобство: нужно переходить на сторонние сервисы, многие из которых ограниченно доступны в России.

Поэтому мы создали AI-агента, который понимает DSL, генерирует паттерны и сразу пишет автотесты.

Архитектура и технологии

Основная модель — Claude Sonnet 4.5. Она лучше всего справлялась с генерацией кода на DSL: следовала промпту, не добавляла «воды».

Агент получил три инструмента:

  1. retrieveChunks: достаёт релевантные фрагменты из базы знаний (Jay Knowledge Hub) — документацию, примеры паттернов.
  2. generateAnswer: генерирует ответы на основе той же базы знаний.
  3. Llm.sendRequest: обращается к LLM (GPT-4o-mini) для самопроверки и исправления ошибок.

Ключевое — не сами инструменты, а логика их использования. Её мы задали через промпт.

Как работает промпт

Хороший промпт — основа успеха. Мы разделили его на сегменты: роль, цель, инструкции. Последние — самые важные.

Сначала мы рассмотрели вариант с отдельными инструментами для паттернов и тестов. Но качественный промпт позволил обойтись без них — всё делает сам агент.

Промпт состоит из четырёх частей:

  1. Общая часть: предобработка запроса. Агент анализирует, что хочет пользователь, и выбирает инструмент.

Алгоритм:

  • Объясни, чем можешь помочь.
  • Определи тип запроса.
  • Используй соответствующий инструмент.
  • Если неясно — уточни у пользователя.
  1. Сегмент «Паттерны»: самый объёмный. Включает:
  • Методологию: этапы анализа — семантический, морфологический, синтаксический.
  • Инструменты: указание, какой тул использовать, и базовые обозначения DSL (например, [] — опциональные блоки).
  • Примеры: эталонные образцы, например: «не работает» → $not_working = (не работа* | сломал* | ошибк* | не функцион*).

Также добавлены правила для оптимальных паттернов:

СТРАТЕГИЯ СОЗДАНИЯ ОПТИМАЛЬНЫХ ПАТТЕРНОВ:

1. СИНОНИМИЧЕСКИЕ ГРУППЫ: сразу группируй синонимы через /
— Вместо: (спасибо | благодарю | спасиб)
— Используй: (спасиб*|благодар*)

2. ОПЦИОНАЛЬНЫЕ БЛОКИ: выделяй необязательные части в [ ]
— Вместо: (за помощь | помощь)
— Используй: ([за] помощ*)

3. ИЕРАРХИЧЕСКАЯ СТРУКТУРА: строй логические уровни вложенности
— Вместо плоского перечисления
— Используй: ((я|мне) (нужн*|необходим*))

4. УМНЫЕ АЛЬТЕРНАТИВЫ: объединяй схожие семантические конструкции

В конце — задание: «Теперь создай ОПТИМИЗИРОВАННЫЙ паттерн для фразы: текст пользователя». Слово «оптимизированный» выделено, чтобы модель не возвращала буквальные, длинные конструкции.

  1. Сегмент «Автотесты»: короткий. Содержит инструкцию по использованию тула и пример готового теста.
  1. Самопроверка: требование проверить результат через Llm.sendRequest и убрать лишнюю разметку.

Такой подход позволил обойтись без дополнительных инструментов и сложной архитектуры.

Проблемы и решения

  1. Модель игнорирует инструкции

Сначала модель часто генерировала паттерны с ошибками или использовала устаревшие конструкции, опираясь на свои знания, а не на документацию.

Решение 1: чёткое разделение источников. База знаний (Jay Knowledge Hub) — для примеров и справки. Промпт — для правил, синтаксиса и ограничений. Это снизило «самодеятельность» модели.

Решение 2: мы использовали другую LLM — DeepSeek — чтобы оптимизировать сам промпт. Она сделала его чётче и структурированнее, что повысило стабильность генерации.

  1. Отсутствие вариативности

Модель выдавала однотипные конструкции, просто переставляя слова.

Решение: вручную добавили в промпт примеры с синонимами, сленгом и разными синтаксическими формами.

  1. Трудности с многоязычностью

На английском и русском модель справлялась хорошо, но на турецком и немецком ошибалась в морфологии и пропускала словоформы.

Решение: добавили в промпт инструкцию: «Сначала определи язык запроса, затем примени специфические правила построения паттернов».

Более надёжным решением было бы наполнить базу знаний реальными примерами на всех языках. Но это требует ресурсов. Мы выбрали прагматичный путь — тонкая настройка промпта.

Результат

Агент интегрирован в Telegram для удобства тестирования. Он умеет:

  1. Генерировать паттерны на DSL по одной фразе, учитывая вариативность. Например, на «привет, как дела» — предлагает «привет», «здравствуйте», «добрый день» и другие. Полезно для онбординга новичков.
  1. Показывать примеры фраз, которые покрывает паттерн, демонстрируя его гибкость.
  1. Писать автотесты на основе тех же фраз. Количество тестов не фиксировано, но можно задать минимум в промпте.
  1. Работать с несколькими языками: генерирует паттерны отдельно для каждого, не смешивая. Работоспособность проверяется автотестами.

Бот не выходит за рамки своей задачи, но освоил написание сценариев на DSL — хотя мы его этому не учили. Вероятно, модель извлекла информацию из документации в базе знаний.

Цифры и эффект

Раньше задача занимала часы. Теперь — секунды.

Пример: 20 фраз от клиента, нужно сделать паттерны на четырёх языках (русский, турецкий, испанский, английский), добавить вариативность и написать автотесты.

Ручная работа:

  • 1 час — паттерны на русском.
  • Не менее 3 часов — на три других языка.
  • 1 час — автотесты.
  • ~1 час — придумывание вариаций.

Итого: минимум 6 часов монотонной работы, плюс правки и ошибки.

AI-агент справляется за 1 минуту. Ускорение — в 360 раз.

Конечно, результат всё ещё требует проверки. Но даже с учётом ревью экономия времени колоссальная.

Читать оригинал