
Go で AI エージェントを自作:anthropic-sdk-go 入門
Go で AI エージェントを作る核心は「モデルが tool_use を返したら Go の関数を実行し、tool_result を返して再び呼ぶ」ループです。公式の anthropic-sdk-go(v1.78.0)で、このループを手書きする方法と、beta の Tool Runner に任せる方法の両方を、API をモックしたテスト付きで解説します。

Go で AI エージェントを作る核心は「モデルが tool_use を返したら Go の関数を実行し、tool_result を返して再び呼ぶ」ループです。公式の anthropic-sdk-go(v1.78.0)で、このループを手書きする方法と、beta の Tool Runner に任せる方法の両方を、API をモックしたテスト付きで解説します。
Go で AI エージェントを作るなら、Anthropic 公式の Go SDK(github.com/)でツール呼び出しのループを書くのが基本です。モデルが tool_use を返したら Go の関数を実行し、結果を tool_result として送り返す。これを、モデルがツールを使わずに答えるまで繰り返します1。
この記事では、作業ディレクトリのファイルを読んで質問に答える小さなエージェントを作ります。ループを自分で書く方法と、SDK の Tool Runner(beta)に任せる方法の両方を、API をモックしたテストで確かめます。コードはすべて Go 1.26.2・SDK v1.78.0 で go build・go vet・go test を通したものです(2026 年 10 月 5 日時点)。
AI エージェントとは、モデルが自分で道具(ツール)を選んで使い、結果を見て次の行動を決めるプログラムです。Claude API では、この「道具を使う」部分を tool use(ツール呼び出し)と呼びます。

