Обновить
1024K+

Программирование *

Искусство создания компьютерных программ

1 211,58
Рейтинг
Сначала показывать
Порог рейтинга

T-shaped снова в моде?

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

В обиход входит слово tiny teams. По представлениям сбера (это их инициатива), это компактные команды в несколько человек с большой степенью автономности находящиеся внутри ai sdlc, где все процессы изменены, где все знания доступны агентам и так далее. В общем ai native организации, вместо (зачеркни ненужное) бирюзовых, agile и других слов.

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

Сейчас же ИИ действительно позволяет увеличить производительность, что само по себе приводит к укрупнению зон ответственности, но это явление временное. Когда агенты станут такой же обыденностью как персональные компьютеры (представьте разницу между теми у кого они были и у кого их не было в 80 годы), то для увеличения производительности труда снова придется дробить ответственности и брать больше людей.

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


Через 5 лет мы будем оглядываться назад и говорить о том, как все было очевидно, вот это работает, а вот это бы не заработало никогда. Как говорится, знал бы прикуп жил бы в Омске

Теги:
Всего голосов 5: ↑4 и ↓1+5
Комментарии0

Как мы закрываем задачу: тесты, диптрак, аудит и ещё пара рубежей

Продолжение серии про работу с ИИ-агентом. В прошлый раз разбирали, где живёт задача. Теперь — что с ней происходит, прежде чем она станет done.

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

1. Автоформат — молча и сразу. После каждого Edit/Write срабатывает хук: Pint для PHP, Prettier для JS/TS правят изменённый файл. Не блокирует, ничего не спрашивает. Форматирование просто снято с повестки — про пробелы и переносы мы не спорим никогда.

2. Приёмка «прогнал — работает» (скилл verify-task). Финал задачи — не «по идее работает», а таблица. Перечитываем Definition of Done, по каждому пункту: как проверено → PASS/FAIL. Внутри:

  • прогон тестов затронутой области (Pest/PHPUnit) — зелёные, а не «вроде есть»;

  • smoke живого сценария через tinker или artisan-команду;

  • корнер-кейсы: пусто, граница, null, таймаут внешнего сервиса;

  • в diff нет ключей и .env.

Любой FAIL — задача не закрыта. Без «ну это мелочь, потом починим».

3. Deptrac — границы слоёв (Stop-хук). На попытке закрыть ход прогоняется анализатор архитектуры. Уехала логика из сервиса в контроллер, модель полезла напрямую во внешний API — exit 2, ход не закрывается, пока не переложишь код в правильный слой. Тот же гейт стоит в CI, а легаси-долг зафиксирован baseline’ом, чтобы старые грехи не блокировали новую работу. Правило в конфиге кажется неверным? Правь конфиг явно и объясняй — обходить молча нельзя.

4. Секреты не текут (guard-secrets). Отдельный хук стережёт, чтобы содержимое .env, ключей и дампов не улетело в чат: cat/grep по секретному файлу блокируются, Read на него — тоже. Править такие файлы можно (Edit/scp), а вываливать в переписку — нет.

5. Рефлексия — иначе не закрыть (guard-discipline). Код менялся, а записи в task/history за сегодня нет? Снова exit 2. Хук требует короткий разбор: что ставили, как решал, решено да/нет/частично, что можно было лучше. Следующая сессия начнёт с этих заметок и не наступит на те же грабли.

6. Независимый аудит — по коду, а не по рассказу. После нетривиальной доработки запускается отдельный агент, который не видел, как ты решал. Ему дают diff и чек-лист: все ли call-сайты покрыты, нет ли регрессий, есть ли тесты, скрытые баги, не уехали ли слои, не утекли ли секреты. Вердикт — APPROVE или CHANGES NEEDED со списком «файл:строка — почему». Нашёл проблему — не чинит молча, возвращает автору. Без аудита мёрдж не предлагаем.

7. И только теперь — в done и на мёрдж. Задача переезжает в task/done до открытия MR, в той же ветке. Прямой push в main закрыт хуком — только через merge request. А прод-pull делает человек: guard-prod fail-closed не пускает агента мутировать боевой сервер, агент лишь готовит команды.

Тут важно, кто есть кто. Автоформат, Deptrac, защита секретов, рефлексия, запрет пуша в main и защита прода — это хуки. Они срабатывают автоматически на события (после правки файла, при попытке закрыть ход, перед bash-командой) и возвращают exit 2, если что-то не так. Их нельзя «забыть» или уговорить — они не читают промпт, они перехватывают действие. А приёмка и аудит — это скиллы, процедуры, которые агент запускает сам: тут уже нужна голова, а не только стенка. Стенки ловят механику, скиллы — смысл.

Звучит как гора бюрократии — но пять рубежей из семи срабатывают сами и молча. Человека дёргают только там, где цена ошибки настоящая: на аудите и на проде.

«Готово» — не когда агент дописал код, а когда код прошёл все рубежи.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Must-read для Python-разработчика: 5 статей от практика с сотнями интервью за плечами 

Делимся подборкой статей от Евгения Бартенева, эксперта курсов Практикума и разработчика с 20-летним опытом. А ещё он активно занимается созданием образовательного контента: является автором и техлидом курса «Python-разработчик», пишет статьи и проводит бесплатные мок-интервью для всех желающих в рамках проекта Boreesych.

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

