Communitygithub.com

Go Mastery Skill

Produktionsreifes, idiomatisches Go für KI-Codierungsagenten – eine gemessene Agent Skill (Go 1.22–1.26). +12–26 Prozentpunkte Korrektheit bei Claude und GPT-5, keine Regressionen im In-Domain-Bereich.

Was ist Go Mastery Skill?

Diese Skill vermittelt KI-Codierungsagenten (wie Claude Code) die kumulierte Weisheit des Go-Ökosystems für Go 1.22 bis 1.26. Sie umfasst eine umfassende Wissensdatenbank mit Referenzdateien zu Themen wie Concurrency, HTTP-APIs, Datenbanken, Tests und Fehlerbehandlung sowie moderne Go-Funktionen. Die Skill legt einen klaren Fokus auf Produktionsreife und idiomatischen Go-Code, mit einer Kernphilosophie, die Klarheit, Komposition und die Nutzung der Standardbibliothek priorisiert. Entwickler, die diese Skill einsetzen, erhalten eine systematische Anleitung zu Projektstruktur, Namenskonventionen, Fehlerbehandlung und Concurrency-Mustern, ergänzt durch detaillierte Referenzmaterialien, die nur bei Bedarf gelesen werden sollen.

Funktioniert mit✓Claude Code✓Codex CLI✓Cursor
npx skills add mythicalhacker/go-mastery

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht Go Mastery Skill?

Schreibe produktionsreifes, idiomatisches Go für jeden Zweck. Diese Skill kodiert die kollektive Weisheit des Go-Ökosystems ab Go 1.22+ (2024–2026).

Go-Versionsbasis: 1.22 | Features bis: 1.26 | Aktualisiert: Februar 2026

Bevor du Go-Code schreibst, verinnerliche die folgenden Prinzipien. Für tiefgehende Einblicke zu spezifischen Themen lies die referenzierten Dateien.

Referenzdateien – Nach Bedarf lesen

