Anthropic のコードの 90% は Claude エージェントによって書かれています。 エンジニアがチャットウィンドウに入力するのではなく、自律エージェントがループを実行し、ツールを呼び出し、チームが寝ている間にコードを出荷しています。
最新の AI 情報を入手するには、私の Substack をフォローしてください:
これが正確なセットアップです。ステップバイステップで。最初の API 呼び出しから、任意のタスクに向けられる動作するエージェントまで。
この記事では以下をカバーします:
1 - ほとんどの人が作る「エージェント」が実際にはエージェントではない理由
2 - 動作するエージェントに必要な 5 つのパーツ
3 - Claude を使って各パーツをコードで構築する方法
4 - エージェントが出荷前に壊れてしまうミス
ブックマークしてください。以下のすべてのコードブロックは動作します。
01. ほとんどの「AI エージェント」はエージェントではない
私は数え切れないほどのエージェントを構築し、壊してきました。彼らが夜通しトークンを燃やし、何も生み出さないのを見てきました。同じファイルを 30 回も書き換えるのを見てきました。テストを削除することで自分のテストに合格するのを見てきました。

すべての失敗が同じ教訓を教えてくれました:モデルが問題なのではありません。その周りのアーキテクチャが問題なのです。このガイドは、私が学んだすべてを、あなたに提供できる最短のパスに凝縮したものです。
ほとんどの人が「AI エージェント」と言うときに作るものはこれです:
1while True:2 user_input = input("> ")3 response = call_claude(user_input)4 print(response)
それはチャットボットです。あなたを待ちます。あなたの言うことをします。セッション間ですべてを忘れます。タブを閉じれば停止します。
エージェントとは、あなたが目の前に座っていなくても、目標に向かって動作するシステムです。何をする必要があるかを発見し、計画を立て、実行し、結果を確認し、まだ完了していなければ再試行します。あなたが方向性を設定します。エージェントが作業を行います。
「Claude Code は、数ヶ月でゼロから 4 億ドルの収益に成長しました。ハッカソンプロジェクトとして始まりました。今でもパブリック API のみを使用しています。」 -
Boris Cherny、Claude Code 責任者
あなたが今すぐアクセスできるのと同じ API です。同じモデルです。違いはモデルの周りのアーキテクチャです。

02. 本物のエージェントの 5 つのパーツ
動作するすべてのエージェント(Claude Code、Devin、Codex、または自分で構築するもの)は、5 つのパーツから構成されています。1 つ欠けると壊れます。

03. API レイヤー
すべてはここから始まります。Claude を呼び出し、Claude が応答します。しかし、呼び出し方によって、チャットボットになるかエージェントになるかが決まります。

重要なのは 3 つです:システムプロンプト、構造化出力、そして温度です。
システムプロンプトは挨拶ではありません。それはエージェントの運用マニュアルです。すべてのルール、制約、動作はここに入ります。これがないと、Claude はあなたが何を望んでいるかを推測します。これがあれば、Claude はあなたの仕様に従います。
1import anthropic23client = anthropic.Anthropic()45response = client.messages.create(6 model="claude-sonnet-4-6",7 max_tokens=4096,8 system="""あなたはコードレビューエージェントです。910ルール:11- コメントする前に差分全体を読んでください12- スタイルの好みではなく、実際のバグのみをフラグしてください13- 問題がなければ、"LGTM" と言って停止してください14- 頭の中でテストしていない変更を提案しないでください15- 出力形式: {file, line, issue, fix} の JSON 配列""",16 messages=[{"role": "user", "content": diff_content}]17)
構造化出力により、エージェントの応答が機械可読になります。Claude が自由テキストを返す場合、コードでそれを解析する必要があります。Claude が JSON を返す場合、コードはそれを直接使用できます。
1# 正確な形状を Claude に伝えることで JSON 出力を強制2system = """有効な JSON のみを返してください。Markdown は不要です。説明は不要です。3スキーマ:4{5 "status": "pass" | "fail",6 "issues": [{"file": str, "line": int, "issue": str}],7 "summary": str8}"""
温度。 決定論的なエージェントには 0 に設定します。クリエイティブな作業には 0.3〜0.5 に設定します。デフォルト(1.0)は、エージェントではほとんど必要としないランダム性を追加します。
04. ツール
ツールのないモデルは推論できても行動できません。どのファイルを編集すべきか教えることはできても、編集することはできません。クエリを説明することはできても、実行することはできません。