1 回のループで起きることは次の 4 つです1。
tools にツールの定義(名前・説明・入力の JSON スキーマ)を付けて Messages API を呼ぶstop_reason が tool_use になり、content に tool_use ブロック(id・name・input)が入るrole: user のメッセージに tool_result ブロック(tool_use_id と結果)を入れて送り返すstop_reason が tool_use 以外(end_turn など)になったら、最後の文章が答えポイントは、ツールを実行するのは自分のプログラムだということです。モデルは「この引数でこのツールを呼んでほしい」と頼むだけです。何を許し、何を止めるかは Go の側で決められます。
Go の AI エージェント向けの道具が、2026 年に入って一通りそろったからです。
ModelClaudeOpus5_5 など)も入っています2| 回答 | 割合(%) |
|---|---|
| 主にエージェントとして使う | 17 |
| ときどき使う | 23 |
| まれに使う | 17 |
| エージェントは使わない | 41 |
| 分からない | 2 |
Google トレンド(日本・過去 90 日、2026-10-05 取得)の相対値でも、「Go言語」は直近 4 週の平均が 2.0、その前の 8 週の平均が 0.3 でした。値は小さいものの上向きです5。Go は単一バイナリで配れて並行処理が書きやすいので、社内ツールやバッチとしてエージェントを動かす用途に向いています。
SDK は go get で入れます。README によると Go 1.24 以降が必要です2。
mkdir read-agent && cd read-agent
go mod init example.com/read-agent
go get github.com/anthropics/anthropic-sdk-go@v1.78.0
export ANTHROPIC_API_KEY=sk-ant-... # anthropic.NewClient() が環境変数から読む
モデルは、2026 年 10 月時点の公式ドキュメントでは次の 4 つが現行です6。SDK には同じ ID の定数があります。
| モデル | API のモデル ID | SDK の定数 | 入力 / 出力(100 万トークンあたり) |
|---|---|---|---|
| Claude Fable 5.1 | claude-fable-5-1 | anthropic.ModelClaudeFable5_1 | $10 / $50 |
| Claude Opus 5.5 | claude-opus-5-5 | anthropic.ModelClaudeOpus5_5 | $4 / $20 |
| Claude Sonnet 5.5 | claude-sonnet-5-5 | anthropic.ModelClaudeSonnet5_5 | $2 / $10 |
| Claude Haiku 4.5 | claude-haiku-4-5-20251001 | anthropic.ModelClaudeHaiku4_5_20251001 | $1 / $5 |
| モデル | 入力(ドル) | 出力(ドル) |
|---|---|---|
| Fable 5.1 | 10 | 50 |
| Opus 5.5 | 4 | 20 |
| Sonnet 5.5 | 2 | 10 |
| Haiku 4.5 | 1 | 5 |
ツール呼び出しのループは API を何度も呼ぶので、入力トークンが積み上がります。公式は迷ったら Opus 5.5 から始めるよう勧めていますが6、この記事の例のように手順が単純なエージェントなら、料金が半分の Sonnet 5.5 で試し、足りなければ Opus 5.5 に上げる順でもよいでしょう。モデルの違いは Claude Opus 5.5 と Sonnet 5.5 の使い分け で詳しく比べています。
まずは SDK のヘルパーに頼らず、ループを自分で書きます。仕組みが分かると、承認を挟む・ログを取るなどの調整がしやすくなります。
ツールは「モデルに渡す定義(anthropic.ToolParam)」と「Go で実行する関数」の組にします。今回はファイル一覧と読み取りの 2 つだけで、書き込みはさせません。safeJoin で作業ディレクトリの外を読めないようにしています。
// tools.go
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/anthropics/anthropic-sdk-go"
)
// Tool は、モデルに渡す定義と、Go で実行する関数の組です。
type Tool struct {
Param anthropic.ToolParam
Run func(input json.RawMessage) (string, error)
}
// fileTools は root 以下だけを読める 2 つのツールを返します(書き込みはしない)。
func fileTools(root string) []Tool {
return []Tool{
{
Param: anthropic.ToolParam{
Name: "list_files",
Description: anthropic.String("ディレクトリ内のファイル名を一覧する。path は作業ディレクトリからの相対パス。"),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"path": map[string]any{"type": "string", "description": "相対パス。省略時は ."},
},
},
},
Run: func(input json.RawMessage) (string, error) {
var in struct {
Path string `json:"path"`
}
if err := json.Unmarshal(input, &in); err != nil {
return "", err
}
dir, err := safeJoin(root, in.Path)
if err != nil {
return "", err
}
entries, err := os.ReadDir(dir)
if err != nil {
return "", err
}
var names []string
for _, e := range entries {
name := e.Name()
if e.IsDir() {
name += "/"
}
names = append(names, name)
}
return strings.Join(names, "\n"), nil
},
},
{
Param: anthropic.ToolParam{
Name: "read_file",
Description: anthropic.String("テキストファイルの中身を返す。path は作業ディレクトリからの相対パス。"),
InputSchema: anthropic.ToolInputSchemaParam{
Properties: map[string]any{
"path": map[string]any{"type": "string", "description": "読むファイルの相対パス"},
},
Required: []string{"path"},
},
},
Run: func(input json.RawMessage) (string, error) {
var in struct {
Path string `json:"path"`
}
if err := json.Unmarshal(input, &in); err != nil {
return "", err
}
p, err := safeJoin(root, in.Path)
if err != nil {
return "", err
}
b, err := os.ReadFile(p)
if err != nil {
return "", err
}
const max = 20_000 // 大きなファイルでコンテキストを使い切らないように切る
if len(b) > max {
b = b[:max]
}
return string(b), nil
},
},
}
}
// safeJoin は root の外(../ や絶対パス)を指すパスを拒否します。
func safeJoin(root, rel string) (string, error) {
if rel == "" {
rel = "."
}
if filepath.IsAbs(rel) {
return "", fmt.Errorf("絶対パスは使えません: %s", rel)
}
p := filepath.Join(root, rel)
r, err := filepath.Rel(root, p)
if err != nil || r == ".." || strings.HasPrefix(r, ".."+string(filepath.Separator)) {
return "", fmt.Errorf("作業ディレクトリの外は読めません: %s", rel)
}
return p, nil
}
説明文(Description)は、モデルがツールを選ぶいちばんの手がかりです。公式ドキュメントも、何をするか・いつ使うか・引数の意味を 3〜4 文以上で書くよう勧めています7。
Messages.New を呼び、StopReason が tool_use の間はツールを実行して結果を返し続けます。
// agent.go
package main
import (
"context"
"errors"
"fmt"
"github.com/anthropics/anthropic-sdk-go"
)
// Agent はツール呼び出しのループを回します。
type Agent struct {
Client anthropic.Client
Model anthropic.Model
Tools []Tool
MaxTurns int // API を呼ぶ上限(無限ループ防止)
OnTool func(name, input, result string) // ログ用(nil 可)
}
// Run は prompt を送り、モデルがツールを使い終えるまで繰り返して最後の文章を返します。
func (a *Agent) Run(ctx context.Context, prompt string) (string, error) {
byName := map[string]Tool{}
var toolParams []anthropic.ToolUnionParam
for _, t := range a.Tools {
byName[t.Param.Name] = t
toolParams = append(toolParams, anthropic.ToolUnionParam{OfTool: &t.Param})
}
messages := []anthropic.MessageParam{
anthropic.NewUserMessage(anthropic.NewTextBlock(prompt)),
}
for turn := 0; turn < a.MaxTurns; turn++ {
msg, err := a.Client.Messages.New(ctx, anthropic.MessageNewParams{
Model: a.Model,
MaxTokens: 4096,
Tools: toolParams,
Messages: messages,
})
if err != nil {
return "", fmt.Errorf("messages.new: %w", err)
}
// アシスタントの返答(tool_use を含む)をそのまま履歴に積む
messages = append(messages, msg.ToParam())
if msg.StopReason != anthropic.StopReasonToolUse {
return textOf(msg), nil
}
// tool_use ブロックをすべて実行し、結果を 1 つの user メッセージにまとめて返す
var results []anthropic.ContentBlockParamUnion
for _, block := range msg.Content {
use, ok := block.AsAny().(anthropic.ToolUseBlock)
if !ok {
continue
}
out, isErr := a.call(byName, use)
if a.OnTool != nil {
a.OnTool(use.Name, string(use.Input), out)
}
results = append(results, anthropic.NewToolResultBlock(use.ID, out, isErr))
}
messages = append(messages, anthropic.NewUserMessage(results...))
}
return "", errors.New("MaxTurns に達しました")
}
// call はツールを実行します。失敗はエラー文字列として is_error 付きでモデルに返し、ループは止めません。
func (a *Agent) call(byName map[string]Tool, use anthropic.ToolUseBlock) (string, bool) {
t, ok := byName[use.Name]
if !ok {
return "unknown tool: " + use.Name, true
}
out, err := t.Run(use.Input)
if err != nil {
return err.Error(), true
}
return out, false
}
func textOf(msg *anthropic.Message) string {
var s string
for _, block := range msg.Content {
if t, ok := block.AsAny().(anthropic.TextBlock); ok {
s += t.Text
}
}
return s
}
押さえておきたい点は 3 つです。
msg.ToParam() で tool_use ブロックごと戻します。tool_result は、対応する tool_use の直後のメッセージに置く決まりです1tool_result はメッセージの先頭に並べ、文章を足すならその後ろに置きます1is_error で返してループを止めない: エラー文を読んだモデルが、引数を直して呼び直せます1// main.go
// read-agent は、カレントディレクトリのファイルを読んで質問に答える小さなエージェントです。
package main
import (
"context"
"fmt"
"log"
"os"
"strings"
"github.com/anthropics/anthropic-sdk-go"
)
func main() {
if len(os.Args) < 2 {
log.Fatal("使い方: read-agent \"質問\"")
}
root, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
agent := &Agent{
Client: anthropic.NewClient(), // ANTHROPIC_API_KEY を環境変数から読む
Model: anthropic.ModelClaudeSonnet5_5,
Tools: fileTools(root),
MaxTurns: 10,
OnTool: func(name, input, _ string) {
fmt.Fprintf(os.Stderr, "→ %s %s\n", name, input)
},
}
answer, err := agent.Run(context.Background(), strings.Join(os.Args[1:], " "))
if err != nil {
log.Fatal(err)
}
fmt.Println(answer)
}
go vet ./...
go build -o read-agent .
./read-agent "このディレクトリの go.mod を読んで、使っている SDK のバージョンを教えて"
ツールが呼ばれるたびに、標準エラーに → read_file {"path":"go.mod"} のような行が出ます。なお筆者は API キーを使った実行はしておらず、動作は次の節のモックテストで確かめています。
エージェントのテストで実 API を呼ぶと、遅く・費用がかかり・結果も毎回変わります。anthropic-sdk-go は option.WithBaseURL で接続先を変えられるので8、net/ の偽サーバーに向ければ、API キー無しで決まった応答を返せます。
// agent_test.go
package main
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"github.com/anthropics/anthropic-sdk-go"
"github.com/anthropics/anthropic-sdk-go/option"
)
// fakeAPI は /v1/messages に、用意した応答を順に返すテスト用サーバーです。
// 受け取ったリクエストの本文も記録します。
func fakeAPI(t *testing.T, responses ...string) (*httptest.Server, *[]string) {
t.Helper()
var bodies []string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/v1/messages" {
t.Errorf("unexpected path %s", r.URL.Path)
}
b, _ := io.ReadAll(r.Body)
bodies = append(bodies, string(b))
if len(bodies) > len(responses) {
t.Fatalf("API が %d 回呼ばれた(想定は %d 回)", len(bodies), len(responses))
}
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, responses[len(bodies)-1])
}))
t.Cleanup(srv.Close)
return srv, &bodies
}
const toolUseResponse = `{
"id": "msg_1", "type": "message", "role": "assistant", "model": "claude-sonnet-5-5",
"stop_reason": "tool_use",
"content": [
{"type": "text", "text": "go.mod を読みます。"},
{"type": "tool_use", "id": "toolu_1", "name": "read_file", "input": {"path": "go.mod"}}
],
"usage": {"input_tokens": 10, "output_tokens": 10}
}`
const finalResponse = `{
"id": "msg_2", "type": "message", "role": "assistant", "model": "claude-sonnet-5-5",
"stop_reason": "end_turn",
"content": [{"type": "text", "text": "モジュール名は example.com/demo です。"}],
"usage": {"input_tokens": 20, "output_tokens": 10}
}`
func TestAgentRunsToolAndReturnsAnswer(t *testing.T) {
root := t.TempDir()
os.WriteFile(filepath.Join(root, "go.mod"), []byte("module example.com/demo\n"), 0o644)
srv, bodies := fakeAPI(t, toolUseResponse, finalResponse)
agent := &Agent{
Client: anthropic.NewClient(
option.WithBaseURL(srv.URL),
option.WithAPIKey("test-key"),
option.WithMaxRetries(0),
),
Model: anthropic.ModelClaudeSonnet5_5,
Tools: fileTools(root),
MaxTurns: 5,
}
got, err := agent.Run(context.Background(), "このモジュールの名前は?")
if err != nil {
t.Fatal(err)
}
if got != "モジュール名は example.com/demo です。" {
t.Errorf("answer = %q", got)
}
if len(*bodies) != 2 {
t.Fatalf("API 呼び出し = %d 回, want 2", len(*bodies))
}
// 2 回目のリクエストに、ツールの実行結果(go.mod の中身)が tool_result として入っている
var req struct {
Messages []struct {
Role string `json:"role"`
Content []json.RawMessage `json:"content"`
} `json:"messages"`
}
if err := json.Unmarshal([]byte((*bodies)[1]), &req); err != nil {
t.Fatal(err)
}
last := req.Messages[len(req.Messages)-1]
if last.Role != "user" || !strings.Contains(string(last.Content[0]), `"tool_use_id":"toolu_1"`) ||
!strings.Contains(string(last.Content[0]), "module example.com/demo") {
t.Errorf("tool_result が送られていない: %s", last.Content[0])
}
}
func TestAgentStopsAtMaxTurns(t *testing.T) {
root := t.TempDir()
os.WriteFile(filepath.Join(root, "go.mod"), []byte("module x\n"), 0o644)
srv, _ := fakeAPI(t, toolUseResponse, toolUseResponse)
agent := &Agent{
Client: anthropic.NewClient(option.WithBaseURL(srv.URL), option.WithAPIKey("k"), option.WithMaxRetries(0)),
Model: anthropic.ModelClaudeSonnet5_5,
Tools: fileTools(root),
MaxTurns: 2,
}
if _, err := agent.Run(context.Background(), "q"); err == nil {
t.Error("MaxTurns を超えてもエラーにならない")
}
}
func TestSafeJoin(t *testing.T) {
tests := []struct {
rel string
wantErr bool
}{
{"go.mod", false},
{"", false},
{"sub/a.go", false},
{"../secret", true},
{"sub/../../secret", true},
{"/etc/passwd", true},
}
for _, tt := range tests {
_, err := safeJoin("/work", tt.rel)
if (err != nil) != tt.wantErr {
t.Errorf("safeJoin(%q) err = %v, wantErr %v", tt.rel, err, tt.wantErr)
}
}
}
1 つ目のテストは、偽 API が「read_file を呼びたい」→「答え」の順に返したとき、次の 3 点を確かめます。
go.mod の中身が tool_result として入る2 つ目は上限で止まること、3 つ目は作業ディレクトリの外を読めないことのテーブル駆動テストです。

