Промты, которые превращают ChatGPT в Go-сеньора: каналы, горутины, gRPC и pprof без боли

Промты, которые превращают ChatGPT в Go-сеньора: каналы, горутины, gRPC и pprof без боли

Go — язык, который прощает мало: забыл закрыть канал — получил deadlock, не ограничил параллелизм — словил OOM, не поставил таймаут на gRPC — сервис висит под нагрузкой. При этом LLM отлично генерируют Go-код, если правильно сформулировать задачу. Проблема в том, что большинство промтов вида «напиши код на Go» дают усреднённый результат: без context, без errgroup, без учёта GOMAXPROCS.

Ниже — 12 промтов, которые я собрал и обкатал на реальных задачах: от генерации идиоматичного кода до ревью горутин, профилирования через pprof и написания бенчмарков. Каждый промт — с описанием задачи, готовым текстом для LLM и примером. Формулировки проверены на актуальных версиях Go (1.21+) и стандартной библиотеке.

Промт Когда применять Ключевая выгода
1. Идиоматичный код Пишете новый пакет Соответствие Effective Go
2. Ревью горутин Проверка перед мержем Ловля утечек и race
3. Каналы и паттерны Пайплайны, fan-in/out Без deadlock
4. gRPC-сервис Новый микросервис Полный boilerplate с interceptors
5. Оптимизация pprof Профилирование CPU/heap Конкретные hotspots
6. Бенчмарки Замер производительности testing.B с b.ReportAllocs
7. Контекст и таймауты Отмена операций Правильные context.WithTimeout
8. Синхронизация Мьютексы, atomic Выбор примитива под задачу
9. Тесты с race detector CI-проверки go test -race сценарии
10. Обработка ошибок Обёртка ошибок errors.Is/As, %w
11. Пул воркеров Ограничение параллелизма Без утечек горутин
12. Чтение чужого кода Разбор legacy Карта зависимостей

1. Идиоматичный Go-код без «Java-акцента»

Задача: сгенерировать код, который не стыдно выложить в open source — с правильными именами, ранними возвратами и без избыточных абстракций.

Промт:

Ты — опытный Go-разработчик. Напиши пакет [имя], который [задача]. Требования: следуй Effective Go (https://go.dev/doc/effective_go) и Code Review Comments (https://go.dev/wiki/CodeReviewComments). Используй короткие имена переменных, ранние возвраты, не создавай интерфейсы «на будущее». Обрабатывай ошибки через fmt.Errorf с %w. Добавь doc-комментарии к экспортируемым символам. Не используй сторонние зависимости, только стандартную библиотеку. Покажи финальный код и поясни, почему выбрал именно такие имена и структуру.

Пример: «Напиши пакет retry, который повторяет операцию с экспоненциальной задержкой и учитывает context.Context». На выходе — функция Do(ctx, attempts, fn) с time.NewTimer и проверкой ctx.Err().

2. Ревью горутин и поиск утечек

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

Промт:

Проанализируй код ниже как ревьюер Go. Найди: (1) горутины, которые не завершаются при отмене контекста; (2) каналы без закрытия или без читателя; (3) блокировки на sync.Mutex без defer. Для каждой проблемы укажи строку, объясни сценарий утечки и предложи исправление. Используй терминологию из документации runtime/pprof и net/http/pprof.

Пример: код с go func() { ch <- result }() без буферизации — LLM укажет, что если читатель отменит контекст, горутина заблокируется навсегда.

3. Паттерны каналов: fan-in, fan-out, pipeline

Задача: построить конкурентный пайплайн без классических ошибок.

Промт:

Реализуй паттерн [fan-in / fan-out / pipeline] на Go. Требования: используй sync.WaitGroup для ожидания воркеров, закрывай каналы только на стороне отправителя, поддерживай отмену через context.Context. Покажи схему потоков данных текстом, затем код. Сравни с альтернативой на golang.org/x/sync/errgroup и объясни, когда что выбирать.

Пример: «Fan-out: 10 воркеров читают из jobs, пишут в results». LLM выдаст for i := 0; i < workers; i++ { go worker(ctx, jobs, results) } с корректным закрытием.

4. gRPC-сервис с interceptors

Задача: сгенерировать сервер и клиент gRPC с логированием, таймаутами и метриками.

Промт:

Сгенерируй gRPC-сервис на Go по proto-файлу ниже. Добавь: unary interceptor для логирования (с request_id), interceptor для recovery от паник, таймаут по умолчанию 5 секунд через context.WithTimeout. Используй google.golang.org/grpc и google.golang.org/grpc/credentials/insecure для локального запуска. Покажи команду protoc для генерации кода и структуру проекта.

Пример: сервис UserService с методом GetUser — на выходе server.go, client.go, interceptors.go и Makefile.

5. Профилирование через pprof

Задача: найти узкие места в сервисе под нагрузкой.

Промт:

Объясни, как профилировать Go-сервис через net/http/pprof. Дай: (1) код подключения /debug/pprof/ к HTTP-серверу; (2) команды go tool pprof для CPU и heap профилей; (3) как читать top, list, web. Затем проанализируй вывод профиля ниже и предложи 3 конкретные оптимизации с оценкой эффекта.

Пример: после go tool pprof http://localhost:6060/debug/pprof/profile?seconds=30 видно, что 40% CPU уходит на encoding/json — LLM предложит заменить на jsoniter или перейти на protobuf.

6. Бенчмарки по всем правилам

Задача: написать бенчмарки, которые реально что-то измеряют.

Промт:

Напиши бенчмарки для функции [имя] в файле _test.go. Используй testing.B, b.ResetTimer(), b.ReportAllocs(). Добавь табличные кейсы с b.Run. Предупреди о типичных ошибках: компилятор может выбросить результат — используй b.ReportAllocs и глобальную переменную sink. Сравни с go test -bench=. -benchmem и объясни, что означает ns/op и B/op.

Пример: бенчмарк для функции конкатенации строк — покажет разницу между +, strings.Builder и bytes.Buffer.

7. Контекст, таймауты и отмена

Задача: добавить корректную отмену во все операции.

Промт:

Отрефактори код ниже, добавив context.Context первым аргументом во все функции, которые делают I/O. Используй context.WithTimeout для внешних вызовов, context.WithCancel для ручной отмены. Не передавай nil контекст — используй context.TODO() только как временную заглушку. Покажи, как пробрасывать request_id через context.WithValue и почему это ок только для request-scoped данных.

Пример: HTTP-хендлер с вызовом БД — LLM добавит ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second) и defer cancel().

