🤯 Представьте, что ваш AI-агент работает так же предсказуемо, как обычный микросервис. Звучит утопически, но это именно то, к чему должна прийти разработка в 2026 году.
Основная боль текущих реализаций — полная непредсказуемость поведения. Сегодня агент выполнил задачу за два шага, а завтра ушёл в рекурсию и потратил все лимиты.
Наш обновлённый курс «Разработка AI-агентов» научит, как приручить этот хаос с помощью
✅ Что вы получите:
— понимание того, как управлять логикой агента на уровне кода;
— навыки работы с
— готовые паттерны для обработки ошибок и галлюцинаций;
— опыт создания систем, которые реально экономят время.
Есть пара мест со скидкой до завтра, решайтесь 👈🏻
Основная боль текущих реализаций — полная непредсказуемость поведения. Сегодня агент выполнил задачу за два шага, а завтра ушёл в рекурсию и потратил все лимиты.
Наш обновлённый курс «Разработка AI-агентов» научит, как приручить этот хаос с помощью
Python и современных фреймворков. Мы не будем учить «общаться» с нейросетью, мы будем строить из неё надёжный инструмент.✅ Что вы получите:
— понимание того, как управлять логикой агента на уровне кода;
— навыки работы с
LangChain и библиотеками оркестрации;— готовые паттерны для обработки ошибок и галлюцинаций;
— опыт создания систем, которые реально экономят время.
Есть пара мест со скидкой до завтра, решайтесь 👈🏻
Что прошло уже не вернуть, но стоит ознакомиться с нашей подборкой прошедшей недели.
— oaswrap/spec v0.4.0
— Патчи с исправлениями безопасности
— Эмулятор AWS-сервисов
— Entity Component System на Go
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
Типичная ситуация: запущен dev-сервер на порту 3000, нужно на полминуты освободить порт под другую задачу. Убиваете процесс и теряете кэши в памяти, состояние билд-вотчера, прогретые соединения. Потом поднимаете всё заново.
Разработчик написал инструмент park, который решает это иначе: замораживает процесс и освобождает порт, а потом возвращает всё как было. Тот же PID, та же память, те же открытые файлы. Процесс не знает, что что-то произошло.
park 3000 # заморозить и освободить порт
# делаем что нужно на порту 3000
park resume 3000 # вернуть всё обратно
Почему Ctrl+Z не работает
Ctrl+Z отправляет SIGSTOP — процесс замирает, но ядро по-прежнему считает порт занятым. Попытка занять его другим процессом даёт Address already in use. SIGSTOP не закрывает сокет.park решает это через инъекцию
close(fd) прямо в работающий процесс без его перезапуска и изменения кода.Установка:
curl -fsSL https://raw.githubusercontent.com/mr-vaibh/park/main/install.sh | sh
Инсталлятор сам определяет ОС и архитектуру. На macOS автоматически подписывает бинарник с нужными правами для инъекции в процессы.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Большинство Go-разработчиков знают про
go generate, но редко его используют. А зря — это простой способ убрать ручную работу из цикла разработки.Что такое go generate и зачем оно нужно
В каждом проекте есть код, который кто-то должен написать руками: моки для тестов, protobuf-файлы, бойлерплейт для новых сущностей. Обычно это делается руками, иногда забывается, иногда делается неправильно.
go generate решает эту проблему. Вы один раз описываете команду прямо в коде, а потом запускаете одну команду и всё генерируется автоматически.Как это работает
Вы добавляете специальный комментарий в .go-файл:
//go:generate mockgen -source=service.go -destination=mock_service.go -package=service
Потом запускаете:
go generate ./...
Go находит все такие комментарии в проекте и выполняет указанные команды. Всё.
Что можно генерировать
Моки для тестов. Если вы используете
mockgen или moq, достаточно добавить комментарий рядом с интерфейсом и мок всегда будет актуальным://go:generate moq -out=user_repo_mock.go . UserRepository
type UserRepository interface {
FindByID(id int) (*User, error)
Save(user *User) error
}
Protobuf-файлы. Вместо того чтобы каждый раз вспоминать флаги protoc, достаточно один раз прописать команду:
//go:generate protoc --go_out=. --go-grpc_out=. api.proto
Встраивание ресурсов. Генераторы вроде go-bindata упаковывают статику прямо в бинарник.
Строковые представления для констант. stringer автоматически генерирует метод
String() для ваших типов://go:generate stringer -type=Status
type Status int
const (
Active Status = iota
Inactive
Banned
)
Практический совет
Добавьте
go generate ./... в ваш Makefile или CI-пайплайн. Тогда сгенерированный код всегда будет пересоздаваться при сборке, и никто не забудет обновить моки после изменения интерфейса:generate:
go generate ./...
build: generate
go build ./...
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
🧑💻 Свой diff-драйвер для git
Чем это отличается от
Есть более простой способ —
Что git передаёт в драйвер
Многие ожидают, что инструмент получит два аргумента: файл «до» и файл «после». На самом деле git передаёт семь:
При создании или удалении файла вместо несуществующей версии придёт
Пример драйвера:
Аргументы
Как подключить драйвер
В
В
После этого
Diff-драйвер нужен, когда стандартный вывод git бесполезен. Написать его несложно: достаточно bash-скрипта, который принимает семь аргументов и знает, что делать с
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
git diff умеет делегировать сравнение файлов внешнему инструменту. Это называется diff-драйвер. Штатный вывод git не всегда читаем особенно для JSON, YAML или OpenAPI-спецификаций. Вместо того чтобы смотреть на кашу из + и -, можно подключить инструмент, который покажет изменения в удобном виде.Чем это отличается от
textconvЕсть более простой способ —
textconv. Он конвертирует файл в текст, и git сравнивает уже текст. Но если нужно не просто показать разницу построчно, а сформировать собственный вывод, например, changelog между двумя версиями API, textconv не подойдёт. Тут нужен полноценный драйвер.Что git передаёт в драйвер
Многие ожидают, что инструмент получит два аргумента: файл «до» и файл «после». На самом деле git передаёт семь:
# при изменении существующего файла
my-diff-tool \
path/to/file.json # 1: путь к файлу в репозитории
/tmp/git-blob-xxx/file.json # 2: "до"
f0a1311ae439... # 3: SHA-1 хэш "до"
100644 # 4: octal mode "до"
/tmp/git-blob-yyy/file.json # 5: "после"
e39975894a72... # 6: SHA-1 хэш "после"
100644 # 7: octal mode "после"
При создании или удалении файла вместо несуществующей версии придёт
/dev/null, а неприменимые аргументы заменяются точкой .:# новый файл
my-diff-tool \
path/to/file.json
/dev/null # файла "до" не было
.
.
/tmp/git-blob-yyy/file.json
5c55e5b99b21...
100644
# удалённый файл
my-diff-tool \
path/to/file.json
/tmp/git-blob-xxx/file.json
6b24e38aa4aa...
100644
/dev/null # файла "после" нет
.
.
Пример драйвера:
#!/usr/bin/env bash
# diff-драйвер для OpenAPI-спецификаций через oasdiff
if [[ "$2" == "/dev/null" ]]; then
echo "$1 was added"
exit 0
elif [[ "$5" == "/dev/null" ]]; then
echo "$1 was deleted"
exit 0
fi
oasdiff changelog "$2" "$5" --color always
Аргументы
$2 и $5 это пути к временным файлам «до» и «после», которые git уже подготовил.Как подключить драйвер
В
.gitattributes указываем, для каких файлов его использовать:*.yaml diff=oasdiff
В
.git/config или глобальном ~/.gitconfig регистрируем сам драйвер:[diff "oasdiff"]
command = /path/to/oasdiff-driver.sh
После этого
git diff будет вызывать скрипт для всех .yaml-файлов вместо стандартного построчного сравнения.Diff-драйвер нужен, когда стандартный вывод git бесполезен. Написать его несложно: достаточно bash-скрипта, который принимает семь аргументов и знает, что делать с
/dev/null для новых и удалённых файлов. Всё остальное берёт на себя git.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍2
Когда проект растёт, рано или поздно кто-то импортирует не то, что нужно. Репозиторий тянет сервис, хендлер лезет напрямую в базу и архитектура начинает разваливаться. Go решает это на уровне компилятора.
Что такое internal
Папка
internal это встроенный механизм Go для ограничения импортов. Любой пакет внутри internal/ можно импортировать только из кода, который находится в родительском модуле этой папки. Всё остальное компилятор просто не пропустит.Типичная структура проекта:
myapp/
├── cmd/
│ └── main.go
├── internal/
│ ├── service/
│ │ └── user.go
│ └── repository/
│ └── user.go
└── pkg/
└── utils/
Код в
cmd/ может импортировать internal/service и internal/repository. А вот внешний пакет или другой модуль нет. Go выдаст ошибку компиляции:imports myapp/internal/service: use of internal package not allowed
Можно вкладывать internal глубже
internal работает не только на уровне корня проекта. Его можно положить внутрь любого пакета:
myapp/
├── payment/
│ ├── internal/
│ │ └── processor/
│ └── payment.go
internal это не соглашение, а правило, которое компилятор применяет сам.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16❤🔥5👍5🔥1🌚1
Doors это бэкенд-фреймворк для веб-приложений на Go. Он позволяет строить реактивный UI без JS-фреймворков, без гидратации и без npm. Весь бизнес-логика живёт на сервере, браузер работает только как тонкий клиент для отображения.
Стандартный стек Go + React требует писать и поддерживать два слоя: API на Go и фронт на JS. Это дублирование типов, синхронизация состояния, сборка, зависимости. Htmx даёт частичные обновления страницы, но не даёт нормального реактивного состояния и контроля из Go.
Doors убирает API-слой полностью. Сервер держит живое состояние каждой вкладки пользователя, а браузер просто синхронизирует изменения DOM.
Как это работает
При загрузке страницы сервер создаёт экземпляр сессии и отдаёт cookie. Дальше между клиентом и сервером держится лёгкое соединение через короткие HTTP-запросы с поддержкой QUIC.
Пользователь что-то делает и событие летит на Go-обработчик. Сервер считает изменения и отдаёт конкретные обновления DOM.
Два ключевых примитива:
Door — динамический контейнер в HTML. Умеет обновляться, заменяться, удаляться. Каждый Door имеет свой жизненный цикл и локальный context, который можно использовать как хук при размонтировании.
Beam — реактивное состояние на сервере. SourceBeam хранит мутабельное значение, производные Beam считаются из него. Обновления гарантированно консистентны по дереву контейнеров.
Пример запуска:
import "github.com/doors-dev/doors"
func main() {
app := doors.New()
// регистрация страниц и обработчиков
app.Run(":8080")
}
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥9👍5❤3🌚1
Senior Go Developer — удаленно по Москве
Golang Middle/Senior Developer — до 420 000 ₽, удаленно кроме РФ, РБ и Израиля
Junior Бэкенд-разработчик — от 80 000 до 120 000 ₽ в офис в Тамбове
#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
Мокать базу данных — занятие неблагодарное. Каждое изменение схемы тянет за собой правки в моках, а уверенности в корректности поведения всё равно нет. Настоящий тест это тест против реального PostgreSQL, Redis или любого другого сервиса.
ory/dockertest решает эту задачу: библиотека поднимает Docker-контейнеры прямо из Go-теста и убирает их по завершении.Как это работает:
func TestPostgres(t *testing.T) {
pool := dockertest.NewPoolT(t, "")
postgres := pool.RunT(t, "postgres",
dockertest.WithTag("14"),
dockertest.WithEnv([]string{
"POSTGRES_PASSWORD=secret",
"POSTGRES_DB=testdb",
}),
)
hostPort := postgres.GetHostPort("5432/tcp")
err := pool.Retry(t.Context(), 30*time.Second, func() error {
db, err := sql.Open("pgx", "postgres://postgres:secret@"+hostPort+"/testdb")
if err != nil {
return err
}
return db.Ping()
})
if err != nil {
t.Fatalf("не удалось подключиться: %v", err)
}
}Контейнер поднимается, тест выполняется, контейнер удаляется. Всё через
t.Cleanup, без лишнего кода.Установка:
go get github.com/ory/dockertest/v4
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16😁2
🖼 Работа с изображениями в терминале
gowall это CLI-инструмент на Go, который перекрашивает изображение под любую заданную цветовую схему. Вы отдаёте ему картинку и говорите «сделай в стиле Gruvbox». Он берёт доминирующие цвета и заменяет их на цвета из нужной палитры.
Изначально gowall создавался именно для перекраски обоев, но со временем оброс другими возможностями. Сейчас это целый набор утилит для обработки изображений из командной строки.
Помимо перекраски есть OCR — извлечение текста из изображений и PDF. Поддерживает 9+ провайдеров, в том числе визуальные языковые модели и гибридные методы.
Работает через Unix pipes и вписывается в любые скрипты и пайплайны.
Пример использования
Перекрасить обои под тему Nord:
Посмотреть все доступные темы:
Извлечь цветовую палитру из изображения:
Сжать изображение:
Что нового в v0.2.4
Четыре дня назад вышел свежий релиз. Главное: улучшенное удаление фона и новый набор утилит для работы с цветом.
Вместо того чтобы искать обои под нужную палитру, можно взять любую картинку и перекрасить за одну команду.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
gowall это CLI-инструмент на Go, который перекрашивает изображение под любую заданную цветовую схему. Вы отдаёте ему картинку и говорите «сделай в стиле Gruvbox». Он берёт доминирующие цвета и заменяет их на цвета из нужной палитры.
Изначально gowall создавался именно для перекраски обоев, но со временем оброс другими возможностями. Сейчас это целый набор утилит для обработки изображений из командной строки.
Помимо перекраски есть OCR — извлечение текста из изображений и PDF. Поддерживает 9+ провайдеров, в том числе визуальные языковые модели и гибридные методы.
Работает через Unix pipes и вписывается в любые скрипты и пайплайны.
Пример использования
Перекрасить обои под тему Nord:
gowall convert wallpaper.png --theme nord
Посмотреть все доступные темы:
gowall list
Извлечь цветовую палитру из изображения:
gowall palette photo.jpg
Сжать изображение:
gowall compress image.png
Что нового в v0.2.4
Четыре дня назад вышел свежий релиз. Главное: улучшенное удаление фона и новый набор утилит для работы с цветом.
Вместо того чтобы искать обои под нужную палитру, можно взять любую картинку и перекрасить за одну команду.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
25 апреля в Санкт-Петербурге пройдет Я.Субботник по Go: митап для тех, кто строит и масштабирует сервисы на Go
Встречаемся в питерском офисе Яндекса или на онлайн-трансляции, чтобы обсудить все, что волнует Go-сообщество.
В программе выступлений:
— Владимир Тельбухов, руководитель группы разработки Городских сервисов, расскажет, как построить устойчивую систему в интеграциях с внешними сервисами
— Иван Похабов, разработчик Yandex Cloud, разберет, как устроен GoBGP, какие баги в нём встречаются и как их исправляют в production
— Сергей Толмачев, разработчик Yandex Infrastructure, разберет S3 Inventory, основываясь на практическом опыте внедрения
— Имран Турсунов, разработчик Персональных сервисов, сделает практический разбор observability
Все, кто будет очно, после докладов смогут принять участие в круглых столах и квизе по Go. А чтобы посетить экскурсию по офису перед началом мероприятия, офлайн-участникам нужна будет предварительная регистрация.
▶️ Подробности и регистрация
Встречаемся в питерском офисе Яндекса или на онлайн-трансляции, чтобы обсудить все, что волнует Go-сообщество.
В программе выступлений:
— Владимир Тельбухов, руководитель группы разработки Городских сервисов, расскажет, как построить устойчивую систему в интеграциях с внешними сервисами
— Иван Похабов, разработчик Yandex Cloud, разберет, как устроен GoBGP, какие баги в нём встречаются и как их исправляют в production
— Сергей Толмачев, разработчик Yandex Infrastructure, разберет S3 Inventory, основываясь на практическом опыте внедрения
— Имран Турсунов, разработчик Персональных сервисов, сделает практический разбор observability
Все, кто будет очно, после докладов смогут принять участие в круглых столах и квизе по Go. А чтобы посетить экскурсию по офису перед началом мероприятия, офлайн-участникам нужна будет предварительная регистрация.
▶️ Подробности и регистрация
👍2❤1🌚1
🔄 dockertest v4
У dockertest вышло мажорное обновление, быстро смотрим под капот.
Автоматическая очистка через
В v3 нужно было явно вызывать
Переиспользование контейнеров по умолчанию
Контейнеры с одинаковым
Функциональные опции вместо
Context везде
Лёгкий клиент и безопасность
v3 тащил за собой 6000+ строк вендорного Docker-клиента с известными CVE. v4 использует официальный Moby-клиент — зависимости стали значительно чище.
Sentinel errors
Вместо строковых ошибок — типизированные:
Миграция:
➡️ Полный гайд по миграции
🔗 Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoLive
У dockertest вышло мажорное обновление, быстро смотрим под капот.
Автоматическая очистка через
t.CleanupВ v3 нужно было явно вызывать
defer pool.Purge(resource). В v4 NewPoolT регистрирует очистку автоматически. Контейнеры удаляются при завершении теста без единой строки дополнительного кода.Переиспользование контейнеров по умолчанию
Контейнеры с одинаковым
repository:tag автоматически шарятся между тестами в рамках одного запуска. Это существенно ускоряет локальную разработку. Отключается через WithoutReuse(), а для одного образа с разными конфигами WithReuseID("my-key").Функциональные опции вместо
RunOptions// v3
pool.RunWithOptions(&dockertest.RunOptions{
Repository: "postgres",
Tag: "14",
Env: []string{"POSTGRES_PASSWORD=secret"},
})
// v4
pool.RunT(t, "postgres",
dockertest.WithTag("14"),
dockertest.WithEnv([]string{"POSTGRES_PASSWORD=secret"}),
)
Context везде
pool.Retry теперь принимает context.Context и явный таймаут:// v3
pool.Retry(func() error { return db.Ping() })
// v4
pool.Retry(t.Context(), 30*time.Second, func() error { return db.Ping() })
Лёгкий клиент и безопасность
v3 тащил за собой 6000+ строк вендорного Docker-клиента с известными CVE. v4 использует официальный Moby-клиент — зависимости стали значительно чище.
Sentinel errors
Вместо строковых ошибок — типизированные:
if errors.Is(err, dockertest.ErrImagePullFailed) { ... }
if errors.Is(err, dockertest.ErrContainerStartFailed) { ... }Миграция:
go get github.com/ory/dockertest/v4
# Обновить импорты
find . -name "*.go" -exec sed -i \
's|github.com/ory/dockertest/v3|github.com/ory/dockertest/v4|g' {} \;
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2