Claude Code(Anthropic Claude)の最大の特徴は、Function Calling(ツール呼び出し)を活用した外部システム連携です。ECサイトのAIカスタマーサービス、エンタープライズRAGシステム、パーソナル開発プロジェクトなど、実務でClaudeのツール呼び出しを活用する場面が増えています。本ガイドでは、HolySheep AI を基盤としたClaude Tool Useの実装方法を基礎から丁寧に解説します。

Claude Tool Use とは?基本概念の理解

Claude Tool Useは、Claudeモデルが外部ツール(関数)を呼び出し、その結果を次の思考に組み込む仕組みです。これにより、Claudeは以下が可能になります:

従来のプロンプトエンジニアリングだけでは実現困難だった「外部データと連携した動的な応答生成」が、Tool Useによって可能になります。

HolySheep AI 利用の準備

HolySheep AI は、Anthropic互換のAPIを提供する信頼性の高いプラットフォームです。以下の理由から、Claude Tool Useの実装に適しています:

tools パラメータの設定方法

tools パラメータの構造

Claude Tool Use的核心は、toolsパラメータの正しい設定です。以下の構造を理解しましょう:

tools = [
    {
        "name": "get_product_inventory",
        "description": "指定されたSKUの在庫数を取得する関数",
        "input_schema": {
            "type": "object",
            "properties": {
                "sku": {
                    "type": "string",
                    "description": "商品のSKUコード(例:SKU-12345)"
                }
            },
            "required": ["sku"]
        }
    },
    {
        "name": "calculate_shipping",
        "description": "配送先住所に基づいて送料を計算する関数",
        "input_schema": {
            "type": "object",
            "properties": {
                "prefecture": {
                    "type": "string",
                    "description": "配送先の都道府県"
                },
                "weight_kg": {
                    "type": "number",
                    "description": "商品の重さ(kg)"
                }
            },
            "required": ["prefecture", "weight_kg"]
        }
    },
    {
        "name": "process_order",
        "description": "注文を確定し、払い金額を計算する関数",
        "input_schema": {
            "type": "object",
            "properties": {
                "sku": {"type": "string"},
                "quantity": {"type": "integer"},
                "prefecture": {"type": "string"}
            },
            "required": ["sku", "quantity", "prefecture"]
        }
    }
]

nameは関数の識別子、descriptionはClaudeがいつ呼び出すべきかを判断するための重要な手がかりとなります。input_schemaはJSON Schema形式で関数の引数を定義します。

ユースケース1:ECサイトのAIカスタマーサービス

ECサイトのAIカスタマーサービスでよくある)「この商品の在庫はありますか?」という質問に対する応答を実装します。

import openai
from typing import List, Dict, Any

HolySheep API設定

client = openai.OpenAI( api_key="YOUR_HOLYSHEEP_API_KEY", base_url="https://api.holysheep.ai/v1" )

ツール定義

tools = [ { "name": "check_inventory", "description": "商品の在庫状況を確認する。在庫確認が必要な時に必ず呼び出す。", "input_schema": { "type": "object", "properties": { "product_name": { "type": "string", "description": "商品名またはSKU" } }, "required": ["product_name"] } }, { "name": "get_product_price", "description": "商品の価格を取得する。价格在確認が必要な時に呼び出す。", "input_schema": { "type": "object", "properties": { "product_name": { "type": "string", "description": "商品名" } }, "required": ["product_name"] } } ]

ダミーのツール実装

def execute_tool(tool_name: str, arguments: Dict[str, Any]) -> str: """ツール実際の実行ロジック(実際のシステムと連携)""" if tool_name == "check_inventory": # 実際のDBクエリ或其他システム連携 inventory_db = { "ノートPC": 25, "ワイヤレスマウス": 150, "キーボード": 80 } stock = inventory_db.get(arguments["product_name"], 0) return f"在庫数: {stock}個" elif tool_name == "get_product_price": price_db = { "ノートPC": 89800, "ワイヤレスマウス": 3500, "キーボード": 7500 } price = price_db.get(arguments["product_name"], None) if price: return f"価格: ¥{price:,}" return "該当商品が見つかりません"

