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

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

深夜3時、ターミナルで20分間実行されていたエージェントのタスクを眺めていました。それは無限ループに陥り、同じツールを繰り返し呼び出していました。まるで行き止まりに入り込んだ酔っ払いのように。

これは初めての失敗ではありません。過去2年間、エージェント開発をしてきて、同様の失敗を何度も目にしてきました。ReAct エージェントがなぜか無限ループに陥ったり、マルチエージェントシステムがまるで口論大会のようになったり、Plan-and-Execute パターンが動的なタスクに対応できなかったり。

正直なところ、初めて ReAct、Plan-and-Execute、Multi-Agent という用語を目にした時、おそらく戸惑うでしょう。どれを選ぶべきか?何が違うのか?いつシングルエージェントを使い、いつマルチエージェントが必要なのか?

この記事では、これ数年の経験と失敗から学んだことを整理して解説します。以下の内容を取り上げます:

  • エージェントアーキテクチャの3つのレベル、そして「シンプルにできるなら複雑にしない」理由
  • ReAct、Plan-and-Execute、Multi-Agent の3つのコアパターンの原理とコード実装
  • 5つのマルチエージェントオーケストレーションパターン:Sequential、Concurrent、Group Chat、Handoff、Magentic
  • LangChain、AutoGen、CrewAI、Claude Agent SDK の選び方
  • Claude Agent SDK で動くエージェントを作る

それでは、始めていきましょう。

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

まず、多くの初心者が見落としがちな原則を提示します。シンプルなソリューションで解決できるなら、複雑なアーキテクチャを使わない

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 どう選ぶ?意思決定テーブル

あなたのシーン推奨レベル理由
単純なQ&A、テキスト処理モデル直接呼び出し十分、オーバーエンジニアリングしない
データベース照会、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, // 推論プロセスを出力、デバッグに必須
});

メリット・デメリット分析

メリットデメリット
柔軟性が高く、動的なタスクを処理可能無限ループに陥る可能性がある
推論プロセスが透明、デバッグしやすい単一呼び出しのコストが高い
ステップを事前定義する必要がない複雑なマルチステップタスクの計画能力に限界がある

失敗談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}
詳細な実行計画を生成してください。各ステップを文字列で、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(マルチエージェント協調)パターン

タスクが複雑すぎて単一エージェントでは対処できない場合、マルチエージェントの出番です。

コアとなる考え:各エージェントは一つの領域に専門化し、チームのように協力します。

コード実装(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 の入力になり、パイプラインのように進みます。

[エージェント A] → [エージェント B] → [エージェント 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(並行オーケストレーション)

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

           → [エージェント A] →
[入力]  →  → [エージェント B] →  → [アグリゲーター] → 最終結果
           → [エージェント 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(グループチャットオーケストレーション)

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

[エージェント A] ⇄ [エージェント B] ⇄ [エージェント C]
     ↑           ↓
   [モデレーター/調整役]

適用シーン:ブレインストーミング、品質検証、複数ラウンドの議論が必要な意思決定シーン。

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人のエージェントが永遠に議論し続けます。また、モデレーター役を用意して、議論を収束させるのが望ましいです。

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

あるエージェントがタスクを完了した後、次のエージェントに作業を引き継ぎます。

[エージェント A] が B の専門能力が必要と検出 → [エージェント 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(マグネティックオーケストレーション)

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

[タスクプール] → [スマートスケジューラー] → タスクの特徴に応じて [エージェント 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マルチエージェント協調会話型協調、人間とAIの協調複雑なマルチエージェントシステム、人間の介入が必要なシーン
CrewAIロールプレイ協調API がシンプル、概念が直感的チームシミュレーション、役割分担が明確なシーン
Claude Agent SDKClaude ネイティブコード理解、ファイル操作、Claude との深い統合Claude エコシステム、コードエージェント、自動化タスク

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

LangChain:老舗、エコシステムが最も成熟。

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

AutoGen:Microsoft 製品、マルチエージェント協調の首选。

  • コアコンセプトは「会話」、エージェント間はメッセージ受け渡しで協調
  • Human-in-the-loop(人間とAIの協調)をサポート
  • 複数ラウンドの議論、意思決定が必要なシーンに適している
  • デメリット?学習曲線が急で、マルチエージェントシステムのデバッグは大変

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. 人間とAIの協調が必要?

    • 必要 → AutoGen の Human-in-the-loop 設計が優れている
    • 不要 → 他のフレームワークでOK

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

いろいろ話しましたが、最も重要なのは実際に手を動かしてみることです。小さなプロジェクトを見つけて、エージェントを構築して走らせてみてください。いくつか失敗すれば、理解できるはずです。

質問があればコメント欄で議論してください。または、前の2つの記事「MCP Server 開発入門」と「エージェントツール呼び出し実践」を直接見てください。この3つは一脈相通じています。

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

環境準備から最初のエージェントの実行までの完全なステップ

⏱️ Estimated time: 30 min

  1. 1

    Step1: 依存関係をインストールし環境を設定

    以下のコマンドを実行してください:

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

    注意:API Key は Anthropic の公式サイトから取得する必要があります。環境変数に保存することを推奨します。
  2. 2

    Step2: 基本的なエージェントインスタンスを作成

    エージェント作成時に3つのコアパラメータを設定する必要があります:

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

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

    Step3: タスクを実行し結果を取得

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

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

    エラーハンドリングとログ記録を追加することを推奨します。
  4. 4

    Step4: セキュリティ保護を設定

    本番環境では保護策を必ず設定してください:

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

FAQ

ReAct、Plan-and-Execute、Multi-Agent の3つのパターンはどう選ぶ?
タスクの特徴に基づいて選択します:ReAct はタスクステップが不確定で、動的な意思決定が必要なシーンに適しています(カスタマーQ&Aなど);Plan-and-Execute はステップが予見可能で、安定した出力が必要なシーンに適しています(レポート生成など);Multi-Agent は複数の専門スキルの協力が必要な複雑なタスクに適しています(ソフトウェア開発パイプラインなど)。
なぜ Azure はグループチャットエージェントを3つ以内に制限することを推奨している?
グループチャットエージェントの数が多すぎると2つの問題が発生します:1つ目は議論が収束しにくく、複数のエージェントが終わりのない議論に陥る可能性があること;2つ目はデバッグコストが指数関数的に上昇し、エージェント間の状態同期とメッセージ受け渡しが極めて複雑になることです。3つのエージェント(モデレーター+2つの対立する視点)は、議論と意思決定が必要なほとんどのシーンをカバーできます。
LangChain と AutoGen/CrewAI はどう選ぶ?
ほとんどのシーンでは LangChain で十分です。ツール統合が豊富で、ReAct 実装が成熟しており、コミュニティサポートも良いです。マルチエージェント協調が必要だと確定した場合にのみ、AutoGen または CrewAI を検討してください。AutoGen は人間とAIの協調(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 エージェントはこれらを設定していなかったため、一晩中走り続けました。

8 min read · 公開日: 2026年3月21日 · 更新日: 2026年3月22日

コメント

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

関連記事