0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LangChain Agentの種類完全ガイド:JavaScriptで学ぶ各エージェントの特徴と使い方

Posted at

LangChain Agentの種類完全ガイド:JavaScriptで学ぶ各エージェントの特徴と使い方

はじめに

LangChainでは、様々な種類のAgentが提供されており、それぞれ異なる思考プロセスと実行戦略を持っています。この記事では、LangChain.jsを使用して、主要なAgentの種類とその特徴、実装方法を詳しく解説します。各Agentの適切な使い分けを理解することで、より効果的なAIエージェントアプリケーションを構築できます。

Agentとは

Agentの基本概念

Agentは、LLMとツールを組み合わせて、複雑なタスクを自律的に実行するシステムです。Agentは以下の能力を持ちます:

  1. 思考: タスクを分析し、必要なアクションを決定
  2. ツール使用: 外部ツールを呼び出して情報を取得
  3. 観察: ツールの結果を観察し、次のアクションを決定
  4. 反復: 目標達成まで必要なアクションを繰り返し実行

Agentの基本構造

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { ChatPromptTemplate } from "@langchain/core/prompts";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// ツールの定義
const tools = [/* ツールの配列 */];

// Agentの作成
const agent = await createOpenAIFunctionsAgent({
  llm,
  tools,
  prompt: ChatPromptTemplate.fromMessages([/* プロンプト */]),
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  verbose: true,
});

主要なAgentの種類

1. ReAct Agent

特徴

ReAct(Reasoning + Acting)Agentは、推論と行動を交互に行うAgentです。思考プロセスを明示的に示しながら、ツールを使用してタスクを実行します。

特徴:

  • 思考プロセスが透明
  • 段階的な問題解決
  • デバッグが容易

実装例

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createReactAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { pull } from "langchain/hub";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// ツールの定義
const calculatorTool = new DynamicStructuredTool({
  name: "calculator",
  description: "数式を計算します。例: (2 + 2) * 3",
  schema: z.object({
    expression: z.string().describe("計算する数式"),
  }),
  func: async ({ expression }) => {
    try {
      return eval(expression).toString();
    } catch (error) {
      return `エラー: ${error.message}`;
    }
  },
});

const tools = [calculatorTool];

// ReAct Agentのプロンプト
const prompt = await pull<ChatPromptTemplate>("hwchase17/react");

// Agentの作成
const agent = await createReactAgent({
  llm,
  tools,
  prompt,
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  verbose: true,
  maxIterations: 15,
});

// Agentの実行
const result = await agentExecutor.invoke({
  input: "2 + 2 の結果に 3 を掛けて、その結果を 2 で割ってください",
});

console.log(result.output);

実行例の出力

思考: まず 2 + 2 を計算する必要があります。
行動: calculator
行動入力: {"expression": "2 + 2"}
観察: 4
思考: 次に 4 * 3 を計算します。
行動: calculator
行動入力: {"expression": "4 * 3"}
観察: 12
思考: 最後に 12 / 2 を計算します。
行動: calculator
行動入力: {"expression": "12 / 2"}
観察: 6
思考: 計算が完了しました。答えは 6 です。
最終回答: 6

2. OpenAI Functions Agent

特徴

OpenAI Functions Agentは、OpenAIのFunction Calling機能を活用したAgentです。構造化されたツール定義を使用し、高精度なツール呼び出しが可能です。

特徴:

  • OpenAIのFunction Callingを活用
  • 構造化されたツール定義
  • 高精度なツール選択

実装例

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// 天気情報を取得するツール
const weatherTool = new DynamicStructuredTool({
  name: "get_weather",
  description: "指定された都市の天気情報を取得します",
  schema: z.object({
    city: z.string().describe("天気を取得する都市名"),
  }),
  func: async ({ city }) => {
    // 実際の実装では、天気APIを呼び出す
    return `${city}の天気は晴れ、気温は22度です`;
  },
});

// 計算ツール
const calculatorTool = new DynamicStructuredTool({
  name: "calculator",
  description: "数式を計算します",
  schema: z.object({
    expression: z.string().describe("計算する数式"),
  }),
  func: async ({ expression }) => {
    try {
      return eval(expression).toString();
    } catch (error) {
      return `エラー: ${error.message}`;
    }
  },
});

const tools = [weatherTool, calculatorTool];

// プロンプトの作成
const prompt = ChatPromptTemplate.fromMessages([
  ["system", "あなたは親切なアシスタントです。利用可能なツールを使用して質問に答えてください。"],
  ["human", "{input}"],
  new MessagesPlaceholder("agent_scratchpad"),
]);