8. Мьютексы, atomic и выбор примитива

Задача: не блокировать горутины там, где можно обойтись atomic.

Промт:

У меня есть счётчик, который инкрементируется из 1000 горутин. Сравни три подхода: sync.Mutex, sync/atomic и sync.RWMutex. Для каждого покажи код, объясни, когда он выигрывает по производительности, и приведи бенчмарк. Учти, что atomic.Int64 доступен с Go 1.19.

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

9. Тесты с race detector

Задача: поймать data race до продакшена.

Промт:

Напиши тест для функции ниже, который запускает её из нескольких горутин и проверяет отсутствие data race. Используй go test -race. Покажи, как воспроизвести race намеренно (через общий слайс без мьютекса), и как его исправить. Объясни, что race detector не находит все гонки — только те, что реально произошли во время запуска.

Пример: тест с 100 горутинами, инкрементирующими общий счётчик — с -race упадёт, после исправления пройдёт.

10. Обработка ошибок по-гошному

Задача: уйти от if err != nil { return err } без контекста.

Промт:

Перепиши обработку ошибок в коде ниже. Используй fmt.Errorf с %w для обёртки, errors.Is и errors.As для проверки. Создай sentinel-ошибки через errors.New и кастомный тип ошибки с полями. Покажи, как не терять原始 ошибку и почему errors.Is работает через цепочку обёрток.

Пример: ошибка от БД оборачивается как fmt.Errorf("get user %d: %w", id, err), а наверху проверяется errors.Is(err, sql.ErrNoRows).

11. Пул воркеров с ограничением

Задача: обработать 100 000 задач, но не запустить 100 000 горутин.

Промт:

Реализуй пул воркеров на Go: N воркеров читают задачи из канала, результат пишут в другой канал. Добавь context.Context для отмены, sync.WaitGroup для ожидания, обработку паник в воркере. Покажи, как ограничить N через runtime.NumCPU() и почему не стоит ставить N больше числа ядер для CPU-bound задач.

Пример: парсер 1 млн URL с 20 воркерами — потребление памяти стабильно, в отличие от go func() на каждую задачу.

12. Разбор чужого кода

Задача: быстро понять legacy-сервис и найти в нём проблемы.

Промт:

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

Пример: на входе 500 строк legacy — на выходе список из 10 точек, где нужно вмешаться.

Как использовать эти промты

Главное правило: LLM не знает ваш проект. Чем больше контекста вы дадите — версия Go, используемые библиотеки, ограничения по памяти — тем точнее ответ. Всегда проверяйте сгенерированный код через go vet, staticcheck и go test -race. Ни один промт не заменяет профилирование на реальной нагрузке: pprof покажет правду, которой нет в теории.

Начните с промтов 1–3, если пишете новый код, и с 2, 5, 12 — если разбираете существующий сервис. Сохраните подборку в закладки: в следующий раз, когда ChatGPT выдаст «Java-стиль» на Go, вы будете знать, как его поправить.

← Все статьи

Комментарии

Читайте также

От разработки к продукту: что нужно, чтобы стать автором маркетплейса Инфостарт

14 июля 2026

7 промтов для миграции кода: Python 2→3, JavaScript→TypeScript, REST→GraphQL

2 июля 2026

Как AI-агент ASI Biont автоматизирует закупки в SAP Business One: интеграция без программирования

5 июля 2026

Маркетинг с ИИ без хаоса: 15 промтов, которые закрывают воронку — от сегментации до аналитики кампаний

20 сентября 2026

Как избежать штрафов и отзывов продукции: курс «CE-маркировка и технические регламенты ЕС — Product Compliance» на asibiont.com

23 июня 2026

Ассистент, а не агент: как спроектировать предсказуемую LLM-систему

20 июля 2026

Terraform и IaC: управление инфраструктурой как кодом на AWS, GCP и Azure

18 июня 2026

Как автоматизировать транзакционные письма с помощью SendGrid и AI-агента ASI Biont: руководство по интеграции без кода

16 июля 2026

Будущее программирования: как AI меняет разработку ПО и что ждет разработчиков

4 июня 2026