Недавно на созвоне в Соер.Клубе обсуждали вопросы создания Architecture Decision Record (ADR), у нас была задача описать условия при которых целесообразно создавать и вести ADR.
Обсудили огромное количество деталей, которые хочется обобщить и зафиксировать в виде коротких подсказок. Возможно вам тоже будет полезно.
#cards #adr
Обсудили огромное количество деталей, которые хочется обобщить и зафиксировать в виде коротких подсказок. Возможно вам тоже будет полезно.
#cards #adr
1👍43 9 6🔥5
Forwarded from Соер.Клуб | эволюция
Первый шаг к понимаю архитектуры ПО - понимание контекста решаемого вопроса.
Я много консультирую, провожу воркшопы, делаю курсы по архитектуре и заметил одну важную деталь - часто люди упускают момент, который является основным ключом к пониманию архитектуры - контекст.
Сложность в том, что по архитектуре ПО нет общего стандарта, который можно было бы брать за основу и говорить всем "так и только так правильно", одни и те же термины используются разными авторами в разных контекстам по-разному (например, "зависимость" в UML и зависимость в DIP - имеют разные смыслы, или "пасивность view" в MVC и MVP тоже разные, более того есть свой вариант MVC для десктопов и веб).
Поэтому при проектировании я придерживаюсь следующего порядка:
1. Определить контекст
2. Определит архитектурную идею (об этом как-нибудь тоже расскажу)
3. Отразить схему или диаграмму для иллюстрации идеи.
Графическое представление идеи - очень важно, но без контекста может сильно запутать. Пока не появится привычки отделять "мух от котлет" ни о каком понимании речи идти не может.
Я много консультирую, провожу воркшопы, делаю курсы по архитектуре и заметил одну важную деталь - часто люди упускают момент, который является основным ключом к пониманию архитектуры - контекст.
Сложность в том, что по архитектуре ПО нет общего стандарта, который можно было бы брать за основу и говорить всем "так и только так правильно", одни и те же термины используются разными авторами в разных контекстам по-разному (например, "зависимость" в UML и зависимость в DIP - имеют разные смыслы, или "пасивность view" в MVC и MVP тоже разные, более того есть свой вариант MVC для десктопов и веб).
Поэтому при проектировании я придерживаюсь следующего порядка:
1. Определить контекст
2. Определит архитектурную идею (об этом как-нибудь тоже расскажу)
3. Отразить схему или диаграмму для иллюстрации идеи.
Графическое представление идеи - очень важно, но без контекста может сильно запутать. Пока не появится привычки отделять "мух от котлет" ни о каком понимании речи идти не может.
1👍14 4 3🔥1
Хочу поделиться с вами публичным гайдом Как правильно использовать и обрабатывать исключения в программе, который поможет улучшить обработку ошибок и исключений на бэкенде. Если хотите такой же гайд для обработки ошибок на фронтенде, то давайте соберем 100 отметок 💡 и я подготовлю материал для вас.
Please open Telegram to view this post
VIEW IN TELEGRAM
SOER.MEDIA
Как правильно использовать и обрабатывать исключения в программе (для бэкенда)
Постоянно сталкиваюсь с глубоким непониманием того как должны обрабатываться исключения в современных приложениях, реализующих клиент-серверный подход. Поэтому решил собрать краткий гайд об основных моментах, которые нужно учесть при обработке исключений
Сейчас на практике встречается четыре основных подход в архитектуре:
1️⃣ Монолит
2️⃣ Сервисный подход
3️⃣ Микросервисный
4️⃣ Событийный подход
Последний часто комбинируется вместе с микросервисами и по сути является способом организовать реактивное поведение в системе.
Это базовая четвёрка является основой абсолютного большинства решений на рынке. Я сделал небольшой обзор каждого из них. Думаю будет полезно ознакомиться каждому.
Последний часто комбинируется вместе с микросервисами и по сути является способом организовать реактивное поведение в системе.
Это базовая четвёрка является основой абсолютного большинства решений на рынке. Я сделал небольшой обзор каждого из них. Думаю будет полезно ознакомиться каждому.
Please open Telegram to view this post
VIEW IN TELEGRAM
SOER.MEDIA
Чем отличаются монолитная, сервисная, микросервисная и event-driven архитектуры
В современной разработке программного обеспечения существует несколько фундаментальных архитектурных стилей, определяющих структуру, принципы взаимодействия компонентов и эволюцию системы. Понимание их различий является критически важным для выбора оптима
3❤34👍22 9 6🔥1
В прошлом посте об обработке ошибок на бэкенде мы собрали больше 100 отметок 💡 , выполняю свое обещание и публикую новую заметку на тему исключений - Как правильно обрабатывать исключения (для фронтенда). На этот раз я больше задумался об архитектурных вопросах обработки ошибок, и в итоге получил более полный и глубокий разбор, надеюсь вам понравится.
SOER | PRO | Boosty
SOER | PRO | Boosty
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
S0ER
Хочу поделиться с вами публичным гайдом Как правильно использовать и обрабатывать исключения в программе, который поможет улучшить обработку ошибок и исключений на бэкенде. Если хотите такой же гайд для обработки ошибок на фронтенде, то давайте соберем 100…
1 19👍13 4
Программирование в значительной степени эмпирическая штука, теория строится не на базе строго доказанных теорем, а на основе обобщения личного опыта. Поэтому трудно винить программистов в том, что они придумывают и придумывают новые правила.
Ради справедливости стоит сказать, что некоторые правила оказываются весьма удачными, потому что просты и понятны. Примеры хороших правил - "is-a" и "has-a".
IS-A
гласит, что наследование уместно использовать там, где можно вместо слова "наследование" подставить "is-a" (является). Если мы хотим понять, может ли стул наследоваться от стола, то фраза "стул является столом" подсказывает, что нет, не можем.
HAS-A
гласит, что композицию уместно использовать там, где слово "композиция" может быть заменена на "has-a" (имеет). Например, "Стол это композиция столешницы и ножек" может быть заменен на "Стол имеет столешницу и ножки", правило выполняется, а следовательно композиция в данном случае применима.
Ради справедливости стоит сказать, что некоторые правила оказываются весьма удачными, потому что просты и понятны. Примеры хороших правил - "is-a" и "has-a".
IS-A
гласит, что наследование уместно использовать там, где можно вместо слова "наследование" подставить "is-a" (является). Если мы хотим понять, может ли стул наследоваться от стола, то фраза "стул является столом" подсказывает, что нет, не можем.
HAS-A
гласит, что композицию уместно использовать там, где слово "композиция" может быть заменена на "has-a" (имеет). Например, "Стол это композиция столешницы и ножек" может быть заменен на "Стол имеет столешницу и ножки", правило выполняется, а следовательно композиция в данном случае применима.
2👍65 10 6❤3👎2🔥2👌1
Forwarded from Соер.Клуб | эволюция
#бриф
Соер.Клуб активно пополняется новыми материалами, мы наконец-то подошли к концу курса по монолитной архитектуре и активно готовимся к курсу по сервисной архитектуре. Далее короткий список материалов, с которыми можно ознакомиться:
Без подписки (публичные материалы):
- Как правильно использовать и обрабатывать исключения в программе (для бэкенда)
- Как правильно обрабатывать исключения (для фронтенда)
- Чем отличаются монолитная, сервисная, микросервисная и event-driven архитектуры
- Что такое URL, URN и URI. В чем их различие
- Алгоритм работы https handshake
Лекции по архитектуре
- Лекция. Сбор требований
- Лекция. Архитектурный ландшафт монолитного приложения
- Лекция. Проведение границ и разделение обязанностей, модульные монолиты
- Лекция. Проектирование (модель C4)
- Лекция. Введение в паттерны проектирования
- Лекция. Шаблонизация
- Лекция. Работа с контейнерной инфраструктурой для монолита
- Лекция. Облачные провайдеры и виртуализация
- Лекция. Проксирование и маршрутизация запросов в монолитных приложениях
- Лекция. Анализ вектора развития приложения
Воркшопы
- Воркшоп. Разбираем сбор требований на примере
- Воркшоп. Описание архитектурного ландшафта приложения
- Воркшоп. Анализ границ готового приложения
- Воркшоп. Пример описания проекта по модели C4
- Воркшоп. Развертывание приложения NestJS в монорепозитории
- Воркшоп. Примеры применения шаблонизации
- Воркшоп. Контейнеризация приложения
- Воркшоп. Разбор примера облачной инфраструктуры
- Воркшоп. Развертывание Nginx как прокси сервера
Созвоны
- Созвон. Анализ и подготовка требований
- Созвон.Архитектурный ландшафт монолитного приложения
- Созвон. Рефакторинг архитектуры и сбор требований
- Созвон. Компонентная диаграмма и зависимости
- Созвон. Обсуждение модели С4, обсуждения эффективных методов погружения в архитектуру
- Созвон. Использование мультиагентных систем ИИ и планировние контекст
- Созвон. Обсуждение С4 и эволюции архитектуры
- Созвон. Terraform vs Ansible, планы на развитие курсов
Гайды
- Установка и настройка nginx
- Автоматизированное развертывание Docker с помощью Ansible
Все перечисленные материалы можно получить по подписке, до конца месяца действует льготная цена на подписки STREAM, WORKSHOP
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥7❤1
Промпт для исправления ошибок в коде
Некоторое время использую QWEN3-Coder-480b-А35b-Instruct и QWEN Coder. Модель в чем-то хороша, в чем-то не очень. Хочу рассказать о своем опыте борьбы с неверным поведением модели.
Когда ИИ генерирует программный код, он может допускать ошибки, как и обычный разработчик. Синтаксические проблемы исправляются довольно просто, но встречаются и более сложные случаи, связанные с семантикой.
Хочу разобрать конкретный пример, который демонстрирует, насколько по-разному может работать ИИ в зависимости от формулировки промпта.
Сообщение от интерпретатора выглядит так:
На первый взгляд кажется, что это стандартная синтаксическая ошибка, но в действительности наша проблема связана с семантикой. Рассмотрим фрагмент кода, на который указывает интерпретатор:
Особенность в том, что "function" здесь представляет собой имя поля в таблице, а не ключевое слово Lua для объявления функций. Это требование продиктовано не локальными особенностями, а спецификацией OpenAI API. Следовательно, ИИ должен не только диагностировать суть недочёта, но и предложить корректное решение. Например, вместо замены имени поля следует использовать обращение через квадратные скобки:
Некоторое время использую QWEN3-Coder-480b-А35b-Instruct и QWEN Coder. Модель в чем-то хороша, в чем-то не очень. Хочу рассказать о своем опыте борьбы с неверным поведением модели.
Когда ИИ генерирует программный код, он может допускать ошибки, как и обычный разработчик. Синтаксические проблемы исправляются довольно просто, но встречаются и более сложные случаи, связанные с семантикой.
Хочу разобрать конкретный пример, который демонстрирует, насколько по-разному может работать ИИ в зависимости от формулировки промпта.
Сообщение от интерпретатора выглядит так:
Failed to run `config` for agentsoer.nvim
vim/loader.lua:0: ...soer/projects/agentsoer.nvim/lua/agentsoer/engine/ai.lua:43: '<name>' expected near 'function'
# stacktrace:
- vim/loader.lua:0
- lua/agentsoer/commands.lua:5
- lua/agentsoer/init.lua:4
- ~/.config/nvim/lua/plugins/init.lua:34 _in_ **config**
- ~/.config/nvim/init.lua:17
На первый взгляд кажется, что это стандартная синтаксическая ошибка, но в действительности наша проблема связана с семантикой. Рассмотрим фрагмент кода, на который указывает интерпретатор:
42 local function handle_tool_call(tool_call)
43 if tool_call.function.name == "list_directory" then
44 local success, params = pcall(vim.fn.json_decode, tool_call.function.arguments)
45 if success then
Особенность в том, что "function" здесь представляет собой имя поля в таблице, а не ключевое слово Lua для объявления функций. Это требование продиктовано не локальными особенностями, а спецификацией OpenAI API. Следовательно, ИИ должен не только диагностировать суть недочёта, но и предложить корректное решение. Например, вместо замены имени поля следует использовать обращение через квадратные скобки:
['function'].name.GitHub
GitHub - QwenLM/qwen-code: Qwen Code is a coding agent that lives in the digital world.
Qwen Code is a coding agent that lives in the digital world. - QwenLM/qwen-code
👍8❤7👎6
Здесь проявляется любопытная закономерность. Если просто попросить LLM исправить сообщение об ошибке, система воспримет информацию от интерпретатора буквально и сосредоточится на синтаксических аспектах, вместо того чтобы исследовать корневую причину.
Неудачный промпт:
Эффективный промпт:
Неудачный промпт:
Исправь ошибку
vim/loader.lua:0: ...soer/projects/agentsoer.nvim/lua/agentsoer/engine/ai.lua:43: '<name>' expected near 'function'
# stacktrace:
...
Эффективный промпт:
Проанализируй причину возникновения ошибки, рассмотри несколько подходов к решению и предложи способ устранения:
vim/loader.lua:0: ...soer/projects/agentsoer.nvim/lua/agentsoer/engine/ai.lua:43: '<name>' expected near 'function'
# stacktrace:
...
👎9👍5 2
В своих экспериментах я использовал QWEN3-Coder-480b-А35b-Instruct. При первом подходе модель начинала с синтаксического разбора, затем последовательно анализировала файл в поисках непечатных символов, способных сбить с толку интерпретатор, после чего пыталась создать минимально работоспособную версию и доработать её. В конечном счёте этот процесс приводил к исчерпанию лимитов сессии.
При втором, более эффективном подходе, та же самая модель находила и корректировала неточность всего за 2-3 итерации после начала диалога.
Чтобы сэкономить токины я в первую очередь предлагаю исправлять ИИ ошибки как синтаксические, потому что стадия "анализа ошибки" может быть весьма объемной, если ИИ не справляется с первого раза, то переходить на второй вариант. Если и второй вариант не помог, то смотреть ошибку самому. Как я уже сказал, большая часть проблема отсекается на первом этапе, семантические проблемы на втором. И крайне редко приходится смотреть самому, как правило если речь заходит о рефакторинге, где старый код сильно сбивает ИИ.
При втором, более эффективном подходе, та же самая модель находила и корректировала неточность всего за 2-3 итерации после начала диалога.
Чтобы сэкономить токины я в первую очередь предлагаю исправлять ИИ ошибки как синтаксические, потому что стадия "анализа ошибки" может быть весьма объемной, если ИИ не справляется с первого раза, то переходить на второй вариант. Если и второй вариант не помог, то смотреть ошибку самому. Как я уже сказал, большая часть проблема отсекается на первом этапе, семантические проблемы на втором. И крайне редко приходится смотреть самому, как правило если речь заходит о рефакторинге, где старый код сильно сбивает ИИ.
👍10👎6 1
Завел себе канал в Максе, говорят там самая адекватная аудитория! Когда телегу поблочат, увидимся с вами там)
https://max.ru/softwareengineervlog
https://max.ru/softwareengineervlog
max.ru
MAX – быстрое и легкое приложение для общения и решения повседневных задач
MAX позволяет отправлять любые виды сообщений и звонить даже на слабых устройствах и при низкой скорости интернета.
1👎326😁74👍27👀7 5❤3🥰2 2🔥1
Сколько токенов в сутки потребляют ваши ИИ агенты?
Anonymous Poll
68%
Не использую агентов
19%
До 10 млн. токенов
4%
10-30 млн. токенов
1%
30-60 млн. токенов
1%
60-120 млн. токенов
7%
Более 120 млн. токенов
😁19👎5❤2
Forwarded from Соер.Клуб | эволюция
This media is not supported in your browser
VIEW IN TELEGRAM
У меня две основные модели для кодинга - GLM-4.6 и Qwen3-code. Недавно мне стало интересно насколько модели могут осознать сами себя и я решил начать с простой рефликсии - скажи свое имя. Результат в видео.
😁11 4
Активно работаю с ИИ агентами, постепенно "высушиваю" промпты и описание сабагентов до минимально работающих функций. Заметил, что в моих промптах чаще всего используются ASCII деревья.
Это происходит потому что почти все программирование это структуры и операции над ними. А самая популярная структура - дерво. Есть ощущение, что любая декомпозийия в конечном итоге - дерево.
Далее, как ни странно, в описаниях лидируют "стек" и "очередь".
А завершает цепочку рекурсивное описание.
А вот условия встречаются крайне редко.
Получается, что я работаю с агентами в функциональном стиле - и основная задача декларативно описать результат, который хочу получить, а дальше пусть сам думает.
Это происходит потому что почти все программирование это структуры и операции над ними. А самая популярная структура - дерво. Есть ощущение, что любая декомпозийия в конечном итоге - дерево.
Далее, как ни странно, в описаниях лидируют "стек" и "очередь".
А завершает цепочку рекурсивное описание.
А вот условия встречаются крайне редко.
Получается, что я работаю с агентами в функциональном стиле - и основная задача декларативно описать результат, который хочу получить, а дальше пусть сам думает.
1👍23🔥7❤1
Forwarded from Соер.Клуб | эволюция
Сейчас идет активное переосмысление старых подходов к разработке, много разговоров про вайб-кодинг. Под вайб-кодиногом обычно имеют в виду использование одного умного агента, которому достаточно поставить задачу, а он все сделает сам. В текущих реалиях так сделать не получается, приходится постоянно корректировать результат работы LLM, что иногда не только не упрощает, но усложняет разработу.
Мы в своей лаборатории решили не придумывать велосипед, а начали работать по направлению метапрограммирования, взяли старую добрую идею "код - это тоже данные", ушли от идеи "одного агента" и сделали замкнутую агентскую систему (т.е. агенты сами "видят" результаты изменения кода).
Такой подход позоляет:
Какие выводы мы сделали:
- вайб-кодинг в его текущем варианте "одного агента" не заменит обычную разработку до появления AGI;
- агентские системы, основанные на идеях метапрограммирования, уже сейчас могут взять на себя решение типовых задач без необходимости постоянного контроля со стороны разработчика.
Основные проблемы: медленная работа LLM, большое потребление токенов (результат есть, но пока довольно дорого с позиции денег).
Думаю, что AGI в ближайшее время ждать не стоит, а вот агентские системы внедряться будут активно.
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍13🔥6❤1😁1👀1
Пришло время полезных тредов. Давайте обсудим какие llm вы запускаете локально, на каком железе и какие модельки вам нравятся. Заходите и делитесь опытом в комментариях, думаю всем будет полезно 👇👇👇
👍6👎1
Попросил DeepSeek сделать таблицу истиности для конъюнкции, используя язык JavaScript и битовые операции, вот что получил:
На собесах, идея использования вложенных циклов - это самое популярное решение. Тем временем мне больше нравится такой вариант:
Здесь я добавил иллюстрацию закона Де Моргана, пока не обращайте на него внимание.
Интересно, что многие программисты жалуются на излишнюю сложность второго варианта, мол нет насмотренности на битовые операци, сложно быстро понять код.
В целом с булевой алгеброй тоже возникают сложности, часто люди не могут применить закон Де Моргана, чтобы упростить свои условия. Я, конечно, по-стариковски думаю "Да, были люди в наше время, Не то, что нынешнее племя", но понимаю, что код должен быть понятен всем участникам проекта и первый вариант имеет в этом смысле явное преимущество, но при этом я хотел бы работать с ребятами, которые легко читают второй вариант, в целом это будет совсем другой "средний уровень команды".
Поэтому, интересно ваше мнение какой из двух вариантов кода вам нравится больше и почему? Пишите в комментариях 👇👇👇
console.log("Таблица истинности для a && b (битовые операции)");
console.log("a\tb\ta & b");
console.log("---------------");
// Используем битовые операции с числами 0 и 1
for (let a = 0; a <= 1; a++) {
for (let b = 0; b <= 1; b++) {
// Битовая операция И
const result = a & b;
console.log(`${a}\t${b}\t${result}`);
}
}
На собесах, идея использования вложенных циклов - это самое популярное решение. Тем временем мне больше нравится такой вариант:
for(let i = 0; i < 4; i++) {
const a = i & 1;
const b = i >> 1 & 1;
console.log(`\t${a} & ${b} = ${a && b} (${Number(!(!a || !b)}))`);
}
Здесь я добавил иллюстрацию закона Де Моргана, пока не обращайте на него внимание.
Интересно, что многие программисты жалуются на излишнюю сложность второго варианта, мол нет насмотренности на битовые операци, сложно быстро понять код.
В целом с булевой алгеброй тоже возникают сложности, часто люди не могут применить закон Де Моргана, чтобы упростить свои условия. Я, конечно, по-стариковски думаю "Да, были люди в наше время, Не то, что нынешнее племя", но понимаю, что код должен быть понятен всем участникам проекта и первый вариант имеет в этом смысле явное преимущество, но при этом я хотел бы работать с ребятами, которые легко читают второй вариант, в целом это будет совсем другой "средний уровень команды".
Поэтому, интересно ваше мнение какой из двух вариантов кода вам нравится больше и почему? Пишите в комментариях 👇👇👇
👎27👍6