// Agentの作成
const agent = await createOpenAIFunctionsAgent({
  llm,
  tools,
  prompt,
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  verbose: true,
});

// Agentの実行
const result = await agentExecutor.invoke({
  input: "東京の天気を教えて、その気温に10を足した値を計算してください",
});

console.log(result.output);

3. Structured Chat Agent

特徴

Structured Chat Agentは、構造化された出力を生成するAgentです。複雑なタスクを段階的に処理し、各ステップで構造化された情報を扱います。

特徴:

  • 構造化された出力
  • 複雑なタスクの段階的処理
  • 明確なアクションプラン

実装例

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createStructuredChatAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// データベース検索ツール
const searchDatabaseTool = new DynamicStructuredTool({
  name: "search_database",
  description: "データベースから情報を検索します",
  schema: z.object({
    query: z.string().describe("検索クエリ"),
    table: z.string().describe("検索するテーブル名"),
  }),
  func: async ({ query, table }) => {
    // 実際の実装では、データベースクエリを実行
    return `テーブル ${table} から "${query}" で検索した結果: 3件のレコードが見つかりました`;
  },
});

// レポート生成ツール
const generateReportTool = new DynamicStructuredTool({
  name: "generate_report",
  description: "レポートを生成します",
  schema: z.object({
    data: z.string().describe("レポートに含めるデータ"),
    format: z.enum(["json", "csv", "markdown"]).describe("レポートの形式"),
  }),
  func: async ({ data, format }) => {
    return `${format}形式のレポートを生成しました: ${data}`;
  },
});

const tools = [searchDatabaseTool, generateReportTool];

// プロンプトの作成
const prompt = ChatPromptTemplate.fromMessages([
  ["system", `あなたはデータ分析エージェントです。以下の手順でタスクを実行してください:
1. データベースから必要な情報を検索
2. 検索結果を分析
3. レポートを生成

利用可能なツール: {tool_names}`],
  ["human", "{input}"],
  new MessagesPlaceholder("agent_scratchpad"),
]);

// Agentの作成
const agent = await createStructuredChatAgent({
  llm,
  tools,
  prompt,
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  verbose: true,
});

// Agentの実行
const result = await agentExecutor.invoke({
  input: "ユーザーテーブルからアクティブなユーザーを検索して、JSON形式のレポートを生成してください",
});

console.log(result.output);

4. Plan-and-Execute Agent

特徴

Plan-and-Execute Agentは、まず全体の計画を立て、その後計画に従って実行するAgentです。複雑なタスクを複数のステップに分解して処理します。

特徴:

  • 事前計画の作成
  • 段階的な実行
  • 計画の調整が可能

実装例

import { ChatOpenAI } from "@langchain/openai";
import { PlanAndExecuteAgentExecutor } from "langchain/experimental/plan_and_execute";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// ファイル読み込みツール
const readFileTool = new DynamicStructuredTool({
  name: "read_file",
  description: "ファイルの内容を読み込みます",
  schema: z.object({
    filepath: z.string().describe("読み込むファイルのパス"),
  }),
  func: async ({ filepath }) => {
    // 実際の実装では、ファイルシステムから読み込む
    return `ファイル ${filepath} の内容: サンプルデータ`;
  },
});

// ファイル書き込みツール
const writeFileTool = new DynamicStructuredTool({
  name: "write_file",
  description: "ファイルに内容を書き込みます",
  schema: z.object({
    filepath: z.string().describe("書き込むファイルのパス"),
    content: z.string().describe("書き込む内容"),
  }),
  func: async ({ filepath, content }) => {
    return `ファイル ${filepath} に書き込みました`;
  },
});

// データ処理ツール
const processDataTool = new DynamicStructuredTool({
  name: "process_data",
  description: "データを処理します",
  schema: z.object({
    data: z.string().describe("処理するデータ"),
    operation: z.enum(["filter", "sort", "aggregate"]).describe("実行する操作"),
  }),
  func: async ({ data, operation }) => {
    return `${operation} 操作を実行しました: 処理済みデータ`;
  },
});

const tools = [readFileTool, writeFileTool, processDataTool];

// Plan-and-Execute AgentExecutorの作成
const executor = PlanAndExecuteAgentExecutor.fromLLMAndTools({
  llm,
  tools,
  verbose: true,
});

// Agentの実行
const result = await executor.invoke({
  input: "data.txtファイルを読み込んで、データをフィルタリングし、結果をoutput.txtに保存してください",
});

console.log(result.output);

5. Self-Ask-with-Search Agent

特徴

Self-Ask-with-Search Agentは、質問を自分自身に投げかけ、検索ツールを使用して情報を取得するAgentです。段階的な推論を行います。

