Заметки AI инженера
18 subscribers
6 photos
25 links
Заметки про AI Engineering, Golang, Domain Driven Design, архитектуру и остальное.

https://igorlazarev.ru
https://github.com/strider2038
Download Telegram
Выпустил новую версию генератора DI Container'а - библиотеку DIGEN v0.3

* (поломка обратной совместимости) Переработан раздел errorHandling в конфигурации для более тонкого контроля генерируемого кода обработки ошибок.
* (поломка обратной совместимости) Удалена опция external для определений сервисов. При изучении кода не увидел в ней необходимости. Поэтому решил убрать.
* ⚠️ Изменен способ передачи id сервиса в битовой карте. Теперь id генерируется в виде автоинкрементируемой константы. Это снизит количество конфликтов между различными ветками, т.к. числовые идентификаторы часто смещаются.
* Фикс дефекта. Теперь сервис помечается в битовой карте как проинициализированный только в том случае, если фабрика не вернула ошибку. В предыдущей версии логика могла приводить к панике при закрытии контейнера.
Мне кажется отличный пример того случая, когда вместо добавления комментария можно было сделать сам код более выразительным. Комментарий виден только в приписке к методу, а имя функции видно еще и в месте где она вызывается.

#чистыйкод #рефакторинг
Интересная тема заявлена на митапе

Транзакционность в DDD

Применение тактических паттернов DDD на практике неизбежно приводит к вопросам транзакционности. Как обеспечить согласованность данных, не нарушая границы агрегатов? В своем докладе расскажу, как я решаю эту проблему, разберу типичные ошибки и покажу, как правильно расставлять границы агрегатов для эффективной работы системы.
Forwarded from Evrone IT meetups
🚀 Митап по Go: Тактические паттерны DDD, weak pointers и операторы Kubernetes – 20 марта, 19:00

Программа митапа:

✔️ Применение тактических паттернов DDD на практике — Гонозов Дмитрий, Яндекс

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

✔️ Разбор weak pointers в Go: механизм работы и влияние на управление памятью — Солдатенко Дмитрий, Ви.Tech

Go 1.24 принес изменения в работу с памятью: пакет weak был перемещён в публично доступные. Дмитрий объяснит, как устроены слабые указатели, когда их стоит использовать, а когда лучше выбрать другие подходы. Обсудим влияние на производительность и примеры из реальных проектов.

✔️ Разрабатываем операторы Kubernetes: как создать свои CRD — Михейкин Иван, Флант

Изучим, как разрабатывать операторы Kubernetes и проектировать пользовательские ресурсы (CRD), которые будут удобны как для пользователей, так и для автоматизации. Иван расскажет о том, как проектировать Conditions и Events, валидацию полей и соблюдение совместимости с IaC.

🧑🏻‍💻 Эксперт — Кирилл Кузин, Ви.Tech, Senior-разработчик на Go
🧑🏻‍💻 Модератор — Виталий Левченко,
Wildberries, engineering manager



🗓 20 марта, начало в 19:00 мск, Четверг

🌐 ОНЛАЙН

Ссылка на регистрацию

Партнер: Ви.Tech — это команда инженеров, которая строит IT для ВИ.ру — одной из крупнейших e-com компаний на рынке.

Для Go-разработчиков: свобода в архитектуре, сильная аналитика, высоконагруженные сервисы без легаси, возможность влиять на стек и research days.

Реклама ООО «Ви.Тех‎» erid: 2VfnxvLM4XS
Please open Telegram to view this post
VIEW IN TELEGRAM
Перевозил сайты на новый хостинг и заодно решил стряхнуть пыль с полок и заняться своим журналом. Предыдущая версия журнала поддерживалась с помощью статического генератора сайтов Jekyll. Моментами это было неудобно: нужно было тянуть зависимости на Ruby, периодически от security бота github прилетали оповещения об уязвимостях (хотя для локальной работы они вообще не критичны). Тем временем где-то в Golang телеграм каналах периодически мелькал Hugo.

Читать далее https://igorlazarev.ru/p/new-blog-life-with-hugo/
👍2
Microsoft переписывает компилятор TypeScript на языке Go