多輪ツール呼び出しの処理

def chat_with_tools(user_message: str) -> str: messages = [ {"role": "system", "content": "あなたはECサイトのAIコンシェルジュです。在庫や価格の確認が必要な場合は、必ずツールを呼び出してください。"} ] messages.append({"role": "user", "content": user_message}) response = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice="auto" ) assistant_message = response.choices[0].message messages.append(assistant_message) # ツール呼び出しがある場合 while assistant_message.tool_calls: for tool_call in assistant_message.tool_calls: tool_name = tool_call.function.name arguments = eval(tool_call.function.arguments) # JSON文字列を辞書に変換 # ツールを実行 tool_result = execute_tool(tool_name, arguments) # ツール結果をmessagesに追加 messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": tool_result }) # 次のレスポンスを取得 response = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice="auto" ) assistant_message = response.choices[0].message messages.append(assistant_message) return assistant_message.content

実行例

result = chat_with_tools("ノートPCの在庫と価格を教えてください") print(result)

ユースケース2:エンタープライズRAGシステム

企業内の文書検索をRAGで実現し、Claudeのツール呼び出しでより精度の高い回答生成を行います。

from openai import OpenAI
import json

client = OpenAI(
    api_key="YOUR_HOLYSHEEP_API_KEY",
    base_url="https://api.holysheep.ai/v1"
)

RAG検索ツール定義

tools = [ { "name": "search_company_documents", "description": "企业内部の文書を検索する。経費申請手続きや休假規定などの確認が必要な時に呼び出す。", "input_schema": { "type": "object", "properties": { "query": { "type": "string", "description": "検索クエリ" }, "category": { "type": "string", "enum": ["経費", "人事", "法務", "技術", "全部"], "description": "文書のカテゴリ" }, "top_k": { "type": "integer", "description": "取得する上位の結果数", "default": 5 } }, "required": ["query"] } }, { "name": "get_employee_info", "description": "社員情報を取得する。特定の社員の情報を確認する際に呼び出す。", "input_schema": { "type": "object", "properties": { "employee_id": { "type": "string", "description": "社員ID" } }, "required": ["employee_id"] } } ]

文書検索結果の模擬データ

def simulate_vector_search(query: str, category: str = "全部", top_k: int = 5): """ вектор検索のシミュレーション(実際の実装ではEmbeddings APIを使用)""" mock_results = { "経費申請": [ {"title": "経費精算ガイドライン", "content": "経費申請は每月末日までに翌月分の申請を行ってください。...", "score": 0.95}, {"title": "出張旅費規定", "content": "国内出張の 교통비は実費精算となります。...", "score": 0.88} ], "休假": [ {"title": "年次休假取得規則", "content": "入社後6ヶ月で10日、1年後に11日の年次休假が付与されます。...", "score": 0.92}, {"title": "特別休假实施办法", "content": "婚姻・出産・ смерть等の際に特別休假が付与されます。...", "score": 0.85} ] } return mock_results.get(query, [{"title": "一般的な社内文書", "content": "詳細については社内のイントラネットをご確認ください。", "score": 0.70}]) def execute_rag_tool(query: str, category: str = "全部", top_k: int = 5) -> str: """RAGツールの実装""" search_results = simulate_vector_search(query, category, top_k) formatted_results = "\n\n【検索結果】\n" for i, result in enumerate(search_results[:top_k], 1): formatted_results += f"{i}. 【{result['title']}】(関連度: {result['score']:.0%})\n" formatted_results += f" {result['content']}\n\n" return formatted_results def rag_chat(user_query: str) -> str: messages = [ {"role": "system", "content": """あなたは企業のスマートアシスタントです。 社員からの質問に対して、社内文書を検索して正確な回答を生成してください。 文書検索で得られた情報を基に、簡潔かつ正確に回答してください。"""} ] messages.append({"role": "user", "content": user_query}) response = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice="auto", max_tokens=2000 ) assistant_message = response.choices[0].message messages.append(assistant_message) # ツール呼び出しの処理 while assistant_message.tool_calls: for tool_call in assistant_message.tool_calls: tool_name = tool_call.function.name args = json.loads(tool_call.function.arguments) tool_result = execute_rag_tool( query=args.get("query", ""), category=args.get("category", "全部"), top_k=args.get("top_k", 5) ) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": tool_result }) response = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice="auto", max_tokens=2000 ) assistant_message = response.choices[0].message messages.append(assistant_message) return assistant_message.content

