Communitygithub.com

mythicalhacker/go-mastery

Agente de habilidad de codificación Go de grado de producción e idiomático para agentes de codificación de IA (Go 1.22–1.26). +12–26pp de corrección en Claude y GPT-5, sin regresiones en el dominio.

¿Qué es go-mastery?

Esta habilidad (skill) proporciona un conocimiento completo del ecosistema Go, diseñado específicamente para que agentes de IA como Claude Code, Cursor o Codex escriban código Go idiomático y de grado de producción. Cubre desde Go 1.22 hasta 1.26, incorporando las últimas características del lenguaje, mejores prácticas de la comunidad y patrones de diseño. La habilidad incluye referencias detalladas sobre concurrencia, APIs, bases de datos, pruebas, manejo de errores, rendimiento, seguridad y muchos otros temas. Su objetivo es que el agente de IA genere código que no solo compile, sino que también siga las convenciones y principios del ecosistema Go, mejorando la corrección entre un 12 y 26 puntos porcentuales sin causar regresiones. Es compatible con múltiples plataformas y se actualiza regularmente para reflejar los cambios en el lenguaje y el ecosistema.

Compatible con✓Claude Code✓Codex CLI✓Cursor
npx skills add mythicalhacker/go-mastery

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Habilidad de Go Mastery

Escribe Go idiomático de grado de producción para cualquier propósito. Esta habilidad codifica la sabiduría colectiva del ecosistema Go a partir de Go 1.22+ (2024-2026).

Versión base de Go: 1.22 | Funciones hasta: 1.26 | Actualizado: Febrero de 2026

Antes de escribir cualquier código Go, interioriza los principios a continuación. Para profundizar en temas específicos, lee los archivos referenciados.

Archivos de Referencia — Leer Según sea Necesario

