AIエージェント開発の現場において、「何度も同じエラーを繰り返す」「Assistantが的外れな判断をする」という課題に直面したことがある方は多いのではないでしょうか。私は、以前のプロジェクトでこれらの壁にぶつかり、ReActパターンを導入することで劇的に改善できました。本記事では、ReActパターンの理論的基礎から実務的なPython実装まで、具体的に解説します。

ReActパターンとは?

ReAct(Reasoning + Acting)は、大規模言語モデルに「思考」と「行動」を交互に実行させるアーキテクチャです。以下の3フェーズを繰り返します:

このサイクルにより、エージェントは動的に状況を判断しながらタスクを完遂できます。

ReActとHolySheep AIの相性

ReActパターンの効果を最大化するには、API呼び出しのレイテンシとコストが重要です。HolySheep AIは、DeepSeek V3.2が$0.42/MTokという破格の料金体系中、<50msという低レイテンシを実現しています。ReActの複数ターン対話において、このレイテンシーの低さは体感速度に直接影響します。

Python実装:基礎クラス

"""
ReAct Agent 基本実装
HolySheep AI APIを使用
"""

import json
import requests
from typing import List, Dict, Any, Optional

class HolySheepReActAgent:
    """ReActパターンを実装したAIエージェント"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.conversation_history: List[Dict[str, str]] = []
        self.max_iterations = 10
        
    def _call_api(self, messages: List[Dict[str, str]]) -> str:
        """HolySheep AI APIを呼び出し"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "deepseek-chat",
            "messages": messages,
            "temperature": 0.7,
            "max_tokens": 2000
        }
        
        response = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json=payload,
            timeout=30
        )
        
        if response.status_code == 401:
            raise ConnectionError("401 Unauthorized: APIキーが無効です")
        elif response.status_code == 429:
            raise ConnectionError("429 Rate Limited: リクエスト上限に達しました")
        elif response.status_code != 200:
            raise ConnectionError(f"API Error {response.status_code}: {response.text}")
        
        return response.json()["choices"][0]["message"]["content"]
    
    def add_system_prompt(self, prompt: str):
        """システムプロンプトを設定"""
        self.conversation_history.append({
            "role": "system",
            "content": prompt
        })
    
    def run(self, user_input: str) -> Dict[str, Any]:
        """ReActサイクルを実行"""
        self.conversation_history.append({
            "role": "user", 
            "content": user_input
        })
        
        steps = []
        
        for iteration in range(self.max_iterations):
            response = self._call_api(self.conversation_history)
            steps.append({"iteration": iteration + 1, "response": response})
            
            # 終了条件の判定(実際の実装ではより厳密に)
            if "FINAL_ANSWER:" in response:
                final_answer = response.split("FINAL_ANSWER:")[-1].strip()
                return {"success": True, "answer": final_answer, "steps": steps}
            
            # 思考内容を履歴に追加
            self.conversation_history.append({
                "role": "assistant",
                "content": response
            })
            
        return {"success": False, "answer": None, "steps": steps, "error": "最大イテレーション超過"}

使用例

agent = HolySheepReActAgent(api_key="YOUR_HOLYSHEEP_API_KEY") agent.add_system_prompt("""あなたは問題を段階的に解決するReActエージェントです。 各ステップで以下を出力してください: Thought: [現在の状況分析と次の行動計画] Action: [実行する具体的な行動] Observation: [行動結果の観察] """) result = agent.run("東京都の今日の天気を調べて、傘が必要かを教えて") print(result)

ツール呼び出し機能を拡張した完全版

"""
ReAct Agent 完全版:ツール呼び出し機能付き
"""

import re
import json
from dataclasses import dataclass
from typing import Callable, Dict, Any, Optional, List
import requests

@dataclass
class Tool:
    """ツール定義"""
    name: str
    description: str
    parameters: Dict[str, str]
    function: Callable

