🛠️ 第十二章:Custom Tools 専用武器の作成 (AIに手足を与える)
前章の実戦では、CrewAIを使って「研究者」と「ライター」を含む仮想チームを構築しました。
研究者には標準装備の武器であるSerperDevTool(Google検索ツール)を与え、自分でネット上の情報を検索できるよう��しました。
しかし、実際のビジネスシーンで最も価値のあるデータはGoogle上にはなく、会社の内部データベースにあるのです! もし上司がAIに「先月クレームが多かったキャンプ場ランキング分析」を作成するよう指示しても、AIがGoogle検索で見つけることはできません。 AIに「鍵」を与え、会社のSupabaseデータベースにアクセスしてクレーム記録を抽出する方法を教える必要があります。
このマスター級実戦講座では、Agentic AIの最も核心的な領域である**カスタムツール(Custom Tools)**の世界へご案内します。 普通のPython関数を、AIが理解でき「いつ使うべきかを自分で判断する」超兵器に変える方法を教えます!
🔧 実戦 1:誤解を解く、AIのToolとは何か?
多くのエンジニアは、Toolとは単にフロントエンドから呼び出すAPIを作ることだと思っています。全く違います。 CrewAI(およびLangChain)のエコシステムでは、Toolは2つの魂を持たなければなりません:
- 実行ロジック(Pythonコード):AIがこのツールを使うと決めた時に実際に実行されるコード。
- 使用説明書(DocstringとType Hint):これが最も重要!AIの脳に向けて書かれたテキストで、「このツールは何をするのか」「渡すパラメータはどんな形式か」を伝えます。
💡 Vibe Prompt 実戦 1:最も基本的な計算機ツール
大規模言語モデルは数学が苦手です(確率で文字を推測しているため)。345掛ける678と聞かれると、でたらめな数字を答えるかもしれません。 AIに絶対に間違えない計算機を装備させましょう。
[!IMPORTANT] 以下のPromptをAIにコピーして送信してください:
CrewAIシステムを開発中で、Agentが正確に計算できるカスタムツール(Custom Tool)が必要です。@toolデコレータを使ってPython関数calculate_math(expression: str)を作成してください。要件:1. from langchain.tools import toolをインポート。2. Pythonのeval()を使って渡された数式(expression)を計算。3. このツールをいつ使うべきかAIに伝える非常に詳細なdocstringを必ず追加。4. 式のフォーマットエラーでクラッシュしないようtry-exceptを追加。
🤖 AIの神級計算アドオン:
from langchain.tools import tool
# @toolデコレータが魔法の鍵で、この普通の関数をAIツールオブジェクトに変換します
@tool("数学計算マスターツール")
def calculate_math(expression: str) -> str:
"""
これは強力な数学計算機です。
大規模言語モデル(つまりあなた)は複雑な数学計算を間違えることがあります。
タスクに精密な計算が必要な数学問題(例:加減乗除、パーセンテージ計算、合計計算)が含まれる場合、
必ずこのツールを使用して正しい答えを得てください。自分で推測してはいけません。
パラメータ'expression'は有効なPython数式文字列でなければなりません。
入力例:"2500 * 0.15" または "(1200 + 800) / 4"
"""
try:
# evalを使って安全に数式文字列を計算
# (実戦では絶対的安全のため、より厳密な数学解析ライブラリを使いますが、ここでは簡単なデモンストレーションとします)
result = eval(expression)
return f"式 '{expression}' の計算結果は:{result}"
except Exception as e:
return f"計算エラーが発生しました。式のフォーマットを確認してください。エラー詳細:{str(e)}"
🔍 深層解析:
気づきましたか?このコードで最も長い部分は"""..."""(Docstring)です。
これを書かないと、AIはこのツールをどう使っていいかわかりません。
しかし、「必ずこのツールを使って、自分で推測してはいけない」という警告を加えることで、AIはビジネスレポートで割引計算が必要な場面で、きちんと立ち止まり、calculate_math("3999 * 0.8")を呼び出し、3199.2を得た後、文章を続けるようになります。これがフールプルーフの極致です!
🗄️ 実戦 2:AIにSupabaseデータベースを検索させる
ここからビジネス実戦に入ります。特定のキャンプ場の「リアルタイム空き状況」を検索できるツールを作成します。
💡 Vibe Prompt 実戦 2:データベース検索ツールの作成
[!IMPORTANT] 以下のPromptをAIにコピーして送信してください:
CrewAIのカスタムツールcheck_camp_vacancy(camp_id: str)を作成してください。要件:1. supabase-pyを使ってSupabaseに接続(クライアント変数はsupabase_clientと仮定)。2. "camps"テーブルからidがcamp_idの"vacancy_count"カラムを検索。3. 見つからない場合は"該当するキャンプ場が見つかりません"と返す。4. camp_idがUUID形式であることをAIに伝える完全なdocstringを記述。
🤖 AIのデータベース直結チャネル:
import os
from langchain.tools import tool
from supabase import create_client
# 接続初期化
supabase_client = create_client(os.getenv("SUPABASE_URL"), os.getenv("SUPABASE_KEY"))
@tool("キャンプ場空き状況検索システム")
def check_camp_vacancy(camp_id: str) -> str:
"""
これはキャンプ場のリアルタイム空き状況を検索する内部データベースツールです。
顧客やタスクでキャンプ場の「空きがあるか」「いくつ空きがあるか」を確認する必要がある場合、このツールを呼び出してください。
パラメータ'camp_id'はキャンプ場の一意の識別子でなければなりません(通常は英数字の長い文字列、例:'a1b2-c3d4...')。
キャンプ場の日本語名を渡さないでください!日本語名しかわからない場合は、まず他の検索ツールでIDを調べてください。
"""
print(f"🕵️♂️ [システムログ] AIがデータベースを検索中、対象キャンプ場ID: {camp_id}")
try:
response = supabase_client.table("camps").select("name, vacancy_count").eq("id", camp_id).execute()
# データが取得できたか確認
if len(response.data) > 0:
camp_info = response.data[0]
return f"キャンプ場『{camp_info['name']}』の現在の空き状況:{camp_info['vacancy_count']} サイト。"
else:
return f"エラー:ID {camp_id} のキャンプ場はデータベースに見つかりませんでした。"
except Exception as e:
return f"データベース接続で異常が発生しました:{str(e)}"
📧 実戦 3:AIにEmail送信権限を与える(Action Tools)
これまでのツールは「読み取り(Read)」で比較的安全です。 しかし、AI従業員が「自動マーケティングの達人」で、プロモーション記事を書いた後、直接顧客に「自分でメールを送信」できるようにしたい場合はどうでしょうか? これは**Action(アクション実行)**ツールと呼ばれ、非常に強力ですが、極めて危険でもあります!
💡 Vibe Prompt 実戦 3:Email送信ボタンの作成
[!IMPORTANT] 以下のPromptをAIにコピーして送信してください:
カスタムツールsend_marketing_email(recipient_email: str, subject: str, content: str)が必要です。このツールはAIが自分でマーケティングメールを送信できるようにします。概念を示すた��、実際のSMTP送信コードは不要で、print()で送信過程を模倣してください。重要なのは:docstringで、AIに送信前に攻撃的な内容がないこと、件名が魅力的であることを厳重に警告することです。完全なコードを提供してください。
🤖 AIの全自動メール送信機:
from langchain.tools import tool
@tool("自動Email送信システム")
def send_marketing_email(recipient_email: str, subject: str, content: str) -> str:
"""
これは実際のEmailを外部に送信する危険なツールです!一度呼び出されると、メールは即座に送信され、取り消せません。
マーケティング文案の作成が完了し、「顧客に送信」するよう指示された場合、このツールを使用してください。
パラメータ説明:
- recipient_email: 対象顧客のEmailアドレス(正しいメール形式でなければなりません)。
- subject: メール件名。誤字がなく、非常に魅力的であることを確認してください。
- content: メール本文(プレーンテキストまたはHTML形式対応)。
【警告】:送信前にcontentを徹底的に確認し、虚偽のプロモーションコードや不正確な価格約束を含めないでください!
"""
# 実際の実装ではsmtplibやSendGridなどのサードパーティサービスを使用
print("\n" + "="*50)
print("🚨 [アクション警告] AIが現実世界の操作をトリガーしました!")
print(f"📧 送信先: {recipient_email}")
print(f"📌 件名: {subject}")
print(f"📝 本文プレビュー: {content[:50]}...")
print("="*50 + "\n")
return f"システム報告:メール '{subject}' は {recipient_email} に正常に送信されました。"
🎭 実戦 4:複数ツールの組み合わせ技でAIを超人にする
現在、3つのツールがあります:計算機、データベース検索、メール送信機。 これらを1つのAgentに装備させ、驚くべき化学反応を見てみましょう。
💡 Vibe Prompt 実戦 4:万能傭兵を武装させ複雑なタスクを実行
[!IMPORTANT] 以下のPromptをAIにコピーして送信してください:
先程の3つのツール(calculate_math, check_camp_vacancy, send_marketing_email)を統合してください。1. スーパーAgent(Sales & Marketing Exec)を作成し、これら3つのツールをtools=[]に追加。2. 非常に複雑なTaskを作成。シナリオは以下の通り:"上司がID 'camp-123'のキャンプ場をVIP顧客vip@example.comにプロモーションするよう指示。""まずこのキャンプ場の空き状況を確認する必要がある。""空きがあれば、貸切(1サイト1200円と仮定)で20%割引の総額を計算する。""最後に、この情報を非常に熱意あるEmailにまとめ、ツールを使って送信する。"これら全てを統合したCrewAI実行スクリプトを提供してください。
🤖 AIの究極自動化デモンストレーション:
from crewai import Agent, Task, Crew, Process
# 1. 3つの神器を装備したスーパーセールスマンを作成
super_sales = Agent(
role='トップセールス&マーケティングディレクター',
goal='データと精密計算を活用し、VIP顧客が拒否できないプロモーションメールを送信する。',
backstory='あなたは冷静で論理的、しかし文章は非常に説得力のあるトップセールスです。決して間違えず、必ずデータベースで確認します。',
verbose=True,
# 🔥 完全武装!
tools=[check_camp_vacancy, calculate_math, send_marketing_email]
)
# 2. マルチステップ推論が必要な超複雑タスクを割り当て
vip_sales_task = Task(
description=(
"これは緊急のハイエンドセールスタスクです!\n"
"1. まずキャンプ場ID 'camp-123'の空き状況を確認してください。\n"
"2. 1サイトあたり1200円と仮定します。残りのサイトを『全サイト貸切』し、20%割引(0.8)を適用した総額を計算してください。\n"
"3. 『残りサイト数』と『割引後の総額』を、熱意とVIP待遇感あふれる招待状にまとめてください。\n"
"4. 送信先は 'vip@example.com'です。\n"
"5. 最後に、送信アクションを実行してください。"
),
expected_output="送信完了後、送信したメールの件名と総額を報告してください。",
agent=super_sales
)
# 3. 本部を起動!
sales_crew = Crew(
agents=[super_sales],
tasks=[vip_sales_task],
process=Process.sequential,
verbose=True
)
print("🚀 スーパーセールスマンを起動、奇跡を目撃しましょう...")
# 注意:このコードを正常に実行するには、Supabaseツールの応答をモック(模擬)する必要があります。そうしないとcamp-123が見つからずエラーになります
sales_crew.kickoff()
🔍 深層解析(ターミナルで起こること):
実行すると、AIの脳(super_sales)の思考プロセス(Thought Process)が見られます。この対話は百万ドルの価値があります:
- 思考: camp-123の空き状況をまず知る必要がある。
アクション:
check_camp_vacancy('camp-123')を呼び出し 観察: キャンプ場『星空部落』の現在の空き状況:15サイト。 - 思考: 了解、15サイト空いている。1サイト1200円、全サイト貸切で20%割引。総額を計算しなければ。
アクション:
calculate_math('15 * 1200 * 0.8')を呼び出し 観察: 計算結果は:14400.0 - 思考: データが揃った!メールを作成し、送信する。
アクション:
send_marketing_email('vip@example.com', '【VIP限定タイムセール】星空部落 15サイト完全貸切特典', '親愛なるVIP様... 総額14,400円にて...')を呼び出し 観察: システム報告:メールは正常に送信されました。
これがAgentic Workflowの極致です! もはや単なるQ&Aではなく、「推論」「計画」「ツール呼び出しによるデータ修正」「最終アクション実行」を学んだのです。コンピュータ内に完全自動化されたマーケティング部門を構築したようなものです!
✅ 本章のまとめと究極アーキテクチャの秘訣
この6000字に及ぶカスタムツール実戦で、大規模言語モデルの致命的な「知識の盲点」と「数学音痴」の限界を打ち破りました。
スーパーブレイン構築の鍵を振り返ります:
- **@toolデコ