Особенности Python, о которых вас точно спросят на техническом собеседовании. Часть 2. Евгений выпустил продолжение, так как первая часть вызвала оживлённое обсуждение: в комментариях читатели делились собственным опытом и задавали отличные уточняющие вопросы. В этой части ещё больше подводных камней Python — уже традиционно без абстракций и банальщины.

Строки в Python: всё не так просто, как кажется. Начинающим разработчикам строки обычно кажутся едва ли не самым простым, что есть в языке программирования, но для Python это не совсем так. Евгений разбирает, какие бывают строки, чем они отличаются друг от друга, какие возможности дают и какие подводные камни могут встретиться в работе с ними. Здесь и о базовом использовании, и о важных деталях, которые стоит помнить каждому разработчику. 

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

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

Если хотите освоить профессию Python-разработчика с нуля, сделать это можно на курсе «Python-разработчик» в Практикуме. Первые 30 уроков доступны бесплатно: вы попробуете себя в роли разработчика, познакомитесь с образовательной платформой и поймёте, подходит ли вам курс.

Теги:
Всего голосов 5: ↑5 и ↓0+7
Комментарии0

Type-driven development в Rust: делаем недопустимые состояния невыразимыми

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

Начинаем с type-driven development в Rust — подхода, при котором правила предметной области выражаются в типах, а код, нарушающий эти правила, не компилируется. О том, как применять его на практике расскажет Никита Тимофеенко, разработчик команды MXDR компании F6.

Серия рассчитана на тех, кто уже пишет на Rust и хочет от системы типов большего, чем борьба с borrow checker-ом. Теории типов не будет — только приёмы и шаблоны для рабочего кода, почти всё на стабильном Rust.

После первой части вы сможете посмотреть на свои структуры с флагами и Option-ами, посчитать, сколько недопустимых состояний они позволяют собрать, перепроектировать их так, чтобы эти состояния перестали компилироваться, и удалить часть defensive-проверок.

В первой статье — пять техник, каждая разобрана по схеме «проблема -> решение -> хорошие практики -> как это используют известные крейты или std библиотека».

Примеры во всей серии — из биржевой торговли, но сами приёмы работают в любом домене со сложными состояниями и правилами их изменения:

  • newtype — свой тип для каждой роли вместо голого примитива: значения разных типов не перепутать местами, а инварианты проверяются один раз — при создании (smart constructor);

  • ADT — «одно из» через enum с данными в вариантах вместо булевых флагов и Option-ов, допускающих бессмысленные комбинации;

  • uninhabited types — типы без значений: как убрать ветку ошибки, которая «никогда не случится», так, чтобы это гарантировал компилятор, а не unreachable!();

  • phantom types — параметры-маркеры без рантайм-представления: одна generic-обёртка с типом-тегом вместо семейства одинаковых newtype-ов;

  • typestate — состояние объекта в его типе: у каждого состояния свой набор методов, переход возвращает новый тип, а неверный порядок шагов не компилируется.

Первая статья — «Type-driven development в Rust. Часть 1/5: делаем недопустимые состояния невыразимыми» — уже на GitHub. Там же — компилируемые примеры ко всем приёмам: Cargo workspace, который собирается и проходит тесты.

Теги:
Всего голосов 3: ↑3 и ↓0+5
Комментарии0

Задача — это файл в git, а не сообщение в чате

Предисловие. За год плотной работы с ИИ-агентами — пять проектов доехали до продакшна — у нас сложился набор практик. Разбираем по одной. Первая и базовая: где живёт задача.

Приходит, значит, товарищ к агенту: сделай, милый, вот такую фичу. Агент кивает, бодро пишет код, всё замечательно. Проходит два дня. Товарищ открывает новый чат — а там пусто. Агент не помнит ни фичи, ни уговора, ни что «готово» вообще должно было означать. У него каждое утро чистый лист. И сидит наш товарищ, восстанавливает контекст по диффу, как археолог по черепкам.

Причина простая: задача жила в переписке, а переписка не версионируется и сессию не переживает. Поэтому у нас задача — это файл в git, рядом с кодом. Он коммитится вместе с кодом, который его закрывает, и едет в той же feature-ветке.

Структура папок

Всё, что касается задач, лежит в репозитории и отслеживается git (у нас — 294 файла):

task/                  ← активные задачи (сейчас в работе)
├── done/              ← закрытые
└── history/           ← рефлексия по сессиям (отдельная практика)
plans/                 ← длинные roadmap'ы
  • task/ — только то, что сейчас в работе. Незакрытое и без хвостов. У нас тут обычно 1–3 файла.

  • task/done/ — задача переезжает сюда, как только выполнен Definition of Done. Не после деплоя, а сразу как критерий закрыт. Это архив сделанного: сейчас 121 задача, каждую можно открыть и посмотреть, что и как решали.

  • plans/ — большие направления, которые не влезают в одну задачу. Roadmap режется на пачку мелких task-файлов; агент читает общий план, потом берёт из него конкретный кусок. Сейчас 9 роадмапов.

  • task/history/ — рефлексия по сессиям. Это уже про память агента, отдельная практика; здесь только упоминаю, чтобы структура была полной.

Имя файла — YYYY-MM-DD_HH-MM-название.md, с датой и временем создания. Даёт хронологию из коробки: задачи сортируются по возникновению, имена не конфликтуют, ничего не перетирается.

