本文へスキップ
sobolewski.pro今日の AI を毎晩お届け登録する

1日1回。ワンクリックで配信停止できます。 プライバシーポリシー

AIエージェントの作り方【Python】Claude Agent SDK入門

AIエージェントの作り方をPythonで解説。Claude Agent SDKを導入し、コードを自分で読んで直す最初のエージェント、独自ツール、MCPまで順に作ります。

4 分で読めます

この記事の他の言語版:العربيةDeutschEnglishEspañolFrançaisItalianoPolski简体中文

この記事の内容
  1. 開発者から見た AI エージェントとは?
  2. ステップ1: Claude Agent SDK のインストール方法は?
  3. ステップ2: API キーの設定方法は?
  4. ステップ3: 最初の AI エージェントの書き方は?
  5. ステップ4: エージェントが自分でできることをどう決める?
  6. ステップ5: エージェントに独自ツールを持たせるには?
  7. ステップ6: エージェントを MCP サーバーにつなぐには?
  8. 最初のエージェントの次は?
  9. 気をつけたいことは?
  10. FAQ

ループをゼロから書かずに AI エージェントを作るには、どうすればよいのでしょうか。私が知るいちばんの近道は Claude Agent SDK です。Python と TypeScript 向けのライブラリで、Claude Code を動かしているのと同じツール、エージェントループ、コンテキスト管理をそのまま使えます。十数行のコードを書くだけで、エージェントが自分でファイルを読み、バグを直し、コマンドを実行します。

この記事では、AI エージェントの作り方を順に見ていきます。Python で最初のエージェントを作り、権限を設定し、独自ツールと MCP サーバーを追加します。コマンドとコードはすべて Agent SDK の公式クイックスタートと、途中でリンクするドキュメントからのものです。

開発者から見た AI エージェントとは?

ドキュメントによると、エージェントとは次の手順を自分で計画し、ツールを呼び出してタスクをこなすアプリケーションです。ファイルを読む、コマンドを実行する、コードを編集する、といった具合です。コードなしの全体像は AI エージェントとは で解説しました。

開発者にとって大事なのはループです。モデルが考え、ツールを呼び、結果を見て、次に何をするか決める。Agent SDK はこのループ、ツールの実行、コンテキスト管理、リトライを引き受けてくれるので、私たちはメッセージのストリームを読むだけです。

ドキュメントは Claude との付き合い方を4つに分けています。

  1. Agent SDK: Claude Code のエージェントを自分のアプリケーション内で動かすライブラリ(プロセスは自分で管理)
  2. Claude Code CLI: 日々の対話的な作業に使うターミナル(Claude Code チュートリアルで紹介)
  3. Client SDK: Claude API への直接アクセス。ツールのループは自分で書く(またはベータ版の「tool runner」に任せる)
  4. Managed Agents: Anthropic がホストし、API で設定するエージェント

この記事で扱うのは1つ目です。

ステップ1: Claude Agent SDK のインストール方法は?

必要なのは Python 3.10 以上(TypeScript なら Node.js 18.14 以上)と Claude Console のアカウントです。まずプロジェクトのフォルダを作ります。

mkdir my-agent
cd my-agent

エージェントはデフォルトで、このディレクトリとそのサブディレクトリのファイルにアクセスできます。ドキュメントのおすすめはパッケージマネージャーの uv です。

uv init
uv add claude-agent-sdk

通常の pip(macOS と Linux)ならこうなります。

python3 -m venv .venv
source .venv/bin/activate
pip install claude-agent-sdk

面白いことに、Claude Code を別途インストールする必要はたいていありません。どちらの SDK にも Claude Code のネイティブバイナリが同梱されているからです。例外はビルド済みパッケージのないプラットフォームで、たとえば Windows ARM64 です (その場合は Claude Code を手動でインストールすれば、SDK が PATH から見つけます)。

ステップ2: API キーの設定方法は?

キーは Claude Console で作成し、エージェントを実行するターミナルで環境変数として設定します。

export ANTHROPIC_API_KEY=your-api-key

SDK は .env ファイルを自動では読み込みません。キーを .env に置くなら、自分で読み込む必要があります(たとえば dotenv パッケージで)。Anthropic のキーの代わりに Amazon Bedrock、Claude Platform on AWS、Google Cloud、Microsoft Foundry も使えます。対応する変数、たとえば CLAUDE_CODE_USE_BEDROCK=1 を設定するだけです。

ドキュメントの注意点をひとつ。事前の承認なしに、Agent SDK で作った製品が claude.ai アカウントでのログインを提供したり、サブスクリプションの利用枠を使ったりすることを Anthropic は認めていません。エージェントは API キーで動き、トークン分の料金を払います(トークンの追跡方法は Claude API のコストの記事で書きました)。

ステップ3: 最初の AI エージェントの書き方は?

クイックスタートの例は、コードのバグを見つけて直すエージェントです。まず、わざと2つのバグを入れた utils.py を作ります。

def calculate_average(numbers):
    total = 0
    for num in numbers:
        total += num
    return total / len(numbers)


