Go 言語は、Claude Code のような AI エージェントが「書く→確かめる→直す」を回しやすい言語です。型のエラー・go vet・gofmt・go test が標準でそろい、失敗が機械的に読めるからです。一方で、学習後に出た新機能や新しい書き方には弱く、go fix などで補う必要があります。実行結果・CLAUDE.md の設定例・実践手順で解説します。
Go 言語は、Claude Code のような AI エージェントにとって書きやすく、確かめやすい言語です。型の誤りはコンパイラが、怪しい書き方は go vet が、書式の揺れは gofmt が、動作の誤りは go test が、どれも標準のコマンドで機械的に教えてくれます。エージェントは「書く→確かめる→直す」のループを、人の手を借りずに回せます。
一方で苦手な点もあります。モデルの学習後に出た新機能や新しい書き方を知らず、古い書き方をしがちです。この記事では、筆者が 2026 年 10 月 5 日に実際に動かした go vet・go test・Claude Code の出力を根拠に、相性の良い点と悪い点、CLAUDE.md や hooks の Go 向け設定例、実践の手順をまとめます。
go vet は、Printf の書式と引数の型が合わないなど、コンパイルは通るが怪しい書き方を見つけます。さらに go test は、テストの前に go vet の確度の高いチェック(printf など)を自動で実行し、問題があればテストを走らせません2。
$ go test ./...
# example.com/greet# [example.com/greet]
./greet.go:6:29: fmt.Sprintf format %d has arg name of wrong type string
FAIL example.com/greet [build failed]
つまり CLAUDE.md に「go test ./... を通してから終える」と 1 行書くだけで、テストと主要な静的解析の両方が効きます。テストの書き方も標準の testing パッケージ 1 つなので、フレームワーク選びで AI が迷いません。
Go では、失敗しうる関数は error を戻り値で返し、呼び出し側が if err != nil で扱います。例外のように見えない経路で処理が飛ばないので、AI が書いたコードを人がレビューするとき、失敗時の流れを上から順に読めます。冗長に見える書き方ですが、生成とレビューの両方で「どこで失敗が扱われているか」が明確になります。
HTTP サーバー・JSON・テストなど、多くの機能が標準ライブラリにあります。AI が知らない外部ライブラリの API を推測で書く場面が減ります。また Go には「Go 1 の仕様で書いたプログラムは、仕様が続く限りそのまま動く」という互換性の約束があり、古い知識で書かれたコードでも、動かなくなることは起きにくい言語です。
実際に、上の %d の誤りを入れたコードを Claude Code に直させました。CLAUDE.md には「go test ./... と go vet ./... を通してから終える」とだけ書き、ヘッドレス実行(claude -p)で頼んでいます。
claude -p "go test が落ちています。原因を調べて直してください" \
--allowedTools "Read""Edit""Bash(go test *)""Bash(go vet *)""Bash(gofmt *)" \
--model sonnet --output-format stream-json --verbose
Claude Code が go test を実行して失敗を読み、greet.go の %d を %s に直してから go test・go vet・gofmt を通すまでのツール呼び出し筆者の環境(Claude Code 2.1.289・--model sonnet)で実行した出力。ツール呼び出しは stream-json 出力から抜き出したもの
stream-json の記録では、Claude Code は次の順に動きました。
go test ./... を実行して失敗を読む
greet.go と greet_test.go を読む
%d を %s に直す
go test ./... && go vet ./... && gofmt -l . で確かめる
最後に「go vet のチェックが go test の中でも走るため、テストが実行される前にビルド失敗になっていた」と、原因まで正しく説明しています。この例は 6 ターン・約 17 秒で終わり、Claude Code が表示した費用の目安は約 0.12 ドルでした(小さな例 1 回の値で、規模や条件で変わります)。
古い書き方への対策として、Go チームは go fix を作り直しました。Go 1.26 で go fix は解析フレームワークの上に書き直され、数十の「モダナイザー」(新しい書き方に直す修正)が入っています3。筆者の環境(Go 1.26.2)で、AI が書きがちな古い書き方のコードに go fix -diff を実行した結果の一部です。
- for _, x := range xs {- if x == target {- return true- }- }- return false+ return slices.Contains(xs, target)-func Repeat(n int) []interface{} {- var out []interface{}- for i := 0; i < n; i++ {+func Repeat(n int) []any {+ var out []any+ for i := range n {- i := strings.Index(s, "=")+ before, _, ok := strings.Cut(s, "=")
ループは slices.Contains に、interface{} は any に、3 つの式の for 文は range n に、strings.Index での切り出しは strings.Cut に直りました。AI に書かせたあと go fix ./... をかけ、差分を確かめてからコミットする流れにすると、古い書き方が残りにくくなります。
go fix -diff を実行し、古い for ループや interface{}、strings.Index が slices.Contains・any・range n・strings.Cut に置き換わる差分筆者の環境(macOS・Go 1.26.2)で実行した出力の抜粋