Что внутри задачи

  • Одна задача = одна функция. Она же — одна feature-ветка и один MR. Есть задача на эту фичу — работаем с ней, вторую не заводим: два файла на одно дело — и потом сам не разберёшь, который из них настоящий.

  • Фазы со статусом. Внутри — шаги, у каждого [ ] или [x]. Сессия оборвалась — следующая открывает файл и видит, где остановились: что сделано, что ждёт, что готово, но не проверено. Состояние читается из файла, а не восстанавливается по памяти.

  • Definition of Done — перечисляемым списком. Не «сделать фичу», а конкретные пункты: что именно должно работать. Без списка «готово» у каждого своё. Этот же список потом становится чек-листом приёмки: пункт → проверка → PASS/FAIL, любой FAIL — задача не закрыта.

  • Итоговый блок. В конце — реализовано целиком или нет, что осталось, какие решения приняли и почему.

Скелет реальной задачи из проекта:

# Фаза 7 — калибровка порога confidence
**Тип:** chore + small feat
**Ветка:** chore/retrieval-calibration
**Зависимости:** фаза 6 в проде
**Статус:** Шаг 1 готов; Шаги 2-3 ждут трафика

## Прогресс
- [x] Шаг 1 — инструментовка. Тесты зелёные.
- [ ] Шаг 2 — сбор датасета с прода (ждёт трафика).
- [x] Шаг 3 — эвал-команда готова. Осталось прогнать на реальных данных.

## Контекст
Почему пороги пока с потолка и что от них зависит.

Что это даёт

  • Переживает сессию и машину. Контекст не теряется между чатами: новый агент читает файл и продолжает с той же точки.

  • Едет в ревью вместе с кодом. Ревьюер видит не только дифф, но и зачем он и по каким критериям принимать.

  • Имеет историю. Кто завёл, когда, что и почему решили — в git-логе, а не в чьей-то памяти. Через полгода понятно без археологии.

  • Держит остальные практики. Приёмку не сверить, если непонятно, что считалось «сделано». DoD из файла и есть этот критерий.

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

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии1

Всем привет!

Сегодня поделюсь своим проектом, где использовал возможности открытых моделей LLM для создания автоматизированного конвейера по переводу англоязычных pdf-файлов в русскоязычные pdf. Как человек, интересующийся именно технологиями в области ИИ мне особенно было интересно максимальное приближенное к оригиналу сохранение содержимого переведенного материала, включая схемы, математические формулы, блоки кода (python) и bash-команд, рисунков (само собой), сохранение сносок, ссылок и пр. метаданных. Целью проекта было применение всевозможных доступных стеков и программ, использующих LLM в конкретной практической задаче. И как оказалось, на первый взгляд, простая задача перевода, с которой современная LLM, созданная и обученная на архитектуре трансформеров справляется на сегодняшний день блестяще, для pdf-формата оказалась не совсем простой (но и не скажу, что особо сложной).

О выборе программного стека технологий. Здесь во многом все определило глубина моих познаний и практических умений работать с LLM-моделями и тем оборудованием (потребительским, конечно), которое имеется дома. Поэтому, исходя из пары-тройки (пары) вычислительных узлов (ноутбуков) в домашней локалке мой выбор определил следующие программные и аппаратные компоненты.

Программные компоненты. Прежде всего это среда выполнения wsl. Просто работает в windows, удобна мне как новичку. В wsl установка обычной env стандартным python. И далее уже конкретные ПО для выполнения задачи перевода pdf на русский. Тут пришлось почитать в сети что есть свободное (исходя из цели использования только открытого ПО и LLM, чтобы оценить уровень их развития). Были опробованы такие программы как Docling, Marker-pdf и еще какую-то). В итоге, для извлечения из pdf в markdown формат я использовал Marker-pdf. У него имеется целый набор специализированных ocr-моделей для парсинга содержимого pdf. Marker в режиме конвейера осуществляет извлечение в указанную папку все содержимое исходного pdf в виде отдельных jpg-файлов, файла метаданных и итогового англоязычного .md файла. Для обратного процесса конвертации переведенного на русский язык ru.md я использовал WeasyPrint и Pandoc. Мой выбор - Pandoc. Сложнее, но поддержка xeLatex и куча настроек через опции командной строки и переменных окружения wsl. Pandoc - единственное ПО в моем конвейере, которое не использует LLM. И собственно, середина - перевод. Готовый скрипт на python. Перевод разбитых на части (chanks) в endpoint LLM - requests.post. Фишкой является url, который через специальный балансировщик, управляющий вычислительными узлами в локалке отправляется в requests.post. Получается параллельный перевод на нескольких узлах с  развернутыми OpenAI-совместимыми LLM. Количество узлов - сколько найдется в домашней ИИ лаборатории))). До и после отправки на перевод в LLM - чистка регулярками от различных костылей и защиты от перевода не нужных элементов (чистка колонтитулов, пагинация, сглаживание двойных переносов строк, изоляция спец. блоков от LLM блоков кода, мат. формул, кода внутри строк, приведение кода к pep8), подготовка переведенного _ru.md к сборке pdf-файла в Pandoc. В итоге - pipeline в 3 шага: Marker-pdf, Скрипт-переводчик на python, Pandoc.

Основные шаги перевода (marker, python скрипт, pandoc)
Основные шаги перевода (marker, python скрипт, pandoc)

Все вместе также можно запустить скриптом bash-сценария:

Использование: ./pipeline.sh <path_to_input_pdf> <output_path> [page_range]

