Мы уже рассказывали, как собрали AI-менеджера маркетплейсов на регулярках, а потом пересадили его на агента и тут же обложили ограничениями: восемь шагов на ход, узкие инструменты с лимитами, урезанные данные, запись в кабинет только после «да» владельца.
Мы обещали поделиться результатами. Делимся: через четыре дня после запуска мы удалили своего агента целиком. Ниже — что показали тесты, почему не стали чинить и что сделали вместо него.
Что показали тесты
Сначала хорошее. Мы собрали эталон: восемь типовых задач на каждую должность и модель-судья, которая ставит ответу оценку от 1 до 5 и видит данные, на которых агент отвечал. Агент обошёл старый разбор фраз у семи должностей из девяти, менеджер маркетплейсов набрал 4,28.
А потом мы стали читать сами разговоры, и картина стала другой.
Агент отвечал уверенно, но поверхностно. Владелец спрашивает, почему просели продажи. Агент смотрит десять товаров из сотни, потому что инструмент отдаёт «до 15 результатов», а в таблице для модели — обрезка. Вывод звучит гладко, только сделан он по десятой части магазина. Судья такой ответ не ловит: данные, которые видел агент, с выводом сходятся.
Узкие инструменты упирались в стену. Обёртка над отзывами отдавала свежие отзывы, а не все. Попросить «разбери все отзывы за полгода» было нельзя: нужного метода в обёртке просто не было. Агент честно звал «нет инструмента» и отвечал «пока не умею». Список таких просьб в админке рос быстрее, чем мы успевали дописывать обёртки.
Наши инструкции мешали модели думать. В описаниях инструментов мы писали, как ими пользоваться:, «один-два вызова широкими словами», «до 15». Модель слушалась. Даже там, где задача требовала двадцати вызовов, она делала два и отвечала тем, что есть.
Лимиты хода били по длинным задачам. Восемь шагов — это «посмотреть продажи, открыть карточку, проверить рекламу». На «разберись, почему падает ниша» их не хватало. Мы подняли лимит до 50 шагов и 15 минут, но это мало что изменило: агент упирался не в число шагов, а в то, что каждый шаг давал ему кусочек данных.
Получилось, что все проблемы растут из одного места. Мы боялись свободы агента и решали за него: сколько смотреть, что показывать, как пользоваться инструментом. Каждое такое решение по отдельности выглядело разумным. Все вместе они превращали агента в старательного стажёра, который делает ровно то, что написано в инструкции.
Почему удалили, а не починили
Своё ядро агента — это цикл, вызовы инструментов, повторы при обрывах, сжатие старых шагов, группы инструментов. Каждую из этих задач мы решали сами, и каждая требовала поддержки. При этом ничего уникального в цикле не было: под прошлой статьёй нам справедливо заметили, что это обычный ReAct.
Уникальное у нас в другом: в инструментах для площадок, в правилах записи в кабинет и в том, как ответ показывается владельцу. Цикл можно взять готовый.
Поэтому мы удалили своё ядро целиком и перевели ход агента на Pydantic AI. Коммит получился такой: 582 строки удалено, 121 добавлена.
agent = Agent(
model,
instructions=system + ASK, # промпт должности и правило «Сделать?»
toolsets=[DeferredLoadingToolset( # редкие инструменты — по поиску, не все в каждом шаге
FunctionToolset(our_tools), tool_names=rare)],
tools=[duckduckgo_search_tool(max_results=8), # интернет: поиск
web_fetch_tool()], # и страница по ссылке
)
r = agent.run_sync(question, message_history=history,
usage_limits=UsageLimits(request_limit=None)) # без лимита шагов
Наши инструменты остались нашими: каждый вызов идёт через ту же функцию, что и раньше, поэтому таблицы владельцу, журнал действий и правила записи не изменились. Поменялось то, что вокруг.
Доступы, а не логика****
Вместе с ядром мы поменяли главный принцип. Раньше мы давали агенту инструменты и объясняли, как ими пользоваться. Теперь даём доступ, инструмент и справку. Как пользоваться, решает агент.
Весь API площадки — один инструмент. Вместо десятков обёрток над отдельными методами Wildberries у агента теперь один инструмент wb_api, через который доступен любой из 307 методов, и второй, wb_help, — официальная справка по ним. Карточки, фото, размеры, цены, остатки, заказы, поставки, реклама, отзывы, чаты, финансы — всё, что умеет API, умеет и агент.
def api(ctx, a):
o = find(a["method"], a["path"]) # метод ищем в официальной справке WB
if o is None:
return Out("Такого метода в справке WB нет — сверьте через wb_help.")
if o["ro"]: # GET и методы-чтения — сразу и целиком
return Out(wb.raw(ctx.tenant, ...), big=True)
pack_add(ctx, a) # запись — только в пакет на «да» владельца
return Out("Подготовлено. Ничего не изменено. Соберите пакет и спросите «Делаю?».")
Так же подключили сервис аналитики MPStats: весь его API одним инструментом и справка рядом.
Данные — целиком. Обрезку таблиц, названий и ячеек для модели убрали. Нужно агенту сто товаров — он видит сто.
Интернет. Агент может искать и читать страницы: правила площадок, свежие изменения в комиссиях, разборы практиков. Библиотеку знаний, которую мы собирали в прошлой версии, убрали из промпта: официальная справка площадки теперь лежит рядом с её API, а остальное агент находит сам.
Никаких «пачкой не зовите». Мы прошлись по всем описаниям инструментов и убрали всё, что диктовало модели, сколько звать и как отвечать.
Что мы оставили
Одно правило пережило и переписывание, и смену принципа: любая запись в кабинет — только после «да» владельца.
Только теперь агент не спрашивает о каждой правке отдельно. Все записи хода копятся в один пакет: «поменять цену у трёх товаров, поднять ставку в двух кампаниях, ответить на четыре отзыва». Владелец видит пакет целиком, «было → станет», и отвечает одним «да». Пакет выполняется по порядку и останавливается на первой ошибке.
Чтение по-прежнему без спроса.
Мелочи, которые оказались важными
Чтения — параллельно. Пока агент смотрит заказы, он уже смотрит и остатки, и рекламу. Правки — строго по одной.
Текст — по мере написания. Владелец видит ответ сразу, а не через минуту, и видит, что агент делает: «ищу правила акции», «читаю отзывы за март».
Рецепты. Удачный вызов API запоминается в проекте. В следующий раз агент зовёт нужный метод сразу, без похода в справку.
Обрыв — не конец хода. Если модель или веб-поиск отвалились посреди задачи, ход продолжается с того же места, а не начинается заново.
Теперь у агента весь API Wildberries, интернет и ни одного нашего лимита. Первые же разговоры показали, что копать он стал по-настоящему глубоко. Настолько глубоко, что нам пришлось задуматься, ту ли модель мы вообще ему дали. Что мы увидели в тестах и что сделали дальше, расскажем, когда закончим разбор.
Автор: Haimi