Claude のツール使用機能により、モデルが呼び出せる関数を定義できます。関数を説明します。Claude がそれを呼び出すタイミングを決定します。あなたが実行して結果を返します。Claude は結果を使用して推論を続けます。
1tools = [{2 "name": "run_sql",3 "description": "データベースに対して読み取り専用の SQL クエリを実行します",4 "input_schema": {5 "type": "object",6 "properties": {7 "query": {8 "type": "string",9 "description": "実行する SQL SELECT クエリ"10 }11 },12 "required": ["query"]13 }14},15{16 "name": "write_file",17 "description": "ディスク上のファイルにコンテンツを書き込みます",18 "input_schema": {19 "type": "object",20 "properties": {21 "path": {"type": "string"},22 "content": {"type": "string"}23 },24 "required": ["path", "content"]25 }26}]
ツールの説明は、あなたが思う以上に重要です。Claude はそれを読んで、いつ、どのようにツールを使用するかを決定します。曖昧な説明は誤った呼び出しにつながります。正確な説明は正確な呼び出しにつながります。
3〜5 つのツールから始めてください。ファイルの読み取り、ファイルの書き込み、コマンドの実行、検索、そしてユースケースに固有の 1 つのドメイン固有ツールです。これでエージェントタスクの 90% をカバーできます。

05. ループ
これがスクリプトをエージェントに変える部分です。ループがないと、コードは Claude を 1 回呼び出して停止します。ループがあれば、コードは Claude を呼び出し、結果を確認し、ジョブが完了するまで再度呼び出します。

3 つのコンポーネント:
- 検証機。 出力が良いかどうかをチェックするもの。テストスイート、型チェッカー、リンター、厳格な基準を持つ 2 回目の Claude 呼び出し。これがないと、エージェントは繰り返し自分自身と同意することになります。
- 状態。 何が起こったかの記録。何が機能し、何が失敗し、次に何を試すか。状態がないと、エージェントは毎回同じ間違いを犯します。
- 停止条件。 目標が達成されたか、または「N 回試行したら停止して報告する」というハードリミット。これがないと、ループは永遠に実行され、アカウントを枯渇させます。
1import json2from pathlib import Path34def run_agent(task: str, max_attempts: int = 5):5 state = {"task": task, "attempts": [], "done": False}67 for i in range(max_attempts):8 # 状態からコンテキストを構築9 context = build_prompt(state)1011 # ツールを使って Claude を呼び出す12 result = call_claude(context, tools)1314 # ツール呼び出しを実行15 output = execute_tools(result)1617 # 結果を検証18 check = verify(output)1920 # 状態を更新21 state["attempts"].append({22 "attempt": i + 1,23 "action": result.summary,24 "passed": check.passed,25 "reason": check.reason26 })2728 if check.passed:29 state["done"] = True30 break3132 # 次の実行のために状態を保存33 Path("state.json").write_text(json.dumps(state, indent=2))34 return state
これが完全な骨格です。すべてのプロダクションエージェントは、このパターンのバリエーションです。詳細は変わります。形状は変わりません。
06. メモリ
メモリがないと、すべてのセッションがゼロから始まります。エージェントはプロジェクト構造を再発見します。規約を再学習します。昨日犯したのと同じ間違いを繰り返します。

