言語を切り替える
テーマを切り替える

AI エージェント開発実践:アーキテクチャ設計と実装ガイド

ある ReAct エージェントが 20 分動いたあと無限ループにはまり、同じツールを繰り返し呼び続けました。原因は maxIterations を設定していなかったこと。これを超えたら強制停止し、デッドロックを防ぐためのものです。これはエージェント開発で最もよくある落とし穴です。ReAct エージェントが無限ループに陥る、マルチエージェントシステムが収束しない、Plan-and-Execute が動的なタスクに柔軟に対応できない、といった具合です。

エージェントのアーキテクチャは3つのレベルに分かれます。モデルの直接呼び出しは単一ステップのタスクに向き、シングルエージェント+ツールは多くの場面でのデフォルト、マルチエージェントは慎重に導入します。3つの基本パターンにはそれぞれ適した場面があります。ReAct は動的な意思決定、Plan-and-Execute は安定した処理フロー、Multi-Agent は専門分業です。Azure は公式に、グループチャットのエージェントを3つ以内に抑えるよう勧めています。超えると議論が収束しにくくなるからです。

この記事では、2年分の落とし穴の経験を余すところなく整理します。3つのアーキテクチャパターンの原理とコード実装、5つのマルチエージェントオーケストレーションパターン、LangChain / AutoGen / CrewAI / Claude Agent SDK の選び方、そして Claude Agent SDK で実際に動くエージェントを書く方法までを扱います。

一、エージェントアーキテクチャの3つのレベル

まず、初心者が見落としがちな原則を1つ。シンプルな方法で解決できるなら、複雑なアーキテクチャを持ち出さないことです。

Azure は公式に、エージェントのアーキテクチャを3つのレベルに分けています。この分類はとても実用的です。

1.1 モデルの直接呼び出し(Direct Model Call)

最もシンプルな層です。タスクをモデルに投げると、モデルがそのまま答えを返してくれます。

// 最も基本的な呼び出し方
const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'このテキストを要約して...' }]
});

向いている場面:単一ステップのタスク、確定性が高い場面、外部ツールを必要としない場面。たとえばテキスト要約、翻訳、コード補完です。

メリットは? シンプルで、安く、コントロールしやすいこと。デメリットは? 複数ステップの推論が必要な複雑タスクを扱えず、外部ツールを呼び出せないことです。

1.2 シングルエージェント+ツール(Single Agent with Tools)

これは多くの企業の場面でのデフォルトです。エージェントがツールを呼び出せるようになり、複数ステップのタスクを処理できます。

// LangChain のシングルエージェント例
import { ChatAnthropic } from '@langchain/anthropic';
import { AgentExecutor, createToolCallingAgent } from 'langchain/agents';
import { tool } from '@langchain/core/tools';
import { z } from 'zod';

// 天気を問い合わせるツールを定義
const weatherTool = tool(
  async ({ city }) => {
    // 天気 API 呼び出しをモック
    return `${city}は今日晴れ、気温 22°C`;
  },
  {
    name: 'get_weather',
    description: '指定した都市の天気情報を取得する',
    schema: z.object({
      city: z.string().describe('都市名'),
    }),
  }
);

const model = new ChatAnthropic({
  model: 'claude-sonnet-4-20250514',
  temperature: 0,
});

const agent = await createToolCallingAgent({
  llm: model,
  tools: [weatherTool],
  prompt: 'あなたは役に立つアシスタントです。',
});

const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [weatherTool],
});

// 実行
const result = await executor.invoke({
  input: '東京の今日の天気はどう?',
});

向いている場面:ツール呼び出しが必要で、タスクを分解でき、ステップが比較的固定された場面。たとえばデータ分析、コード実行、API オーケストレーションです。

1.3 マルチエージェントオーケストレーション(Multi-Agent Orchestration)

最も複雑な層です。複数の専門エージェントがそれぞれの役割を担い、協力してタスクを完成させます。