DateiWann lesen
references/concurrency.mdJegliche Goroutinen, Channels, Sync-Primitive oder parallele Arbeit
references/http-and-apis.mdHTTP-Server, Router, Middleware, REST/gRPC-APIs, WebSockets
references/database.mdSQL, ORMs, Verbindungspools, Migrationen, Transaktionen
references/testing.mdUnit-Tests, Integrationstests, Benchmarks, Fuzzing
references/errors-and-resilience.mdFehlerbehandlung, Wiederholungen, Circuit Breaker, Graceful Degradation
references/performance.mdProfiling, Speicherreduzierung, GC-Tuning, Benchmarking
references/cli-and-config.mdCLI-Frameworks, Konfiguration, Umgebungsverwaltung
references/project-patterns.mdProjektstruktur, DI, Plugin-Systeme, Code-Generierung
references/platform-and-build.mdCross-Kompilierung, Windows-Spezifika, Einbettung, Distribution
references/security.mdAuthentifizierung, Secrets, Eingabevalidierung, TLS, OWASP-Muster
references/modern-go.mdGo 1.21–1.26 Features, veraltete Muster, was Pre-Training falsch macht
references/advanced-patterns.mdGenerics, Zustandsmaschinen, Streaming, Scheduling, KI/LLM-Integration
references/advanced-resources.mdKuratierte externe Ressourcen: Compiler/Runtime-Interna, Assembler, unsafe, cgo, Raft, K8s-Operatoren, Wasm, Kryptographie, Profiling, Bücher, Konferenzen, wissenschaftliche Arbeiten
references/observability.mdOpenTelemetry-Setup, Tracing, Metriken, strukturiertes Logging mit Trace-Korrelation, Health Checks, Flight Recorder, Produktions-Instrumentierungs-Checkliste
references/ecosystem-and-tooling.mdKuratierte Listen (awesome-go), Framework-Vergleiche (Web, ORM, CLI, DI, Config), Styleguides, CI/CD, Docker, Release-Management, Schwachstellenscans, Lernplattformen, Go-Governance
references/internals.mdGMP-Scheduler, Garbage Collector, Speichermodell, Stack-Management, Speicher-Allokator, Compiler-Pipeline, unsafe, Reflection, Compiler-Direktiven
references/networking.mdTCP/UDP-Server, net.Conn-Deadlines, Verbindungspooling, mTLS, Unix-Sockets, DNS-Resolver, benutzerdefinierte Binärprotokolle, gnet
references/mcp-and-agents.mdMCP-Server (mcp-go, offizielles SDK), Tools/Ressourcen/Prompts, Agent-Frameworks (ADK, langchaingo, eino), Multi-Agent-Muster, gopls MCP
references/api-design.mdREST-Benennung, Paginierung (Cursor/Offset), RFC 9457-Fehler, Ratenbegrenzung, API-Versionierung, OpenAPI-Codegen (oapi-codegen), Abwärtskompatibilität, Deprecation-Header
references/cgo-and-interop.mdCGo-Grundlagen, C-Typzuordnung, Speicherverwaltung über Grenzen hinweg, Zeigerübergaberegeln, Callbacks, statisches/dynamisches Linken, Cross-Kompilierung, reine Go-Alternativen
references/design-patterns.mdGoF-Muster in Go (Factory, Builder, Strategy, Observer, Decorator), Komposition über Vererbung, Entscheidungsbaum
references/distributed-systems.mdRaft, Outbox-Muster, Sagas, verteiltes Sperren, Idempotenz, CRDTs, konsistentes Hashing
references/cloud-native.mdKubernetes client-go, controller-runtime-Operatoren, Admission Webhooks, Leader Election, Helm/Kustomize
references/debugging-and-diagnostics.mdDelve-Debugger, Stack-Traces, GODEBUG-Flags, Profiling-Workflow, Symptom-zu-Diagnose-Tabellen
references/style-synthesis.mdZusammengeführte Google + Uber + Community-Stilregeln, Benennung, Formatierung, Code-Organisation
references/modules-and-dependencies.mdgo.mod-Operationen, MVS, Workspaces, GOPROXY, GOAUTH, Vendoring, Multi-Modul-Monorepos
references/encoding-and-serialization.mdJSON (v1/v2), Protocol Buffers, MessagePack, CBOR, CSV, YAML, TOML, Format-Entscheidungstabelle
references/wasm-and-embedded.mdWebAssembly (WASI, Browser), go:wasmexport, TinyGo, eingebettete/IoT-Muster
references/migration-guides.mdIdiomatische Go-Übersetzungen von Python, Java, TypeScript, Rust, C++ – Konzeptkarten und Fallstricke
references/testing-advanced.mdProperty-basiertes Testen (rapid), Vertragstests (Pact), Lasttests (Vegeta), Chaos Engineering, synctest advanced
references/supply-chain-security.mdgovulncheck, SBOM-Generierung, SLSA-Framework, cosign, reproduzierbare Builds, GODEBUG-Kompatibilität
references/ebpf.mdeBPF aus Go (cilium/ebpf), bpf2go-Workflow, Tracing, Networking, Profiling auf Kernel-Ebene
references/event-driven.mdKafka, RabbitMQ, NATS-Consumer/Producer, Watermill-Framework, DLQ, Exactly-Once-Muster
references/data-structures-and-caching.mdcontainer/heap, container/list, LRU-Caches, singleflight, sharded maps, Bloom-Filter, Weak-Reference-Caches, Cache-Strategie-Muster (aside/write-through/write-behind)
references/ai-ml-beyond-llm.mdONNX Runtime-Inferenz, Gonum, Vektor-DB-Clients, Embedding-Pipelines, ML-Serving aus Go
references/file-io.mdDateioperationen, io.Reader/Writer-Komposition, gepufferte E/A, Streaming, Pfadverarbeitung, os.Root, fs.FS-Abstraktion, fsnotify

Kernphilosophie

