Как организовать работу с промптами для AI-агентов
В RetailCRM мы начинали с промптов в формате строки или f-string. Для простых промптов это ок.
Но вот ты написал первую версию промпта, запустил, увидел косяки или ненужное поведение LLM, дорабатываешь промпт. Потом добавляются какие-то данные, которые надо динамически подсовывать. Потом появляются куски промпта, которые нужно подставлять условно, исходя из контекста. В итоге у тебя получается какая-то лапша нечинаемой смеси кода и кусков текста.
Промпт в AI-агентах — это такая же часть бизнес-логики (на самом деле, одна из самых важных), как и код, поэтому важно, чтобы этот "код" на человеческом языке был наглядный, читаемый и с подсветкой синтаксиса.
Мы пришли к тому, что промпт наиболее удобно оформлять в jinja шаблонах (или любом другом шаблонизаторе) с markdown внутри. Покажу на примере.
Пример
Допустим мы решили сделать мини агента, который с помощью нашего сервиса Geohelper определит часовой пояс клиента по номеру телефона.
Сделали начальный промпт
Запустим
Доработаем, чтобы выводил кратко и более содержательно:
Запустим
Уже лучше. Представим, что мы хотим подсказывать смещение относительно нашего часового пояса.
Глянем
Спустя время мы захотели добавить параметр --short в вызов скрипта, чтобы выводить информацию только о разнице во времени. Доработаем промпт:
Проверим:
Как итог
* Промпт читаемый с подсветкой (как jinja, так и markdown)
* Работают проверки от IDE (в том числе на орфографию/пунктуацию)
* Промпт можно обогащать вкраплениями логики
* Одно из самых важных Фрагменты промпта можно дополнять комментариями
А как выглядит финальный промпт в IDE, можно увидеть на картинке к посту.
🔗 Инженерия и AI | Ilyas Salikhov
В RetailCRM мы начинали с промптов в формате строки или f-string. Для простых промптов это ок.
Но вот ты написал первую версию промпта, запустил, увидел косяки или ненужное поведение LLM, дорабатываешь промпт. Потом добавляются какие-то данные, которые надо динамически подсовывать. Потом появляются куски промпта, которые нужно подставлять условно, исходя из контекста. В итоге у тебя получается какая-то лапша нечинаемой смеси кода и кусков текста.
Промпт в AI-агентах — это такая же часть бизнес-логики (на самом деле, одна из самых важных), как и код, поэтому важно, чтобы этот "код" на человеческом языке был наглядный, читаемый и с подсветкой синтаксиса.
Мы пришли к тому, что промпт наиболее удобно оформлять в jinja шаблонах (или любом другом шаблонизаторе) с markdown внутри. Покажу на примере.
Пример
Допустим мы решили сделать мини агента, который с помощью нашего сервиса Geohelper определит часовой пояс клиента по номеру телефона.
Сделали начальный промпт
Ты помощник, который определяет часовой пояс по номеру телефона.
Запустим
$ python get_timezone.py 89132342323
Номер +7 913 234-23-23
Информация о часовом поясе:
- Регион: Алтайский край
- Сдвиг от UTC: +07:00
Если нужно, могу показать текущее местное время для этого номера или конвертировать заданное время в этот часовой пояс.
Доработаем, чтобы выводил кратко и более содержательно:
Ты помощник, который определяет часовой пояс по номеру телефона.
{# Иначе выводит многословно #}
Выведи результат очень кратко и строго эти данные: часовой пояс, смещение UTC, регион и страну.
Запустим
$ python get_timezone.py 89132342323
Смещение UTC: +03:00
Регион: Алтайский край
Страна: Россия (RU)
Уже лучше. Представим, что мы хотим подсказывать смещение относительно нашего часового пояса.
Ты помощник, который определяет часовой пояс по номеру телефона.
Текущий часовой пояс пользователя: {{ server_timezone }} (UTC{{ "%+d" | format(server_offset) }})
Текущее время у пользователя: {{ current_time }}
{# Иначе выводит многословно #}
Выведи результат очень кратко и строго эти данные:
- Разница во времени + пример, сколько времени у пользователя и абонента
- Регион абонента
- Страна абонента
Глянем
python get_timezone.py 89132342323
- Разница во времени: +4 ч — у вас 17:37, у абонента 21:37
- Регион абонента: Алтайский край
- Страна абонента: Россия (RU)
Спустя время мы захотели добавить параметр --short в вызов скрипта, чтобы выводить информацию только о разнице во времени. Доработаем промпт:
Ты помощник, который определяет часовой пояс по номеру телефона.
Текущий часовой пояс пользователя: {{ server_timezone }} (UTC{{ "%+d" | format(server_offset) }})
Текущее время у пользователя: {{ current_time }}
{# Иначе выводит многословно #}
Выведи результат очень кратко и строго эти данные:
- Разница во времени + пример, сколько времени у пользователя и абонента
{% if not short %}
- Регион абонента
- Страна абонента
{% endif %}
Проверим:
$ python get_timezone.py 89132342323
Разница: +4 ч — у вас 17:43, у абонента 21:43
Регион: Алтайский край (Asia/Barnaul)
Страна: Россия (RU)
$ python get_timezone.py 89132342323 --short
Разница: +4 ч — у пользователя 17:44, у абонента 21:44
Как итог
* Промпт читаемый с подсветкой (как jinja, так и markdown)
* Работают проверки от IDE (в том числе на орфографию/пунктуацию)
* Промпт можно обогащать вкраплениями логики
* Одно из самых важных Фрагменты промпта можно дополнять комментариями
А как выглядит финальный промпт в IDE, можно увидеть на картинке к посту.
🔗 Инженерия и AI | Ilyas Salikhov
👍2
Ilyas Salikhov
Как организовать работу с промптами для AI-агентов В RetailCRM мы начинали с промптов в формате строки или f-string. Для простых промптов это ок. Но вот ты написал первую версию промпта, запустил, увидел косяки или ненужное поведение LLM, дорабатываешь…
Как тестировать AI-агентов (python-пакет llm-flaky)
AI-агентов надо тестировать. С этим, думаю, никто не спорит.
Конечно, можно использовать ручное тестирование, но по мере усложнения агента это делать всё сложнее. Да и есть такая «неприятная» часть бизнес-логики, которая заложена в виде промпта. А его изменение, бывает, начинает влиять на поведение агента там, где не ожидаешь.
Короче, тесты нужны. Мы их пишем в виде обычных
Но LLM — вещь недетерминированная. Сейчас она ответила так, а при следующем прогоне иначе. Мы регулярно сталкивались с «миганиями» тестов. И пришли к тому, что для LLM это ок. Они по определению не гарантируют правильный ответ в всех случаях.
Мы для себя задаем планку в 80% успешных прогонов. Реализуем через многократный прогон теста нужное количество раз. Для 80% тест должен успешно выполниться как минимум 4 раза из 5.
Все упаковали и оформили в pypi-пакет llm-flaky.
Как пользоваться llm-flaky
1. Ставите пакет
2. Размечаете llm-тесты
3. Прогоняете и на выходе получаете красивый отчет 🙂
Вы можете настроить свои пороги успешного прохождения llm-теста, в пакете предусмотрены соответствующие параметры.
Также поддерживается рапараллеливание через
🔗 Инженерия и AI | Ilyas Salikhov
AI-агентов надо тестировать. С этим, думаю, никто не спорит.
Конечно, можно использовать ручное тестирование, но по мере усложнения агента это делать всё сложнее. Да и есть такая «неприятная» часть бизнес-логики, которая заложена в виде промпта. А его изменение, бывает, начинает влиять на поведение агента там, где не ожидаешь.
Короче, тесты нужны. Мы их пишем в виде обычных
pytest-ов.Но LLM — вещь недетерминированная. Сейчас она ответила так, а при следующем прогоне иначе. Мы регулярно сталкивались с «миганиями» тестов. И пришли к тому, что для LLM это ок. Они по определению не гарантируют правильный ответ в всех случаях.
Мы для себя задаем планку в 80% успешных прогонов. Реализуем через многократный прогон теста нужное количество раз. Для 80% тест должен успешно выполниться как минимум 4 раза из 5.
Все упаковали и оформили в pypi-пакет llm-flaky.
Как пользоваться llm-flaky
1. Ставите пакет
2. Размечаете llm-тесты
import pytest
@pytest.mark.llm
async def test_llm_response():
response = await call_llm("What is 2+2?")
assert "4" in response
3. Прогоняете и на выходе получаете красивый отчет 🙂
Вы можете настроить свои пороги успешного прохождения llm-теста, в пакете предусмотрены соответствующие параметры.
Также поддерживается рапараллеливание через
pytest-xdist. Сильно ускоряет прогоны.🔗 Инженерия и AI | Ilyas Salikhov
👍2🔥1
Жизнеспособен ли подход: толстый backend и тонкий frontend
На митапе (проводим их регулярно) Саша Черняев, эксперт в мире Laravel, рассказывал про Hotwire. Если кратко: сервер рендерит HTML, а браузер получает обновления частями и добавляет немного JS для поведения – вместо SPA с большим клиентским состоянием.
Я уже сталкивался с Hotwire и, чтобы опробовать, делал внутреннюю систему на стеке Symfony + Hotwire.
Из доклада узнал, что появилась поддержка мобилок. Приложения выглядят классно. Но, как понимаете, без интернета не работает от слова «совсем».
Какие впечатления от технологии сложились у меня:
➕ Плюсы
1. Работает очень быстро. По ощущениям все летает
2. Нет тяжёлой «первой загрузки» SPA-бандла
2. Не нужно возиться с Webpack/React/... и их настройкой
3. Не требуется разрабатывать API для общения бекенда и фронта
4. Готовое решение для мобилок (правда веб-ориентированное)
➖ Минусы
1. Не подходит для сайтов, которые и не сайты, а скорее приложения, аля Figma или RetailCRM со сложными интерфейсами. Логика становится запутанной
2. Разработчикам требуется достаточно уверенно чувствовать себя в обоих стеках (бекенд и фронтенд)
Когда целесообразно использовать
1. В проекте есть и бекенд, и фронтенд
2. Фронтовая логика не очень сложная
3. Проект небольшой или средний (условно до ~300k строк)
4. Команда разработчиков небольшая
5. Разработчики фуллстеки (умеют и во фронт, и в бекенд)
В таком случае Hotwire помогает быстрее стартовать, а интерфейс получается быстрым. Если же вы разрабатываете сложное «толстое» приложение с богатым клиентским состоянием, разумнее сразу смотреть в сторону SPA.
🔗 Инженерия и AI | Ilyas Salikhov
На митапе (проводим их регулярно) Саша Черняев, эксперт в мире Laravel, рассказывал про Hotwire. Если кратко: сервер рендерит HTML, а браузер получает обновления частями и добавляет немного JS для поведения – вместо SPA с большим клиентским состоянием.
Я уже сталкивался с Hotwire и, чтобы опробовать, делал внутреннюю систему на стеке Symfony + Hotwire.
Из доклада узнал, что появилась поддержка мобилок. Приложения выглядят классно. Но, как понимаете, без интернета не работает от слова «совсем».
Какие впечатления от технологии сложились у меня:
1. Работает очень быстро. По ощущениям все летает
2. Нет тяжёлой «первой загрузки» SPA-бандла
2. Не нужно возиться с Webpack/React/... и их настройкой
3. Не требуется разрабатывать API для общения бекенда и фронта
4. Готовое решение для мобилок (правда веб-ориентированное)
1. Не подходит для сайтов, которые и не сайты, а скорее приложения, аля Figma или RetailCRM со сложными интерфейсами. Логика становится запутанной
2. Разработчикам требуется достаточно уверенно чувствовать себя в обоих стеках (бекенд и фронтенд)
Когда целесообразно использовать
1. В проекте есть и бекенд, и фронтенд
2. Фронтовая логика не очень сложная
3. Проект небольшой или средний (условно до ~300k строк)
4. Команда разработчиков небольшая
5. Разработчики фуллстеки (умеют и во фронт, и в бекенд)
В таком случае Hotwire помогает быстрее стартовать, а интерфейс получается быстрым. Если же вы разрабатываете сложное «толстое» приложение с богатым клиентским состоянием, разумнее сразу смотреть в сторону SPA.
🔗 Инженерия и AI | Ilyas Salikhov
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
Media is too big
VIEW IN TELEGRAM
JS-модули в RetailCRM
Год назад начали активно развивать (и продолжаем развивать) JS API в RetailCRM.
Технология построена на подходе vue-remote, когда реальный код js-модуля выполняется в песочнице и его интерпретация в безопасном режиме применяется в интерфейсу системы.
За год появилось много полезной функциональности от партнеров и нас самих, расширяющей возможности системы: заметки к заказу, работа с промокодами и акциями, вывод фискальных чеков и многое другое.
На данный момент можно встраиваться в существующие страницы. Дальше планируем дать возможность регистрировать JS-модулям новые страницы системы. Даст новый огромный пласт для расширения системы!
Кстати код js-модулей отлично пишется AI-шкой в силу их небольшого размера и знакомого для AI стека VueJS. Плюс мы даем готовый набор компонентов, которые сами используем для построения интерфейса, что дает возможность строить интерфейсы модуля еще быстрее.
На видео все шторки и попапу рендерятся JS-модулями.
🔗 Инженерия и AI | Ilyas Salikhov
Год назад начали активно развивать (и продолжаем развивать) JS API в RetailCRM.
Технология построена на подходе vue-remote, когда реальный код js-модуля выполняется в песочнице и его интерпретация в безопасном режиме применяется в интерфейсу системы.
За год появилось много полезной функциональности от партнеров и нас самих, расширяющей возможности системы: заметки к заказу, работа с промокодами и акциями, вывод фискальных чеков и многое другое.
На данный момент можно встраиваться в существующие страницы. Дальше планируем дать возможность регистрировать JS-модулям новые страницы системы. Даст новый огромный пласт для расширения системы!
Кстати код js-модулей отлично пишется AI-шкой в силу их небольшого размера и знакомого для AI стека VueJS. Плюс мы даем готовый набор компонентов, которые сами используем для построения интерфейса, что дает возможность строить интерфейсы модуля еще быстрее.
На видео все шторки и попапу рендерятся JS-модулями.
🔗 Инженерия и AI | Ilyas Salikhov
🔥7👍1
GraphQL — идеальный формат для AI (скажи нет MCP)
Anthropic создали протокол MCP для подключения апишек к LLM, и если почитать их блог, то теперь им приходится изобретать способы, как обойти перегруженность этого формата.
О каких проблемах MCP я говорю:
1. LLM видит, какие «ручки» можно вызвать, но не видит, что возвращается, пока не вызовет
2. LLM не может управлять тем, что именно она хочет получить. В MCP мы вынуждены отдавать все, что есть, как в REST API, забивая контекст ненужной информацией
3. Чтобы получить достаточный объем данных для решения своей задачи, LLM может требоваться сделать N запросов.
Все это про то, что MCP очень негибкий для использования LLM. При этом есть прекрасный формат GraphQL, в котором предусмотрено решение всех этих проблем:
📜 GQL-схема
Есть gql-схема, по которой LLM может увидеть, какие «ручки» она может дергать и какие данные можно получить. Все описано с точностью до полей
⚙️ GQL query syntax
LLM может точно указать, какие поля она хочет получить. Представьте, что LLM нужно получить заказы с их стоимостью. Объект заказа легко может содержать 100+ полей, а LLM для ее задачи нужно 4: номер, дата оформления, статус и стоимость. Экономия контекста может быть до 95%.
🌲 Nested objects querying
Еще одной киллер-фичой GQL в контексте LLM является возможность за один запрос вытаскивать вложенные данные. Особенно, когда речь про 1+N запросы. Представьте что LLM получила список заказов, и для каждого заказа ей нужно еще получить связные с ними задачи на менеджеров. В GQL это можно описать в одном query. Тем самым мы сильно экономим на количестве вызовов.
А что вы думаете про работу с MCP и GQL в AI-агентах?
🔗 Инженерия и AI | Ilyas Salikhov
Anthropic создали протокол MCP для подключения апишек к LLM, и если почитать их блог, то теперь им приходится изобретать способы, как обойти перегруженность этого формата.
О каких проблемах MCP я говорю:
1. LLM видит, какие «ручки» можно вызвать, но не видит, что возвращается, пока не вызовет
2. LLM не может управлять тем, что именно она хочет получить. В MCP мы вынуждены отдавать все, что есть, как в REST API, забивая контекст ненужной информацией
3. Чтобы получить достаточный объем данных для решения своей задачи, LLM может требоваться сделать N запросов.
Все это про то, что MCP очень негибкий для использования LLM. При этом есть прекрасный формат GraphQL, в котором предусмотрено решение всех этих проблем:
📜 GQL-схема
Есть gql-схема, по которой LLM может увидеть, какие «ручки» она может дергать и какие данные можно получить. Все описано с точностью до полей
⚙️ GQL query syntax
LLM может точно указать, какие поля она хочет получить. Представьте, что LLM нужно получить заказы с их стоимостью. Объект заказа легко может содержать 100+ полей, а LLM для ее задачи нужно 4: номер, дата оформления, статус и стоимость. Экономия контекста может быть до 95%.
orders {
number
createdAt
status { name }
totalSum {
amount
currency
}
}
🌲 Nested objects querying
Еще одной киллер-фичой GQL в контексте LLM является возможность за один запрос вытаскивать вложенные данные. Особенно, когда речь про 1+N запросы. Представьте что LLM получила список заказов, и для каждого заказа ей нужно еще получить связные с ними задачи на менеджеров. В GQL это можно описать в одном query. Тем самым мы сильно экономим на количестве вызовов.
orders {
number
createdAt
tasks {
noscript
deadline
manager { id name }
}
}
А что вы думаете про работу с MCP и GQL в AI-агентах?
🔗 Инженерия и AI | Ilyas Salikhov
👍7
Как эффективно использовать Claude Code
Создатель Claude Code показал свой «ванильный» сетап, и в нем есть хорошие идеи, которые стоит утащить себе в работу.
Главная мысль: продуктивность растёт от выстроенной системы вокруг модели.
1) Параллелит задачи
Он держит 5 сессий в терминале + 5–10 в вебе. Не потому что «хаос», а потому что разные потоки работы: одна сессия планирует, другая правит код, третья гоняет проверки, четвёртая разбирает баг-репорт и т.д.
Важно: чтобы работа спорилась, он настроил системные нотификации, когда агенту нужен человек.
2) Выбирает модель дороже, но быстрее по итогу
Использует Opus 4.5 постоянно: она медленнее, но требует меньше «ручного управления» и лучше работает с инструментами → меньше итераций → быстрее доходим до результата.
3) Командная «память» как код
У команды общий CLAUDE.md в репозитории. Любая повторяющаяся ошибка агента → добавили правило в этот файл → закоммитили → вся команда получает «анти-грабли».
При этом он обычно просит доработать CLAUDE.md самого Claude.
4) Планирование как обязательный этап
Большинство сессий стартует в Plan mode: пока план не нравится, обсуждает с агентом и уточняет. А когда план ок — переключается в режим авто-принятия правок, и PR часто получается «в один заход».
5) Рутину упаковывает в slash-команды
Всё, что повторяется десятки раз в день, превращает в /команду (и хранит в репе). Как пример, приводит команду
6) «Субагенты» под типовые роли
Отдельные агенты под частые задачи: упростить код после правок, прогнать end-to-end проверку, и т.п. Сюда идет то, что уже не умещается в слеш-команду в силу сложности или нечеткой логики.
7) Форматирование на хуках Claude
Настраивает форматирование на хуках Claude. Как правило код сразу ок, но
8) Права заранее, а не “skip everything”
Он не работает в режиме dangerously-skip-permissions. Вместо этого заранее разрешает безопасные команды через
9) 📍Самое важное: верификация
Лучший буст качества — дать агенту способ проверять себя.
У них Claude тестирует изменения (вплоть до UI в браузере) и итеративно чинит, пока не добъется отсутствия ошибок. Верификация может быть любой: тесты, скрипт, симулятор, ручной чек-лист — но она должна быть надёжной.
Тут я на 100% подтверждаю: чем сложнее задача, тем важнее наличие тестов или аналога для верификации новой версии кода.
🔗 Инженерия и AI | Ilyas Salikhov
Создатель Claude Code показал свой «ванильный» сетап, и в нем есть хорошие идеи, которые стоит утащить себе в работу.
Главная мысль: продуктивность растёт от выстроенной системы вокруг модели.
1) Параллелит задачи
Он держит 5 сессий в терминале + 5–10 в вебе. Не потому что «хаос», а потому что разные потоки работы: одна сессия планирует, другая правит код, третья гоняет проверки, четвёртая разбирает баг-репорт и т.д.
Важно: чтобы работа спорилась, он настроил системные нотификации, когда агенту нужен человек.
2) Выбирает модель дороже, но быстрее по итогу
Использует Opus 4.5 постоянно: она медленнее, но требует меньше «ручного управления» и лучше работает с инструментами → меньше итераций → быстрее доходим до результата.
3) Командная «память» как код
У команды общий CLAUDE.md в репозитории. Любая повторяющаяся ошибка агента → добавили правило в этот файл → закоммитили → вся команда получает «анти-грабли».
При этом он обычно просит доработать CLAUDE.md самого Claude.
4) Планирование как обязательный этап
Большинство сессий стартует в Plan mode: пока план не нравится, обсуждает с агентом и уточняет. А когда план ок — переключается в режим авто-принятия правок, и PR часто получается «в один заход».
5) Рутину упаковывает в slash-команды
Всё, что повторяется десятки раз в день, превращает в /команду (и хранит в репе). Как пример, приводит команду
/commit-push-pr, которую он и Claude используют по несколько раз в день.6) «Субагенты» под типовые роли
Отдельные агенты под частые задачи: упростить код после правок, прогнать end-to-end проверку, и т.п. Сюда идет то, что уже не умещается в слеш-команду в силу сложности или нечеткой логики.
7) Форматирование на хуках Claude
Настраивает форматирование на хуках Claude. Как правило код сразу ок, но
PostToolUse-hook доводит форматирование «последних 10%» кода, чтобы не ловить глупые ошибки в CI.8) Права заранее, а не “skip everything”
Он не работает в режиме dangerously-skip-permissions. Вместо этого заранее разрешает безопасные команды через
/permissions и шарит настройки с командой.9) 📍Самое важное: верификация
Лучший буст качества — дать агенту способ проверять себя.
У них Claude тестирует изменения (вплоть до UI в браузере) и итеративно чинит, пока не добъется отсутствия ошибок. Верификация может быть любой: тесты, скрипт, симулятор, ручной чек-лист — но она должна быть надёжной.
Тут я на 100% подтверждаю: чем сложнее задача, тем важнее наличие тестов или аналога для верификации новой версии кода.
🔗 Инженерия и AI | Ilyas Salikhov
X (formerly Twitter)
Boris Cherny (@bcherny) on X
I'm Boris and I created Claude Code. Lots of people have asked how I use Claude Code, so I wanted to show off my setup a bit.
My setup might be surprisingly vanilla! Claude Code works great out of the box, so I personally don't customize it much. There is…
My setup might be surprisingly vanilla! Claude Code works great out of the box, so I personally don't customize it much. There is…
👍5🔥2
AI Commerce
Прокомментировал в Forbes появление в Алисе AI карточек товаров.
ChatGPT, Gemini, Microsoft Copilot, Алиса — по сути все подобные платформы движутся семимильными шагами в сторону AI Commerce (подбор товара при общении и оформление заказа). Логичное развитие.
У Алисы сейчас новая веха, когда она помимо уже привычного голосового помощника активно укрепляется и как текстовый. Яндекс запустил ее как отдельное приложение для мобилок. Также не стоит забывать Я.Браузер, где, уверен, Алиса будет очень плотно встроена. За счет Алисы Яндекс имеет шансы заметно потеснить маркетплейсы (Ozon, WB). Не очень успешно получалось с помощью Я.Маркета, может, сейчас получится.
🔗 Инженерия и AI | Ilyas Salikhov
Прокомментировал в Forbes появление в Алисе AI карточек товаров.
ChatGPT, Gemini, Microsoft Copilot, Алиса — по сути все подобные платформы движутся семимильными шагами в сторону AI Commerce (подбор товара при общении и оформление заказа). Логичное развитие.
У Алисы сейчас новая веха, когда она помимо уже привычного голосового помощника активно укрепляется и как текстовый. Яндекс запустил ее как отдельное приложение для мобилок. Также не стоит забывать Я.Браузер, где, уверен, Алиса будет очень плотно встроена. За счет Алисы Яндекс имеет шансы заметно потеснить маркетплейсы (Ozon, WB). Не очень успешно получалось с помощью Я.Маркета, может, сейчас получится.
🔗 Инженерия и AI | Ilyas Salikhov
👍6❤2
Продакшен RetailCRM в цифрах 🔵
RetailCRM в IT-сфере не так на слуху, как в ecom/retail, всё-таки нишевое решение. В декабре традиционно подводили итоги года, и я посмотрел актуальные цифры по нашему продакшену. Подумал: почему бы не поделиться?
✨Ключевые цифры:
→ ~6000 заказов/час проходит через систему
→ 45 000+ внешних систем интегрировано и регулярно обменивается данными
→ 100+ млн HTTP-запросов/день прилетает в приложения
→ ~100 000 tps — нагрузка на базы PostgreSQL (транзакций в секунду)
→ 250+ серверов — размер продакшена
→ 550 ГБ логов или 0,5 млрд записей в сутки
Для многих клиентов RetailCRM — core-система их IT-инфраструктуры, и это ответственность. Уделяем большое внимание стабильности и надежности.
И могу без преувеличения сказать, что мы №1 решение для e-commerce и ритейла.
🔗 Инженерия и AI | Ilyas Salikhov
RetailCRM в IT-сфере не так на слуху, как в ecom/retail, всё-таки нишевое решение. В декабре традиционно подводили итоги года, и я посмотрел актуальные цифры по нашему продакшену. Подумал: почему бы не поделиться?
✨Ключевые цифры:
→ ~6000 заказов/час проходит через систему
→ 45 000+ внешних систем интегрировано и регулярно обменивается данными
→ 100+ млн HTTP-запросов/день прилетает в приложения
→ ~100 000 tps — нагрузка на базы PostgreSQL (транзакций в секунду)
→ 250+ серверов — размер продакшена
→ 550 ГБ логов или 0,5 млрд записей в сутки
Для многих клиентов RetailCRM — core-система их IT-инфраструктуры, и это ответственность. Уделяем большое внимание стабильности и надежности.
И могу без преувеличения сказать, что мы №1 решение для e-commerce и ритейла.
🔗 Инженерия и AI | Ilyas Salikhov
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥15👍3❤2
Конструктор сценариев в RetailCRM и при чем тут Temporal [Часть 1]
В последнем релизе RetailCRM мы запустили раздел Сценарии. Если объяснять просто, можно накидывать на холсте сложную логику процессов, в первую очередь коммуникации с клиентами через email, чаты, sms, но не только. А чтобы не составлять руками, научили AI-помощника собирать сценарии по вводным от пользователя. Но обо всём по порядку.
Модуль сложный и интересный, кажется, тянет на серию постов.
Расскажу сначала, в чем были технические сложности задачи. Вводные были таковы:
1. Создание и запуск динамических workflow
Пользователь должен сам настроить логику сценария, а мы её выполнить
2. Асинхронное выполнение сценариев
Сценарий должен запуститься по событию и пройти свой путь, не блокируя точку запуска сценария. События могут вызываться часто).
3. Распределенность выполнения сценария
Разные функции RetailCRM физически локализованы в разных сервисах. Созданное решение должно обеспечивать распределенное прохождение разных частей сценария в разных сервисах.
4. Протяженное время выполнения сценария
Должны быть блоки ожидания от нескольких минут до месяцев. Сценарии могут выполняться долго и не должны «ломаться» при деплоях новых версий.
Примеры:
• отправили письмо → ждем час → проверяем, что письмо не открыто → отправляем чат-сообщение
• заказ перешел в статус Выполнен → ждем 3 месяца → проверяем, что за 3 месяца у клиента не было заказов → отправляем каскад имейл/чат/смс с предложением повторить заказ
5. Отказоустойчивость выполнения сценариев
Должна быть заложена обработка неудачного выполнения шагов. Это может быть временная недоступность внешних сервисов (например, email-транспорт), внутренних сервисов, временные ошибки. Возможность задать логику ретраев и времени ожидания выполнения шага.
6. Версионность сценариев
Например, пользователь создал первую версию сценария и запустил её. После этого изменил флоу сценария и запустил обновленную версию. Все срабатывания первой версии, что уже на этапе выполнения, должны не сломаться и довести свою работу до конца.
7. Контекст выполнения сценария
Контекст сценария должен быть наполнен стартовыми данными (объект клиента, данные события) и обогащаться данными выполненных шагов сценария (отправленное ранее письмо и его статус, поставленная задача, созданный/измененный заказ и тд)
⚙️ Почему Temporal?
Под подобные задачи есть класс решений (Cadence, Restate, DBOS). Изучая их, мы пришли к Temporal. За него кстати также активно топят ребята из @php_fart.
Temporal выступает таким мастер-менеджером, который не знает, по какой логике нужно выполнить workflow, не знает, какие элементы workflow надо выполнить, но знает, куда сходить за этими знаниями, и обеспечит выполнение всего, что ему сказали выполнить, в тех местах, где ему указали выполнить.
Что дает Temporal:
• Workflow-as-code — элементы воркфлоу реализуются в коде, что позволяет нам реализовать логику предоставляемых «кубиков» Сценария
• Обширный набор SDK под разные языки. В том числе под наши: PHP и Go
• Отказоустойчивость, настраиваемая политика ретраев и таймаутов
• Масштабируемость — Temporal состоит из нескольких компонентов и каждый из них можно масштабировать
• Observability: API и GUI для просмотра, что происходит в рантайме с детализацией до отдельных шагов workflow
• История выполнений workflow
• Протокол общения gRPC, это быстро
• Self-hosted, open source (MIT) — можно использовать в своем продукте на своих серверах
Temporal — важная, но лишь одна из составляющих решения. Как выглядит архитектура в целом, расскажу в следующих постах.
Кстати, отличный рассказ про Temporal и Сценарии в RetailCRM был от Ивана Чернявцева на нашем митапе.
🔗 Инженерия и AI | Ilyas Salikhov
В последнем релизе RetailCRM мы запустили раздел Сценарии. Если объяснять просто, можно накидывать на холсте сложную логику процессов, в первую очередь коммуникации с клиентами через email, чаты, sms, но не только. А чтобы не составлять руками, научили AI-помощника собирать сценарии по вводным от пользователя. Но обо всём по порядку.
Модуль сложный и интересный, кажется, тянет на серию постов.
Расскажу сначала, в чем были технические сложности задачи. Вводные были таковы:
1. Создание и запуск динамических workflow
Пользователь должен сам настроить логику сценария, а мы её выполнить
2. Асинхронное выполнение сценариев
Сценарий должен запуститься по событию и пройти свой путь, не блокируя точку запуска сценария. События могут вызываться часто).
3. Распределенность выполнения сценария
Разные функции RetailCRM физически локализованы в разных сервисах. Созданное решение должно обеспечивать распределенное прохождение разных частей сценария в разных сервисах.
4. Протяженное время выполнения сценария
Должны быть блоки ожидания от нескольких минут до месяцев. Сценарии могут выполняться долго и не должны «ломаться» при деплоях новых версий.
Примеры:
• отправили письмо → ждем час → проверяем, что письмо не открыто → отправляем чат-сообщение
• заказ перешел в статус Выполнен → ждем 3 месяца → проверяем, что за 3 месяца у клиента не было заказов → отправляем каскад имейл/чат/смс с предложением повторить заказ
5. Отказоустойчивость выполнения сценариев
Должна быть заложена обработка неудачного выполнения шагов. Это может быть временная недоступность внешних сервисов (например, email-транспорт), внутренних сервисов, временные ошибки. Возможность задать логику ретраев и времени ожидания выполнения шага.
6. Версионность сценариев
Например, пользователь создал первую версию сценария и запустил её. После этого изменил флоу сценария и запустил обновленную версию. Все срабатывания первой версии, что уже на этапе выполнения, должны не сломаться и довести свою работу до конца.
7. Контекст выполнения сценария
Контекст сценария должен быть наполнен стартовыми данными (объект клиента, данные события) и обогащаться данными выполненных шагов сценария (отправленное ранее письмо и его статус, поставленная задача, созданный/измененный заказ и тд)
⚙️ Почему Temporal?
Под подобные задачи есть класс решений (Cadence, Restate, DBOS). Изучая их, мы пришли к Temporal. За него кстати также активно топят ребята из @php_fart.
Temporal выступает таким мастер-менеджером, который не знает, по какой логике нужно выполнить workflow, не знает, какие элементы workflow надо выполнить, но знает, куда сходить за этими знаниями, и обеспечит выполнение всего, что ему сказали выполнить, в тех местах, где ему указали выполнить.
Что дает Temporal:
• Workflow-as-code — элементы воркфлоу реализуются в коде, что позволяет нам реализовать логику предоставляемых «кубиков» Сценария
• Обширный набор SDK под разные языки. В том числе под наши: PHP и Go
• Отказоустойчивость, настраиваемая политика ретраев и таймаутов
• Масштабируемость — Temporal состоит из нескольких компонентов и каждый из них можно масштабировать
• Observability: API и GUI для просмотра, что происходит в рантайме с детализацией до отдельных шагов workflow
• История выполнений workflow
• Протокол общения gRPC, это быстро
• Self-hosted, open source (MIT) — можно использовать в своем продукте на своих серверах
Temporal — важная, но лишь одна из составляющих решения. Как выглядит архитектура в целом, расскажу в следующих постах.
Кстати, отличный рассказ про Temporal и Сценарии в RetailCRM был от Ивана Чернявцева на нашем митапе.
🔗 Инженерия и AI | Ilyas Salikhov
🔥8👍5
Ближайшие два года в разработке: что нас ждет с точки зрения AI 🤖
Addy Osmani (Google Cloud AI director, 14 лет в Chrome/DevTools) разбирает в своем недавнем посте пять ключевых вопросов, которые определят нашу профессию в 2026-2027. Поделюсь главными тезисами + своими мыслями.
1. Проблема junior-разработчиков 👨💻
Исследование Harvard на 62 млн работников показало: компании, внедрившие генеративный AI, сокращают наем junior на 9-10% в течение 6 кварталов. При этом наем senior почти не меняется.
Big Tech за последние 3 года наняли на 50% меньше выпускников. Логика проста: зачем платить junior $90K, если AI-агент справляется дешевле?
Но есть и оптимистичный сценарий: AI может разблокировать спрос на разработчиков в новых индустриях — healthcare, manufacturing, агро. Не заменить, а распределить разработку туда, где её раньше не было.
Мои мысли: Долгосрочный риск очевиден — если обрубить pipeline junior-ов сегодня, через 5-10 лет получим дефицит senior/tech lead. Индустрия будет рубить сук, на котором сидит.
2. Атрофия навыков или их усиление? 🧠
84% разработчиков используют AI регулярно. Многие новички вообще не пишут код "с нуля" — только compose промпты и склеивают AI-generated куски.
Риск: поколение, которое не умеет дебажить или писать алгоритмы самостоятельно. AI вносит subtle баги и уязвимости, которые junior могут не заметить.
Контр-сценарий: раз AI берет рутинные 80%, человек фокусируется на сложных 20% — архитектура, интеграции, edge cases. Глубокие знания становятся критичнее, а не наоборот.
Цитата из статьи: "Лучшие инженеры — не те, кто быстрее кодит, а те, кто знает, когда не доверять AI."
Мои мысли: Мы в RetailCRM видим это на практике. AI помогает быстро генерить код, но review требует большего внимания. Архитектурные решения и security всё еще полностью на людях.
3. Роль разработчика: аудитор или оркестратор? 🎭
Пессимистичный вариант: разработчик превращается в "code janitor" — проверяет AI-generated PR, исправляет баги, следит за compliance. Творчество убито.
Оптимистичный: разработчик становится оркестратором — проектирует системы, распределяет задачи между AI-агентами и сервисами, склеивает решения из множества компонентов. Роль становится междисциплинарной: инженер + архитектор + продуктовый стратег.
Мои мысли: Со своей стороны вижу скорее второй вариант. Ключ в том, как компания интегрирует AI. Если видит его как замену труда, то получит аудиторов. Если как усилитель команды — получит оркестраторов.
4. T-shaped инженеры vs узкие специалисты 🔧
Узкая специализация становится рискованной. AI может автоматизировать нишу, и специалист останется не у дел (вспомните Flash, COBOL).
Тренд: T-shaped разработчики — глубокая экспертиза в 1-2 областях + широкий кругозор в других. 45% вакансий уже требуют знаний в нескольких доменах. AI как раз помогает: backend-разработчик с AI может нарисовать UI, frontend — сгенерить серверную часть.
Мои мысли: Полностью согласен. У нас в команде наиболее эффективны именно T-shaped специалисты. Исторически мы стараемся брать фулл-стеков. Понятно, что сейчас невозможно найти одинаково сильного человека и в бекенде, и во фронте, но более широкий кругозор позволяет снимать ботлнеки и работать более компактными командами. А с приходом AI в одного человека запилить очень приличный не то, что MVP, а вполне себе небольшой продукт.
↓ продолжение
🔗 Инженерия и AI | Ilyas Salikhov
Addy Osmani (Google Cloud AI director, 14 лет в Chrome/DevTools) разбирает в своем недавнем посте пять ключевых вопросов, которые определят нашу профессию в 2026-2027. Поделюсь главными тезисами + своими мыслями.
1. Проблема junior-разработчиков 👨💻
Исследование Harvard на 62 млн работников показало: компании, внедрившие генеративный AI, сокращают наем junior на 9-10% в течение 6 кварталов. При этом наем senior почти не меняется.
Big Tech за последние 3 года наняли на 50% меньше выпускников. Логика проста: зачем платить junior $90K, если AI-агент справляется дешевле?
Но есть и оптимистичный сценарий: AI может разблокировать спрос на разработчиков в новых индустриях — healthcare, manufacturing, агро. Не заменить, а распределить разработку туда, где её раньше не было.
Мои мысли: Долгосрочный риск очевиден — если обрубить pipeline junior-ов сегодня, через 5-10 лет получим дефицит senior/tech lead. Индустрия будет рубить сук, на котором сидит.
2. Атрофия навыков или их усиление? 🧠
84% разработчиков используют AI регулярно. Многие новички вообще не пишут код "с нуля" — только compose промпты и склеивают AI-generated куски.
Риск: поколение, которое не умеет дебажить или писать алгоритмы самостоятельно. AI вносит subtle баги и уязвимости, которые junior могут не заметить.
Контр-сценарий: раз AI берет рутинные 80%, человек фокусируется на сложных 20% — архитектура, интеграции, edge cases. Глубокие знания становятся критичнее, а не наоборот.
Цитата из статьи: "Лучшие инженеры — не те, кто быстрее кодит, а те, кто знает, когда не доверять AI."
Мои мысли: Мы в RetailCRM видим это на практике. AI помогает быстро генерить код, но review требует большего внимания. Архитектурные решения и security всё еще полностью на людях.
3. Роль разработчика: аудитор или оркестратор? 🎭
Пессимистичный вариант: разработчик превращается в "code janitor" — проверяет AI-generated PR, исправляет баги, следит за compliance. Творчество убито.
Оптимистичный: разработчик становится оркестратором — проектирует системы, распределяет задачи между AI-агентами и сервисами, склеивает решения из множества компонентов. Роль становится междисциплинарной: инженер + архитектор + продуктовый стратег.
Мои мысли: Со своей стороны вижу скорее второй вариант. Ключ в том, как компания интегрирует AI. Если видит его как замену труда, то получит аудиторов. Если как усилитель команды — получит оркестраторов.
4. T-shaped инженеры vs узкие специалисты 🔧
Узкая специализация становится рискованной. AI может автоматизировать нишу, и специалист останется не у дел (вспомните Flash, COBOL).
Тренд: T-shaped разработчики — глубокая экспертиза в 1-2 областях + широкий кругозор в других. 45% вакансий уже требуют знаний в нескольких доменах. AI как раз помогает: backend-разработчик с AI может нарисовать UI, frontend — сгенерить серверную часть.
Мои мысли: Полностью согласен. У нас в команде наиболее эффективны именно T-shaped специалисты. Исторически мы стараемся брать фулл-стеков. Понятно, что сейчас невозможно найти одинаково сильного человека и в бекенде, и во фронте, но более широкий кругозор позволяет снимать ботлнеки и работать более компактными командами. А с приходом AI в одного человека запилить очень приличный не то, что MVP, а вполне себе небольшой продукт.
↓ продолжение
🔗 Инженерия и AI | Ilyas Salikhov
👍7🔥3🤔1
↑ начало
5. Судьба традиционного образования 🎓
4-летний CS degree остается стандартом, но под вопросом. Университеты не успевают за индустрией — студенты не изучают cloud, DevOps, современные AI-инструменты.
Альтернатива: bootcamp'ы, онлайн-курсы, сертификации, работодательские программы. 45% компаний в 2024 планировали убрать требование о наличии степени для части позиций.
Мои мысли: фундаментальные знания из CS программ всё ещё важны. Высшая математика, алгоритмы, архитектура, теория баз данных, низкоуровневые языки — это фундамент, на котором выкладываются кирпичики дальнейших знаний и опыта. И ChatGPT нужно использовать не для решения домашек, а как очень крутого ментора и учителя, с которым можно на повышенной скорости поглощать новые темы.
Общий вывод 💡
Индустрия на перепутье. AI не убьет разработку, но сильно её изменит. Ключ к выживанию:
→ Непрерывное обучение
→ T-shaped навыки
→ Фокус на то, что AI не может: критическое мышление, архитектура, коммуникация
→ Умение работать С AI, а не ВМЕСТО него
Лучший способ предсказать будущее — активно его создавать.
Оригинал: https://addyosmani.com/blog/next-two-years/
🔗 Инженерия и AI | Ilyas Salikhov
5. Судьба традиционного образования 🎓
4-летний CS degree остается стандартом, но под вопросом. Университеты не успевают за индустрией — студенты не изучают cloud, DevOps, современные AI-инструменты.
Альтернатива: bootcamp'ы, онлайн-курсы, сертификации, работодательские программы. 45% компаний в 2024 планировали убрать требование о наличии степени для части позиций.
Мои мысли: фундаментальные знания из CS программ всё ещё важны. Высшая математика, алгоритмы, архитектура, теория баз данных, низкоуровневые языки — это фундамент, на котором выкладываются кирпичики дальнейших знаний и опыта. И ChatGPT нужно использовать не для решения домашек, а как очень крутого ментора и учителя, с которым можно на повышенной скорости поглощать новые темы.
Общий вывод 💡
Индустрия на перепутье. AI не убьет разработку, но сильно её изменит. Ключ к выживанию:
→ Непрерывное обучение
→ T-shaped навыки
→ Фокус на то, что AI не может: критическое мышление, архитектура, коммуникация
→ Умение работать С AI, а не ВМЕСТО него
Лучший способ предсказать будущее — активно его создавать.
Оригинал: https://addyosmani.com/blog/next-two-years/
🔗 Инженерия и AI | Ilyas Salikhov
👍10🔥2❤1🙏1