正直に言うと、この層でなければ解決できない場面は、思っているほど多くありません。マルチエージェントの導入は、調整のオーバーヘッド、状態管理の複雑さ、デバッグの難しさが指数関数的に増えることを意味します。

向いている場面:分野をまたぐ複雑タスク、専門分業が必要で、単一エージェントでは対応できない場面。たとえばソフトウェア開発のパイプライン(要件分析 → 設計 → コーディング → テスト)や、複雑な意思決定システムです。

1.4 どう選ぶ? 判断のための表

あなたの場面おすすめのレベル理由
シンプルな質問応答、テキスト処理モデルの直接呼び出しこれで十分。過剰設計はしない
データベース照会や API 呼び出しが必要シングルエージェント+ツール定番の方法で、安定性が高い
タスクは分解できるがステップが不確定シングルエージェント+ツール(ReAct パターン)エージェント自身にステップを計画させる
複数の専門役割の協調が必要マルチエージェント慎重に。本当に必要かまず評価する

ひとことで言うと:シンプルに始め、必要なものを必要なだけ足す。

二、3大基本アーキテクチャパターンの詳細

どのレベルを使うか決めたら、次はパターンを選びます。この3つのパターンは排他的ではなく、多くの場面で組み合わせて使います。

2.1 ReAct(推論-行動)パターン

ReAct は Reasoning + Acting の略で、モデルに「考えながら動かせる」ことが核心の考え方です。

動作原理

ユーザー入力 → Thought(思考)→ Action(行動)→ Observation(観察)→ ループまたは終了

例として、ユーザーが「東京の明日の天気はアウトドアに向いている?」と尋ねたとします。

  1. Thought:まず東京の明日の天気を調べる必要がある
  2. Actionget_weather ツールを呼び出し、引数は city: "東京"
  3. Observation:東京は明日くもり、気温 18〜25°C、降水確率 10%
  4. Thought:気温は適度で降水確率も低いので、アウトドアに向いている
  5. Final Answer:東京は明日アウトドアに向いています。薄手の上着をおすすめします

コード実装(LangChain):

import { ChatAnthropic } from '@langchain/anthropic';
import { AgentExecutor, createReactAgent } from 'langchain/agents';
import { pull } from 'langchain/hub';

// ReAct プロンプトのテンプレート
const prompt = await pull('hwchase17/react');

const agent = await createReactAgent({
  llm: model,
  tools: [weatherTool, searchTool], // あなたのツールリスト
  prompt,
});

// 最大反復回数を設定し、無限ループを防ぐ!
const executor = AgentExecutor.fromAgentAndTools({
  agent,
  tools: [weatherTool, searchTool],
  maxIterations: 10, // 重要:デッドロックを防ぐ
  verbose: true, // 推論プロセスを出力。デバッグの必需品
});

メリットとデメリットの分析

メリットデメリット
柔軟性が高く、動的なタスクを扱える無限ループに陥る可能性がある
推論プロセスが透明で、デバッグしやすい1 回あたりの呼び出しコストが高め
ステップを事前に定義しなくてよい複雑な複数ステップのタスクは計画力に限界

落とし穴の注意maxIterations は必ず設定してください。さもないと、完了できないタスクに当たったとき、エージェントが延々と走り続けます。私の最初の ReAct エージェントは、まさにそうやって一晩中走りました。

2.2 Plan-and-Execute(計画-実行)パターン

ReAct の問題は「一歩進んで様子を見る」やり方であり、複雑なタスクでは脱線しやすいことです。Plan-and-Execute の発想は、まず計画を固め、それから一歩ずつ実行する、というものです。

動作原理

ユーザー入力 → Planner(計画器)が計画を生成 → Executor が順に実行 → 結果を返す

コード実装(LangGraph):

import { ChatAnthropic } from '@langchain/anthropic';
import { StateGraph, END } from '@langchain/langgraph';

// 状態の構造を定義
interface AgentState {
  input: string;
  plan: string[];
  pastSteps: string[];
  response: string;
}

