Go Specialist
Go言語の設計・実装・レビューを行う専門スキル。
references/go-practices.md を規約の源泉とし、慣用的で堅牢なGoコードを生成する。
必須リファレンス
作業開始前に必ず references/go-practices.md を読み込むこと。
命名規則・エラーハンドリング・並行処理・テスト・セキュリティなど、すべての規約がこの文書に定義されている。
| ファイル | 内容 |
|---|---|
| references/go-practices.md | 全モードで必読のコーディング規約(Go 1.24+対応) |
モード判定
冒頭でユーザーの依頼からモードを判定する。複数該当・あいまいな場合のみ推奨案を含む複数の選択肢を提示してユーザーに確認する。
| キーワード例 | モード | |---|---| | 作って / 書いて / 実装して / 新規 / CLIツール / APIサーバー | Mode 1: 設計・実装 | | レビュー / チェック / 検証 / 改善 / 品質 | Mode 2: レビュー | | リファクタ / 書き直して / モダンに / 整理して | Mode 3: リファクタリング | | 教えて / 使い方 / ベストプラクティス / 違いは | Mode 4: 技術相談 |
Mode 1: 設計・実装
新規Goコードを設計・実装する。
手順
- 要件の把握:
$ARGUMENTSまたはユーザーの依頼から、目的・入出力・パッケージ構成を整理する - リファレンス読込:
references/go-practices.mdを読み込む - 設計: パッケージ構成・型設計・インターフェース・エラー戦略を決定する
- 実装: リファレンスの規約に準拠してコードを書く
- 検証:
go vet/staticcheck/go test -shuffle on -race -cover ./...の実行はサブエージェントに委譲し、メインには合否と失敗時の要点(落ちたテスト名・主要エラー)だけを戻させる。修正はメインで行い、全パスするまで検証は都度委譲して繰り返す。単一ファイルの軽微な修正など出力が少量に収まる場合は、委譲せずメインで直接実行してよい
実装時の必須チェックリスト
リファレンスに加え、以下を常に意識する:
- エラーは必ずチェック:
errを_に捨てない — 無視されたエラーは原因不明の障害を招く。early returnパターンを徹底 - エラーをラップしてコンテキストを追加:
fmt.Errorf("操作名: %w", err)— 元のエラー情報を保持し、errors.Is/Asでの判定を可能にする - エクスポートされる識別子にはGodocコメント: 英語で、識別子名から始める —
go docやエディタ補完でAPIドキュメントとして表示される - 構造体フィールドのjsonタグはsnake_case:
json:"field_name"— REST APIのJSON慣例に合わせ、フロントエンドとの一貫性を保つ - スライスの事前キャパシティ確保: サイズが予測できる場合は
make([]T, 0, n)—appendの再割り当てとコピーコストを抑える - 文字列結合は
strings.Builder: ループ内での+結合は毎回新しい文字列を割り当てるため O(n²) になる - goroutine起動時は
sync.WaitGroupで管理: 起動したら必ず完了を待つ手段を用意 — 待機なしだとmain終了時にgoroutineが途中で打ち切られる - 共有リソースへのアクセスは
sync.Mutexで保護: mapへの並行書き込みはランタイムpanicになる context.Contextを最初の引数に: キャンセルやタイムアウトを呼び出しチェーン全体に伝搬させるGoの標準パターンlog.Fatalfではなくlog.Panicf:log.Fatalfはos.Exit(1)を呼ぶためdeferブロックが実行されず、リソースリークの原因になる- テストポートは
13000,28080のように競合しにくい番号:3000,8080は他のアプリと競合しやすく、CIでテストが不安定になる
プロジェクト構成の基本パターン
project/
├── cmd/
│ └── appname/
│ └── main.go # エントリーポイント
├── internal/ # 外部から参照されない実装
│ ├── handler/
│ ├── service/
│ └── repository/
├── pkg/ # 外部に公開するパッケージ(必要な場合のみ)
├── go.mod
├── go.sum
└── README.md
CLIツールの場合:
cmd/配下にサブコマンドごとのエントリーポイント- フラグ解析は
flagパッケージまたはcobra等を用途に応じて選択 internal/にビジネスロジックを分離し、main.goは薄く保つ
インターフェース設計の原則
- インターフェースは利用する側で定義: 提供側で大きなインターフェースを定義しない
- インターフェースは小さく保つ: 1-3メソッドが理想。
io.Readerが良い手本 - 具体的な型を返し、インターフェースを受け取る: "Accept interfaces, return structs"
Mode 2: レビュー
既存Goコードの品質をレビューする。
手順
- 対象の特定:
$ARGUMENTSのパスまたはユーザー指示からレビュー対象を決定 - リファレンス読込:
references/go-practices.mdを読み込む - コード読込: 対象ファイルを読み込む
- 静的解析実行: 利用可能であれば
go vet/staticcheckの実行をサブエージェントに委譲し、結果(指摘一覧)を収集する。対象が単一ファイルのレビューであれば、委譲せずメインで直接実行してもよい - 手動レビュー: 以下の観点で評価
レビュー観点
| カテゴリ | チェック項目 |
|---|---|
| 命名 | mixedCaps / パッケージ名の適切さ / エクスポート判定の妥当性 |
| エラー処理 | エラー無視の有無 / %w でのラップ / エラーメッセージの具体性 |
| 関数設計 | 単一責任 / 引数の数(3つ以下が目安) / 名前と処理の一致 |
| 並行処理 | WaitGroupの使用 / Mutex保護 / goroutineリーク / contextの伝搬 |
| テスト | テーブル駆動テスト / t.Parallel() / エッジケースのカバー / 外部依存のモック |
| パフォーマンス | スライスのキャパシティ / strings.Builder / 不要なアロケーション |
| セキュリティ | 入力バリデーション / SQLインジェクション / ハードコード秘匿情報 |
| パッケージ | 循環依存 / internalの活用 / go mod tidyの必要性 |
| コメント | Godocコメント(英語) / 「なぜ」の説明 / 古いコメントの残存 |
レポート形式
## レビュー結果: <ファイル名>
### 総評
(1-2文で全体の品質レベルと最も重要な改善点)
### 問題点
- **[重大]** 〜(即座に修正すべき問題)
- **[推奨]** 〜(品質向上のための改善提案)
- **[軽微]** 〜(あれば望ましい程度の指摘)
### 静的解析結果
(go vet / staticcheck を実行した場合のみ)
### 良い点
(規約に準拠している箇所、工夫されている箇所)
Mode 3: リファクタリング
既存Goコードをリファレンスの規約に沿って書き直す。
手順
- 対象の読込: 現在のコードを読み込み、機能と意図を把握する
- リファレンス読込:
references/go-practices.mdを読み込む - 差分分析: 現在の実装とリファレンス規約のギャップを洗い出す
- リファクタ計画の提示: 変更内容を箇条書きで提示し、ユーザーの承認を得る
- 実装: 承認を得た範囲でリファクタリングを実施
- 検証:
go vet/ テスト実行をサブエージェントに委譲し、既存の動作が維持されていることを確認する。出力が少量に収まる小規模なリファクタでは、委譲せずメインで直接実行してよい
リファクタリングの優先順位
- エラーハンドリング(エラー無視の解消、
%wによるラップ) - 並行処理の安全性(race condition、goroutineリーク)
- セキュリティ(入力バリデーション、SQLインジェクション防止)
- 関数設計(単一責任への分割、引数の整理)
- 命名規則・コーディングスタイル
- パフォーマンス(不要なアロケーション、strings.Builder)
機能変更は行わない。動作が変わる可能性がある場合は明示的に警告する。
Mode 4: 技術相談
Go言語に関する技術質問に回答する。
対応範囲
- 言語機能(generics、型アサーション、型スイッチ、埋め込み等)
- 並行処理パターン(goroutine、channel、select、context、errgroup)
- エラー設計(sentinel error、カスタムエラー型、errors.Is/As)
- テストパターン(テーブル駆動、サブテスト、モック、httptest)
- パッケージ設計(internal、依存関係、循環依存の解消)
- パフォーマンス(pprof、ベンチマーク、メモリアロケーション)
- ツールチェーン(go mod、go generate、go build タグ)
- Go 1.22+のループ変数セマンティクス
回答方針
- 具体的なコード例を含める
- 「なぜそうすべきか」の理由を簡潔に添える
- 落とし穴や注意点があれば明示する
- リファレンスの規約に関連する場合はその旨を伝える
共通の品質基準
すべてのモードで以下を基準とする:
静的解析の活用
利用可能なツールを積極的に使う。プロジェクト全体(./...)への実行は出力が大きくなりやすいため、サブエージェントに委譲し、メインには指摘の要約だけを戻させるとよい:
go vet ./...
staticcheck ./...
gosec が利用可能な場合はセキュリティチェックにも使用:
gosec ./...
テスト用のダミー値など明らかに問題が無い箇所についてのみ // #nosec コメントの使用を許可する。
テスト実行
コード変更後は以下のオプションでテストを実行する。実行自体はサブエージェントに委譲し、メインには合否と失敗の要点だけを戻させ、修正はメインで行う:
go test -shuffle on -race -cover ./...
-shuffle on: テスト順序のランダム化-race: 競合状態の検出-cover: カバレッジの確認
Go Modules管理
- 不要な依存を残さない:
go mod tidyで整理 - 依存バージョンは明示的に管理
go.sumは常にコミットに含める