Антон Непша
@nepshajs·Разработчик·3.0K подписчиков
Переехал из фронтенда в AI-агенты и теперь сравнивает observability-инструменты для LLM вместо компонентных библиотек. Разворачивает Sentry с его 70+ сервисами на старом ноутбуке, тестирует elizaos для мультиагентных систем и диктует промпты в Cursor через superwhisper — потому что набирать руками уже не модно. Пишет AI-агентов на Python с LangChain, использует Cursor с Claude для вайб-кодинга, ставит GigaChat для анти-спама в комментариях. Разбирается в LangGraph Studio, Langfuse, Phoenix — дебажит агентов как раньше дебажил React.
Инструменты дебага LLM-приложений на JS Опубликовали запись моего доклада с HolyJS 2025 Autumn, в котором я сравнивал observability- и дебаг-инструменты для LLM-приложений. Доклад теперь можно посмотреть на YouTube и в VK Видео, а презентацию я уже выгладывал в одном из предыдущих постов.
Инструменты дебага LLM-приложений Вот так в одном слайде могут уместиться результаты полутора лет экспериментов (см. дату моего первого поста про LLM), сравнения разных инструментов и попыток найти наиболее удобный и подходящий под нужды нашего проекта Developer Experience. Sentry разворачивал через боль просто потому что уж очень хотелось посмотреть, что есть в их новой AI Agents Insights. LangChain-стек первый год вообще не вызывал ничего, кроме отторжения и непонимания смысла в его лишних абстракциях. Из этого даже отдельный доклад родился. Разобрался, стало легче. Понравилась их студия, которая позволяет, собственно, «дебажить». Уже позже пришел к Langfuse и Phoenix, и остановился на Langfuse из-за наиболее подходящего под мои нужды набора инструментов и OpenSource лицензии. В общем, выступил сегодня на HolyJS с обзором возможностей Sentry, LangGraph Studio, Langfuse, Arize Phoenix, Mastra и Lunary в плане дебага, observability и удобства разработки. Самый главный слайд — перед вами) Вся презентация выложена на сайте конференции. Как только доклад выложат в открытый доступ, тоже сразу поделюсь тут:)
Сегодня этому каналу исполняется два года Перед тем, как писать этот пост, я решил для сравнения прочитать итоги, которые я подводил год назад. Боже, какой же я тогда был наивный, счастливый и беспечный)) В этот раз хочется обойтись без клише про «стимулы для развития», поэтому попытаюсь рассказать всё как есть) Из-за смены тех. стека мне стало сложнее совмещать канал с основной работой, поэтому посты стали выходить реже. Расскажу на что сейчас уходит мой ресурс и чем приходится заниматься на работе: изучать Python с лангчейном, погружаться в работу k8s и OpenShift (пришлось вспомнить всё, что я знал о линуксах), писать докерфайлы и CI/CD пайплайны, изучать работу новой платформы, в которой каждую неделю появляется что-то новое, разворачивать в банке OpenTelemetry-тулинг для всего этого, и даже писать юнит-тесты на изменение КОСИНУСНОГО РАССТОЯНИЯ. Параллельно я стараюсь погружать во всё это разработчиков, аналитиков, тестировщиков и архитекторов из соседних трайбов, продумывать удобный DX и разрабатывать целевой релизный процесс. Ну и доделывать оставшиеся задачи по СберБанк Онлайн — они ведь тоже никуда не делись. Но я не жалуюсь — задачи правда интересные. И ими тоже хочется делиться, хоть они и не совсем подходят под изначальную тематику канала. Поэтому основной итог года для канала — его превращение из канала про Frontend в канал про Frontend-AI-DevOps))
UI киты для создания AI-агентов В последнее время всё чаще приходится создавать прототипы своих AI-ассистентов, чат-ботов, визуализировать агентский воркфлоу и т.д. Лично я за этот год поучаствовал в трёх или четырёх таких проектах, где нужно было прототипизировать фронт для чат-ботов, поэтому решил собрать список UI китов, предназначенных именно для этих целей: 1. AI Elements от Vercel — самое популярное решение для разработки чат-ботов. Содержит кучу компонентов, работает с Next.js, AI SDK и вообще с экосистемой Vercel. Есть даже компонент Web Preview для отрисовки превью разрабатываемых сайтов в iframe. Правда, пока просматривал документацию, поймал себя на мысли, что комплексити этих компонентов иногда даже пугает. Особенно тут, где одна плашка подтверждения разбита на целых 7 компонентов. 2. Assistant UI — ещё один UI kit для чат-ботов. В отличие от предыдущего кита это open source-проект, не Vercel, и с более простым, на мой взгляд, синтаксисом. При этом точно так же, как и AI Elements, компоненты можно устанавливать отдельно через CLI. 3. prompt-kit — набор компонентов поскромнее, чем у предыдущих двух, но вполне может подойти для прототипирования интерфейсов простых чат-ботов. Тем более, даже у этого open source решения тоже есть свой MCP сервер с документацией, который можно подключить к себе в Cursor, например. 4. shadcn-chatbot-kit — практически не отличается от предыдущего UI кита. Чуть меньше компонентов, чуть меньше звёзд на GitHub. Но он очень простой и свою задачу вполне выполняет. Да и выпиливать его будет проще, когда будете переезжать на Assistant UI или на самописный кит) 5. Напоследок решил немного отойти от только чат-ботов и добавить в список несколько библиотек для визуализации графов и диаграмм. Например, ReactFlow сейчас используется практически всеми инструментами с агентскими воркфлоу: на ней работает LangGraph Studio, на ней построен компонент Workflow из Vercel AI Elements и Workflow из Mastra AI Studio. А ещё есть SvelteFlow. И Vue Flow, на котором построен UI в n8n. В общем, если когда-нибудь захотите сделать свой клон n8n или LangGraph Studio, сможете выбрать сразу из нескольких решений. Заметил, что популярных UI китов под создание агентов как будто бы не так много. Если сесть и целый день целенаправленно их гуглить, найдёшь только пару самых популярных монополистов, а всё остальное будет похоже на их упрощённые форки: везде один и тот же radix-ui + Tailwind под капотом. Разве что, нашёл ещё полузаброшенный CUI Kit, который на написан emotion. Скорее всего, все либо пилят кастом, либо используют киты с более широкой областью применения, такие как GravityUI. На одном проекте, например, я использовал Plasma UI от SberDevices. Ну либо radix-ui и Tailwind — это новый стандарт. У той же elizaos фронт тоже на radix-ui написан.
Кто-нибудь разворачивал Sentry локально? Я вот попробовал. Правда, надо было сначала обратить внимание на минимальные системные требования в 4 ядра CPU и 16 GB RAM + 16 GB swap. С такими запросами Sentry нагружал до 90% CPU у игрового ноутбука 3-летней давности и забирал почти всю оперативную память. При этом, ставился он часа два (долго скачивались пакеты), а все его 70+ сервисов в Docker Compose поднимались после установки ещё минут 15. И ты сидишь такой с тормозящим ноутбуком и пытаешься ОШИБКИ ОТЛАВЛИВАТЬ)) Такой себе опыт разработки получился) Хорошо, что у меня оказался второй ноутбук Хоть он и старый, но с 32GB RAM, которые как раз можно было бы удачно утилизировать на поднятие Sentry. Правда, на нём винда, а Sentry на винду ставиться не захотел. Благо, у Windows есть возможность развернуть виртуальную Ununtu через команду: wsl.exe --install Ubuntu-24.04 Далее в этой виртуальной Ubuntu я ставлю Sentry, и остаётся только настроить port-forwarding, чтобы перенаправлять запросы из локальной сети до WSL. Делается это через Windows Powershell: netsh interface portproxy add v4tov4 listenport=9000 listenaddress=0.0.0.0 connectport=9000 connectaddress=$wsl_ip Ну и там же настраиваем Windows Firewall: New-NetFirewallRule -DisplayName "Sentry WSL Access" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 9000 Теперь с любого устройства, подключенного к моему Wi-Fi, есть доступ до 9000 порта виртуальной Ubuntu на старом ноуте, где у меня развёрнут и работает Sentry. Естественно, Sentry полностью забрал на себя почти всю мощность старого ноутбука (vmmem забирает на нём 20+гб RAM), но зато на том устройстве, с которого я привык работать, теперь есть и доступ к Sentry, и все ресурсы свободны. Вот зачем, оказывается, люди себе домашние серверы ставят. Радуюсь, как ребёнок.
Как из фронтендера стать AI-инженером Термин "AI-инженер" я подсмотрел в роадмапе AI-инженера, ссылкой на который недавно делился Саня Стародубцев. Я ведь недавно и сам перешёл из фронтенд-разработки в разработку AI-агентов, поэтому мне стало интересно, стал ли я AI-инженером? Мой собственный опыт "переквалификации" не совсем ложится на эту дорожную карту. Есть ещё один роадмап, вот этот, но там порядок тоже не совсем такой, как у меня. В общем, решил поделиться здесь своей альтернативной версией) Пререквизиты Опыт работы с бэкендом всё-таки понадобится. Одной фронтенд-экспертизы явно будет недостаточно. Работать с API нейросетей скорее всего придётся с бэкенда. С фронта тоже можно, конечно, но в этом есть большой риск утечки вашего API-ключа. Благо у нас, JavaScript-разработчиков, с этим проблем нет)) Впоследствии, конечно, нужно будет углубляться в бэкенд-разработку и заполнять пробелы, если они есть. Но для старта вполне достаточно умения развернуть сервер на Node.js. Нужен ли ML? Здесь ситуация чем-то напоминает необходимость изучения алгоритмов для junior-фронтендера в 2019 году. Вызвать API DeepSeek можно и без знания линейной алгебры. Но я бы всё-таки порекомендовал хотя бы в фоне изучить этот бесплатный вводный курс по ML от Google. Очень поможет снять розовые очки и демистифицировать работу самих LLM. Пишем чат-бота Прям сразу. На практике разбираться будет проще всего. У меня всё началось с телеграм-бота, и я всем советую начинать с простых текстовых чат-ботов. Для этого придётся изучить работу с текстовыми сообщениями в OpenAI API или DeepSeek API. Лично я рекомендую начать с руководства GigaChat API, т.к. оно на русском языке, а многие концепции у разных моделей очень схожие. Бесплатных токенов за регистрацию в GigaChat API будет более чем достаточно для старта. Учим чат-бота выполнять функции Их ещё называют tools. Об этом у меня тоже был пост и примеры кода к нему на JS и на Python. Они нарочно очень простые. У GigaChat тоже есть статья с примерами. А если хочется чего-то совсем запутанного, можно взять шаблон чат-бота из Vercel AI SDK в качестве референса. Векторные хранилища и RAG Про векторы есть отличная глава в упомянутом мной выше курсе от Google. В роадмапе AI-инженера, кстати, тоже неплохие ссылки по этой теме в разделах Embeddings и RAG. Фреймворки Лично я пока продолжаю погружаться в LangChain. Я уже трижды выступил с докладом про этот фреймворк (в последний раз — на MoscowJS), выпустил два поста с ответами на вопросы (раз, два) и всё ещё не погрузился до конца)) По этому фреймворку есть миллиард примеров от моих коллег из GigaChain: есть примеры на Python, JavaScript и даже на Java. А от создателей LangChain есть кайфовый видеокурс по LangGraph. Он на английском, но его легко смотреть, даже не зная Python и не зная LangChain. Источники новостей и апдейтов Очень удобно получать новости с конференций вроде нашего недавнего BigTechNight или с HolyJS, где я тоже скоро буду выступать. Или c разделов на Reddit о тех инструментах, которые вы используете (я, например, читаю в основном про LangChain). Ещё есть Matt Pocock, который параллельно с нами перешёл из TypeScript гуру в гуру нейросетей, выпускает неплохие статьи и видео. Громкие новости об обновлениях у моделей OpenAI / Anthropic / DeepSeek и т.д. всё равно не удастся пропустить. Остальные рандомные новости из соцсетей, кстати, наоборот стараюсь фильтровать: в X что ни пост — так очередная технореволюция)) Хотя, возможно, кто-нибудь в комментариях тоже поделится неплохими источниками информации)
Промпт vs Tools, часть 2 Продолжаю тестировать промпты и тулы по мотивам предыдущего поста, но в этот раз увеличил количество тестов с 25 до 100 и запустил их на зарубежном сервере с доступом к OpenAI API. Ниже делюсь результатами: Разница в скорости между тулами и промптами у моделей OpenAI не так значительна gpt-4o-mini обработала 100 запросов с промптами за 35 секунд, с функциями — за 60, т.е. медленнее в 1,7 раза. GigaChat-2-Max справился с аналогичной задачей за 29 и 107 секунд соответственно, здесь тулы работают медленнее промптов в 3,6 раза. Местоположение влияет, но не так, как я предполагал Запущенные мной из дома 100 тест-кейсов с GigaChat-2-Max отработали за 29 секунд. Эти же 100 кейсов, запущенные с зарубежного сервера, выполнились за 158 секунд. И вроде кажется, всё логично — сервер зарубежный, поэтому такая разница в скорости. Вот только o4-mini справилась с этими же 100 тестами за целых 170 секунд, gpt-5-nano — за 200. Если бы не gpt-4o-mini, отработавшая за 35 секунд, я бы подумал, что с сервером что-то не то. Что в итоге Во-первых, конечно, сравнивать скорость и результат стоило бы у сопоставимых по параметрам и объёму моделей, а не у всех подряд. Но тогда этот пост превратился бы в курсач)) Во-вторых, под каждую задачу, которую вы решаете, нужно подбирать модель отдельно. И это я ещё у самих моделей параметры не менял. По-хорошему, нужно было выставить temperature на минимум и ограничить max_tokens: двух-трёх output-токенов уже будет достаточно для того, чтобы LLM смогла выбрать одно из пяти ключевых слов по моему запросу. Ну и в-третьих, если вы работаете из России, то вам совершенно нет смысла не использовать GigaChat. Ну или точно нет смысла исключать его из списка моделей, которые вы рассматриваете. С рядом задач он справится значительно быстрее.
Маршрутизация LLM через промпт или через tools Я никакой не Data Scientist, я просто фронтендер. Но даже фронтендеру иногда бывает интересно, что лучше отработает — обычный промпт типа такого: Верни слово "auto", если пользователь говорит про автомобили. Верни слово "movie", если пользователь говорит о фильмах… или передача в LLM функций (или тулов) с описанием каждой из категорий, между которыми LLM нужно сделать выбор. И да, эту задачу можно было бы решить и с помощью векторов, но мне захотелось сравнить именно эти два подхода. Первый способ может показаться ненадёжным и контринтуитивным — мы ведь не используем structured_output, поэтому ответ модели здесь не так строго типизирован, как во втором случае. Но так ли всё просто? Как я сравнивал промпт и тулы — Написал первый промпт. Он будет проверять, насколько хорошо LLM маршрутизирует, используя обычное текстовое описание: Твоя основная задача — правильно определить категорию вопроса пользователя. Если вопрос касается автомобилей, ответь "auto". Если вопрос касается кораблей, ответь "ship". Если вопрос касается фильмов, ответь "movie". Если вопрос касается мотоциклов, ответь "moto". Если вопрос не относится ни к чему из вышеперечисленного, ответь "incorrect". Если из фразы клиента не удалось понять, к какой категории относится вопрос, задай клиенту уточняющий вопрос. — Второй промпт выглядел так же, как и предыдущий, но без описания категорий — их я вынес отдельно в функции. Этим промптом я буду проверять качество маршрутизации с помощью тулов. Получилось в итоге следующее: Твоя основная задача - правильно определить категорию вопроса пользователя. Если из фразы клиента не удалось понять, к какой категории относится вопрос, задай клиенту уточняющий вопрос. — Описал 25 тестовых фраз и их ожидаемый результат по каждой из них. — Запустил все 25 тестов с первым промптом, затем 25 этих же тестов со вторым промптом и тулами. — Повторил проверки на шести разных моделях GigaChat и на DeepSeek. Результаты Что касается DeepSeek, то почему-то даже на один мой запрос их API отвечал целых 5 секунд, поэтому он выбыл из гонки, так особо в ней и не поучаствовав. А вот GigaChat показал интересную статистику: Во-первых, промпт с тулами отрабатывал в среднем в 2-3 раза медленнее обычного текстового промпта — 25 вызовов GigaChat с текстовым промптом отрабатывали за 6-8 секунд, в зависимости от модели. А 25 запросов с тулами занимали в сумме от 18 до 23 секунд. Во-вторых, промпт с тулами расходовал в 2-3 раза больше токенов — от 800 до 2300 за обычный текстовый промпт, и от 2400 до 4600 токенов за промпт со structured_output. В-третьих, structured output не всегда давал 100% точность. Было интересно увидеть, как GigaChat-Max и GigaChat-2-Max с обычными текстовыми промптами показали максимальную точность (25 из 25) среди всех моделей. Что ещё более странно — наименьшую точность среди всех моделей показали эти же GigaChat-Max и GigaChat-2-Max со structured_output (21 из 25). Я понимаю, что объём тестовых данных у меня совсем небольшой. Уверен, что если бы тестов у меня было не 25, а 25000, то результаты, скорее всего, были бы совсем иными. Но в любом случае результаты меня очень удивили. Проверяйте свои инструменты внимательно под каждую задачу))
Чем приходится заниматься вместо фронтенда Несколько месяцев назад я перестал быть фронтендером и перешёл в разработку AI-агентов в Сбере. Направление невероятно популярное и очень увлекательное) Настолько популярное и увлекательное, что фронтенд словно уходит на второй план. Напишешь про какие-нибудь новые проперти для View Transition API в Chrome 140, а у чувака из соседнего канала нейросеть сама пишет целый сайт за один промпт. Да и с переходом на новую роль мне становится всё сложнее выделять время на то, чтобы погружаться в дебри фронтенд-инструментов. Где найти выход?) Лично я стараюсь совмещать эти два направления. Если и есть что-то общее у фронтенда и у AI-агентов, так это JavaScript) JavaScript-экосистема настолько очистилась обширная, что решений для AI-агентов на нашем любимом языке написано очень много)) Вчера, например, тестил elizaos Очень любопытный фреймворк для создания мультиагентных систем на JavaScript. Давно на него смотрел, т.к. звёзд на github у него даже больше, чем у LangChain.js. И в два раза больше форков. Недавно у elizaos добавился cli и обновилась документация, поэтому решил наконец-то попробовать поставить её себе. Чем привлекает elizaos - Из коробки доступна среда для создания чат-ботов или агентов и для общения с ними. Можно создавать общие чаты с несколькими ботами сразу, общаться голосом, загружать в них документы и т.д.; - Интеграция с Telegram и Discord тоже из коробки; - Ботам можно задавать роли и прописывать для них персонажей. Это, конечно, сводится к большому системному промпту и локальной БД для запоминания ключевых фактов из биографии и диалогов, но лично меня так и тянет сгрузить туда пару постов из своего канала и несколько своих переписок, чтобы заставить моего бота общаться так же, как общаюсь я. Понимаю, что это и так не сложно сделать, но в elizaos вся эта логика уже написана за меня, а мне остаётся только подготовить данные; - Работает с API OpenAI, Anthropic, Grok или локальными моделями. Из минусов могу отметить прежде всего тот факт, что это очередной фреймворк, в детали которого придётся погружаться. Причём, скорее всего, не для production-целей. P.S. Вчера с удивлением обнаружил, что OpenRouter больше не пропускает запросы из РФ, и просто так OpenAI API мне уже не вызвать. Пришлось импровизировать с gpt2giga — прокси, который принимает запросы в формате OpenAI, и направляет их в GigaChat)) Всё завелось, хоть и не с первого раза — саму gpt2giga пришлось тоже немного доработать. Плюс, кажется, остались несовместимости в работе эмбеддингов. Но в любом случае пользовательский опыт получился интересный — вводишь пару команд в консоли, и у тебя готовая полноценная команда из чат-ботов.
Superwhisper beta для Windows Superwhisper — это speech2text, он преобразовывает вашу речь в текст. Его очень часто можно было увидеть у разных вайбкодинг-блогеров, которые диктуют свои промпты устно в Cursor и радуются этому. Долгое время superwhisper был доступен только для MacOS, а для Windows можно оставить заявку на Beta-версию. И вот вчера мою заявку на бету аппрувнули, а сегодня я наконец попробовал superwhisper на Windows) Что понравилось - В отличие от, например, VS Code Speech, superwhisper позволяет диктовать текст не только в открытые в VS Code файлы, но вообще в любой инпут: на любых сайтах, в любых программах, даже в чате в World of Warcraft работает, я проверил. - Хорошо распознаёт, когда в речи приходится переключаться с русского языка на английский. Очень полезно для работы в Cursor, когда приходится диктовать фразы типа "Посмотри функцию getProductDataParameters и добавь в неё проверку на errorCode в response". Коллеги из 1С, к вам вопросов нет)) - В платной версии (которая доступна в триале на 15 минут диктования) есть prompt-enhancement, работающий на GPT-4.o и других моделях на выбор. Например, вы надиктовали курсору одно предложение про проверку на errorCode, а GPT-4.o превратит вашу речь в большой и подробный промпт для курсора. - Может перевести на английский язык то, что вы надиктовали на русском. - Бесплатная версия, вроде как, доступна даже без интернета и без временных ограничений. Но это ещё предстоит проверить — я ещё не выговорил все свои 15 минут речи в пробной платной версии) Что не понравилось - Возможно, superwhisper использует мощности вашей видеокарты, чтобы майнить крипту селф-хостить небольшие локальные модели для распознавания речи, но сама эта программа жрёт слишком много моего GPU. Нагружает GPU до 20% даже в свёрнутом состоянии, и даже когда вы ничего не диктуете. - Если вам кажется, что 20% GPU — это много, то предлагаю вам открыть сайт superwhisper.com и увидеть, как этот сайт моментально забивает все 100% вашего GPU)) Зато можно использовать их сайт как образец того, как не надо верстать — уже можно сразу писать отдельный пост с разбором того, что с этим сайтом не так) Буду ли я пользоваться superwhisper? Набор текста вручную занимает втрое больше времени, чем произнесение текста вслух, поэтому воспользоваться однозначно стоит. Superwhisper точно ускорит процесс работы в Cursor, и даже видоизменит его. С чатами в онлайн играх, кстати, тоже очень помогает. Да и в тот же самый дискорд своим друзьям можно будет ответить быстрее. Но вот сам код на нём всё равно не напишешь — тратишь много сил, произносишь "открывающаяся фигурная скобка", а в итоге получаешь саму эту фразу, а не символ "{". А жаль, был бы крутейший инструмент для доступности.
Как устроен LangChain.js и всегда ли он полезен 🤖 LangChain.js создан, чтобы облегчить работу с языковыми моделями. Но в чём именно его польза? И как не запутаться в слоях его абстракций и обёрток? Антон Непша, Lead Frontend Developer в Сбере, покажет, как шаг за шагом освоить работу с LLM без преждевременного погружения в сложные термины и документацию. Разберём, что скрывается под капотом LangChain, на что он действительно способен, а также выясним, когда его использование оправдано, а когда он становится оверхедом. Приходите 14 июня (сб) послушать доклад Антона 😎 Регистрация открыта! 🚀 И как всегда, задаём вопросы спикеру, читайте наше мини-интервью с Антоном. 🎙 Tbilisi JS Chat | YouTube | LinkedIn | Instagram
Используем модели от OpenAI и DeepSeek бесплатно Способ подсказал мой коллега Андрей Власов, который лидирует и развивает технохаб Сбера в Казани. На github есть раздел GitHub Models с каталогом разных LLM, включая OpenAI GPT-4.1, DeepSeek-V3-0324 и т.д., всего около 60 разных моделей. Каждую из них можно протестировать в плейграунде, или настроить их для работы в каком-нибудь вашем приложении. Весь процесс настройки можно посмотреть в этом видео, но всё, что по сути требуется, это сгенерировать свой токен на GitHub и вызывать модели из своего приложения по отдельному гитхабовскому хосту, который на самом деле Microsoft Azure. И всё. Абсолютно бесплатный девелоперский доступ к моделям. Там есть лимиты, но для небольших приложений и прототипов их должно хватить. Использование с LangChain LangChain представляет собой абстракцию над разными API разных LLM. Он удобен, если вам нужно быстро переключаться между разными моделями, не переписывая при этом половину приложения. Правда, из коробки LangChain вызывает отдельные эндпоинты и Auth-токены для каждой модели, а у нас моделей много, а эндпоинт и токен — общие. К счастью, в LangChain можно перебить дефолтный baseURL при объявлении экземпляра модели. Что касается auth-токена, то у OpenAI он передаётся напрямую в конфиг, а DeepSeek можно хакнуть, переопределив переменную DEEPSEEK_API_KEY: import { ChatOpenAI } from "@langchain/openai" import { ChatDeepSeek } from "@langchain/deepseek"; const openAiModel = new ChatOpenAI({ model: "openai/gpt-4.1", configuration: { baseURL: "https://models.github.ai/inference", apiKey: process.env.GITHUB_TOKEN } }) process.env.DEEPSEEK_API_KEY = process.env.GITHUB_TOKEN const deepSeekModel = new ChatDeepSeek({ model: "deepseek/DeepSeek-V3-0324", configuration: { baseURL: "https://models.github.ai/inference" } }) Завтра поделюсь ещё мыслями по поводу использования этого способа. А если у вас есть свои идеи или лайфхаки по использованию LLM — делитесь в комментах или в личку)
Анти-спам для канала Устал удалять спам-комментарии вручную, пора задуматься над тем, как это автоматизировать. Решение в лоб Задача кажется простой, ведь в API телеграма есть флаг is_bot, про который написано: True, if user is a bot. Можно было бы просто удалять сообщения на основе этого флага, или даже банить. Изначально я так и сделал, и чуть не забанил сам себя — оказалось, что если написать комментарий от имени канала, то ты тоже становишься is_bot: true)) Другим решением могло бы быть создание какого-нибудь словаря из стоп-фраз и проверка вхождения подстроки, но я решил сразу перейти к ИИ. Решение с ИИ Буду использовать GigaChat-2-Pro (потому что от него у меня ещё остались токены). В GigaChat я отправляю текст поста, текст комментария и инфо об авторе, а он возвращает мне оценку вероятности спама. В процентах. Сейчас он плохо распознаёт комментарии от спам-ботов, которые напрямую ничего не рекламируют, над этим я ещё буду работать. Тестируем Бот будет оценивать каждый комментарий на предмет спама и будет ставить реакции на комментарии в зависимости от его оценки. Градация следующая: 0% — ❤️🔥; 1 - 25% — ❤️; 26 - 50% — 👍; 51 - 75% — 🤔; 75 - 99% — 😡; 100% — 🤬; В случае ошибок бот будет ставить "🤷🏼♂️" Отредактировано: тестирование закончено, всем большое спасибо))
Советы по вайб-кодингу Я тут на выходных навайбкодил свою первую мини-игру, в которой машинка бесконечно уезжает в закат по пустынной дороге. Если вы никогда не сталкивались с понятием "вайб-кодинг", очень советую ознакомиться со статьёй на Tproger — там хорошо расписана история возникновения понятия, его суть и примеры. Игру сделал с помощью Cursor, весь код сгенерирован моделью claude-3.7-sonnet. На примере этой игры хочу рассказать, с какими сложностями я столкнулся и так ли это просто — писать код с помощью нейросетей. Не пытайтесь уместить огромное ТЗ со всеми нюансами реализации в один промпт Лично в моём случае более результативным оказалось строить маленький MVP и шаг за шагом его улучшать. Мой стартовый промпт выглядел так: Создай веб игру на threejs, где нужно с помощью WASD управлять машинкой и уезжать в закат по пустынной дороге. Дорога всегда идёт вперёд и генерируется динамически перед игроком. В результате я получил игру, в которой у машинки было инвертировано управление, а солнце просто лежало на дороге — но это был лучший результат, которого удалось достичь за 2 часа экспериментов с разными моделями и промптами. Дальнейшая работа строилась из багфиксов и добавления новых фич поверх существующего MVP. Используйте чекпоинты и перефразируйте промпты Если нейросеть не может исправить ваш баг, не нужно бесконечно писать ей «всё равно не работает», «до сих пор ошибка» и т.д. — она просто нагенерит костылей поверх костылей и вы быстро всё сломаете. Вместо этого вернитесь в курсоре на тот чекпоинт, где вы только начали исправлять ошибку, и перефразируйте свой промпт. Разбирайтесь в коде, который генерирует нейросеть Если знать нюансы реализации, становится гораздо проще просить нейросеть вносить изменения. Например, в моей игре был баг: если проехать достаточно далеко от старта, у неба ломался градиент. И я мог бы бесконечно продолжать просить нейросеть «почини градиент», если бы в какой-то момент не решил заглянуть в код. Оказалось, что градиент на небе — это сфера, которая просто стоит на месте. И градиент не ломался, просто игрок выезжал за пределы этой сферы. Используйте git Да, в Cursor есть чекпоинты, но я всё же рекомендую коммитить изменения в git каждый раз, как вы получаете какой-то стабильный инкремент. Иначе есть риск, что нейросеть поломает вам что-нибудь, над чем вы долго работали. Не пытайтесь быть вежливыми Не нужно говорить нейронке «пожалуйста», «спасибо», по всякому её хвалить и быть учтивым — этим вы только потратите свои силы, время и токены. Декомпозируйте Старайтесь с самого начала выносить логику разных частей приложения в отдельные файлы. Особенно, если нейросеть вносит все изменения в один большой файл. При этом, свои идеи по добавлению новых функций тоже можно разбить на более мелкие этапы. Например, такую задачу: Добавь автомобилю шкалу здоровья и отнимай по 10% при каждом столкновении. Когда здоровье доходит до 0, показывай экран Game Over Я разбил на несколько более простых задач: - Добавь коллизии; - Добавь автомобилю шкалу здоровья, отнимай здоровье машины при столкновении; - При достижении 0 показывай экран Game Over; Разрабатывая фичи по отдельности, мы меньше рискуем что-то сломать и упрощаем себе тестирование этих доработок. Создавайте новый чат под каждую новую доработку Нет смысла обсуждать доработку фар автомобиля в том же чате, в котором вы обсуждали цвет неба. Эта информация будет только засорять контекст. А ещё вы сможете открыть второе окно курсора и работать над двумя фичами одновременно: пока один агент пишет код для поведения фар, вы можете ревьюить код другого агента, которому ранее вы задали задачу исправить генерацию камней и кактусов вдоль дороги. Выводы Интересно, что в вайб-кодинге на первый план выходят фундаментальные вещи: использование git, соблюдение принципов KISS, DRY или SOLID. Без них вайб-кодить будет гораздо сложнее, а результат — менее стабильным. Саму игру тоже забрасывать не хочется. В планах добавить кастомизацию автомобиля и возможность пополнять здоровье. Ну и буду рад вашему фидбеку и предложениям по улучшению)
MCP Серверы для фронтендеров Недавно я писал про Browser Tools MCP, который позволяет получить доступ к некоторым браузерным возможностям прямо из вашего Cursor. Подобных MCP-тулзов уже очень много, но среди всей этой кучи хочется выделить те, которые больше всего полезны фронтендерам: Figma Context MCP Берёшь ссылку на макет из Figma и вставляешь прямо в чат в Курсоре. И сразу же в IDE получаешь данные о макете. Помимо того, чтобы верстать что-то с помощью Cursor, данные о макете могут пригодиться ещё и в разработке плагинов для самой Figma или для Pixso) Playwright MCP Через playwright агент сможет открывать для вас браузер, переходить по ссылкам, жать кнопки и смотреть, что происходит. Есть возможность настройки режимов браузера: headed и headless. Puppeteer MCP Ещё один инструмент для работы с браузером из Cursor. Тулзы +- те же самые, что и у Playwright, но Puppeteer MCP сложнее настраивается. Видимо, поэтому уже есть Configurable Puppeteer MCP Server)) npm-search MCP Server Для тех, кому лень писать npm search в консоль — можно попросить нейросеть выполнить npm search за вас. Бонусный контент Если интересно, можете ещё попробовать MCP для GitHub, GitLab, AWS, Atlassian (JIRA и Confluence). А с помощью Superwhisper на MacOS все эти инструменты можно вызывать голосом.
Доступ к девтулзам браузера через Cursor Есть такой инструмент, BrowserTools MCP, который позволяет курсору делать скриншоты страниц, инспектить HTML элементы, анализировать ошибки в консоли и т.д. Работает это по стандарту Model Context Protocol или MCP. Он позволяет разрабатывать свои собственные функции, которые потом могут вызываться AI-агентом в Cursor или где-нибудь ещё. Как работает BrowserTools Нужно поставить браузерное расширение, которое работает с chrome.debugger и шлёт данные из девтулзов по вебсокетам на отдельный локальный сервер на Node.js. Этот сервер объявляет набор функций, которые по MCP передаются в курсор, а курсор передаёт их в LLM. И когда агент собирается вызвать функцию, Cursor обратится к серверу, сервер — к расширению в браузере, а расширение — к вашей странице. Теперь можно просить Cursor покрасить выбранную кнопку за нас. Или спросить, почему при нажатии на неё возникает ошибка — Cursor сам найдёт её в вашем коде благодаря данным о ней из девтулзов. Правда, функционал у BrowserTools ещё не сильно широкий — я бы ещё добавил работу с localStorage, cookies или с performance, но не уверен, насколько разработчики BrowserTools будут рады пулл-реквестам Хорошо, что у протокола MCP есть TypeScript SDK, и при необходимости можно спокойно напилить и своих тулзов для курсора))
Пример AI-агента на GigaChat В дополнение к предыдущему посту решил развернуть на gitverse репозиторий с простым AI-агентом на GigaChat. Там как раз показан пример того, как можно работать с функциями. - Общаемся с GigaChat прямо через терминал. - Если при общении с вами GigaChat поймёт, что вы хотите «посмотреть логи сервера», то он сам вызовет функцию отправки логов в терминал. Вот вам и взаимодействие нейросети с внешним осязаемым миром Точнее, с одной конкретной функцией на вашем сервере)) Но этот пример нарочно сделан простым, чтобы на его основе можно было понять механизм работы функций и самые основы создания AI-агентов. Масштабировать этот подход вы сможете бесконечно)) Главное, не забывайте сообщать нейросети о том, что ваша функция выполнена — иначе на каждое ваше последующее сообщение нейросеть будет заново возвращать признак вызова функции. И ваш сервер будет выполнять её каждый раз. Но в моём примере это учтено))
Как заставить нейросеть выполнить ваш код на JS или Python Нейросети вроде ChatGPT, DeepSeek или GigaChat можно научить взаимодействовать с окружающим миром: менять файлы на вашем диске, вызывать сторонние API или выполнять иные задачи в живом окружении. Это делается довольно просто, и у большинства нейросетей применяется один и тот же подход: как у ChatGPT или DeepSeek, так и у GigaChat. Все они умеют работать с функциями. Что такое функции Если мы посмотрим на API любой нейросети, то функции там будут выглядеть непривычно. Вот пример функции из документации GigaChat: { "name": "weather_forecast", "description": "Возвращает температуру на заданный период", "parameters": { "type": "object", "properties": { "location": { "type": "string", "description": "Местоположение, например, название города" }, "format": { "type": "string", "enum": [ "celsius", "fahrenheit" ], "description": "Единицы измерения температуры" }, "num_days": { "type": "integer", "description": "Период, для которого нужно вернуть" } }, "required": [ "location", "num_days" ] } } Функция — обычный JSON. Какой код эта функция выполнит? Здесь всё просто. Никакой)) До тех пор, пока мы сами его не напишем. Поэтому придётся по-старинке объявить где-то у себя в коде обычную функцию с названием weather_forecast, как в поле name в объекте выше. Принимаемые параметры тоже делаем такими же, как в описании. И реализацию этой функции тоже пишем сами. Как нейросеть сможет её вызвать? Нам нужно сообщить модели о том, что у неё есть такая возможность. Для этого передаём описание этой функции в запросе API нейросети, прямо вместе с вашим текстом. Вот пример тела запроса с функцией в GigaChat API: { "model": "GigaChat", "messages": [ { "role": "user", "content": "Погода в Москве на три дня" } ], "function_call": "auto", "functions": [ // Добавляем все свои функции вот сюда ], } У ChatGPT это работает похожим образом, даже названия полей местами совпадают. Что происходит дальше? Модель распознает ваше сообщение и самостоятельно примет решение о том, нужно ли ей вызывать какую-то из функций, которые мы ей передали. Решение будет приниматься на основании вашего сообщения и текстовых описаний того, что функция делает и какие параметры принимает. Если нейросеть посчитает, что функцию вызвать нужно, она вернёт в ответе название этой функции и параметры, которые нужны для её вызова. А нам остаётся сделать условный: const { function_call } = response.message // проверяем, что в ответе от нейросети есть признак вызова нашей функции if (function_call.name === "weather_forecast") { // вызываем функцию, которую сами же и написали weather_forecast(function_call.arguments) } Всё. Естественно, вместо прогноза погоды функция может быть любой. Мой бот, например, присылает мне в телегу логи с сервера, если я достаточно вежливо его об этом попрошу) А в Python у библиотеки LangChain есть специальный декоратор tool, который упрощает создание функций. Если внутрь функции с этим декоратором добавить описание в docstring, то библиотека сразу сформирует нужную структуру, готовую для того, чтобы передать её в нейросеть.
ChatGPT Operator OpenAI выпустили preview-версию агента, который имеет доступ в интернет и может выполнять там различные задачи. Operator использует модель Computer-Using Agent (CUA), которая натренирована на взаимодействие с графическими интерфейсами, а не с программными API. Что умеет CUA Вы делаете промпт, например: Закажи гавайскую пиццу в такой-то пиццерии на такой-то адрес И агент прямо на сайте openai откроет встроенный браузер, в котором зайдёт на сайт пиццерии и закажет эту пиццу. Что происходит под капотом Работа агента делится на три этапа: 1) Восприятие AI уже умеют анализировать изображения, поэтому агент без труда поймёт, что изображено на скриншоте сайта пиццерии. Скриншот используется в качестве «контекста» модели. 2) Рассуждение Агент анализирует текущее состояние и предыдущие свои действия, выдавая свой «внутренний диалог» в окне чата с пользователем. В случае чего — агент задаёт дополнительные вопросы, прежде чем продолжить. 3) Действие Клик, скролл, ввод текста на сайте. Цикл повторяется до тех пор, пока изначальная задача не будет считаться выполненной, или пока не понадобится какое-то дополнительное подтверждение от пользователя. В теории, так должно работать. На практике агент справляется с рутинными задачами медленнее, чем человек. За то время, пока вы сидите и смотрите, как operator скроллит экран браузера и жмёт какие-то кнопки, вы успели бы заказать уже 10 пицц. Хотя если посмотреть на цифры, то CUA справляется с 57.1% задач бенчмарка при работе с вебом, а человек — с 78.2%. Странный результат, но как будто бы нас почти догнали)) Итоги Где-то год назад я мечтал о том, что AI будет за меня двигать по статусам задачи в JIRA, заполнять релизную документацию и выполнять прочие рутинные вещи. Сегодня мы уже видим, как это может выглядеть. Правда, доступ к operator сейчас есть только у пользователей с ChatGPT Pro (за 200$ в месяц), поэтому я пока не посмотрел, как они сделали встроенный браузер))
Когда поручил пет-проект нейросети Я тут попробовал bolt.new — AI-агента, который прямо в браузере разворачивает виртуальную машину с Node.js и редактором кода, и пишет там код за вас. Браузерная VM работает на WebContainers от StackBlitz, а код за вас будет писать LLM под названием Claude 3.5 Sonnet, которая неплохо показывает себя в бенчмарках. Из плюсов могу отметить следующее: 1) Агент понимает русский язык 2) Токенов в бесплатной версии хватит, чтобы быстро развернуть какой-нибудь прототип или пет-проект и нагенерить там шаблонного кода. 3) Если возникают ошибки, нейросеть сама предлагает их исправить, и сама же и исправляет, прямо в коде. 4) Всё-таки, WebContainers это супер удобно. Лично мне уже больше не захочется после этого вручную стартовать пет-проекты. Слишком удобно, когда бойлерплейт заполняет за вас кто-то другой, прямо у вас на глазах. Я всего лишь описал в чате словами нужный мне интерфейс и функционал, перечислил технологии (мне нужен был React 19, CSS Modules, TypeScript и webpack) — и готово. Но не идеально. Поэтому дальше поговорим о минусах: При первом запуске npm start упал с ошибкой)) Нейронка не указала "type": "module" в package.json. Хорошо, что она предложила это поправить сама. Не знает про React 19 И даже про 18.3.1. Нейронка упорно верит, что последняя версия реакта — 18.2.0, и ставить соглашается только её. Короче, все последние версии библиотек вам придётся ставить вручную. И не вздумайте ей об этом рассказывать, а то она возьмёт и «исправит» вам версии на более старые. Много мусора и навязываемых инструментов Я просил CSS Modules и webpack, и я их получил. Но помимо них я получил в свой проект файлы vite-env.d.ts, tailwind.config.ts и, по классике, библиотеку date-fns, которая нигде не используется. Очевидно, нейросеть обучали на живых проектах))0 Иногда переписывает файлы с нуля целиком Даже при просьбе внести незначительные правки. Итог bolt.new очень удобен для быстрого создания прототипов и шаблонных страниц. Он, конечно, допускает глупые ошибки, и можно было бы над этим посмеяться. С другой стороны, если вы знаете фронтендеров, которые допускают такие же ошибки, то для решения подобных задач уже есть нейросети.
Решил вернуть бота в канал Раньше у меня в канале был бот, который генерировал шутёхи в комментариях по теме поста, но работал он только с emoji или текстом. Теперь он вернулся и реагирует ещё и на стикеры! Давно хотел научить бота распознавать стикеры и реагировать на них, но у гигачата не было API для работы с изображениями. Недавно эта возможность появилась, поэтому бот снова в строю)) Отправляем в комментарии любой стикер и смотрим, что ответит на это бот. По хорошему, коммент от бота должен генерироваться по теме поста, но над этим я ещё поработаю)) Ну и да, анимированные стикеры он пока не распознаёт)