def get_user_name(user):
    return user["name"].upper()

calculate_average([]) はゼロ除算で、get_user_name(None) は TypeError で落ちます。次がエージェント本体の agent.py です。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, ResultMessage


async def main():
    # Agentic loop: streams messages as Claude works
    async for message in query(
        prompt="Review utils.py for bugs that would cause crashes. Fix any issues you find.",
        options=ClaudeAgentOptions(
            allowed_tools=["Read", "Edit", "Glob"],  # Auto-approve these tools
            permission_mode="acceptEdits",  # Auto-approve file edits
        ),
    ):
        # Print human-readable output
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if hasattr(block, "text"):
                    print(block.text)  # Claude's reasoning
                elif hasattr(block, "name"):
                    print(f"Tool: {block.name}")  # Tool being called
        elif isinstance(message, ResultMessage):
            print(f"Done: {message.subtype}")  # Final result


asyncio.run(main())

コードは3つの部分からなります。

  1. query はエージェントループを作り、非同期イテレーターを返します。メッセージは async for で順次読みます。
  2. prompt はタスクです。どのツールを使うかは Claude が自分で決めます。
  3. options は設定です。ここでは allowed_tools が Read、Edit、Glob を事前承認し、permission_mode="acceptEdits" がファイルの変更を自動で受け入れます。

実行します。

uv run agent.py

(有効化した venv なら python agent.py でも OK)。エージェントは考えたことと呼び出したツールを順に表示し、最後に Done: success と出します。終わると utils.py には空のリストやユーザーがいない場合の処理が入っています。エージェントが自分でファイルを読み、境界ケースを見つけ、コードを直したわけです。ツールを扱う関数は1つも書いていません。

Not logged in や Invalid API key が出たら、ほぼ間違いなくそのターミナルで ANTHROPIC_API_KEY が設定されていません。

ステップ4: エージェントが自分でできることをどう決める?

エージェントに何ができるかはツールで決まります。ドキュメントは典型的な組み合わせを3つ挙げています。

  1. Read、Glob、Grep: 分析のみ。ファイルは変更しない
  2. Read、Edit、Glob: 分析とコードの編集
  3. Read、Edit、Bash、Glob、Grep: ターミナルのコマンドも含む完全な自動化

たとえばウェブ検索やテストの実行をさせたいなら、ツールを足してプロンプトを変えるだけです。

options = ClaudeAgentOptions(
    allowed_tools=["Read", "Edit", "Glob", "Bash"], permission_mode="acceptEdits"
)

Bash を有効にした場合、クイックスタートは「Write unit tests for utils.py, run them, and fix any failures」というタスクを提案しています。system_prompt でエージェントに役割を与えることもできます。たとえば PEP 8 を守る経験豊富な Python 開発者です。

もうひとつのレバーが権限モード(permission_mode)です。

  1. "default": 未承認の呼び出しをすべて自分の canUseTool 関数に回し、関数がなければ拒否する
  2. "acceptEdits": ファイルの編集と、作業ディレクトリ内の mkdir や mv のような単純なコマンドを受け入れる
  3. "plan": まずコードを調べて計画を立てさせる
  4. "dontAsk": 一切確認しない。事前承認したものだけが動き、残りは拒否(キーボードの前に人がいないエージェント向き)
  5. "auto": アクションを分類器に通し、1つずつ確認してブロックか許可を決める
  6. "bypassPermissions": 何でも確認なしに実行する。ドキュメントによれば CI やコンテナのような隔離された環境専用

ドキュメントの鉄則は、開発マシンでは "acceptEdits"、"bypassPermissions" はエージェントが大事なものを壊せない場所でだけ、です。なぜ重要なのかは AI エージェントのセキュリティのガイドで説明しています。

上限もすぐに設定しておきましょう。max_turns はターン数を制限し、max_budget_usd は推定コストを超えたところでループを止めます。これがないと、エージェントは自分で終わったと判断するまで動き続けます。「このプロジェクトを改善して」のような終わりのないタスクだと、しばらくかかるかもしれません ;)

ステップ5: エージェントに独自ツールを持たせるには?

組み込みツールはほんの入り口です。独自ツールはデコレーター @tool(名前、説明、入力スキーマ、関数)で定義し、同じプロセス内で動く MCP サーバーに包みます。ドキュメントの例は Open-Meteo API から気温を取得するので、まず httpx ライブラリを追加します。

uv add httpx

ツールの定義です。

from typing import Annotated, Any
import httpx
from claude_agent_sdk import tool, create_sdk_mcp_server


# Define a tool: name, description, input schema, handler
@tool(
    "get_temperature",
    "Get the current temperature at a location",
    {
        "latitude": Annotated[float, "Latitude coordinate"],
        "longitude": Annotated[float, "Longitude coordinate"],
    },
)
async def get_temperature(args: dict[str, Any]) -> dict[str, Any]:
    async with httpx.AsyncClient() as client:
        response = await client.get(
            "https://api.open-meteo.com/v1/forecast",
            params={
                "latitude": args["latitude"],
                "longitude": args["longitude"],
                "current": "temperature_2m",
                "temperature_unit": "fahrenheit",
            },
        )
        data = response.json()

    # Return a content array - Claude sees this as the tool result
    return {
        "content": [
            {
                "type": "text",
                "text": f"Temperature: {data['current']['temperature_2m']}°F",
            }
        ]
    }