https://gitverse.ru/blog/news/595-microsoft-perepisyvaet-kompilyator-typescript-na-yazyke-go

Настало время интересных историй под вечер пятницы 😊
👍1
Nullable или не nullable?

Пожалуй, одна из самых типичных проблем при составлении схем данных - стоит ли объявлять атрибуты с null-значениями? Стоит ли все атрибуты всегда делать nullable или это может привести к неприятным последствиям? В этой статье я постараюсь рассмотреть возможные проблемы nullable-атрибутов.

Читать далее: https://igorlazarev.ru/p/nullable-or-not-nullable/
👍2
Багфикс-релиз digen v0.3.1
https://github.com/strider2038/digen/releases/tag/v0.3.1

исправлено
* убран лишний префикс в версии приложения v при установке приложения через go install
* поправлено генерирование фабричного метода в существующем файле, когда опция factories.returnError установлена в false
👍4
Релиз новой фичи "внешние фабрики" digen v0.4.0
https://github.com/strider2038/digen/releases/tag/v0.4.0

В новой версии DI фабрики (функции конструкторы сервисов) могут быть описаны снаружи пакета DI контейнера. То есть генерируемый код вызова фабрики теперь может ссылаться на любой пакет текущего проекта. Для удобства указания импорта пакета (а это длинная строка) опции для определений сервисов (service definitions) теперь могут описываться в виде комментариев. Так же для работы этой фичи пришлось вынести lookup пакет наружу из внутреннего пакета internal, чтобы можно было ссылаться на контракт lookup.Container из любого участка кода (поломка обратной совместимости).

Для чего это сделано? Теперь фабрики можно будет располагать ближе к местам использования. Это уменьшит количество конфликтов в файлах фабрик.

Наглядный пример. В файле internal/definitions/container.go указываем ссылку на пакет.

type UseCaseContainer struct {
// di: factory_pkg: example.com/project/internal/entities/products/di
FindEntity *usecase.FindEntity
}


Фабрика будет сгенерирована в директории проекта project/internal/entities/products/di

package di

import (
"context"
"example.com/project/internal/entities/products/usecase"
"example.com/di/lookup"
)

func CreateUseCasesFindEntity(ctx context.Context, c lookup.Container) *usecase.FindEntity {
return usecase.NewFindEntity(c.Repositories().EntityRepository(ctx))
}
2
Ого. Тут вышла мажорная версия golangci-lint v2.0 https://golangci-lint.run/product/changelog/

Неожиданно, если честно, но очень любопытно 🧐
🔥1🤔1
Постепенно внедряю в свою жизнь как разработчика работу с популярными нейросетями. До этого момента в основном AI-инструменты использовал как “помогаторы” в написании кода (подсказчики типа Codeium), или для получения краткой выжимки по каким-то статьям или темам (нейро вкладка в Яндекс-поиске). Непосредственно чат-ботами с точки зрения практики пользовался редко, т.к. чаще всего непонятно а что их спрашивать-то? По специфическим вопросам пока они помогают не особо успешно (по экзотическим SQL запросам, например). В основном все равно приходится идти через документацию или ориентироваться на свои знания и опыт. Пару раз задавал вопросы по незнакомым мне темам (о строительстве, например) и в целом получал хорошие ответы.

Но тут на работе возникла такая потребность - нужно на основе метрик Prometheus и Grafana найти наиболее медленные endpoint’ы и сделать по ним дашборд...

Читать далее: https://igorlazarev.ru/p/deepseek-experience/
🔥1
В предыдущей статье я рассматривал какие риски в себе несут nullable-типы. В Golang такие данные обычно описываются с помощью атрибутов-указателей, но есть и другие способы. В этой статье я рассмотрю паттерн Null Type pattern, который уменьшит вероятность возникновения nil pointer panic.

Читать далее: https://igorlazarev.ru/p/go-null-type-pattern/
Активно погружаюсь в Agentic Coding и решил адаптировать свои либы для работы с ИИ тулзами. Обновление валидатора. Теперь будет проще фичи доставлять 😊))

muonsoft/validation v0.18.0