特徴:

  • 自己質問による推論
  • 検索ツールの活用
  • 段階的な情報収集

実装例

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createSelfAskWithSearchAgent } from "langchain/agents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// 検索ツール
const searchTool = new DynamicStructuredTool({
  name: "search",
  description: "最新の情報を検索します",
  schema: z.object({
    query: z.string().describe("検索クエリ"),
  }),
  func: async ({ query }) => {
    // 実際の実装では、検索APIを呼び出す
    return `${query} に関する検索結果: 関連する情報が見つかりました`;
  },
});

const tools = [searchTool];

// プロンプトの作成
const prompt = ChatPromptTemplate.fromMessages([
  ["system", `あなたは情報検索エージェントです。質問に答えるために、以下の手順で進めてください:
1. 質問を分解して、必要な情報を特定
2. 各情報について検索を実行
3. 検索結果を統合して回答

利用可能なツール: {tool_names}`],
  ["human", "{input}"],
]);

// Agentの作成
const agent = await createSelfAskWithSearchAgent({
  llm,
  tools,
  prompt,
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  verbose: true,
});

// Agentの実行
const result = await agentExecutor.invoke({
  input: "LangChainの最新バージョンと、その主な新機能について教えてください",
});

console.log(result.output);

6. Conversational Agent

特徴

Conversational Agentは、会話履歴を保持しながら、ツールを使用してタスクを実行するAgentです。継続的な対話が可能です。

特徴:

  • 会話履歴の管理
  • コンテキストの保持
  • 継続的な対話

実装例

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createConversationalRetrievalAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { BufferMemory } from "langchain/memory";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// メモリの初期化
const memory = new BufferMemory({
  memoryKey: "chat_history",
  returnMessages: true,
});

// カレンダーツール
const calendarTool = new DynamicStructuredTool({
  name: "check_calendar",
  description: "カレンダーを確認します",
  schema: z.object({
    date: z.string().describe("確認する日付(YYYY-MM-DD形式)"),
  }),
  func: async ({ date }) => {
    return `${date} の予定: 会議が2件、タスクが3件あります`;
  },
});

// メール送信ツール
const sendEmailTool = new DynamicStructuredTool({
  name: "send_email",
  description: "メールを送信します",
  schema: z.object({
    to: z.string().describe("送信先のメールアドレス"),
    subject: z.string().describe("メールの件名"),
    body: z.string().describe("メールの本文"),
  }),
  func: async ({ to, subject, body }) => {
    return `メールを ${to} に送信しました: ${subject}`;
  },
});

const tools = [calendarTool, sendEmailTool];

// プロンプトの作成
const prompt = ChatPromptTemplate.fromMessages([
  ["system", "あなたは親切なアシスタントです。会話履歴を参照しながら、利用可能なツールを使用してタスクを実行してください。"],
  new MessagesPlaceholder("chat_history"),
  ["human", "{input}"],
  new MessagesPlaceholder("agent_scratchpad"),
]);

// Agentの作成
const agent = await createConversationalRetrievalAgent({
  llm,
  tools,
  prompt,
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  memory,
  verbose: true,
});

// 継続的な対話
const conversation1 = await agentExecutor.invoke({
  input: "今日の予定を教えてください",
});
console.log(conversation1.output);

const conversation2 = await agentExecutor.invoke({
  input: "その会議の参加者にメールを送ってください",
});
console.log(conversation2.output);

7. Zero-shot Agent

特徴

Zero-shot Agentは、事前の例やトレーニングなしで、ツールの説明のみから適切なツールを選択して使用するAgentです。

特徴:

  • 事前の例が不要
  • ツールの説明から推論
  • 柔軟なツール選択

実装例

import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { DynamicStructuredTool } from "@langchain/core/tools";
import { z } from "zod";

// LLMの初期化
const llm = new ChatOpenAI({
  modelName: "gpt-4",
  temperature: 0,
});

// 多様なツールの定義
const tools = [
  new DynamicStructuredTool({
    name: "get_weather",
    description: "指定された都市の天気情報を取得します",
    schema: z.object({
      city: z.string().describe("都市名"),
    }),
    func: async ({ city }) => `${city}の天気: 晴れ、22度`,
  }),
  new DynamicStructuredTool({
    name: "translate",
    description: "テキストを翻訳します",
    schema: z.object({
      text: z.string().describe("翻訳するテキスト"),
      target_language: z.string().describe("翻訳先の言語"),
    }),
    func: async ({ text, target_language }) => `翻訳結果: ${text} (${target_language})`,
  }),
  new DynamicStructuredTool({
    name: "calculate",
    description: "数式を計算します",
    schema: z.object({
      expression: z.string().describe("計算する数式"),
    }),
    func: async ({ expression }) => {
      try {
        return eval(expression).toString();
      } catch (error) {
        return `エラー: ${error.message}`;
      }
    },
  }),
];

