Искусство. Код... ИИ?
419 subscribers
22 photos
4 videos
1 file
71 links
Канал @vkochetkov о прекрасном (и не очень) вокруг кода, ИИ и безопасности приложений.

FAQ: https://t.me/art_code_ai/7
Download Telegram
Пост-мортем персонального рабочего адвент-календаря 2025

Скучно подводить итоги… с моим-то отношением ко всей этой движухе — так тем более. Ну кому интересно, какие книги я прочитал, какие проекты начал, чего достиг и сколько полимеров оставляю в уходящем году? 🤷‍♂️

Давайте лучше так: один месяц — один накрывший меня в нём (сугубо личный и никому не навязываемый) инсайт вокруг профессиональной области? Погнали.

🗓 Январь

Самой приоритетной и подлежащий тщательному планированию и соблюдению сроков задачей, в любом R&D проекте, является отдых его участников. Да, вот прям в Jira или Youtrack, или хотя бы в персональном календаре. Ежедневный сон, еженедельные выходные, ежеквартальные дейоффы вокруг праздников, и пара больших отпусков в год на перезагрузку. Не отдыхаешь — не работаешь.

🗓 Февраль

Главной целью любого бизнеса является системное и прогнозируемое извлечение прибыли. Главной целью любой семьи — забота друг о друге, и обеспечение целостности перед любыми внешними факторами. Это цели несовместимы. В коммерческой компании, где «мы все здесь, как одна большая семья», херовая — либо «семья», либо бизнес.

🗓 Март

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

🗓 Апрель

Основным инструментом любого руководителя, начиная с сеньора, которому дали на воспитание пару джунов, являются люди. Не его скиллы, опыт или майндсет. Не «проще самому сделать, чем объяснять» или «я сделаю быстрее и лучше». Если продолжаешь делать быстрее и лучше, значит руководить ими должен кто-то другой.

🗓 Май

Оказывается, на весьма примитивном тайм-менеджменте, можно за неделю подготовить два неплохих часовых доклада, параллельно участвуя в организации самого мероприятия, ещё и выполняя при этом свою основную работу. И не только не сгореть, но и получить от всего этого удовольствие.

🗓 Июнь

С возрастом, мы становимся заложниками своего опыта. Мозгу не нужны все эти новомодные языки программирования, технологии, фреймворки, и десятки новостей о прорывах в области ИИ ежедневно. Мозгу нужны простые ответы, укладывающиеся в уже устоявшуюся картину мира. И, если её регулярно не расшатывать, то на обочине можно оказаться, даже не заметив этого. Бродя по ранее протоптанным тропинкам на новую дорогу выйти не получится.

🗓 Июль

Без инсайтов (полноценно отдыхал, да).

🗓 Август

Договариваясь о сроках, умноженных на иррациональный коэффициент собственной внезапности (π, ℇ, √2 — вот это всё), совсем не лишним будет проговорить также и сроки начала работ, с поправкой на те же самые коэффициенты.

🗓 Сентябрь

«Когда мир переворачивается, выигрывают те, кто первыми встают на голову» (с) Про что это — пояснять, думаю, излишне.

🗓 Октябрь

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

🗓 Ноябрь

Rust неплохой язык, на нём интересно писать… пет-проекты в соло и то, для чего раньше стоило бы взять C/C++. Для наших прототипов и нетребовательного прода — всё ещё Python, для всего остального — Go. Угу, как дотнетчик это говорю, вы все правильно поняли)

🗓 Декабрь

Снова без инсайтов (два больших отпуска на перезагрузку, помните?).

Хотя один всё же есть: отпустив дедлайн «успеть в этом году», и работается, и отдыхается в декабре — намного спокойнее и продуктивнее.

Чего вам всем и желаю 🤗 С наступающим новым годом! И до встречи в январе.

❄️
Please open Telegram to view this post
VIEW IN TELEGRAM
5🎄14114👍1
🤝 Ni8mare перед Рождеством — по следам уязвимости

Самой громкой CVE за каникулы стала, пожалуй, брендово-трендовая-и-вот-это-всё CVE-2026-21858 aka Ni8mare, получившая CVSS 10.0 благодаря возможности развития атаки на неё до полноценного RCE. Саму уязвимость не разобрал разве что только ленивый <автор этого канала>. Вот хороший разбор с красивыми картинками и примерами кода, и, опять-таки — повторяться, теперь уже, смысла нет.

