ストーリー
ReActパターンとは
基本概念
ReAct(Reasoning + Acting)は、LLMの推論能力とツール使用を交互に行うエージェント設計パターンです。
ReActの基本ループ:
Thought(思考): 現在の状況を分析し、次に何をすべきか考える
↓
Action(行動): ツールを選択し、パラメータを決めて実行する
↓
Observation(観察): ツールの実行結果を確認する
↓
Thought(思考): 結果を踏まえて次のステップを考える
↓
... 繰り返し ...
↓
Final Answer(最終回答): 目標達成時に最終回答を出力する
具体例:注文状況の確認
ユーザー: 注文番号ORD-12345の配送状況を教えてください
Thought: 注文番号ORD-12345の配送状況を確認する必要がある。
まず注文データベースを検索しよう。
Action: search_orders(order_id="ORD-12345")
Observation: {
"order_id": "ORD-12345",
"status": "shipped",
"tracking_number": "JP1234567890",
"carrier": "yamato"
}
Thought: 注文は発送済みで、ヤマト運輸の追跡番号がある。
配送の詳細状況を追跡番号で確認しよう。
Action: track_shipment(carrier="yamato", tracking="JP1234567890")
Observation: {
"status": "配達中",
"estimated_delivery": "2026-03-06",
"current_location": "東京主管支店"
}
Thought: 配達中で明日届く見込み。必要な情報が揃ったので
ユーザーに回答しよう。
Final Answer: ご注文ORD-12345は現在配達中です。
ヤマト運輸(追跡番号: JP1234567890)にて
東京主管支店を通過済みで、明日(3月6日)に
お届け予定です。
ReActの仕組み
プロンプト構造
ReActパターンのシステムプロンプトは以下の構造を持ちます。
あなたはNetShop社のカスタマーサポートエージェントです。
以下のツールを使用できます:
- search_orders: 注文情報を検索する
- track_shipment: 配送状況を追跡する
- process_refund: 返金処理を行う
以下のフォーマットで回答してください:
Thought: [現在の状況の分析と次のアクションの計画]
Action: [ツール名(パラメータ)]
Observation: [ツールの実行結果(システムが自動挿入)]
... (必要に応じて繰り返し)
Final Answer: [ユーザーへの最終回答]
重要なルール:
- 必ず Thought → Action → Observation の順序を守ること
- 推測で回答せず、必ずツールで確認すること
- 最大5回のアクションまでとする
ループの制御
ReActパターンでは、ループの終了条件を適切に設定することが重要です。
| 終了条件 | 説明 |
|---|---|
| 目標達成 | 必要な情報が揃い、最終回答を出力できる |
| 最大ステップ数 | 無限ループ防止のため上限を設定(例: 10回) |
| エラー蓄積 | 連続したエラーが閾値を超えた場合 |
| ユーザーキャンセル | ユーザーが処理の中断を要求 |
ReActの利点と課題
利点
| 利点 | 説明 |
|---|---|
| 透明性 | Thoughtが思考プロセスを可視化し、デバッグが容易 |
| 柔軟性 | 状況に応じて動的にツールを選択できる |
| 自己修正 | Observationから学習し、次のアクションを修正できる |
| 実装の容易さ | シンプルなループ構造で実装できる |
課題
| 課題 | 説明 | 対策 |
|---|---|---|
| ループの暴走 | 同じアクションを繰り返してしまう | 最大ステップ数の設定、重複検出 |
| 計画性の欠如 | 一歩先しか考えず非効率な行動を取る | Plan-and-Executeとの組み合わせ |
| コストの増大 | Thoughtごとにトークンを消費する | 簡潔なThoughtを促すプロンプト設計 |
| 複雑なタスク | ステップ数が増えると精度が低下する | タスク分解、サブエージェント委任 |
実装パターン
TypeScriptでの基本実装
// ReActエージェントの基本構造
interface AgentState {
messages: Message[];
thoughts: string[];
actions: ActionResult[];
isComplete: boolean;
stepCount: number;
}
const MAX_STEPS = 10;
async function reactAgent(
userMessage: string,
tools: Tool[]
): Promise<string> {
const state: AgentState = {
messages: [{ role: "user", content: userMessage }],
thoughts: [],
actions: [],
isComplete: false,
stepCount: 0,
};
while (!state.isComplete && state.stepCount < MAX_STEPS) {
// 1. LLMに思考させる(Thought + Action or Final Answer)
const response = await llm.chat(state.messages, tools);
if (response.type === "final_answer") {
// 目標達成 → ループ終了
return response.content;
}
// 2. ツールを実行する(Action → Observation)
const observation = await executeTool(
response.toolName,
response.toolArgs
);
// 3. 結果をメッセージ履歴に追加
state.messages.push(
{ role: "assistant", content: response.thought },
{ role: "tool", content: observation }
);
state.stepCount++;
}
return "最大ステップ数に達しました。処理を中断します。";
}
ReActに適するタスク
| 適するタスク | 理由 |
|---|---|
| 情報検索・確認 | 段階的に情報を収集できる |
| トラブルシューティング | 原因を順番に切り分けられる |
| データの検証・更新 | 確認→更新→確認のフローが自然 |
| 問い合わせ対応 | 状況に応じた柔軟な対応が可能 |
まとめ
| ポイント | 内容 |
|---|---|
| ReActの定義 | Reasoning + Acting を交互に行うエージェントパターン |
| 基本ループ | Thought → Action → Observation → … → Final Answer |
| 最大の利点 | 思考プロセスの透明性と自己修正能力 |
| 主な課題 | ループ暴走、計画性の欠如、コスト増大 |
チェックリスト
- ReActパターンの基本ループ(Thought → Action → Observation)を理解した
- ReActのプロンプト構造を説明できる
- ループの終了条件の設計方法を理解した
- ReActの利点と課題を把握した
次のステップへ
次は「Plan-and-Executeパターン」を学びます。ReActの「一歩先しか考えない」弱点を補う、計画立案型のアプローチを理解しましょう。
推定読了時間: 30分