ArchivoCuándo Leerlo
references/concurrency.mdCualquier goroutine, canal, primitiva de sincronización o trabajo paralelo
references/http-and-apis.mdServidores HTTP, enrutadores, middleware, APIs REST/gRPC, WebSockets
references/database.mdSQL, ORMs, pools de conexiones, migraciones, transacciones
references/testing.mdPruebas unitarias, pruebas de integración, benchmarks, fuzzing
references/errors-and-resilience.mdManejo de errores, reintentos, circuit breakers, degradación gradual
references/performance.mdPerfilado, reducción de asignaciones, ajuste de GC, benchmarking
references/cli-and-config.mdFrameworks de CLI, configuración, gestión de entornos
references/project-patterns.mdDiseño de proyectos, DI, sistemas de plugins, generación de código
references/platform-and-build.mdCompilación cruzada, especificidades de Windows, embebido, distribución
references/security.mdAutenticación, secretos, validación de entrada, TLS, patrones OWASP
references/modern-go.mdFunciones de Go 1.21–1.26, patrones obsoletos, lo que el preentrenamiento falla
references/advanced-patterns.mdGenéricos, máquinas de estado, streaming, planificación, integración AI/LLM
references/advanced-resources.mdRecursos externos seleccionados: internos del compilador/runtime, ensamblador, unsafe, cgo, Raft, operadores K8s, Wasm, criptografía, perfilado, libros, conferencias, artículos académicos
references/observability.mdConfiguración de OpenTelemetry, trazado, métricas, registro estructurado con correlación de trazas, health checks, flight recorder, lista de verificación de instrumentación en producción
references/ecosystem-and-tooling.mdListas seleccionadas (awesome-go), comparaciones de frameworks (web, ORM, CLI, DI, config), guías de estilo, CI/CD, Docker, gestión de versiones, escaneo de vulnerabilidades, plataformas de aprendizaje, gobernanza de Go
references/internals.mdPlanificador GMP, recolector de basura, modelo de memoria, gestión de pila, asignador de memoria, pipeline del compilador, unsafe, reflexión, directivas del compilador
references/networking.mdServidores TCP/UDP, plazos de net.Conn, pooling de conexiones, mTLS, sockets Unix, resolutores DNS, protocolos binarios personalizados, gnet
references/mcp-and-agents.mdServidores MCP (mcp-go, SDK oficial), herramientas/recursos/prompts, frameworks de agentes (ADK, langchaingo, eino), patrones multi-agente, gopls MCP
references/api-design.mdNomenclatura REST, paginación (cursor/offset), errores RFC 9457, limitación de velocidad, versionado de API, generación de código OpenAPI (oapi-codegen), compatibilidad hacia atrás, cabeceras de obsolescencia
references/cgo-and-interop.mdConceptos básicos de CGo, mapeo de tipos C, gestión de memoria a través del límite, reglas de paso de punteros, callbacks, enlazado estático/dinámico, compilación cruzada, alternativas puras en Go
references/design-patterns.mdPatrones de GoF en Go (factory, builder, strategy, observer, decorator), composición sobre herencia, árbol de decisión
references/distributed-systems.mdRaft, patrón outbox, sagas, bloqueo distribuido, idempotencia, CRDTs, hashing consistente
references/cloud-native.mdKubernetes client-go, operadores de controller-runtime, admission webhooks, elección de líder, Helm/Kustomize
references/debugging-and-diagnostics.mdDepurador Delve, trazas de pila, banderas GODEBUG, flujo de trabajo de perfilado, tablas de síntoma a diagnóstico
references/style-synthesis.mdReglas de estilo fusionadas de Google + Uber + comunidad, nomenclatura, formato, organización del código
references/modules-and-dependencies.mdOperaciones de go.mod, MVS, workspaces, GOPROXY, GOAUTH, vendoring, monorepos multi-módulo
references/encoding-and-serialization.mdJSON (v1/v2), Protocol Buffers, MessagePack, CBOR, CSV, YAML, TOML, tabla de decisión de formato
references/wasm-and-embedded.mdWebAssembly (WASI, navegador), go:wasmexport, TinyGo, patrones embebidos/IoT
references/migration-guides.mdTraducciones idiomáticas de Go desde Python, Java, TypeScript, Rust, C++ — mapas de conceptos y trampas
references/testing-advanced.mdPruebas basadas en propiedades (rapid), pruebas de contrato (Pact), pruebas de carga (Vegeta), ingeniería del caos, synctest avanzado
references/supply-chain-security.mdgovulncheck, generación de SBOM, marco SLSA, cosign, compilaciones reproducibles, compatibilidad GODEBUG
references/ebpf.mdeBPF desde Go (cilium/ebpf), flujo de trabajo bpf2go, trazado, redes, perfilado a nivel de kernel
references/event-driven.mdConsumidores/productores de Kafka, RabbitMQ, NATS, framework Watermill, DLQ, patrones de exactamente una vez
references/data-structures-and-caching.mdcontainer/heap, container/list, cachés LRU, singleflight, mapas fragmentados, filtros bloom, cachés de referencia débil, patrones de estrategia de caché (aside/write-through/write-behind)
references/ai-ml-beyond-llm.mdInferencia ONNX Runtime, Gonum, clientes de bases de datos vectoriales, pipelines de embeddings, ML servido desde Go
references/file-io.mdOperaciones de archivo, composición io.Reader/Writer, E/S con búfer, streaming, manejo de rutas, os.Root, abstracción fs.FS, fsnotify

Filosofía Central