Причина этой уязвимости, тут же названная «Content-Type Confusion» теми, кому совершенно не жаль составителей таксономий, заключается в ошибках обработки HTTP-запросов с различными Content-Type заголовками в webhook-эндпоинтах n8n: сервер необоснованно доверяет данным из req.body.files даже когда заголовок Content-Type не указывает на multipart/form-data, что позволяет атакующему подменить содержание и структуру тела запроса. Это приводит к тому, что функции обработки считают произвольно сформированные данные «загруженными файлами» и используют их для чтения файлов на сервере. Используя это и функциональность прочих модулей, доступных в n8n, атакующий может развить атаку вплоть до RCE.

Цепляет в уязвимости то, что здесь явно теряется соблюдение в коде границы доверия, но настолько неявным способом, что заметить это, просто читая код глазами или SAST'ом — не так уж и просто. Вот близкий к оригиналу псевдокод, иллюстрирующий уязвимость этого типа:

// Middleware: разбор тела запроса в вебхуке
function parseRequestBody(req) {
if (req.headers['content-type'].startsWith('multipart/form-data')) {
// Парсим форму и файлы (через, например, Formidable)
req.body = parseFormData(req); // сформирует req.body.files для файлов
} else {
// Парсим JSON или другие типы как обычное тело
req.body = parseBody(req); // напрямую десериализует тело в req.body
}
}
// Обработчик webhook формы (уязвимая версия)
app.post('/form-webhook', (req, res) => {
parseRequestBody(req);
const result = prepareFormReturnItem(req.body);
// ...
});
// Функция обработки загруженных файлов
function prepareFormReturnItem(body) {
for (const fileId in body.files) {
// Скопировать файл из временного пути в постоянное хранилище
copyBinaryFile(body.files[fileId].filepath, uploadDir);
}
// ... вернуть результат для workflow
}

Да, copyBinaryFile как бы намекает, что это потенциально опасная операция копирования файлов. Но SAST, не знающий о деталях работы Formidable, как минимум, здесь даст фолз+, на ветке с multipart/form-data, а человек, проводящий триаж/ревью — вообще забьет на обе сработки, т.к. по логике — копирование файлов тут норм, ведь их исходные пути мы получаем от парсера (ведь только от парсера же, да? 😬), выполняющего здесь ещё и роль доверенного санитайзера.

🖥 Что делать разработчикам?

• Структурные входные данные должны валидироваться по схеме конкретного кейса бизнес-логики, следуя принципу fail-closed, прежде, чем начнется работа с их полями (даже их валидация).

• Не стоит смешивать в одном потоке выполнения несколько логических кейсов. В данном случае — следовало бы разнести по разным эндпоинтам работу с разными типами контента (облегчает задачу SAST, делает счастливыми триажеров и ревьюеров — сплошной профит). Но, если уж смешались, то п.1 должен быть корректно реализован для всех веток выполнения.

• Инварианты и гарантии, предоставляемые используемыми парсерами, валидаторами и санитизаторами стоит изучить досконально. Даже в «нормальной» ветке с multipart/form-data, то, что formidable гарантирует загрузку по безопасным путям относительно options.uploadDir — нужно знать, а не предполагать. А ещё лучше — лишний раз убеждаться в этом, прежде, чем работать с полученными результатами. Почему?

• Потому что, Defense in Depth через многоуровневую модель угроз никто не отменял. То, что, например, через обычную читалку файлов стало возможным вытащить .n8n/database.sqlite говорит о том, что уровней внутренних границ доверия у n8n просто не было.

TL;DR: читаем разбор Ni8mare, делаем выводы, сравниваем с написанным выше ✍️
Please open Telegram to view this post
VIEW IN TELEGRAM
43👍3🔥1💯1
Трейд-оффы современных языков программирования

Надеюсь, никакой ящик Пандоры я этим постом не открою... 🫣 Для контекста:

Rust неплохой язык, на нём интересно писать… пет-проекты в соло и то, для чего раньше стоило бы взять C/C++. Для наших прототипов и нетребовательного прода — всё ещё Python, для всего остального — Go.


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

Для каждого языка сформулировал оценку по 10-бальной шкале, относительно трех критериев разработки:

Совокупная стоимость. Интегральная оценка по всем видам затрат, к которым приводит разработка на этом языке: оптимальная численность и стоимость команд, затраты на тестирование, инфру и поддержку.

Скорость. По сути — временная стоимость стори-поинта в проекте медианной сложности (веб, энтерпрайз, облака).

Безопасность. Уровень безопасности, гарантируемый стандартной поставкой языка и его рантайма.

Проставляя оценки по первым двум критериям, опирался на материалы, наиболее интересные из которых, приведены ниже. Там, где не получалось опираться, давал субъективную оценку, исходя из собственного опыта. Оценку по третьему критерию брал из упомянутого выше ресерча, основанного большей частью на аналитике по спекам и докам языков, и их экосистем, и CVE, которыми страдали написанные на них проекты.