// 計画ノード:実行計画を生成
async function planNode(state: AgentState): Promise<AgentState> {
  const plannerPrompt = `ユーザーの目標:${state.input}
詳細な実行計画を生成してください。各ステップを1つの文字列とし、JSON 配列形式で返してください。`;

  const response = await model.invoke(plannerPrompt);
  const plan = JSON.parse(response.content as string);
  return { ...state, plan };
}

// 実行ノード:計画の1ステップを実行
async function executeNode(state: AgentState): Promise<AgentState> {
  const currentStep = state.plan[0];
  const result = await executor.invoke({ input: currentStep });

  return {
    ...state,
    plan: state.plan.slice(1), // 完了したステップを取り除く
    pastSteps: [...state.pastSteps, `${currentStep}: ${result.output}`],
  };
}

// グラフを構築
const workflow = new StateGraph<AgentState>({
  channels: {
    input: { value: null },
    plan: { value: null },
    pastSteps: { value: null, default: () => [] },
    response: { value: null },
  },
});

workflow.addNode('planner', planNode);
workflow.addNode('executor', executeNode);

// エッジを定義:計画が終わったら実行
workflow.addEdge('planner', 'executor');

// 条件付きエッジ:ステップが残っているか確認
workflow.addConditionalEdges('executor', (state) => {
  return state.plan.length > 0 ? 'executor' : END;
});

メリットとデメリットの分析

メリットデメリット
実行が安定し、ステップを制御できる計画はいったん生成すると柔軟性に欠ける
確定的なタスクに向く動的に変化する環境には適応しにくい
監視や中断がしやすい計画の質が Planner の能力に依存する

私の使用感:Plan-and-Execute は「ステップが予測できる」タスク、たとえばバッチデータ処理やレポート生成にとくに向きます。一方、戦略を頻繁に調整する必要があるタスクには、ReAct のほうが合っています。

2.3 Multi-Agent(マルチエージェント協調)パターン

タスクが複雑すぎて単一エージェントでは手に負えなくなったら、マルチエージェントの出番です。

核心の考え方:各エージェントが1つの領域に専念し、チームのように協力します。

コード実装(Claude Agent SDK スタイル):

import { ClaudeAgent } from '@anthropic-ai/claude-agent-sdk';

// 専門エージェントを作成
const researchAgent = new ClaudeAgent({
  name: 'researcher',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'あなたはリサーチ専門家で、情報の収集と整理を担当します。',
  tools: ['WebSearch', 'WebFetch'],
});

const writerAgent = new ClaudeAgent({
  name: 'writer',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'あなたはコンテンツ制作の専門家で、記事の執筆と推敲を担当します。',
  tools: ['Read', 'Write', 'Edit'],
});

const reviewerAgent = new ClaudeAgent({
  name: 'reviewer',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'あなたは品質レビューの専門家で、内容の正確さと読みやすさを確認します。',
  tools: ['Read'],
});

// 協調フロー
async function collaborativeWriting(topic: string) {
  // ステップ1:リサーチ
  const research = await researchAgent.run(`リサーチテーマ:${topic}`);

  // ステップ2:執筆
  const draft = await writerAgent.run(
    `以下のリサーチ結果をもとに、記事を執筆してください:\n${research}`
  );

  // ステップ3:レビュー
  const review = await reviewerAgent.run(
    `以下の記事をレビューし、修正案を提示してください:\n${draft}`
  );

  // ステップ4:修正
  const final = await writerAgent.run(
    `レビュー意見にもとづいて記事を修正してください:\n原稿:${draft}\n意見:${review}`
  );

  return final;
}

マルチエージェントを使うべきとき

  • タスクに複数の専門スキルが必要(たとえばプログラミング+デザイン+ライティング)
  • 単一エージェントのコンテキストウィンドウが足りない
  • 専門分業で、それぞれの役割を担わせたい