Claude エージェントは 3 層のメモリを使用します:
CLAUDE.md は、プロジェクトのルートにあるマークダウンファイルです。Claude Code はすべてのセッションの開始時に自動的にそれを読み取ります。あなたのルール、スタック、規約。一度書けば、永久に読み取られます。
1# CLAUDE.md23## プロジェクト4タスク管理 API。Python 3.12、FastAPI、PostgreSQL。56## ルール7- すべての応答: {data, error, meta} スキーマ8- すべての新しいエンドポイントにはテストが必要9- コミットメッセージ: type(scope): description10- ロギングに print() を使用しないでください。structlog を使用してください。1112## 既知の問題13- 認証ミドルウェアは Authorization ではなく x-auth-token を期待します14- テストスイートはフル実行で 45 秒かかります。イテレーションには --filter を使用してください。
スキル はワークフロー全体をキャプチャします。プロンプトだけでなく、完全な形状:入力形式、ステップ、出力形式、検証ルール。初回実行は 20 分かかります。再生は 30 秒です。
学習ファイル は、間違いの実行ログです。エージェントは各セッションの後にそれに書き込みます。次のセッションでそれを読み取ります。間違いは、書き留められるまで繰り返されます。その後は止まります。
1# learnings.md23- 支払い API はべき等キーをボディではなくヘッダーに期待します4- PostgreSQL NOTIFY はコネクションプールで明示的な LISTEN が必要です5- レート制限は IP ごとではなくキーごとにカウントします。テストには一意のキーが必要です。
07. 検証ゲート
ゲートは構築が最も難しく、最もスキップされやすい部分です。ほとんどの人はそれをスキップします。だからこそ、ほとんどのエージェントがプロダクションで壊れるのです。