Там, где семейство языков объединено единой экосистемой (.NET, JVM, Node) рассматривал общие для всего семейства свойства, т.к. глубоко убежден, что хотя конкретные языки и могут отличаться друг от друга по заданным критериям, определяющим фактором здесь остается все же их экосистема.

Затем, с помощью полученных оценок, plotly.js и такой-то матери ChatGPT, сделал визуализацию всего этого, скрины которой вы видите выше. Для желающих покрутить 3D-сцену мышкой, скину в комментах HTML.

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

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

📰 Материалы, помогавшие делать оценку (заслуживающие внимания):

Top 8 Most Demanded Programming Languages
The 9 cost factors
What Is the Most Secure Coding Language?
2025 Stack Overflow Developer Survey
Which Programming Language Has the Most Vulnerabilities?

TL;DR: в любой непонятной ситуации используйте Python, Go или Rust. В любой понятной — выбирайте язык с умом, под задачу, команду и предметную область. C/C++ не используйте, если можете 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
17🤔1
🪲 Насколько все плохо с безопасностью в Gen-AI коде?

Сентябрьское исследование от Cloud Security Alliance указывает на то, что до 62 % AI-генерированного кода демонстрируют известные уязвимости или конструктивные дефекты безопасности.

В октябрьском Veracode 2025 GenAI Code Security Report исследователи анализировали более 80 задач и более 100 моделей LLM и установили, что примерно 45% AI-генерированного кода содержат уязвимости, включающие слабые места из OWASP Top 10. И это только те, которые могут быть детектированы их SAST'ом.

В декабре 2025 исследование по vibe-кодингу показало, что в продвинутых сценариях реального программирования — когда агенты решали задачи из репозиториев GitHub — около 82–90 % рабочих решений всё равно содержали уязвимости, даже если код был функционально корректным.

И, в свете этого, совсем другими красками играет вышедшее буквально на днях в Science исследование Who is using AI to code? По оценке его авторов, к концу 2024 г. ИИ помог создать примерно 29% всех новых функций, написанных разработчиками из США. Доля ИИ-поддержанных функций варьируется по регионам:

• США ~29%,
• Германия ~23%,
• Франция ~24%,
• Индия ~20%,
• Россия ~15%,
• Китай ~12%.

И это только на GitHub и только в проектах на Python...

Забавно получается, если объединить статистику этого исследования со всеми остальными, не правда ли? 🤩
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥1
🤝 Пара интересных RCE в n8n

Похоже, за n8n взялись всерьез (ну... неудивительно). Если дело так пойдет и дальше, придется заводить под их уязвимости отдельную рубрику.

Разбор упомянутых CVE в деталях можно почитать здесь, «из первых рук», так сказать. В чем суть, вкратце. Обе RCE — ответочка от jFrog на уже реализованные разработчиками n8n меры по устранению ранее обнаруженных уязвимостей, которые в итоге и привели к новым CVE-2026-1470 и CVE-2026-0863. Дело в том, что когда возможность выполнения пользователями <относительно> произвольного кода становится официальной фичей, вопрос безопасной реализации подобной функциональности слегка усложняется. Разработчики n8n пошли по пути синтаксической валидации пользовательского кода на уровне AST в обоих случаях (JavaScript, Python): код разбирается в синтаксическое дерево, дерево обходится визитором, осуществляющим детектирование потенциально опасных узлов.

И это — фиговое решение, как минимум по двум причинам.

1️⃣ Во-первых, по своей сути — это контроль по черным спискам. Собственно, патчи к этим уязвимостям (раз, два) разработчики свели к добавлению в эти списки техник атак, продемонстрированных ресерчерами jFrog. Сколько ещё вариантов поиграться с синтаксисом этих языков для подобных RCE существует прямо сейчас — думаю, jFrog'и скоро расскажут. А, как скоро в новых версиях языков появятся конструкции, не предусмотренные в черных списках n8n, но позволяющие выстроить гаджеты для вот таких RCE — покажет время.

2️⃣ Во-вторых, проверки на уровне AST — это синтаксическая валидация. У всех языков, помимо синтаксиса, есть ещё и семантика. А у динамических языков (коими являются, и JavaScript, и Python), некоторая её часть является сущностью времени выполнения. И эта часть НЕ МОЖЕТ быть эффективно проанализирована статическими проходами по синтаксическому представлению. Иными словами, даже белые списки (исходя из того, что в них было бы необходимо разрешить в свете соответствующих фич n8n) здесь не позволили бы закрыть все потенциальные проблемы.

🤓 Как правильно работать с такими кейсами?

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