Пример1: перевод всего Pdf-файла

./pipeline.sh /mnt/project/raw_data/embeddings.pdf /mnt/project/rendered/embeddings

Пример1: перевод первых 21 страниц Pdf-файла

./pipeline.sh /mnt/project/raw_data/embeddings.pdf /mnt/project/rendered/embeddings 0-20

Репозиторий на github DemonODG/pdf-translator: English-to-Russian PDF Translation Pipeline

Это мой первый пост на тему применения современных LLM моделей в различных практических задачах. Если это вызовет интерес в более подробном описании данного pipeline - напишу статью поподробнее.

Всем добра!

Теги:
Всего голосов 3: ↑2 и ↓1+3
Комментарии0

Greenfield по технологии, brownfield по бизнес-правилам

Сегодня в комментариях к чужой статье про greenfield и brownfield в эпоху AI вспомнил свою миграцию 200К строк JS в TypeScript. Тогда я не думал в этих терминах. Теперь вижу: проект был greenfield и brownfield одновременно, и путаница между ними стоила нам двух недель дебага в середине миграции.

Я думал: раз меняем весь стек, это чистый лист

Оказалось: технология была greenfield, стек новый, границы модулей новые, тесты новые. Бизнес-правила остались brownfield на все сто. Восемь лет продакшена, часть логики нигде не задокументирована, живёт только в поведении старого кода. Агент писал типобезопасный, красивый TypeScript и с той же уверенностью ломал правило, о существовании которого никто в команде уже не помнил.

Я думал: раз тесты зелёные, поведение сохранилось

Оказалось: существующее покрытие было тонким именно там, где пряталась история. Странный if с комментарием «не трогать, тут баг у клиента X» тестами не покрывался, потому что баг был найден руками три года назад и с тех пор просто жил в коде. Агент видел if без контекста и оптимизировал его как мёртвый код.

Что сработало: golden-master тесты перед тем, как подпускать агента

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

Главный вывод

В greenfield-части задачи вопрос «правильно ли мы строим» решается быстрой обратной связью и итерацией. В brownfield-части вопрос другой: «сохранили ли мы то, что уже работает». Агент одинаково уверенно предлагает и то, и другое решение, разницу видно только через инструмент вроде golden-master, не через код-ревью на глаз.

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

Пишу об этом подробнее в канале @ai_in_prod.

Теги:
Всего голосов 1: ↑0 и ↓1-1
Комментарии0

Как управлять окружениями — venv / pip vs pipenv vs poetry?

Привет, Хабр! Продолжаем нашу рубрику с быстрыми ответами на некоторые часто встречающиеся вопросы. Сегодня разберем такую проблему: проекты постоянно ломаются из-за конфликтов зависимостей. Что выбрать для новых проектов и как сделать так, чтобы код работал одинаково, в том числе в CI?

Обычно начало всех проблем — смешение глобальных и локальных пакетов или отсутствие фиксированных версий библиотек. Главный совет: у каждого проекта должно быть собственное окружение с явно указанными зависимостями и сохраненным lock‑файлом в репозитории.

Если говорить о базе, то это связка venv и pip. Плюс она встроена в сам Python. Вы вручную создаете окружение, устанавливаете нужные пакеты и фиксируете их в requirements.txt. 

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

Сейчас это, пожалуй, наиболее сбалансированное решение: он создает и управляет окружениями, отслеживает версии, собирает wheel‑пакеты и умеет публиковать их в PyPI. Lock‑файл (poetry.lock) обеспечивает воспроизводимость сборок, а сам формат pyproject.toml — это стандарт. В итоге вы получаете чистое окружение, детерминированные зависимости и понятное поведение CI.

Вот пример рабочего цикла:

python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install poetry
poetry install
poetry run pytest

В CI чаще используют схему с экспортом зависимостей:

poetry export -f requirements.txt --without-hashes -o reqs.txt
pip install -r reqs.txt
pytest

Отдельно стоит упомянуть uv — относительно новый инструмент, созданный командой Astral (авторы Ruff). Он написан на Rust и совместим с Python. По сути, это те же функции pip, venv и частично poetry, но быстрее. От Poetry он отличается отсутствием публикации пакетов, но при этом умеет сам устанавливать и менять версии Python через .python-version

UV работает с pyproject.toml и имеет собственный uv.lock. Может использоваться вместе с Poetry, но лучше создавать единый uv.lock для строгой воспроизводимости. Для CI это удобно, вы пишите:

pip install uv

Далее есть два варианта:

  • uv venv — создает виртуальное окружение. Это аналог python3.13 -m venv .venv, но работает быстрее и с автоустановкой версии Python.

  • uv init — помимо .venv, добавляет шаблон проекта с pyproject.toml для зависимостей, Git-репозиторий и базовые файлы. Идеально для нового проекта.

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

Если хотите освоить инструменты Python, то в Академии Selectel у нас есть отдельная подборка статей. Там мы рассказываем, как настраивать инструменты, работать с базами данных, создавать программы с интерфейсом и использовать Python для парсинга.

Теги:
Всего голосов 4: ↑4 и ↓0+8
Комментарии0

Что изучить на неделе: 23 бесплатных урока по разработке, ИИ и инфраструктуре

С 20 по 23 июля пройдут открытые уроки по разработке, тестированию, архитектуре, сетям, управлению и работе с ИИ. На них можно разобрать конкретную тему с практикующим экспертом, задать вопросы и закрыть отдельные пробелы в знаниях.