Обзор
Новая версия Go validation framework с поддержкой Go 1.24, улучшенным API для работы с нарушениями и новыми возможностями.

---

Новые возможности

Итератор по нарушениям (Go 1.23+)

ViolationList.All() возвращает iter.Seq2[int, Violation] и позволяет итерировать нарушения в range:

for i, v := range violations.All() {
fmt.Printf("#%d: %s at %s\n", i, v.Message(), v.PropertyPath().String())
}


Унифицированная функция UnwrapViolations

Добавлена UnwrapViolations(err error) (*ViolationList, bool) — единая точка для извлечения нарушений из ошибки. Она обрабатывает и одиночное Violation, и ViolationList.

UnwrapViolation и UnwrapViolationList помечены как deprecated в пользу UnwrapViolations.

---

Технические изменения

- Go 1.24 — минимальная версия Go
- Обновление зависимостей:
- github.com/muonsoft/language v0.3.1
- golang.org/x/text v0.33.0
🔥1
Забавно. Теперь с ИИ кодингом можно довольно быстро вносить какие-то новые фичи в библиотеки. Раньше это требовало длительной ручной работы и это становилось блокером - было лень тратить кучу своего свободного времени. А сейчас можно грубо говоря во время поездки на метро закинуть концепт агенту, он там в облаке покодит, а потом остается только поревьюить и залить. Или дал задачу, пошел поставил чайник, прочитал план агента, аппрувнул (или скорректировал), запустил, пошел пить чай, вернулся, поревьюил код и залил. У меня вот так много всяких мелочей завалялось для улучшения кода библиотек.

Сегодня обновил api-testing v0.11.0

Что изменилось:

- assertjson: добавлена поддержка JSON Lines (NDJSON) — методы LinesHas, Lines(t, data).Has(...) для проверки нескольких JSON‑объектов в каждой строке;
- assertjson: добавлены проверки для массива строк;
- assertjson: расширены проверки строк — добавлены проверки на префикс, суффикс, целочисленные значения и числа;
- assertjson: методы Has и FileHas теперь возвращают булевое значение.
🔥3
На этой неделе начал проходить курс LLM Start от DeepSchool. Познакомился с n8n - очень крутое решение для быстрого прототипирования сценариев с AI агентами. Можно буквально за 10 минут накидать на дашборде пайплайн для телеграм бота, который будет говорить прогноз погоды, курсы валют и т.п. В n8n море встроенных интеграций. Отлично подходит для автоматизации каких-нибудь рутинных действий. Можно сделать бота для релизов, для вопросов по документации из Confluence, задач из Jira и т.п.
🔥2
AI-ассистент может замедлять рост инженеров — даже если ускоряет delivery.
https://www.anthropic.com/research/AI-assistance-coding-skills

Anthropic выпустили исследование: 52 разработчика начального уровня решали задачи с AI и без него.

Плохие новости:
Скорость — почти без статистически значимого выигрыша.
Понимание того, что ты только что сделал — заметно хуже (~−17%).
— Сильнее всего проседает debugging: умение читать ошибки, строить гипотезы и чинить причины, а не симптомы.

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

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

Что стоит делать на регулярной основе лично каждому:
1. Для нового/сложного — режим Explain-first: "объясни, дай альтернативы", а не "сделай".
2. Для дебага — "план диагностики, дай гипотезы", а не "дай фикс".
3. В ревью — требовать 2–3 предложения: почему так, какие компромиссы.
👍1
Обновил muonsoft/validation https://github.com/muonsoft/validation/releases/tag/v0.19.0

Добавлено

- Slice validation: Slice, SliceProperty, Each и EachProperty — для валидации срезов с ограничениями для каждого элемента.
- HasUniqueValuesBy — ограничение, гарантирующее уникальность элементов среза по ключевой функции.
- Метод Validate в ограничениях — теперь ограничения можно напрямую использовать с Each и This.

Изменено

- Инициализация валидатора — глобальный валидатор заменён на атомарный указатель для потокобезопасного использования. В тестах следует применять новые методы настройки валидатора.
- CheckNoViolations — теперь принимает вариативные параметры errors для улучшённой обработки ошибок и условий завершения.
- Документация — структура README переработана:
- добавлены разделы об установке, пользовательских ограничениях и путях к свойствам;
- расширено руководство по пользовательским ограничениям (детали об интерфейсах и примеры).

