このチュートリアルの手順では、エージェントで関数ツールを使用する方法について説明します。エージェントは Azure OpenAI チャット補完サービス上に構築されています。
Important
すべてのエージェントの種類で関数ツールがサポートされているわけではありません。 呼び出し元が独自の関数を提供することを許可せずに、カスタム組み込みツールのみをサポートする場合があります。 この手順では、関数ツールをサポートする ChatClientAgentを使用します。
[前提条件]
前提条件と NuGet パッケージのインストールについては、このチュートリアルの 「エージェントの作成と実行 」の手順を参照してください。
関数ツールを使用してエージェントを作成する
関数ツールは、エージェントが必要なときに呼び出せるようにするカスタム コードにすぎません。
AIFunctionFactory.Create メソッドを使用してメソッドから AIFunction インスタンスを作成することで、任意の C# メソッドを関数ツールに変換できます。
関数またはそのパラメーターに関する追加の説明をエージェントに提供する必要がある場合は、異なる関数の中からより正確に選択できるように、メソッドとそのパラメーターに System.ComponentModel.DescriptionAttribute 属性を使用できます。
特定の場所の天気を偽装する単純な関数ツールの例を次に示します。 説明属性で修飾され、エージェントに自身とその場所パラメーターに関する追加の説明を提供します。
using System.ComponentModel;
[Description("Get the weather for a given location.")]
static string GetWeather([Description("The location to get the weather for.")] string location)
=> $"The weather in {location} is cloudy with a high of 15°C.";
エージェントを作成するときに、 AsAIAgent メソッドにツールの一覧を渡すことで、関数ツールをエージェントに提供できるようになりました。
using System;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
using OpenAI;
AIAgent agent = new AzureOpenAIClient(
new Uri("https://<myresource>.openai.azure.com"),
new DefaultAzureCredential())
.GetChatClient("gpt-4o-mini")
.AsAIAgent(instructions: "You are a helpful assistant", tools: [AIFunctionFactory.Create(GetWeather)]);
Warnung
DefaultAzureCredential は開発には便利ですが、運用環境では慎重に考慮する必要があります。 運用環境では、待機時間の問題、意図しない資格情報のプローブ、フォールバック メカニズムによる潜在的なセキュリティ リスクを回避するために、特定の資格情報 ( ManagedIdentityCredential など) を使用することを検討してください。
これで、通常どおりにエージェントを実行するだけで、エージェントは必要に応じて GetWeather 関数ツールを呼び出すことができます。
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
ヒント
実行可能な完全な例については、 .NET サンプル を参照してください。
Important
すべてのエージェントの種類で関数ツールがサポートされているわけではありません。 呼び出し元が独自の関数を提供することを許可せずに、カスタム組み込みツールのみをサポートする場合があります。 この手順では、関数ツールをサポートするチャット クライアントを介して作成されたエージェントを使用します。
[前提条件]
前提条件と Python パッケージのインストールについては、このチュートリアルの 「エージェントの作成と実行 」の手順を参照してください。
関数ツールを使用してエージェントを作成する
関数ツールは、エージェントが必要なときに呼び出せるようにするカスタム コードにすぎません。
任意の Python 関数を関数ツールに変換するには、エージェントの作成時にエージェントの tools パラメーターに渡します。
関数またはそのパラメーターに関する追加の説明をエージェントに提供する必要がある場合は、異なる関数の中からより正確に選択できるように、Python の型注釈と Annotated と Pydantic の Field を使用して説明を提供できます。
特定の場所の天気を偽装する単純な関数ツールの例を次に示します。 型注釈を使用して、関数とその場所パラメーターに関する追加の説明をエージェントに提供します。
from typing import Annotated
from pydantic import Field
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
return f"The weather in {location} is cloudy with a high of 15°C."
@toolデコレーターを使用して、関数の名前と説明を明示的に指定することもできます。
from typing import Annotated
from pydantic import Field
from agent_framework import tool
@tool(name="weather_tool", description="Retrieves weather information for any location")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
return f"The weather in {location} is cloudy with a high of 15°C."
name デコレーターでdescriptionパラメーターと@tool パラメーターを指定しない場合、フレームワークは関数の名前と docstring をフォールバックとして自動的に使用します。
エージェントを作成するときに、 tools パラメーターに渡すことで、関数ツールをエージェントに提供できるようになりました。
import asyncio
from agent_framework.azure import AzureOpenAIChatClient
from azure.identity import AzureCliCredential
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful assistant",
tools=get_weather
)
これで、通常どおりにエージェントを実行するだけで、エージェントは必要に応じて get_weather 関数ツールを呼び出すことができます。
async def main():
result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)
asyncio.run(main())
複数の関数ツールを使用してクラスを作成する
メソッドとして複数の関数ツールを含むクラスを作成することもできます。 これは、関連する関数をまとめて整理したり、それらの間で状態を渡したりする場合に役立ちます。
class WeatherTools:
def __init__(self):
self.last_location = None
def get_weather(
self,
location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
"""Get the weather for a given location."""
return f"The weather in {location} is cloudy with a high of 15°C."
def get_weather_details(self) -> int:
"""Get the detailed weather for the last requested location."""
if self.last_location is None:
return "No location specified yet."
return f"The detailed weather in {self.last_location} is cloudy with a high of 15°C, low of 7°C, and 60% humidity."
エージェントを作成するときに、クラスのすべてのメソッドを関数として指定できるようになりました。
tools = WeatherTools()
agent = AzureOpenAIChatClient(credential=AzureCliCredential()).as_agent(
instructions="You are a helpful assistant",
tools=[tools.get_weather, tools.get_weather_details]
)
また、以前と同じ @tool デコレーターで機能を飾ることもできます。
完全な例
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated, Any
from agent_framework import tool
from agent_framework.openai import OpenAIResponsesClient
from pydantic import Field
"""
AI Function with kwargs Example
This example demonstrates how to inject custom keyword arguments (kwargs) into an AI function
from the agent's run method, without exposing them to the AI model.
This is useful for passing runtime information like access tokens, user IDs, or
request-specific context that the tool needs but the model shouldn't know about
or provide.
"""
# Define the function tool with **kwargs to accept injected arguments
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
**kwargs: Any,
) -> str:
"""Get the weather for a given location."""
# Extract the injected argument from kwargs
user_id = kwargs.get("user_id", "unknown")
# Simulate using the user_id for logging or personalization
print(f"Getting weather for user: {user_id}")
return f"The weather in {location} is cloudy with a high of 15°C."
async def main() -> None:
agent = OpenAIResponsesClient().as_agent(
name="WeatherAgent",
instructions="You are a helpful weather assistant.",
tools=[get_weather],
)
# Pass the injected argument when running the agent
# The 'user_id' kwarg will be passed down to the tool execution via **kwargs
response = await agent.run("What is the weather like in Amsterdam?", user_id="user_123")
print(f"Agent: {response.text}")
if __name__ == "__main__":
asyncio.run(main())
# Copyright (c) Microsoft. All rights reserved.
import asyncio
from typing import Annotated, Any
from agent_framework import tool
from agent_framework.openai import OpenAIResponsesClient
from pydantic import Field
"""
AI Function with kwargs Example
This example demonstrates how to inject custom keyword arguments (kwargs) into an AI function
from the agent's run method, without exposing them to the AI model.
This is useful for passing runtime information like access tokens, user IDs, or
request-specific context that the tool needs but the model shouldn't know about
or provide.
"""
# Define the function tool with **kwargs to accept injected arguments
# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
**kwargs: Any,
) -> str:
"""Get the weather for a given location."""
# Extract the injected argument from kwargs
user_id = kwargs.get("user_id", "unknown")
# Simulate using the user_id for logging or personalization
print(f"Getting weather for user: {user_id}")
return f"The weather in {location} is cloudy with a high of 15°C."
async def main() -> None:
agent = OpenAIResponsesClient().as_agent(
name="WeatherAgent",
instructions="You are a helpful weather assistant.",
tools=[get_weather],
)
# Pass the injected argument when running the agent
# The 'user_id' kwarg will be passed down to the tool execution via **kwargs
response = await agent.run("What is the weather like in Amsterdam?", user_id="user_123")
print(f"Agent: {response.text}")
if __name__ == "__main__":
asyncio.run(main())