Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez az oktatóanyag lépés bemutatja, hogyan használhat függvényeszközöket egy ügynökkel, ahol az ügynök az Azure OpenAI Csevegés befejezése szolgáltatásra épül.
Important
Nem minden ügynöktípus támogatja a funkció eszközöket. Egyesek csak egyéni beépített eszközöket támogathatnak, és nem teszik lehetővé, hogy a hívó saját függvényeket adjon meg. Ez a lépés egy ChatClientAgent, amely támogatja a függvényeszközöket.
Prerequisites
Az előfeltételekről és a NuGet-csomagok telepítéséről lásd az egyszerű ügynök létrehozása és futtatása lépést ebben az oktatóanyagban.
Az ügynök létrehozása funkcióeszközökkel
A funkcióeszközök olyan egyéni kódok, amelyeket az ügynök szükség esetén meghívhat.
Bármely C#-metódust függvényeszközsé alakíthat, ha a AIFunctionFactory.Create metódus használatával létrehoz egy példányt AIFunction a metódusból.
Ha további leírásokat kell adnia a függvényről vagy annak paramétereiről az ügynöknek, hogy pontosabban tudjon választani a különböző függvények között, használhatja az System.ComponentModel.DescriptionAttribute attribútumot a metóduson és annak paraméterein.
Íme egy példa egy egyszerű függvényeszközre, amely meghamisít egy adott hely időjárását. Leírási attribútumokkal van díszítve, hogy további leírásokat adjon magáról és helyparaméteréről az ügynöknek.
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.";
Az ügynök létrehozásakor mostantól a függvényeszközt is átadhatja az ügynöknek, ha átadja az eszközök listáját a AsAIAgent metódusnak.
using System;
using Azure.AI.Projects;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
AIAgent agent = new AIProjectClient(
new Uri("<your-foundry-project-endpoint>"),
new DefaultAzureCredential())
.AsAIAgent(
model: "gpt-4o-mini",
instructions: "You are a helpful assistant",
tools: [AIFunctionFactory.Create(GetWeather)]);
Warning
DefaultAzureCredential a fejlesztéshez kényelmes, de a termelési környezetben gondos megfontolást igényel. Éles környezetben fontolja meg egy adott hitelesítő adat (pl. ManagedIdentityCredential) használatát a késési problémák elkerülése, a hitelesítő adatok nem szándékos próbálgatásának és a tartalék mechanizmusokból eredő esetleges biztonsági kockázatok elkerülése érdekében.
Most már csak a szokásos módon futtathatja az ügynököt, és szükség esetén az ügynök meghívhatja a GetWeather függvényeszközt.
Console.WriteLine(await agent.RunAsync("What is the weather like in Amsterdam?"));
Tip
A teljes futtatható példákért tekintse meg a .NET-mintákat .
Important
Nem minden ügynöktípus támogatja a funkció eszközöket. Egyesek csak egyéni beépített eszközöket támogathatnak, és nem teszik lehetővé, hogy a hívó saját függvényeket adjon meg. Ez a lépés a chat ügyfeleken keresztül létrehozott ügynököket használja, amelyek támogatják a funkcióeszközöket.
Prerequisites
Az előfeltételekről és a Python-csomagok telepítéséről lásd a Hozzon létre és futtasson egy egyszerű ügynököt lépést ebben az oktatóanyagban.
Az ügynök létrehozása funkcióeszközökkel
A funkcióeszközök olyan egyéni kódok, amelyeket az ügynök szükség esetén meghívhat.
Bármely Python-függvényt függvényeszközzé alakíthat, ha az ügynök tools paraméterének adja meg az ügynök létrehozásakor.
Ha további leírásokat kell adnia a függvényről vagy annak paramétereiről az ügynöknek, hogy pontosabban tudjon választani a különböző függvények között, a Python típusjegyzeteivel Annotated és Pydantic-jával Field leírásokat adhat meg.
Íme egy példa egy egyszerű függvényeszközre, amely meghamisít egy adott hely időjárását. Típusjegyzetekkel további leírásokat ad meg a függvényről és a helyparaméterről az ügynök számára.
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."
A @tool dekorátor segítségével egyértelműen megadhatja a függvény nevét és leírását.
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."
Ha nem adja meg a name és description paramétereket a @tool dekorátorban, a keretrendszer automatikusan a függvény nevét és a doksorját használja tartalékként.
Kifejezett sémák használata @tool
Amikor teljes mértékben kézben akarja tartani a modell számára megadott sémát, adja át a schema paramétert a @tool számára.
Pydantic-modellt vagy nyers JSON-sémaszótárat is megadhat.
from pydantic import BaseModel, Field
# Load environment variables from .env file
load_dotenv()
# Approach 1: Pydantic model as explicit schema
class WeatherInput(BaseModel):
"""Input schema for the weather tool."""
location: Annotated[str, Field(description="The city name to get weather for")]
unit: Annotated[str, Field(description="Temperature unit: celsius or fahrenheit")] = "celsius"
@tool(
name="get_weather",
description="Get the current weather for a given location.",
)
def get_weather(location: str, unit: str = "celsius") -> str:
"""Get the current weather for a location."""
return f"The weather in {location} is 22 degrees {unit}."
# Approach 2: JSON schema dictionary for a trusted, non-sensitive tool.
# This receives lightweight top-level checks only; use Pydantic for runtime enforcement.
get_current_time_schema = {
"type": "object",
"properties": {
"timezone": {"type": "string", "description": "The timezone to get the current time for", "default": "UTC"},
},
}
@tool(
Konvertált Python paramétertípusok használata
A Pydantic bemeneti modell által támogatott eszközök esetében az Agent Framework ellenőrzi a modell által megadott JSON-argumentumokat, és átadja a konvertált Python értékeket a függvénynek. A támogatott konverziók közé tartoznak az date, datetime, time, timedelta, Decimal, UUID, tuplesetés frozenset értékek. A pydantic modellpéldányokat a rendszer a meghívás előtt újraellenőrzi.
A nyers JSON-sémaszótárral deklarált eszközök továbbra is JSON-natív típusú ellenőrzést használnak a Pydantic-átalakítás helyett.
Csak futásidejű környezet átadása egy eszköznek
Használjon normál függvényparamétereket a modell által megadott értékekhez. Csak futásidejű értékekhez használható FunctionInvocationContext , például function_invocation_kwargs az aktuális munkamenethez. Az injektált környezeti paraméter el van rejtve a modell számára közzétett séma elől.
import asyncio
from typing import Annotated
from agent_framework import Agent, FunctionInvocationContext, tool
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
from pydantic import Field
# Define the function tool with explicit invocation context.
# The context parameter can also be declared as an untyped ``ctx`` parameter.
@tool(approval_mode="never_require")
def get_weather(
location: Annotated[str, Field(description="The location to get the weather for.")],
ctx: FunctionInvocationContext,
) -> str:
"""Get the weather for a given location."""
# Extract the injected argument from the explicit context
user_id = ctx.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 = Agent(
client=OpenAIChatClient(),
name="WeatherAgent",
instructions="You are a helpful weather assistant.",
tools=[get_weather],
)
# Pass the runtime context explicitly when running the agent.
response = await agent.run(
"What is the weather like in Amsterdam?",
function_invocation_kwargs={"user_id": "user_123"},
)
print(f"Agent: {response.text}")
A ctx.kwargsctx.session és a függvény köztes szoftverről további információt a Futtatókörnyezet című témakörben talál.
Csak deklarációs eszközök létrehozása
Ha egy eszköz a keretrendszeren kívül van megvalósítva (például ügyféloldali a felhasználói felületen), deklarálhatja implementáció nélkül a FunctionTool(..., func=None) segítségével.
A modell továbbra is tud érvelni és meghívni az eszközt, és az alkalmazás később is meg tudja adni az eredményt.
# A declaration-only tool: the schema is sent to the LLM, but the framework
# has no implementation to execute. The caller must supply the result.
get_user_location = FunctionTool(
name="get_user_location",
func=None,
description="Get the user's current city. Only the client application can resolve this.",
input_model={
"type": "object",
"properties": {
"reason": {"type": "string", "description": "Why the location is needed"},
},
"required": ["reason"],
},
)
Egyéni eszköz eredményeinek elemzése
Állítsa be a(z) FunctionTool elemet a(z) result_parser vagy @tool elemen, ha egy nyers visszatérési értéket karakterlánccá vagy Content elemek listájává kell alakítania. Ha egy egyéni elemző kivételt dob, a közvetlen meghívás továbbterjeszti a kivételt, míg az automatikus függvényhívás normál eszközhiba-eredményt ad vissza, és figyelembe veszi a(z) include_detailed_errors elemet. A nyers visszatérési érték nem tartalékként használatos, ezért kezelje a helyreállítható konverziós hibákat az egyéni elemzőben.
Az ügynök létrehozásakor most már megadhatja a függvényeszközt az ügynöknek, ha átadja azt a tools paraméternek.
import asyncio
import os
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import AzureCliCredential
agent = OpenAIChatCompletionClient(
model=os.environ["AZURE_OPENAI_CHAT_COMPLETION_MODEL"],
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
credential=AzureCliCredential(),
).as_agent(
instructions="You are a helpful assistant",
tools=get_weather
)
Most már csak a szokásos módon futtathatja az ügynököt, és szükség esetén az ügynök meghívhatja a get_weather függvényeszközt.
async def main():
result = await agent.run("What is the weather like in Amsterdam?")
print(result.text)
asyncio.run(main())
Az automatikus eszközhívás korlátozása
Állítsa be a csevegőügyfél korlátait az automatikus eszközhívás szabályozásához a modellek közötti utazások, a függvényhívások teljes száma és a fali óra eltelt ideje alapján:
max_function_calls és max_duration_seconds alapértelmezés szerint None értékű, ami azt jelenti, hogy korlátlan. Állítsa be őket pozitív értékekre. Amikor az ügyfél eléri a korlátot, leállítja az eszközök meghívását, és végső szöveges választ kér a modelltől.
Ezek a korlátok a legjobb erőfeszítések, amelyeket minden modell által kért eszközhívás után ellenőriznek, így a kötegek túlléphetik a hívásszámot vagy az időtartamot. Az eszközjóváhagyásra való várakozással töltött idő beleszámít a következőbe max_duration_seconds: .
from agent_framework.openai import OpenAIChatCompletionClient
client = OpenAIChatCompletionClient()
client.function_invocation_configuration.update(
{
"max_iterations": 5,
"max_function_calls": 20,
"max_duration_seconds": 30.0,
}
)
Egyidejű eszközhívás szabályozása
Az egy segédüzenetben visszaadott függvényhívások alapértelmezés szerint párhuzamosan futnak. Állítsa a(z) allow_concurrent_invocation értékét False értékre, ha az eszközök módosítható állapoton osztoznak, vagy a modell sorrendjében kell futniuk:
client.function_invocation_configuration["allow_concurrent_invocation"] = False
Ez a beállítás az ügyféloldali eszközvégrehajtást a szolgáltatóoldali beállításoktól, például a allow_multiple_tool_calls értéktől, függetlenül szabályozza. A munkamenet-alapú jóváhagyási kötegek esetében a döntések külön érkezhetnek, de az eszköz nem fut, és a modell addig nem folytatódik, amíg az eredeti köteg minden jóváhagyásának döntése meg nem születik. A jóváhagyott eszközök ezután a modell eredeti sorrendjében futnak.
A vezérlőeszköz hibaadatai
Alapértelmezés szerint include_detailed_errors az False. A függvényvégrehajtási és argumentum-érvényesítési hibák általános eredményeket adnak vissza a modellnek és más szerializált csatornáknak. Az eredeti diagnosztika továbbra is elérhető a megbízható gazdakód számára a(z) Content.exception elemben.
Content.to_dict() Ezt a mezőt egy rögzített, nem bizalmas hibajelölőre cseréli, és a protokollátalakítások nem teszik elérhetővé a diagnosztikát.
Csak akkor állítsa be client.function_invocation_configuration["include_detailed_errors"] = True , ha az eredmény megbízható csatornán marad. A kivételszöveg bizalmas adatokat tartalmazhat, és ez a beállítás hozzáadja a szöveget a csatorna által látható eredményhez.
Osztály létrehozása több függvényeszközzel
Ha több eszköz osztozik függőségeken vagy megváltoztatható állapoton, csomagolja őket egy osztályba, és adja át a kapcsolt metódusokat az ügynök számára. Használjon osztályattribútumokat olyan értékekhez, amelyeket a modell nem adhat meg, például szolgáltatásügyfeleket, funkciójelölőket vagy gyorsítótárazott állapotot.
import asyncio
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.openai import OpenAIChatClient
from dotenv import load_dotenv
class MyFunctionClass:
def __init__(self, safe: bool = False) -> None:
"""Simple class with two tools: divide and add.
The safe parameter controls whether divide raises on division by zero or returns `infinity` for divide by zero.
"""
self.safe = safe
def divide(
self,
a: Annotated[int, "Numerator"],
b: Annotated[int, "Denominator"],
) -> str:
"""Divide two numbers, safe to use also with 0 as denominator."""
result = "∞" if b == 0 and self.safe else a / b
return f"{a} / {b} = {result}"
def add(
self,
x: Annotated[int, "First number"],
y: Annotated[int, "Second number"],
) -> str:
return f"{x} + {y} = {x + y}"
async def main():
# Creating my function class with safe division enabled
tools = MyFunctionClass(safe=True)
# Applying the tool decorator to one of the methods of the class
add_function = tool(description="Add two numbers.")(tools.add)
agent = Agent(
client=OpenAIChatClient(),
name="ToolAgent",
instructions="Use the provided tools.",
)
print("=" * 60)
print("Step 1: Call divide(10, 0) - tool returns infinity")
query = "Divide 10 by 0"
response = await agent.run(
query,
tools=[add_function, tools.divide],
)
print(f"Response: {response.text}")
print("=" * 60)
print("Step 2: Call set safe to False and call again")
# Disabling safe mode to allow exceptions
tools.safe = False
Ez a minta jól illeszkedik a hosszú élettartamú eszközállapothoz. Használja FunctionInvocationContext inkább, ha az érték hívásonként változik.
Függvénykezelő eszközök
A függvényeszközök lehetővé teszik, hogy az ügynökök egyéni Go-függvényeket hívjanak. A functool csomag egyszerű módot kínál a típusbiztos eszközök automatikus sémagenerálással történő definiálására.
Függvényeszköz definiálása
import (
"context"
"github.com/microsoft/agent-framework-go/tool"
"github.com/microsoft/agent-framework-go/tool/functool"
)
var weatherTool = functool.MustNew(functool.Config{
Name: "weather",
Description: "Get the current weather for a given location",
}, func(_ context.Context, location string) (string, error) {
return fmt.Sprintf("The weather in %s is cloudy with a high of 15°C.", location), nil
})
A függvény aláírása határozza meg az eszköz bemeneti sémáját. A context.Context paramétert a keretrendszer injektálja, és nincs kitéve a modellnek.
Strukturált bemeneti típusok
Több paraméterrel rendelkező eszközök esetén adjon meg egy szerkezetet:
type WeatherInput struct {
Location string `json:"location" jsonschema:"description=The city to check weather for"`
Unit string `json:"unit" jsonschema:"description=Temperature unit (celsius or fahrenheit),enum=celsius,enum=fahrenheit"`
}
var weatherTool = functool.MustNew(functool.Config{
Name: "weather",
Description: "Get weather for a location",
}, func(_ context.Context, input WeatherInput) (string, error) {
return fmt.Sprintf("Weather in %s: 15°%s", input.Location, input.Unit), nil
})
Ügynök létrehozása eszközökkel
a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "You are a helpful assistant.",
Config: agent.Config{
Tools: []tool.Tool{weatherTool},
},
})
resp, err := a.RunText(ctx, "What is the weather like in Amsterdam?").Collect()
Ügynök használata függvényeszközként
Bármely ügynök becsomagolható függvényeszközként egy másik ügynök számára:
import "github.com/microsoft/agent-framework-go/tool/agenttool"
weatherAgent := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "You answer questions about the weather.",
Config: agent.Config{
Name: "WeatherAgent",
Description: "An agent that answers weather questions.",
Tools: []tool.Tool{weatherTool},
},
})
mainAgent := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "You are a helpful assistant who responds in French.",
Config: agent.Config{
Tools: []tool.Tool{agenttool.New(weatherAgent, agenttool.Config{})},
},
})
Használja a helyi parancsértelmező eszközt
A Go SDK tartalmazza a(z) tool/shelltool elemet a helyi parancsértelmezőben való végrehajtáshoz. Az eszköz alapértelmezés szerint jóváhagyást igényel, és párosítható egy környezeti környezetszolgáltatóval, így a modell ismeri az aktuális rendszerhéjcsaládot, a munkakönyvtárat és a gyakori eszközverziókat.
import "github.com/microsoft/agent-framework-go/tool/shelltool"
shell, err := shelltool.NewLocal(shelltool.LocalConfig{
Mode: shelltool.ModeStateless,
})
if err != nil {
return err
}
defer shell.Close()
envProvider := shelltool.NewEnvironmentProvider(shell, shelltool.EnvironmentProviderConfig{})
a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
Instructions: "Run shell commands only when needed and summarize the result.",
Config: agent.Config{
Tools: []tool.Tool{shell},
ContextProviders: []agent.ContextProvider{envProvider},
},
})
Akkor használható shelltool.ModeStateless , ha minden hívásnak egy friss rendszerhéjban kell futnia. Csak akkor használható shelltool.ModePersistent , ha egyetlen ügynök munkamenetének rendszerhéjállapotra van szüksége, például módosított könyvtárakra vagy exportált környezeti változókra, hogy a hívások között megmaradjanak. Csak akkor állítsa be AcknowledgeUnsafe: true , ha független elkülönítési határt ad meg, és nincs szüksége a beépített jóváhagyási kapura.
Tip
A teljes példákért tekintse meg a függvényeszközök példáját, az eszközként használt ügynök példáját és a környezettel rendelkező rendszerhéj példáját.
Függvényeszközök használata a Harness Agenttel
Az egyszerű ügynökök az ügynöképítés során átadott eszközöket használják, és minden további szolgáltatót vagy köztes szoftvereket saját maga kell összeállítania. A Harness ügynök ugyanazokat a függvénykezelő eszközöket használja, de előre beállítja a függvényhívási folyamatot, a szolgáltatáshívásonkénti előzmények megőrzését, az eszközjóváhagyás támogatását és a Harness egyéb képességeit.
Adja át a függvényeszközöket a(z) HarnessAgentOptions.ChatOptions.Tools használatával, amikor a(z) AsHarnessAgent segítségével létrehoz egy HarnessAgent elemet:
using Microsoft.Agents.AI;
using Microsoft.Extensions.AI;
AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
ChatOptions = new ChatOptions
{
Instructions = "You are a helpful assistant.",
Tools = [AIFunctionFactory.Create(GetWeather)],
},
});
AgentSession session = await agent.CreateSessionAsync();
AgentResponse response = await agent.RunAsync(
"What is the weather like in Amsterdam?",
session);
HarnessAgent automatikusan konfigurálja FunctionInvokingChatClient-t. A HarnessAgentOptions.MaximumIterationsPerRequest beállításával felülbírálhatja a függvényhívási korlátját; az alapértelmezett null az FunctionInvokingChatClient alapértelmezett értékét használja. A heveder is hozzáadja HostedWebSearchTool alapértelmezés szerint, ezért állítsa be DisableWebSearch = true , ha az ügynöknek csak az eszközöket kell elérhetővé tenni a ChatOptions.Tools.
Adjon át egy eszközt vagy egy eszközsorozatot a tools következő paraméternek create_harness_agent:
from agent_framework import create_harness_agent
agent = create_harness_agent(
client=client,
agent_instructions="You are a helpful assistant.",
tools=get_weather,
)
session = agent.create_session()
response = await agent.run(
"What is the weather like in Amsterdam?",
session=session,
)
print(response.text)
A factory objektum beállítja a függvények automatikus meghívását és az egyes szolgáltatáshívások előzményeinek megőrzését. A @tool elemmel dekorált függvények alapértelmezés szerint a approval_mode="never_require" elemet használják.
disable_web_search=False szintén hozzáadja a kliens webes keresőeszközét, ha a kliens támogatja; az elhagyásához állítsa be a(z) disable_web_search=True értéket.
A tesztkeretrendszer alapértelmezés szerint telepíti a ToolApprovalMiddleware komponenst (disable_tool_auto_approval=False), és ehhez a middleware-hez minden futtatáshoz egy AgentSession szükséges. Adja át a(z) session=agent.create_session()-t a bemutatott módon, vagy állítsa be kifejezetten a(z) disable_tool_auto_approval=True-et, ha nincs szüksége a harness approval middleware-re.
A csomagolt Go-hám jelenleg nem érhető el. Adj függvényeszközöket a agent.Config.Tools elemhez, és közvetlenül állítsd össze a szükséges middleware-elemeket és kontextusszolgáltatókat.
Következő lépések
Eszköz rendelkezésre állásának szabályozása futásidőben
Eszközöket adhat hozzá vagy távolíthat el az ügynök futása közben a FunctionInvocationContext.add_tools() / remove_tools() használatával, vezérelheti a hívásokat függvényköztes rétegen keresztül, vagy kikényszeríthet egy adott első hívást a tool_choice használatával. A teljes mintákhoz tekintse meg az eszközök rendelkezésre állásának szabályozását .