Go ist bewusst einfach. Widerstehe der Versuchung, Komplexität aus anderen Ökosystemen zu importieren.

  1. Klarheit vor Cleverness. Code wird 10x häufiger gelesen als geschrieben. Explizit schlägt implizit – zukünftige Maintainer (einschließlich deines zukünftigen Ichs) werden es dir danken.
  2. Komposition vor Vererbung. Bette Interfaces und Structs ein; vermeide tiefe Hierarchien. Go hat keine Klassen, und das ist beabsichtigt – kleine, komponierbare Teile schlagen komplexe Typbäume.
  3. Akzeptiere Interfaces, gib Structs zurück. Funktionen sollten von Verhalten (Interfaces) abhängen und konkrete Typen bereitstellen. Dies hält Aufrufstellen flexibel, während Implementierungen auffindbar und debuggbar bleiben.
  4. Mache den Nullwert nützlich. Entwerfe Typen so, dass var x T ohne Initialisierung einsatzbereit ist. Dies eliminiert eine ganze Klasse von Nil-Pointer-Bugs und lässt APIs natürlich wirken (bytes.Buffer, sync.Mutex, http.Client funktionieren alle mit Nullwert).
  5. Fehler sind Werte. Behandle sie; ignoriere sie nie. Wickle sie mit Kontext ein, indem du fmt.Errorf("doing X: %w", err) verwendest. Verworfene Fehler werden zu stillen Fehlern, die Stunden später in der Produktion auftauchen.
  6. Starte keine Goroutinen, die du nicht stoppen kannst. Jede Goroutine benötigt einen Shutdown-Pfad durch Context-Cancellation oder Channel-Close. Verwaiste Goroutinen verbrauchen auf unbestimmte Zeit Speicher und machen Graceful Shutdown unmöglich.
  7. Stdlib zuerst. Gos Standardbibliothek ist ungewöhnlich vollständig. Greife nur dann zu Drittanbieterbibliotheken, wenn die Stdlib wirklich zu kurz greift – weniger Abhängigkeiten bedeuten weniger Sicherheitsaudits, weniger Versionskonflikte und schnellere Builds.
  8. Code ist nicht fertig, bis er gofmt-sauber ist, baut und vetted. Führe gofmt/goimports, go build, go vet, go test -race und golangci-lint aus – mache sie zu CI-Gates; der Race-Detektor findet Bugs, die bei Reviews unsichtbar sind. Wenn du Code ohne Tool-Zugriff ausgibst, halte denselben Standard manuell ein: halte ihn gofmt-formatiert und füge nur die Imports ein, die du tatsächlich verwendest (ein ungenutzter Import ist ein Kompilierfehler – der klassische Fehler direkt nach dem Austausch einer Redewendung gegen eine andere).
  9. Ehre den Vertrag des Aufrufers, dann optimiere. Wenn eine Aufgabe genaue Bezeichner, Signaturen, Ausgabeformat oder Typen vorgibt, reproduziere sie exakt – selbst wenn du sie anders benennen oder strukturieren würdest. Standardmäßig die einfachste korrekte Lösung, die die Spezifikation erfüllt; füge Abstraktion, Indirektion oder defensive Schichten nur hinzu, wenn die Komplexität der Aufgabe es erfordert. Die Übereinstimmung mit der geforderten Oberfläche ist Teil der Korrektheit – unnötige Umbenennungen oder Umstrukturierungen brechen Aufrufer und Tests.

Projektstruktur

Starte einfach. Füge Struktur nur hinzu, wenn das Projekt es erfordert.

Einzelne Binärdatei (CLI oder kleiner Service)

myapp/
├── go.mod
├── main.go              # package main, Einstiegspunkt
├── app.go               # Kernanwendungslogik
├── app_test.go
└── internal/            # private Pakete nach Bedarf
    └── parser/
        ├── parser.go
        └── parser_test.go

Mehrere Binärdateien / Produktionsservice

myproject/
├── go.mod
├── cmd/                 # Einstiegspunkte – dünne main()-Funktionen
│   ├── api-server/
│   │   └── main.go
│   └── worker/
│       └── main.go
├── internal/            # privater Anwendungscode (vom Compiler erzwungen)
│   ├── auth/
│   ├── user/            # Domain-Paket: Handler + Service + Repo
│   │   ├── handler.go
│   │   ├── service.go
│   │   ├── repository.go
│   │   └── model.go
│   ├── platform/        # Querschnittsfunktionen: DB, Cache, Logging
│   │   ├── postgres/
│   │   └── redis/
│   └── middleware/
├── pkg/                 # OPTIONAL: öffentlich wiederverwendbare Bibliotheken
├── api/                 # OpenAPI-Spezifikationen, Protobuf-Definitionen
├── migrations/          # SQL-Migrationsdateien
├── scripts/             # Build-, Deploy- und Entwicklungs-Tooling
├── configs/             # Standardkonfigurationsdateien
└── Makefile

