ADKを使用したエージェントへのファンクション・ツールの追加
このチュートリアルでは、生成AIエージェントの既存のエージェントにファンクション・ツールを追加するステップについて説明します。
関数ツールを使用すると、エージェントはカスタム記述のローカル定義関数をツールとして使用できます。ローカル処理、簡単な認証、および既存の機能とのシームレスな統合により、エンタープライズ・ケースに非常に柔軟性があり、特に有用です。
この例では、気象エージェントにカスタム機能ツールが装備されています。これは関数呼び出しエージェントとも呼ばれます。
機能ツールはローカルで実行されます。
OCIサーバー上のリモート・エージェントに送信されるのは、ファンクション定義(ファンクション名、ファンクション・パラメータおよびその説明)です。OCIサーバーはファンクション実装にアクセスしません。
概要
天気問合せが実行されると、リモート・エージェントはget_weather
ツールを使用するようにインテント分類を効果的に実行します。たとえば、自然言語問合せIs it cold in Seattle?
に基づいて、リモート・エージェントは引数スロットを埋めてリクエストを行います。
エージェントは、クライアント・アプリケーションに必要なアクションを含むリクエストを送信します。この場合、クライアントに必要なアクションは、引数location
=Seattle
を使用してget_weather
ファンクション・ツールを起動することです。
エージェント開発キット(ADK)は次のことを行います。
- 必要なアクションを解析します
- ローカル関数が登録されました
- 特定の引数を使用してこの関数を実行します。
- 関数呼び出しの出力を取得します
- エージェントがその出力を使用してユーザー・プロンプトに対する回答を生成できるように、出力をリモート・エージェントに戻します。
前提条件
- コードを実行しているマシンで、OCI API構成ファイルを設定します。構成が、生成AIエージェントがホストされているリージョンを参照していることを確認します。
-
仮想環境の構築:
python3 -m venv <myenv>
仮想環境をアクティブ化します。
source <myenv>/bin/activate
-
ADKをインストールします。Python ADKにはPython 3.10以降が必要です。
pip install "oci[adk]
開発用のコンパートメントの設定
-
管理者に依頼して、次のIAMポリシーを追加してください:
allow <a-group-your-user-name-belongs-to> to manage all-resources in compartment <your-compartment-name>
重要
コンパートメントへの完全なアクセス権の提供は、チュートリアルに便利です。ただし、本番環境では、より限定的なポリシーを使用してエージェントへのアクセスを制限します。生成AIエージェントへのアクセスの取得を参照してください。 - Oracle Cloud Infrastructure Consoleにサインインします。
- ナビゲーション・メニューを開き、「アイデンティティおよびセキュリティ」を選択します。「アイデンティティ」で、「コンパートメント」を選択します。
- 「コンパートメントの作成」を選択します。
-
次の情報を入力します:
- 名前:
<your-compartment-name>
- 説明:
Compartment for <your-description>.
- 親コンパートメント:
<your-tenancy>(root)
- 名前:
- 「コンパートメントの作成」を選択します。
参照: コンパートメントの作成
エージェントの作成
- コンソールのナビゲーション・バーで、前のセクションで構成ファイルに対して選択したリージョンと同じリージョンを選択します。
- 「エージェント」リスト・ページで、「エージェントの作成」を選択します。リスト・ページの検索に関するヘルプが必要な場合は、エージェントのリストを参照してください。
-
次の情報を入力します。
- 名前:
<your-agent-name>
- コンパートメント: 作業権限を持つコンパートメントを選択します。
- 説明: 初期ツールがないエージェント。ADKを使用してツールを追加します。
- ようこそメッセージ: 空白のままにします。
- 工順指示: 空白のままにします。
- 名前:
- 「次へ」を選択して、「ツールの追加」ステップに移動します。このページをスキップして、ツールを追加しないでください。
- 「次へ」を選択します。
- (オプション)「このエージェントのエンドポイントの自動作成」を選択して、エージェントの作成時にエンドポイントを作成し、他のすべてのデフォルト・オプションを保持します。
-
「次へ」を選択し、「エージェントの作成」を選択します。
ノート
要求された場合は、ライセンス条件に同意します。 - エージェントがアクティブになるまで待機します。
必要な情報の収集
-
使用している環境で、設定ファイルに設定したリージョンをメモ帳にコピーします。たとえば、
us-chicago-1
です。 - コンソールの「エージェント」リスト・ページで、このチュートリアルで作成したエージェントを選択します。リスト・ページの検索に関するヘルプが必要な場合は、エージェントのリストを参照してください。
-
エージェントのOCIDをコピーし、次のセクションのノートパッドに貼り付けます。
エージェントOCIDの例:
ocid1.genaiagent.oc1.us-chicago-1.<unique-id>
- このエージェントの「エンドポイント」を選択します。
-
エンドポイントのOCIDをコピーし、次のセクションのノートパッドに貼り付けます。
エンドポイントOCIDの例:
ocid1.genaiagentendpoint.oc1.us-chicago-1.<unique-id>
-
「アイデンティティとセキュリティ」に移動し、「コンパートメント」を選択します。エージェントを含むコンパートメントを選択します。コンパートメントのOCIDをコピーし、ノートパッドに貼り付けます。
コンパートメントOCIDの例:
ocid1.compartment.oc1..<unique-id>
ローカル・ファイルの作成
- ターミナルからホーム・ディレクトリに移動します。
- ADKというディレクトリを作成します。
- ADKディレクトリに移動します。
-
weather_agent.py
というファイルを作成します。 -
次のコードを
weather-agent.py
に貼り付けます。<region-where-agent-is-created>および<your-agent-endpoint>を、収集した値に置き換えます。from typing import Dict from adk import Agent, AgentClient, tool @tool def get_weather(location: str) -> Dict[str, str]: """Get the weather for a given location""" return {"location": location, "temperature": 72, "unit": "F"} def main(): # Create a client with your authentication details client = AgentClient( auth_type="api_key", profile="DEFAULT", region="<region-where-agent-is-created>" ) # Instantiate the agent with your agent endpoint ID and the tool agent = Agent( client=client, agent_endpoint_id="<your-agent-endpoint>", instructions="Perform weather queries using the given tools.", tools=[get_weather] ) # Set up the agent (configures instructions and tools in the remote agent resource) agent.setup() # Run the agent with an input input = "Is it cold in Seattle?" response = agent.run(input) # Print the response response.pretty_print() if __name__ == "__main__": main()
ツールの追加
このチュートリアル用に新しいエージェントを作成するのではなく、既存のエージェントを選択した場合、このファイルを実行する前に、リモート・エージェントにツールがないことを確認してください。このプログラムは、ツールが
get_weather
ツールという名前でないかぎり、リモート・エージェント上のすべてのツールを削除します。リモートのget_weather
ツールが見つかった場合は、ローカル・ツールと同期するようにリモート・ツールが更新されます。-
コンソールで、エージェントの詳細ページに移動し、次の値をメモします。
- 工順指示: 空白にする必要があります。
- 「ツール」を選択します。ツール・リストは空である必要があります。
-
Pythonファイル
get_weather
を実行しますpython3 weather-agent.py
-
出力で、ローカルおよびリモートの機能名を確認し、
get_weather
ツールがリモート・エージェントに追加されていることを確認します。出力例:Waiting for agent to be active... ╭─ Local and remote function tools found ─╮ │ Local function tools (1): │ │ ['get_weather'] │ │ │ │ Remote function tools (0): │ │ [] │ ╰─────────────────────────────────────────╯ Found local tool not in remote tools: get_weather. Adding it to the remote agent... Waiting for tool to be active... Checking synchronization of local and remote RAG tools... No active remote RAG tools found. No local RAG tool to add.
-
コンソールで、エージェントの詳細ページに移動し、更新を確認します。
- エージェントの詳細ページで、ルーティング手順が空白から
Perform weather queries using the given tools.
に変わります - 「ツール」を選択します。ツール
get_weather
がツールのリストに表示されます。 - get_weatherを選択し、作業リクエストで、CREATE_TOOL操作が成功したことを確認します。
- エージェントの詳細ページで、ルーティング手順が空白から
出力を読む
-
出力で、ユーザー・メッセージを確認します。出力例:
╭──────────────────────────────────── Chat request to remote agent ─────────────────────────────────────╮ │ (Local --> Remote) │ │ │ │ user message: │ │ Is it cold in Seattle? │ │ │ │ performed actions by client: │ │ [] │ │ │ │ session id: │ │ ocid1.genaiagentsession.<unique-id> │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯
-
チャットのレスポンスを読む。出力例:
╭────────────────── Chat response from remote agent ──────────────────╮ │ (Local <-- Remote) │ │ │ │ agent message: │ │ null │ │ │ │ required actions for client to take: │ │ [ │ │ { │ │ "action_id": "<unique-id>", │ │ "required_action_type": "FUNCTION_CALLING_REQUIRED_ACTION", │ │ "function_call": { │ │ "name": "get_weather", │ │ "arguments": "{\"location\": \"Seattle\"}" │ │ } │ │ } │ │ ] │ ╰─────────────────────────────────────────────────────────────────────╯
-
エージェントがリクエストしたファンクション・コールを確認します。出力例:
╭─ Function call requested by agent and mapped local handler function ─╮ │ Agent function tool name: │ │ get_weather │ │ │ │ Agent function tool call arguments: │ │ {'location': 'Seattle'} │ │ │ │ Mapped local handler function name: │ │ get_weather │ ╰──────────────────────────────────────────────────────────────────────╯
-
ファンクションの実行結果を確認します。出力例:
╭─────── Obtained local function execution result ────────╮ │ {'location': 'Seattle', 'temperature': 72, 'unit': 'F'} │ ╰─────────────────────────────────────────────────────────╯
-
リモート・エージェントの出力例にチャット・リクエストを確認します。
╭──────────────────────────────────── Chat request to remote agent ─────────────────────────────────────╮ │ (Local --> Remote) │ │ │ │ user message: │ │ null │ │ │ │ performed actions by client: │ │ [ │ │ { │ │ "action_id": "<unique-id>", │ │ "performed_action_type": "FUNCTION_CALLING_PERFORMED_ACTION", │ │ "function_call_output": "{\"location\": \"Seattle\", \"temperature\": 72, \"unit\": \"F\"}" │ │ } │ │ ] │ │ │ │ session id: │ │ ocid1.genaiagentsession.oc1.us-chicago-1.xxx │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────╯
-
リモート・エージェントの出力例からチャット・レスポンスを読みます。
╭─────────────────────────────── Chat response from remote agent ────────────────────────────────╮ │ (Local <-- Remote) │ │ │ │ agent message: │ │ { │ │ "role": "AGENT", │ │ "content": { │ │ "text": "It's not cold in Seattle. The current temperature is 72 degrees Fahrenheit.", │ │ "citations": null, │ │ "paragraph_citations": null │ │ }, │ │ "time_created": "2025-04-10T18:47:33.617000+00:00" │ │ } │ │ │ │ required actions for client to take: │ │ null │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯
-
自然言語によるエージェント実行レスポンスを読む。出力例:
╭──────────────────────────────────────────────── Agent run response ────────────────────────────────────────────────╮ │ agent text message: │ │ It's not cold in Seattle. The current temperature is 72 degrees Fahrenheit. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
工具を取り外す
-
ローカル環境で、次の内容を含む
list_agent_tools.py
というファイルを作成します。また、OCID情報を使用してすべてのID変数を更新します。import json from adk import AgentClient def main(): agent_id = "ocid1.genaiagent.<unique-id>" agent_compartment_id = "<your-compartment-ocid>" region_id = "<your-region-id>" # Enter an OCI region such as "us-chicago-1" or airport code such as "ORD" # Create a client with your authentication details client = AgentClient( auth_type="api_key", profile="DEFAULT", region=region_id ) # Find the tools of the following agent in the following compartment tool_list = client.find_tools(agent_compartment_id, agent_id) json_str = json.dumps(tool_list, indent=4) print(json_str) for item in tool_list: print(f"Tool Name: {item.get('display_name')} \nTool OCID: {item.get('id')}") if __name__ == "__main__": main()
このスクリプトは、クライアントの
find_tool
操作をコールし、指定されたコンパートメント内の指定されたエージェントのすべてのツールを返します。 -
出力を確認します。
[ { "id": "ocid1.genaiagenttool.<unique-id>", "lifecycle_state": "ACTIVE", "time_created": "2025-04-10T21:49:19.350000+00:00", "time_updated": "2025-04-10T21:49:42.132000+00:00", "display_name": "get_weather", "description": "Get the weather for a given location created by ADK", "compartment_id": "<your-compartment-ocid>", "agent_id": "ocid1.genaiagent.<unique-id>", "tool_config": { "tool_config_type": "FUNCTION_CALLING_TOOL_CONFIG", "function": { "name": "get_weather", "description": "Get the weather for a given location", "parameters": { "type": "object", "properties": "{\"location\": {\"type\": \"string\"}}", "required": "['location']" } } }, "metadata": null, "freeform_tags": { "ModifiedBy": "ADK", "CreatedBy": "ADK" }, "defined_tags": { "Oracle-Tags": { "CreatedBy": "john.doe@example.com", "CreatedOn": "2025-04-10T21:49:19.277Z" } }, "system_tags": {} } ] Tool Name: get_weather Tool OCID: ocid1.genaiagenttool.oc1.us-chicago-1.amaa<your-ocid>
-
delete_tools.py
というファイルを作成し、次の情報をコピーして、delete_tool
操作を使用してweather_tool
を削除します。また、OCID情報を使用してすべてのID変数を更新します。import json from adk import AgentClient def main(): agent_id = "ocid1.genaiagent.<unique-id>" agent_compartment_id = "<your-compartment-ocid>" endpoint_id = "ocid1.genaiagentendpoint.<unique-id>" region_id = "<your-region-id>" # Create a client with your authentication details client = AgentClient( auth_type="api_key", profile="DEFAULT", region=region_id ) # Find the tools of the following agent in the following compartment tool_list = client.find_tools(agent_compartment_id, agent_id) json_str = json.dumps(tool_list, indent=4) print(json_str) for item in tool_list: print(f"Tool Name: {item.get('display_name')} \nTool OCID: {item.get('id')}") for item in tool_list: print(f"Deleting tool {item.get('display_name')} with tool OCID: {item.get('id')}") client.delete_tool(item.get('id')) print ("Tool deleted!") if __name__ == "__main__": main()
- コンソールで、エージェントの詳細ページに移動し、ツールが削除されていることを確認します。
-
仮想環境を非アクティブ化します
decativate