Все занятия бесплатные. Это возможность посмотреть, как устроено обучение: оценить подачу материала, познакомиться с преподавателями и понять, насколько программа соответствует вашим задачам.

ИИ и машинное обучение

  • 20 июля, 20:00. «ИИ для продуктового discovery: как анализировать рынок, конкурентов и пользователей быстрее». Записаться

  • 21 июля, 20:00. «Алгоритм DQN — учим нейросеть принимать решение без помощи человека». Записаться

  • 21 июля, 20:00. «Разработка ИИ‑приложений с Claude Code». Записаться

  • 21 июля, 20:00. «Выбор между Serverless и Kubernetes для AI‑ворклоадов: как определить оптимальную платформу под задачу». Записаться

  • 22 июля, 20:00. «Что надо знать про работу LLM‑моделей». Записаться

  • 22 июля, 20:00. «От рутины к влиянию: как HR использовать ИИ в ежедневной работе». Записаться

  • 23 июля, 20:00. «Когнитивные архитектуры: ReAct, Reflection и RAG». Записаться

Разработка и архитектура

  • 20 июля, 20:00. «Асинхронное программирование в Android». Записаться

  • 20 июля, 20:00. «Как перестать писать на Java внутри Go‑проекта». Записаться

  • 21 июля, 20:00. «Данные в TOGAF. Где скрыты? Разбираемся в деталях». Записаться

  • 22 июля, 20:00. «Архитектура программ на C++: как управлять разработкой и функциями приложения». Записаться

  • 22 июля, 20:00. «DAO на Spring JDBC». Записаться

  • 23 июля, 20:00. «Основы многопоточности в Java». Записаться

  • 23 июля, 20:00. «malloc — кто же ты на самом деле?». Записаться

Тестирование и безопасность

  • 21 июля, 19:00. «Оценка трудозатрат в QA: как перестать ошибаться в сроках». Записаться

  • 21 июля, 20:00. «UI‑ и API‑тестирование с Java и Playwright». Записаться

  • 23 июля, 20:00. «Тестирование интернет‑магазина: от каталога до оплаты». Записаться

  • 23 июля, 20:00. «Фаззинг и реверс: как понять, что делает программа, и найти в ней ошибки». Записаться

Инфраструктура и сети

  • 20 июля, 20:00. «Проектирование адресного пространства. Основы сетей ЦОД». Записаться

  • 22 июля, 20:00. «VLAN на пальцах: изоляция трафика и маршрутизация». Записаться

Управление продуктами и командами

  • 22 июля, 20:00. «Как CTO управляет неопределённостью: оценки, планы и ожидания бизнеса». Записаться

  • 22 июля, 20:00. «Как собрать полный CJM — карту клиентского пути». Записаться

  • 22 июля, 20:00. «Операция "Воркшоп": как получить поддержку руководства для новой инициативы». Записаться

Больше открытых уроков июля смотрите в дайджесте.

Теги:
Всего голосов 5: ↑5 и ↓0+9
Комментарии0

Как настроить TLS в клиенте Python при HTTPS-запросах?

Бывает так, что после обновления OpenSSL часть HTTPS-вызовов к внешним сервисам падает с ошибкой ssl.SSLError. Сейчас разберемся, как настроить Python, чтобы handshake проходил успешно и соединение оставалось безопасным.

После апдейтов OpenSSL часто отключают старые протоколы и слабые шифры — старые серверы не проходят handshake. Решение на клиенте — явно создать ssl.SSLContext, задать минимальную версию TLS и, при необходимости, набор шифров, а затем передать этот контекст в HTTP-клиент (например, httpx).

import ssl
import httpx

ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
ctx.minimum_version = ssl.TLSVersion.TLSv1_2
ctx.set_ciphers('ECDHE+AESGCM:!ECDSA:!aNULL:!eNULL')

with httpx.Client(verify=ctx, timeout=10.0) as client:
    r = client.get('https://api.example.com')
    r.raise_for_status()
    print(r.status_code)

В коде мы указываем TLSv1_2 как минимальный порог. Это удобно: если сервер уже поддерживает TLS 1.3, все само заработает на самой новой версии. Но если какой-то внешний сервис еще не успел обновиться, соединение не разорвется, и все продолжит работать на стабильном 1.2. Так мы получаем универсальный код, который не сломается при работе со старыми API.

Для отладки TLS handshake применяйте openssl s_client -connect host:443 -tls1_2 чтобы увидеть, какие шифры поддерживает сервер. Временное ослабление minimum_version даст совместимость, но хуже для безопасности — лучше апгрейдить серверную часть. Сертификаты и ключи храните вне кода (секреты/volumes), не логируйте их, и при работе в контейнерах используйте безопасные механизмы передачи секретов.

Если хотите освоить инструменты Python, то в Академии Selectel у нас есть отдельная подборка статей. Там мы рассказываем, как настраивать инструменты, работать с базами данных, создавать программы с интерфейсом и использовать Python для парсинга.

Теги:
Всего голосов 3: ↑3 и ↓0+7
Комментарии0

Участвуй в МТС True Tech Champ 2026 — всероссийском чемпионате по программированию с призовым фондом 10 250 000 рублей 🔥