実行例

result = rag_chat("経費申請の締め切りは何日ですか?また、承認流程についても教えてください") print(result)

tools_choice パラメータの活用

tool_choiceパラメータは、Claudeにツール選択の方法を指示します。3つのオプションがあります:

# tool_choiceの異なる設定例

自動選択(デフォルト)

response_auto = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice="auto" )

必ずツールを呼び出す

response_any = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice="any" )

特定のツールを強制

response_required = client.chat.completions.create( model="claude-sonnet-4-20250514", messages=messages, tools=tools, tool_choice={"type": "function", "function": {"name": "search_company_documents"}} )

エラーハンドリングの実装

実戦ではツール呼び出し中に様々なエラーが発生します。堅牢なエラーハンドリングを実装しましょう:

import json
from typing import Optional

def safe_tool_execution(tool_name: str, arguments: dict) -> dict:
    """
    安全なツール実行ラッパー
    エラーが発生してもClaudeに通知し、会話を継続できるようにする
    """
    try:
        # ツールの存在確認
        available_tools = {t["name"] for t in tools}
        if tool_name not in available_tools:
            return {
                "success": False,
                "error": f"不明なツール: {tool_name}",
                "result": None
            }
        
        # ツールの実行
        result = execute_tool(tool_name, arguments)
        
        return {
            "success": True,
            "error": None,
            "result": result
        }
        
    except json.JSONDecodeError as e:
        return {
            "success": False,
            "error": f"引数の解析エラー: {str(e)}",
            "result": None
        }
    except KeyError as e:
        return {
            "success": False,
            "error": f"必須パラメータ不足: {str(e)}",
            "result": None
        }
    except Exception as e:
        return {
            "success": False,
            "error": f"予期しないエラー: {str(e)}",
            "result": None
        }

def chat_with_tools_robust(user_message: str, max_turns: int = 10) -> str:
    """堅牢な多輪対話実装"""
    messages = [
        {"role": "system", "content": "あなたは有帮助なAIアシスタントです。"}
    ]
    messages.append({"role": "user", "content": user_message})
    
    turn_count = 0
    
    while turn_count < max_turns:
        response = client.chat.completions.create(
            model="claude-sonnet-4-20250514",
            messages=messages,
            tools=tools,
            tool_choice="auto",
            max_tokens=1500
        )
        
        assistant_message = response.choices[0].message
        messages.append(assistant_message)
        
        if not assistant_message.tool_calls:
            break
        
        for tool_call in assistant_message.tool_calls:
            tool_name = tool_call.function.name
            try:
                args = json.loads(tool_call.function.arguments)
            except json.JSONDecodeError:
                tool_result = "エラー: ツール引数の解析に失敗しました"
            else:
                execution = safe_tool_execution(tool_name, args)
                if execution["success"]:
                    tool_result = execution["result"]
                else:
                    tool_result = f"エラー: {execution['error']}"
            
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": tool_result
            })
        
        turn_count += 1
    
    if turn_count >= max_turns:
        return "処理が複雑すぎました。質問をより具体的にしてください。"