Исправлено

- Корректная обработка единичных нарушений, возвращаемых валидируемыми объектами в validateIt.

Критические изменения

- Тесты, использующие CheckNoViolations или настройку валидатора, необходимо обновить с учётом новых сигнатур и вспомогательных инструментов.
🔥2
Forwarded from from:adam
Сегодня специфичный пост для инженеров.

Много юзаю Claude Code в последнее время и не отпускает одна мысль. В своё инженерное прошлое я всегда угорал по «лучшим практикам» — SOLID, TDD, Clean Architecture, DDD, property-based testing и тд. Большинство команд их игнорировали: сложно, долго, вэлью непонятно. И аргумент про сложность был честным — поддерживать чистую архитектуру и писать тесты до кода реально дорого по времени и когнитивной нагрузке.

Так вот. Кажется, агенты снимают порог входа в эти практики — написать тесты, нарезать интерфейсы, разложить по слоям стоит копейки, когда это делает Claude Code. А сами практики в ответ снимают ключевое ограничение агентов — контекстное окно.

Агент не может держать в голове весь проект. 250к токенов звучит много, но реальная кодовая база вылезает за эти пределы быстро. А даже если влезает — качество падает. Даже с 1м контекстом. Модель теряет детали, путает зависимости, начинает галлюцинировать.

И тут Clean Architecture начинает выглядеть как идеальный интерфейс между тобой и агентом. Чёткие слои, определённые контракты между ними — и для работы с конкретным куском агенту достаточно видеть архитектуру, интерфейсы и код текущего модуля. Не всю кодовую базу, а только нужную часть и интерфейсы взаимодействия с другими слоями.

DDD усиливает эту же идею: bounded contexts — это готовые границы того, что агенту нужно загрузить, а ubiquitous language делает код читаемым без дополнительной документации.

SOLID вообще читается как готовый чеклист «как сделать кодовую базу, с которой агент справится»:

- Single Responsibility — меньше кода нужно видеть для одного изменения
- Open/Closed — агент добавляет новую реализацию, не трогая существующий код, который даже не нужно грузить в контекст
- Liskov Substitution — можно подменить реализацию и ничего не сломается, а тесты это верифицируют
- Interface Segregation — агент видит только нужный ему срез интерфейса, а не всё подряд
- Dependency Inversion — для меня самый показательный. Модуль зависит от абстракции, не от реализации. Агенту не надо тащить в контекст код базы данных, чтобы написать бизнес-логику — хватит интерфейса репозитория

С TDD та же история. Тест — это спецификация поведения, которая влезает в контекст и однозначно верифицирует результат. Агент получил тест, написал реализацию, запустил — красный, зелёный, рефакторинг. Цикл обратной связи без необходимости понимать всю систему.

Отдельно про property-based тестирование. Штука всегда была нишевой — мало кто хотел возиться с генераторами и инвариантами, когда можно накидать пять юнит-тестов. Но с агентами property-based тесты должны давать непропорционально много фидбека при минимуме тестового кода. Один тест с правильно описанным свойством — это тысячи кейсов, которые агент прогоняет за секунды. При этом llm’ки куда быстрее придумывают все инварианты для тестирования, что снимает с разработчика когнитивную нагрузку на имплементацию подхода.

И вот что мне кажется самым интересным: property-based тесты идеально ложатся в цепочку PRD → TDD → реализация. Свойства системы из PRD («баланс не может быть отрицательным», «сумма позиций равна итогу заказа») транслируются в property-тесты почти один к одному. Агент получает свойства как спецификацию и пишет код, который им удовлетворяет. По сути requirements (R из PRD) становятся исполняемой верификацией — без ручной работы по переводу в десятки отдельных тестов.

Годами шли споры, стоит ли Clean Architecture и другие практики своих накладных расходов — всех этих дополнительных абстракций и интерфейсов. Будет забавно, если окажется, что именно эти «лишние» абстракции делают кодовую базу пригодной для работы с AI.
🔥2