class ToolEnabledReActAgent:
    """外部ツールを呼び出せるReActエージェント"""
    
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.holysheep.ai/v1"
        self.tools: Dict[str, Tool] = {}
        self.conversation: List[Dict] = []
        
    def register_tool(self, name: str, description: str, 
                     parameters: Dict[str, str], 
                     function: Callable):
        """ツールを登録"""
        self.tools[name] = Tool(name, description, parameters, function)
        
    def _format_tools_for_api(self) -> str:
        """ツール定義をAPI用フォーマットに変換"""
        tools_prompt = "利用可能なツール:\n"
        for name, tool in self.tools.items():
            params_str = ", ".join(f"{k}: {v}" for k, v in tool.parameters.items())
            tools_prompt += f"- {tool.name}({params_str}): {tool.description}\n"
        return tools_prompt
    
    def _parse_action(self, text: str) -> Optional[tuple]:
        """AI応答からアクションを解析"""
        # Action: tool_name(argument) パターンを検出
        pattern = r'Action:\s*(\w+)\((.*?)\)'
        match = re.search(pattern, text, re.DOTALL)
        if match:
            return (match.group(1), match.group(2).strip())
        return None
    
    def execute_react(self, task: str) -> Dict[str, Any]:
        """ReActサイクルを実行"""
        system_prompt = f"""あなたはReActパターンを実行するAIエージェントです。
{self._format_tools_for_api()}

回答は以下形式で出力してください:
Thought: [状況分析と思考]
Action: [tool_name(argument)] - 必要な場合のみ
Observation: [行動結果の観察]
FINAL_ANSWER: [最終回答] - 完了時のみ
"""
        self.conversation = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": task}
        ]
        
        history = []
        
        for step in range(15):
            # API呼び出し
            response = self._call_api(self.conversation)
            history.append({"step": step + 1, "thought": response})
            
            # アクション解析
            action = self._parse_action(response)
            
            if action:
                tool_name, arg = action
                if tool_name in self.tools:
                    try:
                        # ツール実行
                        result = self.tools[tool_name].function(arg)
                        obs = f"Observation: ツール '{tool_name}' の実行結果: {result}"
                        history[-1]["observation"] = obs
                        self.conversation.append({
                            "role": "assistant", 
                            "content": response + "\n" + obs
                        })
                    except Exception as e:
                        error_obs = f"Observation: エラー発生 - {str(e)}"
                        self.conversation.append({
                            "role": "assistant",
                            "content": response + "\n" + error_obs
                        })
                else:
                    self.conversation.append({
                        "role": "assistant",
                        "content": response + f"\nObservation: ツール '{tool_name}' は存在しません"
                    })
            else:
                # 最終回答チェック
                if "FINAL_ANSWER:" in response:
                    answer = response.split("FINAL_ANSWER:")[-1].strip()
                    return {"success": True, "answer": answer, "history": history}
                self.conversation.append({"role": "assistant", "content": response})
        
        return {"success": False, "error": "ステップ数上限超過", "history": history}
    
    def _call_api(self, messages: List[Dict]) -> str:
        """API呼び出し"""
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        payload = {
            "model": "deepseek-chat",
            "messages": messages,
            "temperature": 0.3,
            "max_tokens": 1500
        }
        
        resp = requests.post(
            f"{self.base_url}/chat/completions",
            headers=headers,
            json=payload,
            timeout=30
        )
        resp.raise_for_status()
        return resp.json()["choices"][0]["message"]["content"]


ツール定義例

def search_wikipedia(query: str) -> str: """Wikipedia検索ツール""" # 実際の実装ではrequests等进行API调用 return f"Wikipedia検索結果: {query}に関する情報を返します" def calculate(expression: str) -> str: """計算ツール""" try: result = eval(expression) return str(result) except: return "計算エラー"

エージェント初期化

agent = ToolEnabledReActAgent(api_key="YOUR_HOLYSHEEP_API_KEY") agent.register_tool( "search_wikipedia", "Wikipediaで情報を検索", {"query": "検索文字列"}, search_wikipedia ) agent.register_tool( "calculate", "数式を計算", {"expression": "数式文字列"}, calculate )

実行

result = agent.execute_react( "東京の人口と面積を求め、人口的密度を計算してください" )

HolySheep AIでのコスト検証

私は実際に複数のモデルでReActエージェントのコストを比較検証しました。以下が1,000回のReActサイクル(月間利用)におけるコスト比較です:

ReActパターンは複数ターン対話が前提のため、DeepSeek V3.2のような低コストモデルは絶大な優位性があります。HolySheep AIでは、DeepSeek V3.2が最安値の$0.42/MTokで提供されており、¥1=$1の交換レート(公式¥7.3=$1比85%節約)で日本の開発者も気軽に利用可能です。

よくあるエラーと対処法

エラー1:ConnectionError: timeout

# 原因:リクエストタイムアウト

解決:タイムアウト設定の確認とリトライロジック実装