// プロンプトの作成
const prompt = ChatPromptTemplate.fromMessages([
  ["system", "あなたは多機能アシスタントです。利用可能なツールの説明を読んで、適切なツールを選択してタスクを実行してください。"],
  ["human", "{input}"],
  new MessagesPlaceholder("agent_scratchpad"),
]);

// Agentの作成
const agent = await createOpenAIFunctionsAgent({
  llm,
  tools,
  prompt,
});

// AgentExecutorの作成
const agentExecutor = new AgentExecutor({
  agent,
  tools,
  verbose: true,
});

// Agentの実行
const result = await agentExecutor.invoke({
  input: "東京の天気を英語で翻訳してください",
});

console.log(result.output);

Agentの選択ガイド

用途別の推奨Agent

用途 推奨Agent 理由
シンプルなタスク OpenAI Functions Agent 高精度で使いやすい
複雑な推論が必要 ReAct Agent 思考プロセスが透明
多段階のタスク Plan-and-Execute Agent 計画と実行を分離
検索が必要 Self-Ask-with-Search Agent 段階的な情報収集
会話型アプリ Conversational Agent 会話履歴の管理
構造化された出力 Structured Chat Agent 明確なアクションプラン

パフォーマンス比較

// パフォーマンス測定関数
async function measureAgentPerformance(agentExecutor, input, iterations = 10) {
  const times = [];
  
  for (let i = 0; i < iterations; i++) {
    const start = Date.now();
    await agentExecutor.invoke({ input });
    const end = Date.now();
    times.push(end - start);
  }
  
  const avgTime = times.reduce((a, b) => a + b, 0) / times.length;
  const minTime = Math.min(...times);
  const maxTime = Math.max(...times);
  
  return {
    average: avgTime,
    min: minTime,
    max: maxTime,
  };
}

// 各Agentのパフォーマンス測定
// const reactPerformance = await measureAgentPerformance(reactExecutor, "タスク");
// const openaiPerformance = await measureAgentPerformance(openaiExecutor, "タスク");

ベストプラクティス

1. 適切なAgentの選択

// タスクの複雑さに応じてAgentを選択
function selectAgent(taskComplexity) {
  if (taskComplexity === "simple") {
    return createOpenAIFunctionsAgent;
  } else if (taskComplexity === "moderate") {
    return createReactAgent;
  } else {
    return createPlanAndExecuteAgent;
  }
}

2. ツールの最適化

// ツールの説明を明確に
const goodTool = new DynamicStructuredTool({
  name: "get_user_info",
  description: "ユーザーIDを指定して、ユーザーの名前、メールアドレス、登録日を取得します",
  // ...
});

// 悪い例:説明が曖昧
const badTool = new DynamicStructuredTool({
  name: "get_info",
  description: "情報を取得します", // 曖昧すぎる
  // ...
});

3. エラーハンドリング

// AgentExecutorのエラーハンドリング
try {
  const result = await agentExecutor.invoke({
    input: "タスク",
  });
  console.log(result.output);
} catch (error) {
  console.error("Agent実行エラー:", error);
  // フォールバック処理
}

4. コスト管理

// トークン使用量の監視
import { getTokenCount } from "@langchain/core/language_models/base";

const tokenCount = await getTokenCount(llm, "プロンプト");
console.log(`使用トークン数: ${tokenCount}`);

まとめ

LangChainでは、様々な種類のAgentが提供されており、それぞれ異なる特徴と用途を持っています。

主要なポイント

  1. ReAct Agent: 推論と行動を交互に行う、思考プロセスが透明
  2. OpenAI Functions Agent: OpenAIのFunction Callingを活用、高精度
  3. Structured Chat Agent: 構造化された出力、複雑なタスクの段階的処理
  4. Plan-and-Execute Agent: 事前計画の作成と段階的な実行
  5. Self-Ask-with-Search Agent: 自己質問と検索ツールの活用
  6. Conversational Agent: 会話履歴の管理、継続的な対話
  7. Zero-shot Agent: 事前の例なしでツールを選択

ベストプラクティス

  1. 適切なAgentの選択: タスクの性質に応じて最適なAgentを選択
  2. ツールの最適化: 明確な説明と適切なスキーマ定義
  3. エラーハンドリング: 適切なエラー処理とフォールバック
  4. パフォーマンス監視: 実行時間とコストの監視

適切なAgentを選択し、最適化することで、効果的なAIエージェントアプリケーションを構築できます。

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?