1️⃣ Если есть возможность влиять на язык, используемый для скриптов, то взять ограниченный валидацией по белым спискам (разрешенные синтаксические конструкции, пространства имен и типы) статический язык с сильной типизацией. Из известных мне языков на эту роль лучше всего подходит C# Scripting.

2️⃣ На этапе прохода по AST инструментировать код проверками на допустимость операций, которые будут осуществляться в рантайме, во время выполнения скрипта. В идеале библиотека рантайма и используемые сторонние библиотеки также должны быть инструментированы (реализацию можно подсмотреть в OpenTelemetry, например). В пределе — это приведет к разработке собственного RASP, заточенного под фичи скриптинга конкретного проекта.

3️⃣ Использовать собственноручно пропатченные интерпретаторы, допускающие только разрешенные синтаксис и семантику. Настолько сложно, что в большинстве случаев нецелесообразно.

Ну и, безотносительно способа первичной защиты: выполнять все пользовательские скрипты в изолированных контейнерах: как минимум — в Docker, как рациональный максимум — в условном FireCracker'е.

TL;DR: разработчики n8n думают, что устранили ещё две RCE, но есть нюанс. И простого способа его обойти у них нет.
Please open Telegram to view this post
VIEW IN TELEGRAM
5👍4🤔1
💻 Уязвимость в cgo (CVE-2025-61732): и снова парсеры

В Go 1.25.7 и 1.24.13 разработчики устранили пару уязвимостей, одна из которых оказалась на мою любимую парсерную тему ☺️

Уязвимость была в стандартном инструменте cmd/cgo — компоненте Go, позволяющем Go-коду взаимодействовать с кодом на C. Из-за расхождений в правилах разбора комментариев между компиляторами Go и C атакующий мог скрыть фрагменты C-кода внутри комментариев. Такие фрагменты игнорировались компилятором Go, но воспринимались как исполняемый код компилятором C, встраиваемым в итоговый бинарник.