Выбирай, какой трек тебе интереснее 👇

  • Алгоритмический (индивидуальный зачет, 2 750 000 ₽). Решай задачи по алгоритмам и структурам данных, которые помогут прокачать навыки для технических собеседований и работы в ведущих ИТ-командах. Лучшие участники пройдут в финал, где в режиме реального времени будут соревноваться в правильности решений и скорости мышления.

  • Программирование роботов (командный формат, 7 500 000 ₽). Напиши алгоритмы для робособаки и робота-манипулятора и проведи их через три этапа соревнований. Сначала — через цифровой симулятор, где нужно пройти трассу и выполнить задания по передаче предметов. Затем — подключись к реальному полигону через удаленный доступ и выполни задания на физических роботах дистанционно. А в очном финале лучшим командам предстоит управлять роботами на площадке, дорабатывать алгоритмы под новые условия и бороться за победу на глазах у зрителей.

Шоу-финал с кодерскими челленджами и выступлениями спикеров состоится 22 октября в МТС Live Холл. А лучшие участники получат шанс на стажировку в MTC Web Services (MWS).

Так после МТС True Tech Hack 2026 к команде присоединились три стажера:

1. Илья Матвеев из команды MCLover, 18 лет, студент 1-го курса бакалавриата Института интеллектуальных кибернетических систем (НИЯУ МИФИ). Вышел на позицию стажера frontend-разработчика в MWS Octapi.

2. Роман Субботин из команды DEP_IT_MISIS, 19 лет, студент 2-го курса бакалавриата НИТУ МИСИС по направлению «Прикладная математика» в институте компьютерных наук. Вышел на позицию стажера Python-разработчика в MWS Octapi.

3. Кирилл Ефимович из команды Моторный шуруповерт, 20 лет, студент третьего курса бакалавриата направления «Разработка ПО», Университет Иннополис, GPA: 4.6. Вышел на позицию стажера DevOps в MWS Tables.

➡️ Зарегистрируйся и стань участником масштабного ИТ-чемпионата.

Теги:
Всего голосов 3: ↑2 и ↓1+4
Комментарии0

Давненько ничего не писал здесь. В свободное время засел за работу, которую хотел взять в качестве дипломной, но не взял, так как тогда не был уверен в собственных силах. Если кратко, что здесь происходит: я нахожу на лице модели белые маркеры (свзяка из LoG-фильтра и поиска локальных экстремумов методом Китчена-Розенфельда) и пытаюсь отследить их движение в кадре (венгерский алгоритм, он же метод Куна-Манкерса в связке с фильтром Калмана). Модель отслеживания обладает инерцией (в реальности маркер не может телепортироваться и двигается согласно законам реального мира) - требуется стабилизация первые несколько кадров, есть запаздывание и возможна путаница, если движения напоминают конвульсии :) В остальном результат достаточно стабилен. Я хочу прикрутить к получившемуся Proof of Concept графический интерфейс, оптимизировать код (в черновом варианте я создаю кучу лишних объектов, что приводит к частой сборке мусора) и использовать записи с нескольких камер для восстановления положения маркеров в пространстве. Полученные данные в свою очередь можно отправить в любимый графический пакет. Это конечно не коммерческое решение для захвата движений уровня Vicon Nexus, скорее забавный велосипед, но всё же. Ждите эпичного результата и подробной статьи.

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии1

Корпорация ценой в три триллиона силами целой армии разработчиков выпустила свою фирменную IDE (Visual Studio 2026) после четырёх лет упорной разработки (предыдущая Visual Studio была 2022):

«Как, и что-то не готово?!» «Не готово, что ж такого».
«Как, и что-то не готово?!» «Не готово, что ж такого».

В наши дни если ты не успевал к релизу перевести настройки в новый формат, тебя били до тех пор, пока ты не успевал. Теперь в мажорном релизе после многих лет разработки можно просто написать: Лифт не работает, пользуйтесь пожарной лестницей. Кажется, это называется «новая искренность»?

Теги:
Всего голосов 3: ↑2 и ↓1+3
Комментарии12

Ближайшие события

Ошибки, которых не видно в сигнатуре: зачем C++ нужен std::expected

Функция выглядит предсказуемо, пока один из вызовов не бросает исключение, о котором никто не вспомнил. Типы ошибок остаются в документации, управление расползается по try/catch, а изменение глубоко в стеке неожиданно ломает обработку выше.

Недавно в статье разобрали std::expected из C++23: как сделать ошибку частью сигнатуры, собирать цепочки через and_then и transform, разделять типы ошибок между слоями и постепенно внедрять подход в legacy-код. Заодно увидели, где std::expected действительно полезен, а где добавит лишнюю сложность.

16 июля в 20:00 продолжим тему на бесплатном уроке «Выразительный C++: кодируем намерения». На практике разберём, как переносить неявные договорённости в типы, сигнатуры и структуру программы. Присоединяйтесь.

Полный список бесплатных уроков июля смотрите в дайджесте.

Теги:
Всего голосов 4: ↑4 и ↓0+8
Комментарии1

Робот Физтеха попытается установить мировой рекорд по сборке мегаминкса

15 июля в Физтехе пройдет официальная попытка установить мировой рекорд по сборке головоломки мегаминкс роботом. Команда лаборатории интеллектуальных технологий робототехники МФТИ готовится к финальной стадии проекта, о котором я писал в начале весны.

Робот-солвер МФТИ для сборки мегаминкса
Робот-солвер МФТИ для сборки мегаминкса