警告:マルチエージェントのデバッグの難しさは指数関数的に上がります。2つのエージェント間の状態同期、メッセージ受け渡し、エラー処理がいずれも複雑になります。単一エージェントで解決できるなら、無理にマルチエージェントを持ち出さないことです。

三、マルチエージェントオーケストレーションの5つのパターン

あなたの場面が本当にマルチエージェントを必要とするなら、次はオーケストレーションパターンを選びます。Azure が公式にまとめたこの5つのパターンは、大半の場面をほぼカバーします。

3.1 Sequential(順次オーケストレーション)

最も直感的なパターンです。エージェント A の出力がエージェント B の入力になり、パイプラインのようにつながります。

[Agent A] → [Agent B] → [Agent C] → 最終結果

適した場面:ドキュメント生成のパイプライン(調査 → 起草 → 校正 → 公開)、コード生成のフロー。

コード例

// 順次オーケストレーションの例
async function sequentialPipeline(input: string) {
  const step1 = await researchAgent.run(input);
  const step2 = await writerAgent.run(step1.output);
  const step3 = await editorAgent.run(step2.output);
  return step3.output;
}

注意点:各ステップの出力フォーマットを事前に取り決めておかないと、下流のエージェントが理解できないデータを受け取ってしまいます。

3.2 Concurrent(並行オーケストレーション)

複数のエージェントが同じ入力を同時に処理し、最後に結果をまとめます。

           → [Agent A] →
[入力]  →  → [Agent B] →  → [集約器] → 最終結果
           → [Agent C] →

適した場面:多視点の分析、株式評価(テクニカル+ファンダメンタル+ニュース面の並行分析)、コードレビュー(セキュリティ+パフォーマンス+スタイルの並行チェック)。

コード例

// 並行オーケストレーションの例
async function concurrentAnalysis(code: string) {
  const [security, performance, style] = await Promise.all([
    securityAgent.run(`セキュリティレビュー:\n${code}`),
    performanceAgent.run(`パフォーマンス分析:\n${code}`),
    styleAgent.run(`コードスタイルチェック:\n${code}`),
  ]);

  // 結果を集約
  return {
    security: security.output,
    performance: performance.output,
    style: style.output,
  };
}

注意点:並行実行では結果集約のロジックに注意が必要です。エージェントごとに矛盾する提案が出ることがあるので、調停の仕組みを設計しておきましょう。

3.3 Group Chat(グループチャットオーケストレーション)

複数のエージェントが1つの「チャットルーム」で議論し、合意に至るかタイムアウトするまで続けます。

[Agent A] ⇄ [Agent B] ⇄ [Agent C]
     ↑           ↓
   [Moderator/調整役]

適した場面:ブレインストーミング、品質検証、複数ラウンドの議論を経て意思決定する場面。

Azure の公式推奨:グループチャットのエージェント数は3つ以内に抑えること。多すぎると言い争い大会になります。

コード例

// グループチャットオーケストレーションの例(擬似コード)
interface ChatMessage {
  sender: string;
  content: string;
}

async function groupChatDiscussion(
  topic: string,
  agents: ClaudeAgent[],
  maxRounds: number = 5
) {
  const history: ChatMessage[] = [];

  for (let round = 0; round < maxRounds; round++) {
    for (const agent of agents) {
      const response = await agent.run(
        `議論テーマ:${topic}\n現在の対話履歴:${JSON.stringify(history)}\nあなたの意見を述べてください。`
      );
      history.push({ sender: agent.name, content: response.output });

      // 合意に至ったか確認
      if (checkConsensus(history)) {
        return summarizeConsensus(history);
      }
    }
  }

  return '議論がタイムアウトし、合意に至りませんでした';
}

落とし穴の経験maxRounds は必ず設定してください。さもないと、頑固な2つのエージェントが延々と言い争えてしまいます。また、議論を収束させる Moderator 役を置くのが望ましいです。

3.4 Handoff(引き継ぎオーケストレーション)

あるエージェントがタスクを終えたら、次のエージェントに仕事を引き継ぎます。