Уязвимость проявлялась в механизме обработки doc-комментариев в cgo. Ранее cgo включал (и весьма криво) пользовательские комментарии из исходников Go в генерируемые заголовочные файлы для сишки, из-за чего было возможно нарушить границы комментария в выходном C-коде и внедрить туда выполняемые строки. Например, вставить символы закрытия/открытия комментария */ и /* внутри строки, начинающейся как комментарий Go. В Go такая строка полностью игнорируется (как комментарий //), но в сгенерированном коде Си она была бы преобразована в активный код.

Выглядит это могло как-то так:

// */ system("rm -rf /"); /* 
//export Func1
func Func1() {}


Здесь строка с // */ system("rm -rf /"); /* интерпретируется Go как комментарий и полностью пропускается. Однако утилита cgo при генерации C-кода убирала префикс //, либо заменяла его на /* (видимо для того, чтобы объединять в один большой многострочный коммент несколько однострочных). В итоге в C-код здесь попадет скрытая от гошных SAST'ов команда system("rm -rf /");.

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

Исправили это разработчики весьма радикально: теперь doc-комментарии тупо не собираются. Что в целом понятно, поскольку согласование грамматик двух здоровых языков, в общем случае — задача сомнительная и неблагодарная. Хотя конкретно этот кейс всё же можно было относительно легко и корректно пофиксить, не жертвуя при этом функциональностью.

TL;DR: В свежих версиях Go пофикисили парсерную уязвимость в cgo, позволявшую внедрить в генерируемые заголовочные C-файлы произвольный код через гошные комментарии.
Please open Telegram to view this post
VIEW IN TELEGRAM
57👾2👏1
💻Средства разработки ИИ-агентов на Go

Что делать, если, устав обкладывать свой Python-код линтерами, тайпчекерами и избыточными тестами, решили свалить на Go, а разрабатывать ИИ-агентов всё ещё нужно? Ниже — подборка библиотек и фреймворков, которые помогут продолжить этим заниматься на Go.

Агентные фреймворки (на выбор):

🌟 LangChainGo (tmc/langchaingo)

Go-порт LangChain с упором на композицию: цепочки, агенты, память, инструменты и интеграции для LLM-приложений. Умеет в агенты/инструменты/память; поддержку нескольких LLM/провайдеров; векторные хранилища.

🌟 Eino (cloudwego/eino)

Go-first фреймворк для LLM/AI-приложений, явно ориентированный на Go-конвенции и вдохновлённый LangChain и другими подходами. В наличии композиция пайплайнов (графы/цепочки); инструменты и агентные workflow блоки; экосистемные интеграции; визуальный дебаг/инспекция узлов и оркестрации.

🌟 tRPC-Agent-Go (trpc-group/trpc-agent-go)

Ещё один фреймворк для построения агентных систем на Go, с фокусом на LLM+tools. Поддерживает автономные/полуавтономные агенты; планировщики (в т. ч. иерархические); долгоживущую память/состояние; телеметрию; управление исполнением инструментов с возможностью внешнего выполнения.

🌟 Blades (go-kratos/blades)

Нишевый и минималистичный, позиционируется как мультимодальный агентный фреймворк на Go, с поддержкой кастомных моделей, инструментов, памяти и миддлвари. Подойдет тем, кто плотно сидит на kratos.

Библиотеки:

🌟MCP Go SDK (modelcontextprotocol/go-sdk)

Официальный Go SDK для протокола интеграции LLM‑приложений с внешними инструментами и источниками данных. Поддерживает примерно всё, что
требуется для реализация клиентов и серверов MCP.

🌟tiktoken-go (pkoukk/tiktoken-go)

Порт OpenAI tiktoken на Go для быстрых BPE‑токенизаций и подсчёта токенов: оценка стоимости, контроль лимитов контекста, чанкинг документов и предотвращение отказов по превышению токенов.

Официальные SDK:

🌟OpenAI Go SDK (openai/openai-go)
🌟Go OpenAI (sashabaranov/go-openai)
🌟Anthropic Go SDK (anthropics/anthropic-sdk-go)
🌟Google Gen AI Go SDK (googleapis/go-genai)
🌟AWS SDK for Go v2: Bedrock (github.com/aws/aws-sdk-go-v2)
🌟Azure OpenAI extensions module for Go (Azure/azure-sdk-for-go, azopenai)

Клиенты векторных БД:

🌟Qdrant Go Client (qdrant/go-client)
🌟Pinecone Go SDK (pinecone-io/go-pinecone)
🌟Weaviate Go Client (weaviate/weaviate-go-client)
🌟pgvector-go (pgvector/pgvector-go)

Локальный инференс:

🌟 Go llama.cpp bindings (go-skynet/go-llama.cpp)

Высокоуровневые биндинги для Go к llama.cpp — производительной библиотеке с открытым исходным кодом, написанной на плюсах, и предназначенной для локального инференса LLM.

🌟Ollama (ollama/ollama)

Легковесная, расширяемая высокоуровневая оболочка llama.cpp для создания и запуска языковых моделей локально, хорошо интегрирующаяся с Go-проектами.

🌟LocalAI (mudler/LocalAI)

Альтернатива, дающая «drop-in replacement» REST API, совместимый с OpenAI‑подобными спецификациями. Поддерживает мультимодальность; агентную совместимость через Open Responses API; и Anthropic API.

А ещё больше подобного — здесь.

TL;DR: Просто сохраняем в избранное ☺️
Please open Telegram to view this post
VIEW IN TELEGRAM
10👀322👍1
Пусть на этом канале будет своя, особенная валентинка 🤗 Код сложил сюда.

P.S: Чуть доработал прошлогоднюю консольную версию, да 🙈
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
1017❤‍🔥2
Как разработчику быстро углубиться в тему LLM? Часть 2

Часть 1.

2. Механизм внимания (self-attention)

Вопрос на разминку: как во фразе «Data visualization empowers users to» понять, что слово empowers относится к visualization? В трансформерах за такие зависимости отвечают механизмы внимания.

Сами трансформеры разберём в следующей части, а пока достаточно знать следующее: это нейросеть для работы с последовательностями (текст, аудио, ДНК и т.д.), которая обновляет представление каждого токена слоями. В обучении/обработке готовой последовательности это делается параллельно по всем токенам; в генерации текста новые токены добавляются шаг за шагом (autoregressive), но внутри каждого шага операции параллельные.

Ключевая операция внутри слоя — self-attention: способ «взвесить» для каждого токена, какие другие токены в контексте ему сейчас важны, и собрать из них непосредственно контекст. Для каждого токена линейными преобразованиями вычисляются три вектора:

• Query (Q): «что я сейчас ищу в контексте?»
• Key (K): «по каким признакам меня можно найти/со мной сопоставиться?»
• Value (V): «какую информацию я передаю, если на меня "посмотрят"?»

Как считается self-attention, по шагам:

1️⃣ Dot product (оценка совместимости): для каждого токена берут его Query и считают скалярные произведения со всеми Key остальных токенов. Получается матрица «оценок внимания» размера n×n (n — длина последовательности).

2️⃣ Scaling (масштабирование): оценки делят на √dₖ, где √dₖ — размерность Key/Query в одной голове внимания.
Зачем это нужно: без деления разброс значений Q·Kᵀ растёт с dₖ softmax начинает «насыщаться» (почти 0/1), и обучение/градиенты становятся менее стабильными.

3️⃣ Mask (маскирование): перед softmax часто запрещают некоторые связи, выставляя им очень большие отрицательные числа (эквивалент −∞), чтобы после него они получили почти нулевой вес. Два самых частых случая:
• padding mask: игнорировать токены-паддинги;
causal mask: в генерации текста запретить смотреть в будущее (токен i видит только позиции ≤ i).

4️⃣ Softmax (и иногда dropout): превращает оценки в нормированные веса (распределение внимания), которые суммируются в 1 по строке — для каждого «смотрящего» токена.

5️⃣ Взвешенная сумма Values: веса умножают на V и суммируют — получается контекстный вектор для каждого токена: он содержит информацию о других токенах пропорционально их важности.

Формально:
Attention(Q,K,V) = softmax(Q·Kᵀ / √dₖ) · V,
где T — транспонирование (чтобы Q·Kᵀ дало матрицу n×n).

Зачем вниманию несколько голов (multi-head)?

Одна голова — это один «взгляд» на последовательность: свои матрицы проекций для Q/K/V и свои веса внимания. Multi-head attention делает такие «взгляды» параллельно: каждая голова считает attention независимо, затем выходы голов конкатенируются и проходят через выходную линейную проекцию (W^O). Практический смысл: разные головы могут подхватывать разные типы зависимостей (локальные, дальние, синтаксические/семантические шаблоны), и итоговый контекст получается богаче.

Наивная реализация self-attention опирается на матрицу n×n, поэтому вычислительная природа операции квадратичная по длине контекста. По памяти квадрат возникает, когда мы явно материализуем/храним attention-матрицу (веса). В продакшене часто используют оптимизированные подходы (например, FlashAttention), которые уменьшают пиковую память за счёт того, что не пишут всю матрицу внимания n×n в глобальную память. В autoregressive inference LLM обычно кэшируют K и V для уже сгенерированных токенов (KV-cache), чтобы не пересчитывать их на каждом шаге. Этот кэш растёт линейно с длиной контекста и на больших окнах часто становится главным потребителем памяти на инференсе. Как прикинуть потребление памяти KV-cache для заданной модели и длины контекста хорошо описано здесь.

✍️ На правах домашнего задания стоит изучить следующие материалы:

The Annotated Transformer
Attention? Attention!
FlashAttention
Краткая история механизма внимания в NLP

... и обязательно поиграться с левой частью интерактивной визуализации 🦄
Please open Telegram to view this post
VIEW IN TELEGRAM
106👍1💯1
Agentity: самомодифицирующийся ИИ-агент

В эфире рубрика «потому что могу» 🦄

Набросал игрушечного (~350 строк кода) ИИ-агента для решения примерно всех задач. Ну... в теории 😬 Из коробки эта кроха умеет только читать собственный код, модифицировать его (преимущественно — добавляя себе реализации новых инструментов, необходимых для достижения цели), и рестартовать с сохранением контекста, чтобы подтягивались сделанные изменения.

В наличии также принудительные проверки всех патчей линтером и тайпчекером, а также режим самопочинки, если крохе удастся досамокодиться до исключений в рантайме.

Задачи «на смекалочку» хорошо решает только с большими моделями, типа gpt-5.2, deepseek и т.п. Увы, но их младшие локальные братья зачастую просто не вдупляют, как им могут помочь доступные на старте три инструмента, несмотря на всё, написанное в системном промпте. Тут и сам промпт оптимизировать надо, и структурированный вывод прикручивать (SGR здесь прям напрашивался, но сразу сделать было лень), и нормальный планировщик запиливать. Ну, или дотошно расписывать в формулировке задачи, как связана модификация кода агента с достижением поставленной цели.

Никаких песочниц или ограничений прав — все сурово и по-взрослому (на всякий случай предупреждаю, если вдруг кто решит запустить).

Ну и пока нормально работает только с задачами, чье решение влезает в одно контекстное окно — ни сжатия/суммаризации контекста, ни суб-агентов, здесь не предусмотрено.

Но, блин, оно работает 🎉 А лежит — здесь.

В комменты скину логи с примерами работы.
Please open Telegram to view this post
VIEW IN TELEGRAM
50🔥91👍1
🎲 Вайб... ресёрчинг?

Вдохновленный OpenSpec'овским opsx-explore (скилл для исследований перед разработкой спеки), сделал его вайбовую версию для ненапряжных ресёрчей по вечерам, когда совсем нехрен делать хочется прекрасного, а думать лень. Воркфлоу предельно простой:

1️⃣ Обозначаете общую тему ресёрча.
2️⃣ ИИ собирает релевантную инфу в сети, обогащает ею контекст, предлагает варианты, и задает уточняющие вопросы.
3️⃣ Отвечаете на вопросы, корректируете текущий вектор мыси на древе, если нужно.
4️⃣ Всё повторяется с шага 2, пока не надоест.

Работает, как часы ☺️ Воткнул его в QoderWork (на скрине, рекомендую — реально хороший агент для повседневных задач, с песочницей и тулами).

В комменты скину SKILL.md, в нём стоит поправить имена тулов для поиска в сети и скачивания контента, если захочется использовать в другом агенте. В теории, ничего не мешает и просто воткнуть текст оттуда в промпт условного ChatGPT, если что.
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥6👍32
🧩 Мой набор кастомных агентских скиллов

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

• vibe-research — скилл из предыдущего поста;
• scamper — трансформация идей по методике SCAMPER;
• explore — обобщенная под произвольные темы ресёрчей версия /opsx-explore из OpenSpec;
• triz-solver — ресёрч через ТРИЗ.

Позднее буду туда докидывать также и скиллы для разработки и прочих смежных задач R&D (сейчас они гвоздями прибиты к моим воркфлоу в Qoder'е, как дойдут руки отвязать — так сразу).
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍103😱1
This media is not supported in your browser
VIEW IN TELEGRAM
Всех подписчиц — с чудесным весенним праздником! 🫶🌷

P.S: код того, что на видео, сложил здесь, если что.
Please open Telegram to view this post
VIEW IN TELEGRAM
512🔥4👍3🥰2
This media is not supported in your browser
VIEW IN TELEGRAM
Вы как, слушаете подкасты? Мне нравится и послушать, и поговорить. Недавно вот, был в гостях у подкаста «В SREду на кухне», который ведут инженеры Avito. Обсуждали, как безопасность влияет на надёжность, где чья зона ответственности и в какой момент разработки уже пора думать о безопасности.

Посмотреть и послушать можно на YouTube, VK Video, RuTube или на странице подкаста.
10👍87🔥5💯3
Тут нечаянно (но зато с душой и в лучших чувствах) родилась вот такая незатейливая утилитка, позволяющая мониторить качество соединения к заданному хосту и фиксировать все отклонения на дашборд и в логи.

Возможно, кому-то окажется полезной 🙈
Please open Telegram to view this post
VIEW IN TELEGRAM
5🔥14😁1
🤏 Как рассуждают кодинг-агенты?

Почему (например) Cline, OpenCode и Claude Code дают настолько разные по полноте и качеству результаты на одной и той же LLM? И почему нетривиальный код, написанный тупо в чате с ChatGPT, почти всегда не заводится с нескольких попыток? Дело здесь не только и не столько в промптах, сколько в модели рассуждений (ризонинге), реализованной в конкретном агенте или чат-боте. Ну и ещё в механизмах управления контекстом, которые, тем не менее, напрямую зависят от ризонинга.

В основе большинства современных агентов лежит композиция нескольких паттернов ризонинга: ReAct задаёт базовый цикл рассуждения и действия, Chain-of-Thought структурирует внутренние рассуждения, Plan-and-Execute разделяет стратегическое планирование и тактическое исполнение, а Reflexion обеспечивает самокоррекцию через вербальную рефлексию.

1️⃣ ReAct: фундаментальный цикл рассуждения и действия

Паттерн ReAct (Reasoning + Acting) является основой практически каждого кодинг-агента. Ключевая идея состоит в том, что на каждом шаге агент генерирует либо «мысль» — свободный рассуждательный трейс, не влияющий на среду, — либо «действие» — вызов инструмента или команду, которая порождает наблюдение из среды.

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

В контексте кодинг-агентов цикл ReAct отображается естественно: мысль — «нужно найти функцию, обрабатывающую аутентификацию», действие — grep -r "def authenticate" src/, наблюдение — список найденных файлов. Далее: мысль — «файл auth.py содержит релевантный код, нужно его прочитать», действие — open auth.py, наблюдение — содержимое файла. И так далее до решения задачи.

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

2️⃣ Chain-of-Thought: структурирование внутреннего ризонинга

Chain-of-Thought (CoT) заставляет модель генерировать промежуточные шаги рассуждения перед финальным ответом. Для генерации кода это означает, что модель сначала рассуждает об алгоритме, структурах данных и граничных случаях, а затем пишет код.

Однако стандартный CoT — это однопроходный процесс без взаимодействия со средой. В кодинг-агентах он играет роль «внутреннего монолога» внутри каждого шага ReAct-цикла: перед тем как выбрать действие, агент проходит через цепочку рассуждений. Именно здесь появляются специализированные варианты CoT для кода.

Structured CoT (SCoT) ограничивает рассуждения программными конструкциями — последовательностью, ветвлением и циклом, зеркально отражая структуру исходного кода. Semantic CoT (SeCoT) направляет модель рассуждать о потоке данных и потоке управления перед генерацией кода, что особенно полезно для задач с нетривиальной логикой. Intention CoT (ICoT) фиксирует алгоритмическую суть и временную сложность до написания кода.

В архитектуре кодинг-агента CoT — не столько самостоятельный паттерн, сколько элемент, встраиваемый в каждый шаг ризонинга внутри ReAct-цикла. Его роль — повысить качество отдельного рассуждения, но без обратной связи из среды он бессилен перед ошибками, которые обнаруживаются только при исполнении.

Продолжение — в следующем посте.
Please open Telegram to view this post
VIEW IN TELEGRAM
47👍3💯1
Продолжение...

3️⃣ Agent-Computer Interface: циклы использования инструментов

Если ReAct задаёт абстрактную схему, то циклы использования инструментов (tool-use loops) наполняют её конкретикой. Кодинг-агент взаимодействует с файловой системой, терминалом, LSP (Language Server Protocol), браузером и интерпретатором кода в итеративных циклах: наблюдение текущего состояния → ризонинг → выбор инструмента и аргументов → исполнение → получение результата → обновление контекста.

Ключевое открытие, определившее направление всего поля, было сделано в SWE-agent: интерфейс между агентом и его инструментами столь же важен, как и базовая модель. Авторы ввели понятие Agent-Computer Interface (ACI) — набора специально спроектированных команд (open, edit, search_dir, find_file), оптимизированных для восприятия LLM. Например, команда edit автоматически проверяет синтаксис и отклоняет некорректные правки, показывая агенту, что пошло не так.

Отдельно стоит упомянуть RepairAgent — первый полностью автономный LLM-агент для ремонта программ, где агент свободно перемежает сбор информации, подготовку патчей для исправления и валидацию, управляемый формальным конечным автоматом.

Ещё один интересный результат был получен в Live-SWE-agent: агент стартует с минимальным набором инструментов (только bash) и автономно эволюционирует собственный скаффолдинг в процессе работы, адекватно поставленной цели. Собственно, agentity был сделан под влиянием именно этой работы, хотя ризонинг там и ограничивается пусть и специализированным, но весьма примитивным ReAct'ом.

4️⃣ Plan-and-Execute: разделение стратегии и тактики

Паттерн Plan-and-Execute (P-t-E) разделяет процесс на две фазы: сначала модель формирует план (последовательность шагов), затем последовательно исполняет каждый шаг. В кодинг-агентах это часто выглядит как: понять задачу, локализовать релевантный код, спланировать изменения, реализовать изменения, проверить тестами, итерировать при необходимости.

Ключевые варианты: статический P-t-E (план фиксирован), динамический реплэнинг (план пересматривается после каждого шага на основе результатов), иерархическое планирование (цели → подзадачи → конкретные действия) и DAG-based execution, где независимые шаги исполняются параллельно.

5️⃣ Reflexion: вербальное обучение с подкреплением

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

Архитектура включает три компонента: Актор (генерирует действия в ReAct-стиле), Оценщик (сигнал о качестве траектории — тесты прошли/не прошли, ошибки компиляции), Рефлектор (анализирует неудачу и генерирует вербальную рефлексию).

Reflection-Driven Control идёт ещё дальше, встраивая рефлексию непосредственно в процесс генерации: агент непрерывно запускает внутренний цикл рефлексии, который мониторит и оценивает его собственный путь принятия решений, извлекая релевантные примеры ремонта и руководства по безопасному коду из эволюционирующей рефлективной памяти.

OmniReflect вводит иерархическую рефлексию: из опыта множества задач дистиллируется «конституция» — компактный набор руководящих принципов, которые переносятся между задачами.

Как паттерны композируются в реальных системах

Кодинг-агенты используют композицию этих паттернов. Общая тенденция: Plan-and-Execute на макроуровне для декомпозиции задач, ReAct на микроуровне для каждого шага исполнения, CoT внутри отдельных шагов рассуждения, tool-use loops для приземления в реальность, и Reflexion для самокоррекции при неудачах.

Но дьявол здесь, как водится, в деталях, которые в итоге и определяют качество «выхлопа» агента: как именно реализован ReAct, чем ограничен CoT и каков он, развит ли Reflexion до re-plan, реализован ли DAG в P-t-E и каким образом и т.п.

Если пост вызовет достаточный интерес, попробую подготовить разбор подходов к ризонингу и контекст-менеджменту, реализованных в конкретных кодинг-агентах.
Please open Telegram to view this post
VIEW IN TELEGRAM
211👍8💯2