Go es deliberadamente simple. Resiste la tentación de importar complejidad de otros ecosistemas.

  1. Claridad sobre astucia. El código se lee 10 veces más de lo que se escribe. Explícito vence a implícito — los mantenedores futuros (incluyéndote a ti mismo) te lo agradecerán.
  2. Composición sobre herencia. Embebe interfaces y structs; evita jerarquías profundas. Go no tiene clases, y eso es intencional — piezas pequeñas y componibles vencen a árboles de tipos complejos.
  3. Acepta interfaces, devuelve structs. Las funciones deben depender del comportamiento (interfaces) y exponer tipos concretos. Esto mantiene flexibles los puntos de llamada mientras mantiene las implementaciones descubribles y depurables.
  4. Haz que el valor cero sea útil. Diseña tipos para que var x T esté listo para usar sin inicialización. Esto elimina toda una clase de bugs de puntero nulo y hace que las APIs se sientan naturales (bytes.Buffer, sync.Mutex, http.Client todos funcionan con valor cero).
  5. Los errores son valores. Manéjalos; nunca los ignores. Envuélvelos con contexto usando fmt.Errorf("haciendo X: %w", err). Los errores descartados se convierten en fallos silenciosos que emergen horas más tarde en producción.
  6. No inicies goroutines que no puedas detener. Cada goroutine necesita una ruta de apagado a través de cancelación de contexto o cierre de canal. Las goroutines filtradas consumen memoria indefinidamente y hacen imposible el apagado gradual.
  7. stdlib primero. La biblioteca estándar de Go es inusualmente completa. Recurre a bibliotecas de terceros solo cuando stdlib realmente se queda corta — menos dependencias significan menos auditorías de seguridad, menos conflictos de versiones y compilaciones más rápidas.
  8. El código no está terminado hasta que está limpio con gofmt, compila y pasa go vet. Ejecuta gofmt/goimports, go build, go vet, go test -race y golangci-lint — conviértelos en compuertas de CI; el detector de carreras encuentra bugs invisibles para la revisión. Al emitir código sin acceso a herramientas, mantén el mismo estándar manualmente: mantenlo formateado con gofmt e incluye solo las importaciones que realmente usas (una importación no utilizada es un error de compilación — el desliz clásico justo después de intercambiar un idioma por otro).
  9. Honra el contrato del llamante, luego optimiza. Cuando una tarea especifica identificadores, firmas, formato de salida o tipos exactos, reprodúcelos exactamente — incluso si los nombrarías o estructurarías de manera diferente. Opta por la solución correcta más simple que satisfaga la especificación; añade abstracción, indirección o capas defensivas solo cuando la complejidad de la tarea lo exija. Coincidir con la superficie requerida es parte de la corrección — renombrar o reestructurar gratuitamente rompe a los llamantes y las pruebas.

Estructura del Proyecto

Empieza simple. Añade estructura solo cuando el proyecto lo demande.

Binario Único (CLI o servicio pequeño)

myapp/
├── go.mod
├── main.go              # package main, punto de entrada
├── app.go               # lógica central de la aplicación
├── app_test.go
└── internal/            # paquetes privados según sea necesario
    └── parser/
        ├── parser.go
        └── parser_test.go

Múltiples Binarios / Servicio de Producción

myproject/
├── go.mod
├── cmd/                 # puntos de entrada — funciones main() delgadas
│   ├── api-server/
│   │   └── main.go
│   └── worker/
│       └── main.go
├── internal/            # código de aplicación privado (exigido por el compilador)
│   ├── auth/
│   ├── user/            # paquete de dominio: handler + service + repo
│   │   ├── handler.go
│   │   ├── service.go
│   │   ├── repository.go
│   │   └── model.go
│   ├── platform/        # transversal: db, caché, logging
│   │   ├── postgres/
│   │   └── redis/
│   └── middleware/
├── pkg/                 # OPCIONAL: bibliotecas públicas reutilizables
├── api/                 # Especificaciones OpenAPI, definiciones protobuf
├── migrations/          # Archivos de migración SQL
├── scripts/             # Herramientas de compilación, despliegue, desarrollo
├── configs/             # Archivos de configuración por defecto
└── Makefile