[Agent A] が B の専門能力が必要だと検知 → [Agent B] に引き継ぐ → 処理を続行

適した場面:カスタマーサポートのボット(プリセールス → テクニカルサポート → アフターサービス)、障害切り分け(診断 → 修復 → 検証)。

コード例

// 引き継ぎオーケストレーションの例
const supportAgent = new ClaudeAgent({
  name: 'support',
  systemPrompt: `あなたはカスタマーサポートです。ユーザーが技術的な質問をしたら "HANDOFF:tech" と返答してください。
アフターサービスの質問をしたら "HANDOFF:after_sales" と返答してください。`,
});

const techAgent = new ClaudeAgent({
  name: 'tech',
  systemPrompt: 'あなたはテクニカルサポートの専門家です。',
});

async function handleWithHandoff(userInput: string) {
  let currentAgent = supportAgent;
  let response = await currentAgent.run(userInput);

  // 引き継ぎシグナルを検知
  while (response.output.includes('HANDOFF:')) {
    const targetAgent = response.output.match(/HANDOFF:(\w+)/)?.[1];

    if (targetAgent === 'tech') currentAgent = techAgent;
    else if (targetAgent === 'after_sales') currentAgent = afterSalesAgent;

    response = await currentAgent.run(userInput);
  }

  return response.output;
}

注意点:引き継ぎのロジックは明確にし、循環的な引き継ぎ(A が B に渡し、B がまた A に渡す)を避けましょう。

3.5 Magentic(マグネティックオーケストレーション)

最も柔軟なパターンです。タスクの性質に応じて、最も適したエージェントを動的に「引き寄せて」処理させます。

[タスクプール] → [インテリジェントなスケジューラ] → タスクの特性に応じて [Agent A/B/C] を選択

適した場面:タスクの種類が多様なシステム、リソースを動的に割り当てる必要がある場面。

実装の考え方

// マグネティックオーケストレーションの例
interface Task {
  type: string;
  priority: number;
  content: string;
}

async function magenticScheduling(task: Task) {
  // タスクの種類に応じて最も適したエージェントを選択
  const agentScores = await Promise.all(
    agents.map(async (agent) => {
      const score = await evaluateAgentFit(agent, task);
      return { agent, score };
    })
  );

  // スコアが最も高いエージェントを選択
  const bestAgent = agentScores.sort((a, b) => b.score - a.score)[0].agent;
  return bestAgent.run(task.content);
}

注意点:「適合度の評価」ロジックをしっかり設計しないと、割り当てがランダムになってしまいます。

3.6 パターン選択の早見表

パターン適した場面複雑さ主なリスク
Sequentialパイプライン型のタスクステップ依存によるブロック
Concurrent多視点の並行分析結果の衝突に調停が必要
Group Chat複数ラウンドの議論で意思決定収束しない、無限の言い争い
Handoff動的な分業協調循環的な引き継ぎ、引き継ぎのデッドロック
Magenticタスクの種類が多様スケジューリングロジックが複雑

四、主要フレームワークの比較と選定

アーキテクチャパターンを語ったので、次は具体的にどのフレームワークを使うかです。ここは確かに目移りしやすいところです。LangChain、AutoGen、CrewAI、Claude Agent SDK、それぞれに言い分があります。

先に私の考えを言うと、最高のフレームワークは存在せず、あなたの場面に最も合うフレームワークがあるだけです。

4.1 フレームワークの位置づけ比較

フレームワーク核心の位置づけ強み適した場面
LangChain汎用エージェントフレームワークツール連携が豊富、ReAct の実装が成熟素早いプロトタイプ、本番アプリ、多くのツール連携が必要
AutoGenマルチエージェント協調対話型の協調、Human-in-the-loop複雑なマルチエージェントシステム、人の介入が必要な場面
CrewAIロールプレイ協調API がシンプル、概念が直感的チームのシミュレーション、役割分担が明確な場面
Claude Agent SDKClaude ネイティブコード理解、ファイル操作、Claude と深く統合Claude エコシステム、コードエージェント、自動化タスク