def call_with_retry(self, messages, max_retries=3, timeout=60): """リトライ機能付きのAPI呼び出し""" for attempt in range(max_retries): try: response = requests.post( f"{self.base_url}/chat/completions", headers=headers, json=payload, timeout=timeout # タイムアウト値を延長 ) response.raise_for_status() return response.json() except requests.exceptions.Timeout: print(f"タイムアウト({attempt + 1}/{max_retries})") if attempt == max_retries - 1: raise ConnectionError("API呼び出しがタイムアウトしました") except requests.exceptions.ConnectionError as e: # ネットワークエラー時の処理 print(f"接続エラー: {e}") time.sleep(2 ** attempt) # 指数バックオフ return None

エラー2:401 Unauthorized

# 原因:APIキーが無効または期限切れ

解決:APIキー検証ロジック追加

def validate_api_key(self): """APIキーの有効性を検証""" headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } test_payload = { "model": "deepseek-chat", "messages": [{"role": "user", "content": "test"}], "max_tokens": 5 } try: response = requests.post( f"{self.base_url}/chat/completions", headers=headers, json=test_payload, timeout=10 ) if response.status_code == 401: raise ConnectionError( "401 Unauthorized: APIキーが無効です。" "https://www.holysheep.ai/register で新しいキーを取得してください" ) return True except Exception as e: print(f"APIキー検証エラー: {e}") return False

エラー3:429 Rate Limit Exceeded

# 原因:リクエスト上限超過

解決:レート制限対応とキュー実装

import time from collections import deque from threading import Lock class RateLimitedAgent: """レート制限対応のReActエージェント""" def __init__(self, api_key, requests_per_minute=60): self.api_key = api_key self.base_url = "https://api.holysheep.ai/v1" self.request_times = deque() self.rpm_limit = requests_per_minute self.lock = Lock() def _wait_for_rate_limit(self): """レート制限まで待機""" with self.lock: now = time.time() # 1分以内のリクエストをクリア while self.request_times and self.request_times[0] < now - 60: self.request_times.popleft() if len(self.request_times) >= self.rpm_limit: # 最も古いリクエストが期限切れになるまで待機 wait_time = 60 - (now - self.request_times[0]) print(f"レート制限: {wait_time:.1f}秒待機") time.sleep(wait_time) self.request_times.append(time.time()) def call_api(self, messages): """レート制限対応のAPI呼び出し""" self._wait_for_rate_limit() headers = { "Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json" } response = requests.post( f"{self.base_url}/chat/completions", headers=headers, json={"model": "deepseek-chat", "messages": messages}, timeout=30 ) if response.status_code == 429: # 429エラーの場合は強制的に待機 time.sleep(5) return self.call_api(messages) return response

エラー4:無限ループ防止

# 原因:AIが同じ思考パターンを繰り返す

解決:反復検出機構の実装

class LoopDetectionMixin: """ループ検出機能付きエージェント""" def __init__(self): self.thought_history = [] self.max_history = 10 self.similarity_threshold = 0.85 def detect_loop(self, current_thought: str) -> bool: """思考のループを検出""" # 簡易的なハッシュベース検出 current_hash = hash(current_thought[:100]) # 先頭100文字でハッシュ for prev_hash in self.thought_history: # 類似度チェック(実際はより高度なNLP手法を使用 if current_hash == prev_hash: return True self.thought_history.append(current_hash) if len(self.thought_history) > self.max_history: self.thought_history.pop(0) return False def force_diversify(self, messages) -> List[Dict]: """多様性を持たせる指示を追加""" system_msg = messages[0] if "temperature" not in str(messages): # 温度を上げて多様性を増加 pass return messages

まとめ

ReActパターンは、AIエージェントに計画立案能力和動的な判断力を付与する強力なアーキテクチャです。実装時には、API呼び出しの信頼性確保、レート制限対応、無限ループ防止などの実務的な課題への対処が重要です。

HolySheep AIは、DeepSeek V3.2の低コスト($0.42/MTok)と<50msレイテンシという性能で、ReActパターンの複数ターン対話を経済的に運用できます。WeChat PayやAlipayにも対応しており、日本の開発者も簡単に始められます。

まずは基礎実装から試して、少しずつツール拡張やエラー処理を実装していくことをおすすめします。ReActパターンをマスターすれば、より複雑なタスクを自律的に処理するAIエージェントを構築できるようになります。

👉 HolySheep AI に登録して無料クレジットを獲得