Reglas clave:

  • internal/ es exigido por el compilador de Go — el código aquí no puede ser importado por módulos externos.
  • cmd/*/main.go debe ser delgado: analizar banderas, conectar dependencias, llamar a run(), manejar el apagado.
  • Agrupa por dominio/característica, no por capa técnica. Evita models/, controllers/, services/ — esto es una estructuración al estilo Java que lucha contra el modelo de paquetes de Go.
  • Evita paquetes utils/, helpers/, common/ — nombra los paquetes por lo que proporcionan, ya que los nombres vagos atraen código no relacionado y hacen que las importaciones sean sin sentido.
  • Un directorio ES un paquete. No crees directorios solo para organización.

Convenciones de Nomenclatura

// Paquetes: cortos, minúsculas, una sola palabra. Sin guiones bajos ni MixedCaps.
package user      // bien
package userService // mal — MixedCaps

// Exportado: MixedCaps. No exportado: mixedCaps. Los guiones bajos son legales pero la
// comunidad los trata como un error de estilo — señalan código no idiomático.
func ParseRequest()  // exportado
func parseHeader()   // no exportado

// Interfaces: sufijo método + "-er" para interfaces de un solo método
type Reader interface { Read(p []byte) (n int, err error) }
type Validator interface { Validate() error }

// Getters: Owner(), no GetOwner(). Setters: SetOwner().
func (u *User) Name() string       // getter — el prefijo "Get" no es Go
func (u *User) SetName(n string)   // setter

// Acrónimos: todo mayúsculas. URL, HTTP, ID, API — no Url, Http, Id, Api.
type HTTPClient struct{}
var userID int

// Variables de error: ErrXxx. Tipos de error: XxxError.
var ErrNotFound = errors.New("no encontrado")
type ValidationError struct { Field string; Message string }

// Context: primer parámetro, siempre nombrado ctx. Esta es una convención universal de Go
// que hace que la propagación del contexto sea instantáneamente reconocible en cualquier código base.
func (s *Service) GetUser(ctx context.Context, id string) (*User, error)

Manejo de Errores

Este es el patrón más distintivo de Go. Domínalo.

// Verifica cada error — envuelve con contexto usando %w
f, err := os.Open(name)
if err != nil {
    return fmt.Errorf("abriendo config %s: %w", name, err)
}
defer f.Close()

// errors.AsType — extracción de error tipado genérico [Go 1.26+]
// Preferido sobre errors.As: type-safe, sin necesidad de variable pre-declarada.
if pathErr, ok := errors.AsType[*fs.PathError](err); ok {
    fmt.Println("falló en la ruta:", pathErr.Path)
}

Reglas clave:

  • return err sin contexto hace que la depuración sea dolorosa — siempre envuelve con fmt.Errorf("haciendo X: %w", err).
  • log.Fatal(err) en código de biblioteca llama a os.Exit(1), saltándose la limpieza diferida — devuelve errores a los llamantes.
  • panic() es para bugs de programador, no para condiciones de tiempo de ejecución — devuelve errores en su lugar.
  • Envuelve errores de terceros con %v (no %w) para evitar acoplar a los llamantes al tipo de error subyacente.
  • Estilo de mensaje de error: minúsculas, sin puntuación: fmt.Errorf("leyendo archivo de configuración: %w", err).

Consulta references/errors-and-resilience.md para errores centinela, tipos de error personalizados, errors.Join, patrones de reintento, circuit breakers y degradación gradual.


Conceptos Esenciales de Concurrencia

Consulta references/concurrency.md para patrones completos, incluyendo errgroup, pools de workers y fan-out/fan-in. Reglas centrales:

  1. Usa contexto para cancelación. Cada goroutine debe verificar ctx.Done() — sin ello, no hay forma de señalar "detener el trabajo".
  2. Prefiere errgroup sobre sync.WaitGroup crudo. Agrupa espera + recolección de errores + cancelación de contexto. Consulta concurrency.md para ejemplos completos con SetLimit.
  3. Protege el estado compartido — canales para comunicación, mutex cuando sea más simple. Comenta qué protege cada mutex.
  4. Cada goroutine necesita una ruta de apagado. Sin verificación de cancelación = goroutine filtrada = fuga de memoria.
  5. Un panic en una goroutine mata todo el proceso. Recupera en goroutines generadas, o usa sourcegraph/conc.

Primitivas de sincronización novedosas:

sync.OnceValue / sync.OnceValues [Go 1.21+] — inicialización perezosa type-safe que reemplaza sync.Once + variable de paquete:

var loadConfig = sync.OnceValues(func() ([]byte, error) {
    return os.ReadFile("config.json") // se ejecuta exactamente una vez, seguro desde cualquier goroutine
})
data, err := loadConfig() // las llamadas posteriores devuelven el resultado en caché

sync.WaitGroup.Go [Go 1.25+] — combina Add(1) + go func + Done():

var wg sync.WaitGroup
wg.Go(func() { process(1) })
wg.Go(func() { process(2) })
wg.Wait()

Tamaño de canales: sin búfer (0) para sincronización, con búfer (1) para señales, con búfer (N) para trabajo conocido y acotado.


Interfaces

// Acepta interfaces, devuelve tipos concretos
type UserStore interface {
    GetUser(ctx context.Context, id string) (*User, error)
}
func NewService(store UserStore) *Service { return &Service{store: store} }

// Mantén las interfaces pequeñas — 1-3 métodos. Compone las más grandes a partir de las pequeñas.
type ReadWriter interface { Reader; Writer }

// Define la interfaz en el lado del consumidor, no del productor.
// Esto evita dependencias circulares y mantiene los paquetes desacoplados.

Formato y Estilo

  • gofmt maneja todo el formato. No discutas sobre llaves, sangría o espaciado — el estándar se aplica automáticamente.
  • La anchura máxima de línea es 123 caracteres (el valor predeterminado de gofmt). No añadas anchos personalizados; gofmt los ignora.
  • goimports gestiona las importaciones: añade las faltantes, elimina las no utilizadas, agrupa en bloque estándar, terceros, locales.
  • Comienza los comentarios de bloque (/* */) con un espacio después de /*. Prefiere // para comentarios de una línea y de documentación.
  • Los comentarios son una oración completa con mayúscula y punto final, incluso si la oración es corta.

Orden de las importaciones (gestión manual):

  1. Biblioteca estándar
  2. Paquetes de terceros
  3. Paquetes locales
import (
    "fmt"
    "os"

    "github.com/google/uuid"
    "golang.org/x/sync/errgroup"

    "myproject/internal/auth"
    "myproject/internal/user"
)

Pruebas

// Nombre de la prueba: describe el comportamiento bajo prueba
func TestUserService_CreateUser_success(t *testing.T) {
    t.Parallel() // acelera los conjuntos de pruebas
    // ...
}

// Tablas de pruebas (table-driven tests) para múltiples casos
func TestParseRequest(t *testing.T) {
    tests := []struct {
        name    string
        input   string
        want    Request
        wantErr bool
    }{
        {name: "válido", input: `{"type":"login"}`, want: Request{Type: "login"}},
        {name: "JSON inválido", input: `{`, wantErr: true},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := ParseRequest(tt.input)
            if (err != nil) != tt.wantErr {
                t.Errorf("ParseRequest() error = %v, wantErr %v", err, tt.wantErr)
            }
            if !reflect.DeepEqual(got, tt.want) {
                t.Errorf("ParseRequest() = %v, want %v", got, tt.want)
            }
        })
    }
}

Reglas clave:

  • Ejecuta go test -race en CI. El detector de carreras es tu mejor aliado contra bugs de concurrencia.
  • Los subtests (t.Run) proporcionan una salida clara y permiten ejecutar casos individuales: go test -run TestFoo/bar.
  • Los names de los subtests (name field in table) son descriptivos pero sin espacios.
  • Los helpers de prueba señalizan fallos con t.Helper(), para que los mensajes de error señalen la línea de llamada, no la del helper.
  • Las pruebas no deben depender del orden de ejecución, variables de entorno externas, o recursos de red — a menos que sean pruebas de integración explícitamente etiquetadas.
  • Separa las pruebas de integración con build tags (ej. //go:build integration) o por nombre de archivo (ej. *_integration_test.go).

Consulta references/testing.md para directrices completas sobre pruebas unitarias, de integración, benchmarks y fuzzing.


Gestión de Dependencias

go get github.com/some/pkg@v1.2.3
  • Prefiere versiones semánticas dentro del mismo módulo principal. Actualizar a través de módulos principales es un cambio que rompe la compatibilidad (breaking change).
  • Usa go mod tidy para limpiar go.mod y go.sum — esto elimina dependencias no utilizadas y registra las faltantes.
  • Las sustituciones locales (replace) están bien para desarrollo local pero deben eliminarse antes de enviar a CI/producción.
  • Usa workspaces (go.work) para el desarrollo en múltiples módulos; no te metas en scripts de reemplazo complejos.
  • Congela dependencias con go mod vendor si el CI tiene acceso limitado a la red, pero prefiere la resolución directa de módulos para la velocidad de compilación.

Código Final

Sigue estos principios y tu código Go será:

  • Legible por cualquier desarrollador de Go
  • Mantenible a través de cambios de funcionalidades
  • Eficiente sin micro-optimizaciones prematuras
  • Correcto en el manejo de bordes y condiciones de error

El ecosistema Go recompensa la disciplina, no el truco. Escribe el código que tenga sentido seis meses después, cuando hayas olvidado lo que hacía.


Para leer más, consulta los archivos en el directorio references/. Cada uno contiene patrones detallados, ejemplos y pautas de selección.

Skills relacionados