4.2 各フレームワークの特徴

LangChain:老舗の選手で、エコシステムが最も成熟しています。

  • TypeScript と Python の両方を完全サポート
  • 大量のツールと連携を内蔵
  • ReAct も Plan-and-Execute も既製の実装あり
  • デメリットは? API の変更が頻繁で、ドキュメントが追いつかないことがある

AutoGen:Microsoft 製で、マルチエージェント協調の第一候補です。

  • 核心の概念は「対話」で、エージェント同士がメッセージ受け渡しで協調する
  • Human-in-the-loop に対応
  • 複数ラウンドの議論や意思決定が必要な場面に向く
  • デメリットは? 学習曲線が急で、マルチエージェントシステムのデバッグがつらい

CrewAI:新顔で、シンプルさが売りです。

  • 「役割」「タスク」「チーム」の概念でモデリングでき、とても直感的
  • API 設計がきれいで、すぐに使い始められる
  • 素早くマルチエージェントのプロトタイプを組むのに向く
  • デメリットは? エコシステムとツール連携が LangChain ほど豊富でない

Claude Agent SDK:Anthropic 公式製で、2026 年に新登場したツールです。

  • Claude モデルと深く統合
  • ファイルの読み書き、コード編集、コマンド実行の機能を内蔵
  • permissionMode で操作権限を制御できる
  • 主力モデルが Claude なら、これが第一候補

4.3 選定の判断ガイド

自分にいくつか問いかけてみましょう。

  1. 主力モデルは何か?

    • Claude → まず Claude Agent SDK
    • OpenAI → LangChain のエコシステムがより成熟
    • マルチモデル → LangChain か AutoGen
  2. タスクの複雑さはどの程度か?

    • シングルエージェント+ツール → LangChain で十分
    • マルチエージェント協調 → AutoGen か CrewAI
    • コード関連のタスク → Claude Agent SDK
  3. チームの技術スタックは何か?

    • Python 中心 → どのフレームワークも対応
    • TypeScript 中心 → LangChain と Claude Agent SDK のサポートが手厚い
  4. Human-in-the-loop は必要か?

    • 必要 → AutoGen の Human-in-the-loop はよくできている
    • 不要 → どのフレームワークでも問題ない

4.4 私の選定のおすすめ

正直に言うと、大半の場面では LangChain で十分です。ツール連携も ReAct の実装も成熟しており、コミュニティのサポートも手厚いです。

マルチエージェントを使うと決めていて、なおかつタスクが複数の専門エージェントの協調を本当に必要とするほど複雑なら、AutoGen は試す価値があります。ただし覚えておいてください。マルチエージェントのデバッグコストは高く、「技術的に先進的だから」という理由で無理に導入してはいけません。

あなたが Claude のヘビーユーザーなら、Claude Agent SDK が現状ベストの選択です。何しろ公式製で、Claude モデルとの相性が最も良いからです。

五、実践 - Claude Agent SDK でエージェントを構築する

理論をだいぶ語ったので、実践に移りましょう。Claude Agent SDK で、実際に動くコードリファクタリングのエージェントを書きます。

5.1 環境準備

# 依存関係をインストール
npm install @anthropic-ai/claude-agent-sdk

# API Key を設定
export ANTHROPIC_API_KEY=your_api_key_here

5.2 基本のエージェント例

import { ClaudeAgent } from '@anthropic-ai/claude-agent-sdk';

// コードリファクタリングのエージェントを作成
const refactorAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit', 'Bash'],
  permissionMode: 'acceptEdits', // 編集操作を自動で承認
  workingDirectory: './src', // 作業ディレクトリ
});

// タスクを実行
async function refactorCode(task: string) {
  const result = await refactorAgent.run(task);
  console.log('リファクタリング結果:', result);
  return result;
}