Инженеры физтеха сконструировали робота, способного собирать одну из самых сложных механических головоломок в мире. Пространство состояний додекаэдра под названием "мегаминкс" оценивается примерно в 10⁶⁸, что на порядки превышает сложность классического кубика Рубика. Проект прошел путь от инженерного прототипа до полноценной системы, объединяющей робототехнику и продвинутые алгоритмы поиска на графах состояний.

Что известно о рекорде

По данным разработчиков, текущая версия системы показывает результаты, которые:

  • в 68 раз превосходят предыдущий мировой результат среди роботов, который был установлен роботом Megaminxer Дэвида Гилдея 15 лет назад и составляет 8 минут 4 секунды;

  • примерно вдвое быстрее лучшего результата человека (текущий рекорд принадлежит спидкуберу из Китая Ziyu Wu и составляет 21.04 секунды).

За счет чего достигается скорость

Рекордные показатели планируется обеспечить не только быстрым манипулятором, но и глубокой алгоритмической работой:

  • Оптимизация планирования движений. Робот выполняет вращения независимых граней параллельно, что критично на коротких дистанциях.

  • Сокращение длины решения. Вокруг проекта сформировалось сообщество энтузиастов, которые через open-source проект CayleyPy и соревнования на Kaggle работают над поиском кратчайших путей в графах Кэли. Участники применяют Pattern Databases, алгоритм Корфа, Beam Search и другие методы. За последние недели среднюю длину решений на тестовых выборках удалось уменьшить на 15–20% до ~90 ходов. Лучшие решения сейчас дают порядка 70 ходов (правда считаются долго).

Место встречи

Установление рекорда запланировано на 15 июля, 17:30–21:30 в Физтех.Клубе МФТИ в Долгопрудном.

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

Если хотите стать свидетелями рекорда в стенах МФТИ, то регистрируйтесь по ссылке.

Количество мест, как понимаете, ограничено, поэтому будет организована трансляция на YouTube.

Присоединяйтесь и к группе проекта в Telegram.

 

Теги:
Всего голосов 13: ↑13 и ↓0+17
Комментарии0

Cтaтья «BotSharp изнyтpи: ищeм cлaбыe мecтa в кoдe ИИ‑плaтфopмы нa.NET»

Пpинятo cчитaть, чтo в AI и ML бeз Python никyдa, a.NET — этo иcключитeльнo иcтopия пpo enterprise, вeб‑paзpaбoткy и гeймдeв. Ho пpoeкт BotSharp гoтoв пocпopить c этим cтepeoтипoм, пpeдлaгaя ИИ‑плaтфopмy нa экocиcтeмe Microsoft.

Mы peшили зaглянyть пoд кaпoт BotSharp и пpoвepить, какие ошибки есть в его иcxoдном кoде.

Теги:
Всего голосов 4: ↑4 и ↓0+7
Комментарии0

Почему ИИ-агент для кода промахивается мимо нужного метода

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

Агент, который ищет код текстом, физически не отличает OrderService.validate от UserDto.validate: для него это просто совпадение символов «validate». Агент, который спрашивает у IDE «кто на самом деле вызывает этот метод», получает точный ответ, потому что IDE знает типы, разрешённые ссылки и видимость каждого символа. Разница между этими двумя подходами не абстрактная, она измеряется в конкретных цифрах.

Точка отсчёта: почему grep и RAG промахиваются

Кодовый агент ищет по проекту двумя способами: grep/ripgrep по содержимому файлов и векторный поиск по эмбеддингам кусков кода. На маленьком проекте оба варианта работают сносно. На enterprise-репозитории на миллионы строк с десятками модулей поведение ломается одинаково: запрос «найди использования метода validate» возвращает тысячу с лишним совпадений, из которых подавляющее большинство - другие методы с тем же именем в других классах. Векторный поиск находит куски кода, которые «похожи по смыслу», но это может быть валидация в совершенно другом домене.

Что показали цифры на 27 задачах

Мы сравнили три версии агента на 27 задачах вида «найди все места, где используется метод X» из реальных тикетов трёх внутренних репозиториев на Java и Kotlin: агент на ripgrep, агент на ripgrep с векторным RAG и агент на PSI-индексе IntelliJ (find_usagesfind_declarationclass_hierarchy вместо текстового поиска).

Вариант поискаPrecisionRecallF1Контекст, токенов$/ответripgrep0,410,820,5578 4001,12ripgrep + векторный RAG0,580,790,6792 1001,38PSI-индекс0,960,930,9416 7000,21
Вариант поискаPrecisionRecallF1Контекст, токенов$/ответripgrep0,410,820,5578 4001,12ripgrep + векторный RAG0,580,790,6792 1001,38PSI-индекс0,960,930,9416 7000,21

Precision показывает, сколько из найденного агентом оказалось реальными использованиями метода, а не случайным совпадением имён. Recall показывает, сколько из всех реальных использований в коде агент вообще нашёл, ничего не пропустив.

У ripgrep recall высокий (0,82): текстовый поиск почти никогда не пропускает совпадения по имени. Но precision низкий (0,41): больше половины найденного - чужие методы с тем же именем, и их приходится разбирать вручную. У PSI-индекса высоки обе величины (0,96 и 0,93): агент находит почти все нужные места и почти не приносит лишнего. F1 сводит обе величины в одно число, и у ripgrep он проседает именно из-за мусора в выдаче, хотя нужные места он и находит.

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