検証ゲートとは、エージェント自身が自分を評価することなく、エージェントの作業をチェックするものです。コードを書いたモデルは、自分の宿題を採点するには寛大すぎます。2 回目のチェックが必要です。
機能する 3 つのパターン:
1. 自動テスト。 エージェントがコードを書きます。テストスイートが実行されます。テストが失敗した場合、エージェントはエラー出力を受け取り、再試行します。これは Claude Code が内部的に動作する方法です。
1def verify(output):2 # テストスイートを実行3 result = subprocess.run(4 ["pytest", "tests/", "-x", "--tb=short"],5 capture_output=True, text=True6 )7 return {8 "passed": result.returncode == 0,9 "reason": result.stdout if result.returncode != 0 else "all tests pass"10 }
2. 型チェッカー / リンター。 変更のたびに mypy、ruff、または tsc --noEmit を実行します。テストを 1 つも書かずに、バグのカテゴリ全体をキャッチします。
3. レビュアーとしての 2 つ目のモデル。 問題のみを探す厳格なシステムプロンプトを持つ、別の Claude 呼び出しを使用します。書き手は高速で安価です。レビュアーは低速で厳格です。この分離が品質の大部分を占めます。
1# レビュアープロンプト - ビルダーとは別2reviewer_system = """あなたは厳格なコードレビュアーです。3あなたの唯一の仕事は問題を見つけることです。45チェック:6- コードは仕様と一致していますか?7- キャッチされていないエッジケースはありますか?8- すべてのテストは実際に正しいものをテストしていますか?910すべてが正しければ、応答: {"passed": true}11何か問題があれば、応答: {"passed": false, "issues": [...]}1213改善点を提案しないでください。実際のバグのみをフラグしてください。"""
書き手は高速で安価です。レビュアーは低速で厳格です。この分離が品質の大部分を占めます。
08. すべてをまとめる
以下は、GitHub の Issue URL を受け取り、Issue を読み、コードを書き、テストを実行し、PR を開く完全なエージェントです。5 つのパーツが連携して動作します。
1import anthropic, subprocess, json2from pathlib import Path34client = anthropic.Anthropic()5CLAUDE_MD = Path("CLAUDE.md").read_text()6LEARNINGS = Path("learnings.md").read_text()78SYSTEM = f"""あなたはコーディングエージェントです。9Issue を読んでください。修正を書いてください。テストを実行してください。1011プロジェクトコンテキスト:12{CLAUDE_MD}1314既知の問題:15{LEARNINGS}1617ルール:18- 何かを変更する前にコードベース全体を読んでください19- すべての変更に対してテストを書いてください20- テストが失敗した場合は、テストではなくコードを修正してください21- すべてのテストが合格したら停止してください"""2223TOOLS = [24 read_file_tool,25 write_file_tool,26 run_command_tool,27 search_codebase_tool,28]2930def run(issue_text, max_attempts=5):31 messages = [{"role": "user", "content": issue_text}]3233 for attempt in range(max_attempts):34 # Claude を呼び出す35 response = client.messages.create(36 model="claude-sonnet-4-6",37 max_tokens=8192,38 system=SYSTEM,39 tools=TOOLS,40 messages=messages41 )4243 # ツール呼び出しを実行44 messages = handle_tool_use(response, messages)4546 # 検証: テストを実行47 test_result = subprocess.run(48 ["pytest", "-x", "--tb=short"],49 capture_output=True, text=True50 )5152 if test_result.returncode == 0:53 print(f"{attempt + 1} 回の試行で完了")54 return True5556 # 失敗をループにフィードバック57 messages.append({58 "role": "user",59 "content": f"テストが失敗しました:\n{test_result.stdout}\n修正して再試行してください。"60 })6162 return False
これが動作するエージェントです。システムプロンプトと CLAUDE.md を持つ API レイヤー。ファイル操作用のツール。リトライ付きのループ。learnings.md からのメモリ。pytest による検証ゲート。
50 行未満です。Claude Code が内部的に使用しているのと同じアーキテクチャです。
10. すべてのエージェントを壊す 5 つのミス
- 検証ゲートがない。 エージェントが自分の宿題を採点します。コードを書き、「良さそうだ」と言って次に進みます。出力は正しく見え、プロダクションで壊れます。
- 停止条件がない。 API 請求額が 200 ドルになるまでループが実行されます。ハードリミットがないと、エージェントは同じファイルを 40 回書き換えて、永遠にリトライします。常に max_attempts を設定してください。常に。
- 状態ファイルがない。 1 回目と 50 回目で同じ間違い。エージェントは自分が何を既に試したかを知りません。失敗を記録するものがないため、同じ壊れた修正を 3 回連続で提案します。
- ツールが多すぎる。 20 個のツールを与えると、Claude は間違ったものを選びます。明確な 5 つのツールを持つモデルは、重複する 20 個のツールを持つモデルよりも優れた選択をします。小さく始めてください。エージェントが壁にぶつかったときにのみツールを追加してください。
- 曖昧なシステムプロンプト。 「良いコーディングアシスタントになってください」は、一般的な出力をもたらします。「すべての応答は有効な JSON でなければなりません。すべての変更にはテストが必要です。/src 外のファイルを決して変更しないでください」は、適切に動作するエージェントをもたらします。
結論:
動作するエージェントは、より優れたプロンプトではありません。それはシステムです:API + ツール + ループ + メモリ + 検証ゲート。5 つのパーツ。1 つ欠けると壊れます。
ほとんどの人はこれを読んで、ブックマークし、Claude をチャットボットとして使い続けるでしょう。彼らは一度に 1 つの質問を貼り付け、応答を手動でコードベースにコピーします。
ループを構築する人は、寝ている間に仕事を出荷するでしょう。同じモデル。同じ API。同じ価格。異なるアーキテクチャ。
上記のコードブロックはすべて動作します。コピーしてください。実行してください。ユースケースに合わせて修正してください。
今週、1 つのエージェントを構築してください。毎日行っているタスクに向けてください。実行させてみてください。