// 使用例
refactorCode('auth.ts ファイルをリファクタリングし、コールバック形式のコードを async/await に変える');

5.3 重要な設定の説明

permissionMode(権限モード)

  • 'acceptEdits':ファイル編集操作を自動で承認
  • 'interactive':操作のたびに人の確認が必要
  • 'planOnly':計画だけ生成し、実行はしない

tools(使えるツール)

  • Read:ファイルを読む
  • Write:新しいファイルを作成
  • Edit:既存ファイルを編集
  • Bash:コマンドラインを実行
  • Glob:ファイルパターンのマッチング
  • Grep:内容の検索

5.4 より複雑な例:制約付きのエージェント

const cautiousAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit', 'Bash'],
  permissionMode: 'interactive', // 慎重モード:人の確認が必要
  maxIterations: 20, // 最大反復回数を制限
  timeout: 300000, // 5 分でタイムアウト

  // システムプロンプト:エージェントの振る舞いの境界を定義
  systemPrompt: `あなたはコードリファクタリングの専門家です。
ルール:
1. テストファイルは一切削除しない
2. package.json は変更しない
3. 修正する前に元ファイルをバックアップする
4. 修正後はテストを実行して機能が正常か確認する`,
});

async function safeRefactor(filePath: string) {
  try {
    const result = await cautiousAgent.run(
      `${filePath} をリファクタリングし、コード構造と可読性を改善してください。`
    );
    return result;
  } catch (error) {
    console.error('リファクタリング失敗:', error);
    // ロールバック処理...
  }
}

5.5 ベストプラクティス

  1. 反復回数を制限する:エージェントが無限ループに陥るのを防ぐ
  2. タイムアウトを設定する:長時間動くタスクには保険をかける
  3. 権限を段階化する:機微な操作には interactive モードを使う
  4. バックアップの仕組み:重要なファイルは修正前にバックアップする
  5. テストで検証する:修正後はテストを実行し、機能が正常か確認する

5.6 デバッグのコツ

// 詳細ログを有効化
const debugAgent = new ClaudeAgent({
  model: 'claude-sonnet-4-20250514',
  tools: ['Read', 'Write', 'Edit'],
  verbose: true, // 詳細な実行プロセスを出力
});

// イベントをリッスン
debugAgent.on('toolCall', (tool, args) => {
  console.log(`ツール呼び出し:${tool}、引数:${JSON.stringify(args)}`);
});

debugAgent.on('thinking', (thought) => {
  console.log(`エージェントの思考:${thought}`);
});

おわりに

ここまで来ると、エージェントアーキテクチャ選択の核心の考え方は、結局ひとことに尽きます。シンプルに始め、必要なものを必要なだけ足すことです。

まずタスクの複雑さを見極めます。

  • 単一ステップのタスク? モデルを直接呼ぶ
  • ツールが必要? シングルエージェント+ツール
  • 複数の専門役割が本当に必要? そこで初めてマルチエージェントを検討する

次にパターンを選びます。

  • タスクが動的に変化する? ReAct
  • ステップが予測できる? Plan-and-Execute
  • 専門分業が必要? Multi-Agent

最後にフレームワークを選びます。

  • Claude ユーザー? Claude Agent SDK
  • マルチモデル、マルチツール? LangChain
  • マルチエージェント協調? AutoGen か CrewAI

いろいろ語りましたが、いちばん大事なのはやはり手を動かして試すことです。小さなプロジェクトを見つけて、エージェントを1つ組んで動かしてみましょう。いくつか落とし穴を踏めば、自然とわかってきます。

質問があればコメント欄で気軽に議論しましょう。あるいは、私の前の2記事をぜひご覧ください。「MCP Server 開発入門」と「Agent ツール呼び出し実践」です。この3本は一本の線でつながっています。

Claude Agent SDK でエージェントを構築する

環境準備から最初のエージェントを動かすまでの完全な手順

