Обновить
2
Алексей Селезнев@chappihappymeal

Пользователь

0,1
Рейтинг
Отправить сообщение

Полезная статья. Тезис "правило держится ровно настолько, насколько оно проверяемо", пожалуй, главное, что стоит понять каждому, кто начинает работать с агентами. Добавлю от себя штуки, которые уменьшили число ошибок агента. Часть из них как раз про проверяемость, часть честно вероятностные, но дешёвые.

1. Плагин superpowers с brainstorm перед реализации любой фичи, даже самой мелкой пишу с ним спеку. Это можно сказать гарантия того, что решена нужная задача, а не абстрактная.
2. Обращение агента ко мне по имени в каждом сообщении. Это канарейка: как только обращение пропало, системный промпт вытеснился из контекста, ровно как вы описываете, и пора начинать новую сессию.
3. Система очков. Забыл обращение -10, не верная итерация -5, верная итерация +1. Трюк чисто вероятностный, но, как оказалось, модели обожают зарабатывать очки Точность растет.
4. Уникальный нейминг и грамотное описание функций в комплекте с плагинами по типу дерева памяти. Уменьшает расход токенов.
5. Ваш пункт про свои анализаторы подтверждаю с другого конца: если инвариант это "ключ, зарегистрированный в одном реестре, обязан быть и в парных" (Name объявлен в A -> должен быть в B и C), достаточно простого теста на двустороннюю регистрацию. Агент нарушает, тест бьет по рукам, документация не нужна.
6. Hook на важные действия или обязательные запреты. Как вы заметили, Claude.md и прочие промпты носят лишь рекомендательный характер. Хук же неумолим и обязателен к выполнению.
7. Для типовых задач вместо ссылок на блоки кода с примерами, стоит выносить в Skill набор инструкций с примерами кода, тогда агент работает в разы точнее.

Подписываюсь под каждым вашим словом. В моих проектах часто используется несколько языков программирования, например, тот же Python как тонкая обертка над определенным функционалом (OCR например). Но контроль над вызовами всегда лежит на плечах Go. Нужно долго ждать ответ от внешнего сервиса? Грамотно манипулировать памятью в многопотоке? Идеальный язык для подобных задач.
Пример проблемы: OCR на своих ресурсах дорого, как по цене GPU и пр. инфры для поддержания, так и по цене обучения LLM человекоресурсами (сбор данных, разметка, тюнинг).
Решение: более простой и дешевый путь, уже готовые модели, по типу тех же OpenAI и Anthropic. Делаем сервис ai-controller который роутит трафик в зависимости от соотношения latency и cost per token между сервисами работы с API AI моделей. Получаем устойчивую систему, которая отвалится только в случае деградации сразу n из n внешних провайдеров (естественно оставляем фолбэк на дремлящий тихим сном собственный LLM). Go сервисы в данном случае могут и должны работать на семафоре по памяти, ибо она и будет bottleneck всей системы. За остальное можно не переживать. Ведь сама по себе рутина легковесный поток, а когда дело доходит до сетевых вызовов, тихо и мирно дремлет не в блокирующем режиме, пока NetPoller не даст ей пинка :)

P.S. естественно, помимо ограничений по памяти нужно учитывать рейт лимиты вызовов к внешним API (как отметил автор), причем в общем хранилище, пусть будет Redis, чтобы данные о вызовах оставались согласованными при HPA.

Крутой мини продукт. Выглядит очень приятно. И тут, наверное, главный плюс. Вы не пытаетесь сказать, что это удобно и полезно везде и всегда.

Конкретная боль - кросс-языковые команды. В этом случае все рассуждения о том, что для того же Go решение наверное не самое идиоматичное, надо доставлять .so рядом, думать про musl/alpine в докере, про комбинации OS/arch и.т.д. это осознанная цена за консистентность.

Единственное, чего мне не хватило бы, доп. синтаксиса для явного указания типа. У вас уже есть :: для форс-строки, и напрашивается то же самое для остальных типов, условные ::int и ::float. Защита от дурака для критичных переменных, где типизация по форме может поехать, плюс ревью конфигов становится проще: тип виден глазами, а не выводится в голове.

Пробежался по репо и заметил одну деталь, тихую канонизацию числовых скаляров при выводе типов (1.10 -> 1.1, 01234 -> 1234). Я с подобным сталкивался в работе, поэтому решил помочь и подготовил issue и PR. Ознакомьтесь, может будет полезным.
Issue: https://github.com/ktav-lang/rust/issues/1
PR: https://github.com/ktav-lang/rust/pull/2

Схема в целом хорошая, добавлю два момента из практики.

Перед походом в processed_events напрашивается кэш обработанных eventId в Redis с TTL по окну ретраев провайдера (у ЮKassa это 24 часа, у Stripe до трёх суток) плюс запас. Основная масса повторных доставок отсекается до БД, а не селектом на каждый ретрай. Важная оговорка: кэш здесь именно фильтр, а не источник истины. Уникальное ограничение (provider, event_id) в базе остаётся, иначе на eviction или рестарте инстанса дедупликация разъедется. И от потока уникальных eventId кэш, разумеется, не спасёт, там уже нужен rate limit на входе.

По реконсиляции: если API провайдера умеет отдавать статусы пачкой, сверку стоит сразу проектировать батчами, а не циклом по одному paymentId. На заметном объёме поштучный опрос упирается в rate limit провайдера и растягивает окно расхождения на часы. Это тоже вопрос требований, стоит явно зафиксировать, какие batch-эндпоинты есть у интеграции и какой у них лимит на размер выборки.

Статья понравилась, спасибо, приятно изложена :)

Добавлю свою историю, как инженера, держащего компонент системы. Раньше я думал, что самая не приятная ситуация, это когда ты о чем то попросил, но твою проблему не решили (ваша ситуация). Но как оказалось есть вещи и по интереснее. Когда дело подходит к росту и руководитель тебе говорит, что в данный момент, ты можешь вырасти на 10-15%, но если подождать пол года до общего пересмотра, то рост будет честный >40%. Ты соглашаешься, а через пол года компания морозит рост на не определенный срок. А ты как был среднего роста, так и остался :)

Информация

В рейтинге
3 694-й
Зарегистрирован
Активность

Специализация

Бэкенд разработчик
Ведущий
От 500 000 ₽
Git
SQL
Python
Docker
Linux
ООП
MySQL
Базы данных
Golang
Английский язык