Wichtige Regeln:

  • internal/ wird vom Go-Compiler erzwungen – Code hier kann nicht von externen Modulen importiert werden.
  • cmd/*/main.go sollte dünn sein: Flags parsen, Abhängigkeiten verdrahten, run() aufrufen, Shutdown handhaben.
  • Gruppiere nach Domain/Feature, nicht nach technischer Schicht. Vermeide models/, controllers/, services/ – das ist Java-artige Schichtung, die gegen Gos Paketmodell kämpft.
  • Vermeide utils/, helpers/, common/-Pakete – benenne Pakete nach dem, was sie bereitstellen, da vage Namen nicht verwandten Code anziehen und Imports bedeutungslos machen.
  • Ein Verzeichnis IST ein Paket. Erstelle keine Verzeichnisse nur zur Organisation.

Namenskonventionen

// Pakete: kurz, Kleinbuchstaben, ein Wort. Keine Unterstriche oder MixedCaps.
package user      // gut
package userService // schlecht – MixedCaps

// Exportiert: MixedCaps. Nicht exportiert: mixedCaps. Unterstriche sind legal, aber
// die Community betrachtet sie als Stilfehler – sie signalisieren nicht-idiomatischen Code.
func ParseRequest()  // exportiert
func parseHeader()   // nicht exportiert

// Interfaces: Methode + „-er"-Suffix für Ein-Methoden-Interfaces
type Reader interface { Read(p []byte) (n int, err error) }
type Validator interface { Validate() error }

// Getter: Owner(), nicht GetOwner(). Setter: SetOwner().
func (u *User) Name() string       // Getter – das „Get"-Präfix ist un-Go
func (u *User) SetName(n string)   // Setter

// Akronyme: alles Großbuchstaben. URL, HTTP, ID, API – nicht Url, Http, Id, Api.
type HTTPClient struct{}
var userID int

// Fehlervariablen: ErrXxx. Fehlertypen: XxxError.
var ErrNotFound = errors.New("not found")
type ValidationError struct { Field string; Message string }

// Context: erster Parameter, immer ctx genannt. Dies ist eine universelle Go-Konvention,
// die Context-Weitergabe in jeder Codebasis sofort erkennbar macht.
func (s *Service) GetUser(ctx context.Context, id string) (*User, error)

Fehlerbehandlung

Dies ist Gos markantestes Muster. Meistere es.

// Jeden Fehler prüfen – mit Kontext mit %w umschließen
f, err := os.Open(name)
if err != nil {
    return fmt.Errorf("opening config %s: %w", name, err)
}
defer f.Close()

// errors.AsType – generische typisierte Fehlerextraktion [Go 1.26+]
// Bevorzugt gegenüber errors.As: typsicher, keine vorab deklarierte Variable erforderlich.
if pathErr, ok := errors.AsType[*fs.PathError](err); ok {
    fmt.Println("failed at path:", pathErr.Path)
}

Wichtige Regeln:

  • return err ohne Kontext macht Debugging schmerzhaft – umschließe immer mit fmt.Errorf("doing X: %w", err).
  • log.Fatal(err) in Bibliothekscode ruft os.Exit(1) auf und überspringt deferred Cleanup – gib Fehler an Aufrufer zurück.
  • panic() ist für Programmierfehler, nicht für Laufzeitbedingungen – gib stattdessen Fehler zurück.
  • Umschließe Fehler von Drittanbietern mit %v (nicht %w), um zu vermeiden, dass Aufrufer an den zugrunde liegenden Fehlertyp gekoppelt werden.
  • Fehlermeldungsstil: Kleinbuchstaben, keine Satzzeichen: fmt.Errorf("reading config file: %w", err).

Siehe references/errors-and-resilience.md für Sentinel-Fehler, benutzerdefinierte Fehlertypen, errors.Join, Wiederholungsmuster, Circuit Breaker und Graceful Degradation.


Concurrency-Grundlagen

Siehe references/concurrency.md für umfassende Muster einschließlich errgroup, Worker-Pools und Fan-Out/Fan-In. Kernregeln:

  1. Verwende Context für Cancellation. Jede Goroutine muss ctx.Done() prüfen – ohne sie gibt es keine Möglichkeit, „Stoppe Arbeit" zu signalisieren.
  2. Bevorzuge errgroup gegenüber rohem sync.WaitGroup. Bündelt Wait + Fehlersammlung + Context-Cancellation. Siehe concurrency.md für vollständige Beispiele mit SetLimit.
  3. Schütze gemeinsam genutzten Zustand – Channels für Kommunikation, Mutex, wenn es einfacher ist. Kommentiere, was jeder Mutex schützt.
  4. Jede Goroutine braucht einen Shutdown-Pfad. Keine Cancellation-Prüfung = verwaiste Goroutine = Speicherleck.
  5. Ein Panic in einer Goroutine killt den gesamten Prozess. Recover in gestarteten Goroutinen oder verwende sourcegraph/conc.

Neuartige Sync-Primitive:

sync.OnceValue / sync.OnceValues [Go 1.21+] – typsichere Lazy-Initialisierung als Ersatz für sync.Once + Paketvariable:

var loadConfig = sync.OnceValues(func() ([]byte, error) {
    return os.ReadFile("config.json") // läuft genau einmal, sicher von jeder Goroutine
})
data, err := loadConfig() // nachfolgende Aufrufe geben das gecachte Ergebnis zurück

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

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

Channel-Größenbestimmung: ungepuffert (0) für Synchronisation, gepuffert (1) für Signale, gepuffert (N) für bekannte begrenzte Arbeit.


Interfaces

// Akzeptiere Interfaces, gib konkrete Typen zurück
type UserStore interface {
    GetUser(ctx context.Context, id string) (*User, error)
}
func NewService(store UserStore) *Service { return &Service{store: store} }

// Halte Interfaces klein – 1-3 Methoden. Baue größere aus kleinen zusammen.
type ReadWriter interface { Reader; Writer }

// Definiere Interfaces dort, wo sie verwendet werden, nicht dort, wo sie implementiert werden.
// Ein Paket userservice, das ein Interface definiert, das das Paypal-Paket implementieren muss,
// erzeugt einen unnötigen Import-Zyklus.

// Leere Interfaces (interface{}) sind ein letzter Ausweg. Verwende sie nicht für Parameter,
// die jeden Typ akzeptieren – das untergräbt die Typsicherheit von Go.

Standardbibliothek zuerst

// HTTP-Server ohne Framework
mux := http.NewServeMux()
mux.HandleFunc("GET /api/users/{id}", handler)
http.ListenAndServe(":8080", mux)

// JSON-Encoding/Decoding – keine externe Bibliothek erforderlich
type User struct { Name string `json:"name"` }
json.NewEncoder(w).Encode(user)

Das net/http-Paket von Go 1.22+ unterstützt Methoden-Matching, Pfadvariablen und Middleware-Chaining – für viele Dienste ist kein Drittanbieter-Router mehr erforderlich. Greife zu chi, gin oder echo, wenn du fortgeschrittene Middleware-Ökosysteme oder Nicht-Standard-Routing-Muster benötigst.


Tests schreiben

// Tabellegetriebene Tests mit Sub-Tests
func TestParseUser(t *testing.T) {
    tests := []struct {
        name    string
        input   string
        want    User
        wantErr bool
    }{
        {"valid", `{"name":"Alice"}`, User{Name: "Alice"}, false},
        {"invalid json", `{bad`, User{}, true},
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := ParseUser(strings.NewReader(tt.input))
            if (err != nil) != tt.wantErr {
                t.Fatalf("ParseUser() error = %v, wantErr %v", err, tt.wantErr)
            }
            if !reflect.DeepEqual(got, tt.want) {
                t.Errorf("ParseUser() = %v, want %v", got, tt.want)
            }
        })
    }
}

// Race-Bedingung in Tests erkennen: go test -race ./...
// Dies ist eine CI-Pflicht – der Race-Detektor hat eine nachgewiesene Erfolgsbilanz
// beim Auffinden von Datenrennen, die Code-Reviews übersehen.

Wichtige Regeln:

  • testing.T ist Wert, kein Zeiger – verwende *testing.T.
  • Verwende t.Helper(), um Helferfunktionen als Testhelfer zu markieren – dies verbessert die Fehlerberichterstattung, indem Helfer aus dem Stack-Trace entfernt werden.
  • Bevorzuge cmpopts oder go-cmp für Deep-Equal-Vergleiche, die keine Export-Felder benötigen.
  • t.Cleanup() für Ressourcenbereinigung – idiomatischer als defer in Tests und funktioniert korrekt mit Sub-Tests.

Siehe references/testing.md für Integrationstests, Benchmarks und Fuzzing.


So verwendest du diese Referenzdateien

Jede Datei in references/ enthält:

  • Eine klare Problemerkennung – wann dieses Muster anwenden
  • Codebeispiele – komplett, ausführbar, mustergültig
  • Anti-Patterns – was nicht zu tun ist
  • Prüflisten – Woran du denken musst, bevor du PR sendest
  • Begründung – Warum dieser Ansatz der richtige für Go ist

Für ein neues Projekt: Lies die Referenz zur Projektstruktur einmal, dann lies nach Bedarf. Mit der Zeit wirst du die Inhalte verinnerlichen und die Referenzen nur noch für ungewohnte Probleme konsultieren.

Verwandte Skills