⏱️ 目安時間: 30 分

  1. 1

    ステップ1: 依存関係をインストールして環境を設定する

    以下のコマンドを実行します。

    ```bash
    npm install @anthropic-ai/claude-agent-sdk
    export ANTHROPIC_API_KEY=your_api_key_here
    ```

    注意:API Key は Anthropic の公式サイトから取得し、環境変数に保存することをおすすめします。
  2. 2

    ステップ2: 基本のエージェントインスタンスを作成する

    エージェントを作成するときは、3つの基本パラメータを設定します。

    ```typescript
    const agent = new ClaudeAgent({
    model: 'claude-sonnet-4-20250514',
    tools: ['Read', 'Write', 'Edit', 'Bash'],
    permissionMode: 'acceptEdits'
    });
    ```

    • model:Claude のモデルバージョンを選択
    • tools:エージェントが使えるツールを指定
    • permissionMode:権限の制御モード
  3. 3

    ステップ3: タスクを実行して結果を取得する

    run メソッドを呼び出してタスクを実行します。

    ```typescript
    const result = await agent.run('auth.ts ファイルをリファクタリング');
    ```

    エラー処理とログ記録を追加することをおすすめします。
  4. 4

    ステップ4: 安全のための防御を設定する

    本番環境では必ず防御策を設定します。

    • maxIterations:最大の反復回数を制限(推奨は 20)
    • timeout:タイムアウト時間を設定(推奨は 5 分)
    • systemPrompt:振る舞いの境界を定義
    • permissionMode:機微な操作には 'interactive' モードを使用

FAQ

ReAct、Plan-and-Execute、Multi-Agent の3つはどう選べばいい?
タスクの特性で選びます。ReAct はステップが不確定で動的な判断が必要な場面(カスタマーサポートの応答など)に向きます。Plan-and-Execute はステップが予測でき、安定した出力が欲しい場面(レポート生成など)に向きます。Multi-Agent は複数の専門スキルの協調が必要な複雑タスク(ソフトウェア開発のパイプラインなど)に向きます。
なぜ Azure はグループチャットのエージェントを3つ以内に抑えるよう勧めるの?
グループチャットのエージェントが多すぎると、2つの問題が起きます。1つは議論が収束しにくいこと。複数のエージェントが終わりのない言い争いに陥りかねません。もう1つはデバッグコストが指数関数的に増えること。エージェント間の状態同期とメッセージ受け渡しが極端に複雑になります。3つ(司会+意見の対立する2者など)あれば、議論で意思決定する大半の場面をカバーできます。
LangChain と AutoGen / CrewAI はどう選ぶ?
大半の場面では LangChain で十分です。ツール連携が豊富で、ReAct の実装も成熟しており、コミュニティのサポートも手厚いです。マルチエージェント協調が確実に必要だと判断したときだけ、AutoGen か CrewAI を検討します。AutoGen は Human-in-the-loop に対応し、人の介入が必要な場面に向きます。CrewAI は API がシンプルで、素早くプロトタイプを組むのに向きます。
Claude Agent SDK はどんな場面に向いている?
Claude Agent SDK は Anthropic 公式のツールで、3つの場面に最も向きます。1つ目は主力モデルが Claude のとき。Claude と深く統合されています。2つ目はコード関連のタスク。ファイルの読み書きやコード編集の機能を内蔵しています。3つ目はきめ細かい権限制御が必要なとき。permissionMode で操作権限を段階的に管理できます。
エージェントが無限ループに陥らないようにするには?
3つの重要な防御策があります。1つ目、maxIterations を設定する(推奨は 10〜20 回)。超えたら強制停止します。2つ目、timeout を設定する(推奨は 5 分)。超過すると自動で中断します。3つ目、systemPrompt で終了条件を明確にし、どんなときに諦めるべきかをエージェントに伝えます。私の最初の ReAct エージェントはこれを設定しておらず、一晩中走り続けました。

6分で読めます · 公開日: 2026年3月21日 · 更新日: 2026年6月8日

関連記事

コメント

GitHubアカウントでログインしてコメントできます