option.WithMaxRetries(0) を付けているのは、偽サーバーの応答が想定外だったときに SDK の自動リトライでテストが長引かないようにするためです。
ループを毎回書くのが面倒なら、SDK の Tool Runner(beta)が使えます。toolrunner.NewBetaToolFromJSONSchema に構造体と関数を渡すと、jsonschema タグから入力スキーマが作られます9。RunToCompletion は、モデルがツールを使い終えるまでループを回します。
// runner/main.go
// Tool Runner(beta)を使って、ループを SDK に任せる版です。
package main
import (
"context"
"fmt"
"log"
"os"
"github.com/anthropics/anthropic-sdk-go"
"github.com/anthropics/anthropic-sdk-go/toolrunner"
)
// ReadFileInput の jsonschema タグから、ツールの入力スキーマが作られます。
type ReadFileInput struct {
Path string `json:"path" jsonschema:"required,description=読むファイルの相対パス"`
}
func newTools() ([]anthropic.BetaTool, error) {
readFile, err := toolrunner.NewBetaToolFromJSONSchema(
"read_file",
"テキストファイルの中身を返す",
func(ctx context.Context, in ReadFileInput) (anthropic.BetaToolResultBlockParamContentUnion, error) {
b, err := os.ReadFile(in.Path) // 実際には safeJoin のような制限を入れる
if err != nil {
return anthropic.BetaToolResultBlockParamContentUnion{}, err // is_error: true で返る
}
return anthropic.BetaToolResultBlockParamContentUnion{
OfText: &anthropic.BetaTextBlockParam{Text: string(b)},
}, nil
},
)
if err != nil {
return nil, err
}
return []anthropic.BetaTool{readFile}, nil
}
func run(ctx context.Context, client anthropic.Client, prompt string) (string, error) {
tools, err := newTools()
if err != nil {
return "", err
}
runner := client.Beta.Messages.NewToolRunner(tools, anthropic.BetaToolRunnerParams{
BetaMessageNewParams: anthropic.BetaMessageNewParams{
Model: anthropic.ModelClaudeSonnet5_5,
MaxTokens: 4096,
Messages: []anthropic.BetaMessageParam{
anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(prompt)),
},
},
MaxIterations: 10, // 0 は無制限なので必ず上限を付ける
})
msg, err := runner.RunToCompletion(ctx)
if err != nil {
return "", err
}
var text string
for _, block := range msg.Content {
if t, ok := block.AsAny().(anthropic.BetaTextBlock); ok {
text += t.Text
}
}
return text, nil
}
func main() {
answer, err := run(context.Background(), anthropic.NewClient(), "go.mod を読んで、モジュール名を教えて")
if err != nil {
log.Fatal(err)
}
fmt.Println(answer)
}
この版も、同じように httptest の偽 API でテストを通しています(go test ./ が PASS)。Tool Runner は、1 回の応答で複数のツールが呼ばれると errgroup で並列に実行します9。
手書きのループと Tool Runner は、次のように使い分けます。公式ドキュメントも、人の承認・独自のログ・条件付きの実行が必要なら手書きのループを勧めています3。
| 観点 | 手書きのループ | Tool Runner(beta) |
|---|---|---|
| コード量 | 多い(履歴・結果の組み立てを自分で書く) | 少ない |
| ツール実行前の承認・拒否 | ループの中で自由に挟める | ツールの関数の中で書く |
| ツールのエラーの扱い | 自由に整形できる | Go 版は送信前に差し替える仕組みがない。関数の中で処理する3 |
| 複数ツールの並列実行 | 自分で書く | errgroup で並列に実行9 |
| API の種類 | 通常の Messages API | beta の Messages API |
| 向いている用途 | 本番の業務ツール・監査が要るもの | 試作・社内の小さなエージェント |
Go でツール呼び出しのループを書くときに、よく引っかかる点をまとめます。
| 症状・リスク | 原因 | 対処 |
|---|---|---|
tool_choice を指定したら 400 エラー | Opus 5.5・Sonnet 5.5・Fable 5.1 は、ツールを強制する any・tool に対応していない7 | auto(既定)のまま、プロンプトでツールを使うよう指示する。入力の形を保証したいなら strict: true |
| 「tool_use ids were found without tool_result blocks」 | tool_result の前に別のメッセージや文章を入れた | アシスタントの返答の直後に、tool_result を先頭に並べた user メッセージを送る1 |
| ループが終わらない・費用が膨らむ | 上限を付けていない | 手書きなら MaxTurns、Tool Runner なら MaxIterations(0 は無制限)を必ず付ける9 |
| 途中で答えが切れる | stop_reason が max_tokens | MaxTokens を増やすか、処理を分ける。手書きのループでは tool_use 以外の停止をすべて「終わり」と扱っているので、必要なら分けて扱う |
| ツールの失敗理由が分からない | Go の SDK は環境変数 ANTHROPIC_LOG を読まない3 | ツールの関数の中でエラーをログに出してから返す(この記事では OnTool で記録) |
| 読んだファイルに「指示」が書かれていた | 間接プロンプトインジェクション | ツールの結果は信頼しない前提で扱い、書き込み系のツールは承認を挟む1 |
特に最後の点は重要です。公式ドキュメントも、Web ページやメール、ユーザーのアップロードなど外から来た内容は信頼できないものとして扱い、tool_result の中に閉じ込めるよう注意しています1。読み取り専用のツールから始め、書き込みや外部送信のツールを足すときは、手書きのループで「実行前に人が確認する」段階を入れるのが安全です。
tool_use を受けて Go の関数を実行し、tool_result を返す」ループMessages.New・msg.ToParam()・NewToolResultBlock の 3 つでループが書けるoption.WithBaseURL と httptest で API をモックすれば、キー無しでループのテストが書けるclaude-sonnet-5-5 や claude-opus-5-5 を定数で指定し、ツールの強制(tool_choice: any)は使わない次の一歩として、作ったツールを MCP サーバーにすれば Claude Code からも使えます。手順は Go で MCP サーバーを作る:公式 Go SDK 入門 で解説しています。Claude Code に Go を書かせるコツは Go 言語と AI エージェントの相性 にまとめました。
2026 年 10 月時点で Tool Runner は beta です3。beta の API は変わる可能性があるので、本番では SDK のバージョンを固定し、更新時に変更履歴を確かめてください。承認や監査ログが必要な業務では、手書きのループのほうが制御しやすいです。
Tool Runner を使うなら、構造体の jsonschema タグから作るのが楽で、Go の型と JSON スキーマのずれも起きません9。手書きのループでも、この記事のように map[string]any で書けます。ツールが増えてきたら、構造体から作る方式にそろえると保守しやすくなります。
content に複数の tool_use ブロックが入ります。すべて実行し、結果の tool_result を 1 つの user メッセージにまとめて返します1。この記事の Agent.Run は順番に実行していますが、Tool Runner は並列に実行します9。
option.WithBaseURL で SDK の接続先を httptest の偽サーバーに向けると、決まった応答を返せます。この記事のテストのように、tool_use を返す応答と最終回答の応答を順に用意すれば、ループ・ツールの実行・履歴の組み立てまでをキー無しで確かめられます。
考え方(ツールを定義し、呼び出しを実行して結果を返すループ)は共通です。ただし、メッセージの形やフィールド名は各社の API で違います。この記事のコードは Claude API 専用です。
Handle tool calls — Anthropic, 公開日不明(2026-10-05 参照) ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9
anthropics/anthropic-sdk-go(README・リリース v1.78.0) — Anthropic, 2026-09-30(2026-10-05 参照) ↩ ↩2
Tool runner (SDK) — Anthropic, 公開日不明(2026-10-05 参照) ↩ ↩2 ↩3 ↩4 ↩5
Results from the 2025 Go Developer Survey — The Go Blog(Todd Kulesza), 2026-01-21(2026-10-05 参照) ↩
Google トレンド「Go言語」(日本・過去 90 日) — Google, 2026-10-05 取得の相対値(2026-10-05 参照) ↩
Models overview — Anthropic, 公開日不明(2026-10-05 参照) ↩ ↩2
Define tools — Anthropic, 公開日不明(2026-10-05 参照) ↩ ↩2
Package option(anthropic-sdk-go) — Anthropic, v1.78.0 時点(2026-10-05 参照) ↩
Tool Helpers(tools.md) — Anthropic, v1.78.0 時点(2026-10-05 参照) ↩ ↩2 ↩3 ↩4 ↩5 ↩6