Точный поиск не отменяет проверку

Даже когда агент точно нашёл все места, где используется метод, и внёс правку во все, это не гарантирует, что правка корректна: точный поиск решает только задачу «найти нужные места», а не «проверить, что код после правки работает». Поэтому прежде чем объявить об успехе, агент должен прогнать компилятор и тесты: тест зелёный, ошибок компиляции нет, покрытие не просело. Пока в выводе компилятора или тестового прогона есть хоть одна ошибка, агент обязан либо исправить её, либо сообщить о проблеме, а не писать об успехе.

Но точный поиск снимает с агента часть ручной работы: не нужно самому перепроверять по всему проекту, все ли использования метода он нашёл - эту проверку берёт на себя IDE, как это устроено в Veai, а оставшуюся часть верификации - компилятор и тесты.

Теги:
Всего голосов 8: ↑8 и ↓0+10
Комментарии2

Написал новую, третью статью из серии «Как работают большие языковые модели»

Почему дорогая LLM дороже: экономика инференса, которую видно в твоём 5-часовом лимите


Что внутри ⤵️

1. Про открытые модели и почему мы используем их как пример
2. Из чего складывается цена токена
3. Про Dense и MoE архитектуры
4. Как считается attention и активные параметры
5. Total ≠ active: тренд на MoE архитектуру
6. Почему output-токены дороже input
7. Reasoning-токены как невидимый output, за который тоже приходится платить
8. Context Window и KV-cache — почему длинный контекст дорогой
9. Как посчитать вес одного токена и из чего он складывается
10. В чем разница между KV-cache и prompt caching
11. За счет чего фронтир модели стоят в разы дороже
12. Почему дорогая модель чаще всего реально «умнее»
13. Как всё это итого собирается в 5-часовой лимит

14. И как бонус — сортировка open-weight моделей по active и total

---------------

Вот две предыдущие статьи из этой же серии

Прочитав эту серию постов, вы станете намного лучше понимать принцип работы современных LLM и агентных систем

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии0

Как все так ловко ИИ пользуются... Обзоры кода делают...

Не знаю, то ли я туповат, то ли невезучий, то ли кругом сказочники. Пытаюсь исследовать, какие новые интересные виды ошибок может находить ИИ в С++ коде, о которых не знает PVS-Studio. Claude Opus то нормально мне про интересные баги рассказывает, то на ровном месте с ума сходит.

Даю файл на вход, а он тревожно:

В присланном файле есть места, где содержимое обрезано/повреждено вставкой </context>, поэтому их я не рассматриваю как «баги кода» — это артефакты форматирования. Разберу реальные логические ошибки.

Шо? Какой context? Там максимум — это #include "context.hxx". Ну ладно, давай ошибки посмотрим.

Так, парочка сообщений по делу. Например, найден лишний аргумент при использовании функции форматирования.

addErrorMessage(&sciErr, API_ERROR_CREATE_ZDOUBLE_IN_NAMED_LIST,
    _("%s: Unable to create list item #%d in Scilab memory"),
    "createComplexZMatrixOfDoubleInNamedList", _iItemPos + 1, _pstName);

В строке форматирования два спецификатора %s и %d, а передаются три аргумента: funcName, _iItemPos+1, _pstName. Да, это баг. Про подобные паттерны PVS-Studio уже знает, хотя, возможно, нужно подсказать, что addErrorMessage — это printf-подобная функция. В целом, тут неинтересно, идём дальше.

Ооо, и тут начинается...

checkListItemPosition — неправильное сравнение границы:

// check a valid item
if (_iItemPos > iItem)
{
    addErrorMessage(...);
    return sciErr;
}

Здесь проверка «позиция валидна» использует >, хотя позиции 1-based, а iItem — количество элементов. Это выглядит как граничный дефект, но по сути _iItemPos == iItem допустимо, _iItemPos > iItem — ошибка. Это в порядке — правильная граница. Не баг. (Указываю, чтобы было понятно, что я это проверил.)

Так баг или не баг? Я три раза прочитал текст и посмотрел функцию с кодом. В итоге я не только не понимаю, есть ли здесь ошибка, но и не понимаю, что Claude пытается мне сказать.

Дальше ещё хуже шарики за ролики зашли.

Баг 5 (реальный): утечка в readCommonMatrixOfPolyInNamedList и др. — нет, это API отдаёт указатели наружу. Не баг.

Это всё описание пятого бага, больше ничего нет. Комментировать — только портить.

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

На сегодня мне ИИ достаточно. Пойду лучше пройдусь по парку, пока погода хорошая.

Теги:
Всего голосов 14: ↑14 и ↓0+18
Комментарии6

Fable 5 вернули в Claude Code. Как не сгенерировать себе техдолг

Fable 5 снова доступен в Claude, и это хороший повод вернуться к более практичному вопросу: что именно делать разработчику с Claude Code, кроме генерации отдельных кусков кода.

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

21 июля в 20:00 на бесплатном уроке разберём, как использовать Claude Code в разработке ИИ-приложений: от Telegram-ботов и агентов до внутренних сервисов, API и автоматизаций. Отдельно поговорим о работе с большими задачами — как дробить их на этапы, вести разработку итерациями, дорабатывать код и находить ошибки. Присоединяйтесь.

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

Теги:
Всего голосов 5: ↑4 и ↓1+7
Комментарии1