# Wrap the tool in an in-process MCP server
weather_server = create_sdk_mcp_server(
    name="weather",
    version="1.0.0",
    tools=[get_temperature],
)

同じファイルで、サーバーをエージェントに渡します。ツールの正式名は mcp__{サーバー}__{ツール} という形式で、これを allowed_tools に書けば許可を求めずに動きます。

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage


async def main():
    options = ClaudeAgentOptions(
        mcp_servers={"weather": weather_server},
        allowed_tools=["mcp__weather__get_temperature"],
    )

    async for message in query(
        prompt="What's the temperature in San Francisco?",
        options=options,
    ):
        # ResultMessage is the final message after all tool calls complete
        if isinstance(message, ResultMessage) and message.subtype == "success":
            print(message.result)


asyncio.run(main())

エージェントは私たちのツールを呼び出し、その結果をもとに答えます。天気の代わりに何でもつなげます。自分のデータベースでも、社内 API でも、スクリプトでも。

ステップ6: エージェントを MCP サーバーにつなぐには?

既製の MCP サーバー(プロトコル自体は MCP とはで解説)は mcp_servers オプションで接続します。ドキュメントの例では、エージェントを HTTP 経由で Claude Code のリモートのドキュメントサーバーにつなぎます。

options = ClaudeAgentOptions(
    mcp_servers={
        "claude-code-docs": {
            "type": "http",
            "url": "https://code.claude.com/docs/mcp",
        }
    },
    allowed_tools=["mcp__claude-code-docs__*"],
)

allowed_tools のアスタリスクは、そのサーバーのツールをすべて承認します。「Use the docs MCP server to explain what hooks are in Claude Code」というプロンプトを渡すと、エージェントはドキュメントを検索して答えを返します。

最初のエージェントの次は?

Agent SDK には Claude Code の残りの機能もそろっています。

  1. フック: ツール呼び出しの前後に実行する自分のコード
  2. サブエージェント: 切り出したサブタスク用
  3. セッション: ResultMessage.session_id の ID で、コンテキストを丸ごと保ったまま会話を再開したり分岐させたりできる
  4. スキル、コマンド、メモリー: Claude Code と同じく .claude/ ディレクトリから読み込まれる

すぐ動くサンプルアプリ(メールアシスタントやリサーチエージェントなど)は claude-agent-sdk-demos リポジトリにあります。

気をつけたいことは?

1つ目はコストです。コンテキストはターンごとに増え、大きなファイルや出力の多いコマンドは一度に数千トークンを消費することがあります。固定部分(システムプロンプト、ツール定義)は自動でキャッシュされますが、それでも max_budget_usd は初日から設定しておくべきです (上限は回答1回分のコストだけ超えることがあるので、余裕を持たせましょう)。

2つ目は権限です。普通のノートパソコンで Bash と bypassPermissions を持たせたエージェントを動かすのは、トラブルを呼び込むようなものです。完全な自動化はコンテナに任せましょう。

3つ目はブランディングです。ドキュメントによると、SDK で作った製品は「Claude Agent」や「 Powered by Claude」のように名乗れますが、「Claude Code」とは名乗れず、Anthropic の製品を装うこともできません。

FAQ

ループをゼロから書かずに AI エージェントを作るには?

いちばん簡単なのは、ループを最初から備えたライブラリ、たとえば Claude Agent SDK を使うことです。claude-agent-sdk をインストールし、ANTHROPIC_API_KEY を設定して、プロンプトと許可するツールのリストを渡して query() を呼びます。ツールの呼び出しやコンテキスト管理といった残りは SDK がやってくれます。

Claude Agent SDK は無料ですか?

ライブラリ自体は無料ですが、エージェントは Claude API を使うので、消費したトークン分の料金がかかります。Anthropic の承認なしに claude.ai のサブスクリプションにつなぐことはできません。

Agent SDK と Claude API の違いは?

通常の Client SDK(Claude API)では、ツールのループを自分で書くか、ベータ版の tool runner を使います。Agent SDK には Claude Code の組み込みツール(ファイルの読み書き、コマンド、ウェブ検索)、権限、セッション、フックが最初から入っています。

TypeScript でもエージェントを書けますか?

書けます。パッケージは @anthropic-ai/claude-agent-sdk で、Node.js 18.14 以上が必要です。ドキュメントの例では、オプション名は Python と同じで、camelCase になるだけです(allowedTools、permissionMode)。

  • AI
  • AIエージェント
  • Claude
  • プログラミング
  • チュートリアル

今日の AI を毎晩お届け

その日の AI の重要ニュースとブログの新着記事を、毎晩お届けします。簡潔に、出典付きで。

1日1回。ワンクリックで配信停止できます。 プライバシーポリシー