Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu öğreticide, AG-UI aracılarınıza işlev araçlarının nasıl ekleneceği gösterilmektedir. İşlev araçları, aracının veri alma, hesaplama yapma veya dış sistemlerle etkileşim kurma gibi belirli görevleri gerçekleştirmek için çağırabileceği özel C# yöntemleridir. AG-UI ile bu araçlar arka uçta yürütülür ve sonuçları otomatik olarak istemciye akışla gönderilir.
Önkoşullar
Başlamadan önce Başlarken öğreticisini tamamladığınızdan ve aşağıdakilere sahip olduğunuzdan emin olun:
- .NET 8.0 veya üzeri
-
Microsoft.Agents.AI.Hosting.AGUI.AspNetCorepaket yüklendi - Azure OpenAI hizmeti yapılandırıldı
- AG-UI sunucusu ve istemci kurulumu hakkında temel bilgiler
Arka Uç Araçları Render Etme nedir?
Arka uç aracı işleme şu anlama gelir:
- İşlev araçları sunucuda tanımlanır
- Bu araçların ne zaman çağrıleceğine yapay zeka aracısı karar verir
- Araçlar sunucu tarafında çalışır
- Araç çağrısı olayları ve sonuçları istemciye gerçek zamanlı olarak akışla gönderilir
- İstemci, araç yürütme ilerleme durumuyla ilgili güncelleştirmeleri alır
İşlev Araçları ile AG-UI Sunucusu Oluşturma
Karmaşık parametre türleriyle araçları kaydetmeyi gösteren eksiksiz bir sunucu uygulaması aşağıdadır:
// Copyright (c) Microsoft. All rights reserved.
using System.ComponentModel;
using System.Text.Json.Serialization;
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Hosting.AGUI.AspNetCore;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.Options;
using OpenAI.Chat;
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Services.AddHttpClient().AddLogging();
builder.Services.ConfigureHttpJsonOptions(options =>
options.SerializerOptions.TypeInfoResolverChain.Add(SampleJsonSerializerContext.Default));
builder.Services.AddAGUI();
WebApplication app = builder.Build();
string endpoint = builder.Configuration["AZURE_OPENAI_ENDPOINT"]
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
string deploymentName = builder.Configuration["AZURE_OPENAI_DEPLOYMENT_NAME"]
?? throw new InvalidOperationException("AZURE_OPENAI_DEPLOYMENT_NAME is not set.");
// Define request/response types for the tool
internal sealed class RestaurantSearchRequest
{
public string Location { get; set; } = string.Empty;
public string Cuisine { get; set; } = "any";
}
internal sealed class RestaurantSearchResponse
{
public string Location { get; set; } = string.Empty;
public string Cuisine { get; set; } = string.Empty;
public RestaurantInfo[] Results { get; set; } = [];
}
internal sealed class RestaurantInfo
{
public string Name { get; set; } = string.Empty;
public string Cuisine { get; set; } = string.Empty;
public double Rating { get; set; }
public string Address { get; set; } = string.Empty;
}
// JSON serialization context for source generation
[JsonSerializable(typeof(RestaurantSearchRequest))]
[JsonSerializable(typeof(RestaurantSearchResponse))]
internal sealed partial class SampleJsonSerializerContext : JsonSerializerContext;
// Define the function tool
[Description("Search for restaurants in a location.")]
static RestaurantSearchResponse SearchRestaurants(
[Description("The restaurant search request")] RestaurantSearchRequest request)
{
// Simulated restaurant data
string cuisine = request.Cuisine == "any" ? "Italian" : request.Cuisine;
return new RestaurantSearchResponse
{
Location = request.Location,
Cuisine = request.Cuisine,
Results =
[
new RestaurantInfo
{
Name = "The Golden Fork",
Cuisine = cuisine,
Rating = 4.5,
Address = $"123 Main St, {request.Location}"
},
new RestaurantInfo
{
Name = "Spice Haven",
Cuisine = cuisine == "Italian" ? "Indian" : cuisine,
Rating = 4.7,
Address = $"456 Oak Ave, {request.Location}"
},
new RestaurantInfo
{
Name = "Green Leaf",
Cuisine = "Vegetarian",
Rating = 4.3,
Address = $"789 Elm Rd, {request.Location}"
}
]
};
}
// Get JsonSerializerOptions from the configured HTTP JSON options
Microsoft.AspNetCore.Http.Json.JsonOptions jsonOptions = app.Services.GetRequiredService<IOptions<Microsoft.AspNetCore.Http.Json.JsonOptions>>().Value;
// Create tool with serializer options
AITool[] tools =
[
AIFunctionFactory.Create(
SearchRestaurants,
serializerOptions: jsonOptions.SerializerOptions)
];
// Create the AI agent with tools
ChatClient chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName);
ChatClientAgent agent = chatClient.AsIChatClient().AsAIAgent(
name: "AGUIAssistant",
instructions: "You are a helpful assistant with access to restaurant information.",
tools: tools);
// Map the AG-UI agent endpoint
app.MapAGUI("/", agent);
await app.RunAsync();
Önemli Kavramlar
- Sunucu tarafı yürütme: Araçlar sunucu işleminde yürütülür
- Otomatik akış: Araç çağrıları ve sonuçları istemcilere gerçek zamanlı olarak akışla gönderilir
Önemli
Karmaşık parametre türlerine (nesneler, diziler vb.) sahip araçlar oluştururken bir serializerOptions parametresini AIFunctionFactory.Create() sağlamanız gerekir. Seri hale getirici seçenekleri, uygulamanın JSON serileştirmesinin geri kalanıyla tutarlılık sağlamak için aracılığıyla yapılandırılan JsonOptionsIOptions<Microsoft.AspNetCore.Http.Json.JsonOptions> uygulamadan alınmalıdır.
Sunucuyu Çalıştırma
Ortam değişkenlerini ayarlayın ve çalıştırın:
export AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"
export AZURE_OPENAI_DEPLOYMENT_NAME="gpt-4o-mini"
dotnet run --urls http://localhost:8888
İstemcide Araç Çağrılarını Gözlemleme
Başlangıç kılavuzunun temel istemci uygulaması, aracının son metin cevap iletisini görüntüler. Ancak, araç çağrılarını ve sonuçları sunucudan canlı olarak aktarılırken gözlemlemek için genişletebilirsiniz.
Araç Yürütme Ayrıntılarını Görüntüleme
Araç çağrılarını ve sonuçlarını gerçek zamanlı olarak görmek için istemcinin akış döngüsünü FunctionCallContent ve FunctionResultContent işleyecek şekilde genişletin.
// Inside the streaming loop from getting-started.md
await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, session))
{
ChatResponseUpdate chatUpdate = update.AsChatResponseUpdate();
// ... existing run started code ...
// Display streaming content
foreach (AIContent content in update.Contents)
{
switch (content)
{
case TextContent textContent:
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write(textContent.Text);
Console.ResetColor();
break;
case FunctionCallContent functionCallContent:
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"\n[Function Call - Name: {functionCallContent.Name}]");
// Display individual parameters
if (functionCallContent.Arguments != null)
{
foreach (var kvp in functionCallContent.Arguments)
{
Console.WriteLine($" Parameter: {kvp.Key} = {kvp.Value}");
}
}
Console.ResetColor();
break;
case FunctionResultContent functionResultContent:
Console.ForegroundColor = ConsoleColor.Magenta;
Console.WriteLine($"\n[Function Result - CallId: {functionResultContent.CallId}]");
if (functionResultContent.Exception != null)
{
Console.WriteLine($" Exception: {functionResultContent.Exception}");
}
else
{
Console.WriteLine($" Result: {functionResultContent.Result}");
}
Console.ResetColor();
break;
case ErrorContent errorContent:
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine($"\n[Error: {errorContent.Message}]");
Console.ResetColor();
break;
}
}
}
Araç Çağrılarıyla Beklenen Çıkış
Aracı arka plan yazılımlarını çağırdığında şunları görürsünüz:
User (:q or quit to exit): What's the weather like in Amsterdam?
[Run Started - Thread: thread_abc123, Run: run_xyz789]
[Function Call - Name: SearchRestaurants]
Parameter: Location = Amsterdam
Parameter: Cuisine = any
[Function Result - CallId: call_def456]
Result: {"Location":"Amsterdam","Cuisine":"any","Results":[...]}
The weather in Amsterdam is sunny with a temperature of 22°C. Here are some
great restaurants in the area: The Golden Fork (Italian, 4.5 stars)...
[Run Finished - Thread: thread_abc123]
Önemli Kavramlar
-
FunctionCallContent:NameveArgumentsparametreleriyle çağrılan bir aracı temsil eder (parametre olarak anahtar-değer çiftleri) -
FunctionResultContent: AracınResultveyaExceptionbarındırdığı,CallIdile tanımlanmış öğesini içerir
Sonraki Adımlar
artık işlev araçları ekleyebildiğinize göre şunları yapabilirsiniz:
- Ön uç araçları: Ön uç araçları ekleyin.
- Dojo ile test etme: Aracılarınızı test etmek için AG-UI'nin Dojo uygulamasını kullanma
Ek Kaynaklar
Bu öğreticide, AG-UI aracılarınıza işlev araçlarının nasıl ekleneceği gösterilmektedir. İşlev araçları, aracının veri alma, hesaplama yapma veya dış sistemlerle etkileşim kurma gibi belirli görevleri gerçekleştirmek için çağırabileceği özel Python işlevleridir. AG-UI ile bu araçlar arka uçta yürütülür ve sonuçları otomatik olarak istemciye akışla gönderilir.
Önkoşullar
Başlamadan önce Başlarken öğreticisini tamamladığınızdan ve aşağıdakilere sahip olduğunuzdan emin olun:
- Python 3.10 veya üzeri
-
agent-framework-ag-uiYüklü - Azure OpenAI hizmeti yapılandırıldı
- AG-UI sunucusu ve istemci kurulumu hakkında temel bilgiler
Uyarı
Bu örnekler kimlik doğrulaması için kullanılır DefaultAzureCredential . Azure ile kimliğinizin doğrulanmış olduğundan emin olun (örneğin aracılığıyla az login). Daha fazla bilgi için Azure Identity belgelerine bakın.
Arka Uç Araçları Render Etme nedir?
Arka uç aracı işleme şu anlama gelir:
- İşlev araçları sunucuda tanımlanır
- Bu araçların ne zaman çağrıleceğine yapay zeka aracısı karar verir
- Araçlar sunucu tarafında çalışır
- Araç çağrısı olayları ve sonuçları istemciye gerçek zamanlı olarak akışla gönderilir
- İstemci, araç yürütme ilerleme durumuyla ilgili güncelleştirmeleri alır
Bu yaklaşım şunu sağlar:
- Güvenlik: Hassas işlemler sunucuda kalır
- Tutarlılık: Tüm istemciler aynı araç uygulamalarını kullanır
- Saydamlık: İstemciler araç yürütme ilerleme durumunu görüntüleyebilir
- Esneklik: İstemci kodunu değiştirmeden araçları güncelleştirme
İşlev Araçları Oluşturma
Temel İşlev Aracı
Herhangi bir Python işlevini @tool dekoratörü kullanarak bir araca dönüştürebilirsiniz.
from typing import Annotated
from pydantic import Field
from agent_framework import tool
@tool
def get_weather(
location: Annotated[str, Field(description="The city")],
) -> str:
"""Get the current weather for a location."""
# In a real application, you would call a weather API
return f"The weather in {location} is sunny with a temperature of 22°C."
Önemli Kavramlar
-
@tooldekoratör: Bir işlevi aracı için kullanılabilir olarak işaretler - Tür ek açıklamaları: Parametreler için tür bilgileri sağlayın
-
AnnotatedveField: Aracının parametreleri anlamasına yardımcı olmak için açıklamalar ekleyin - Docstring: İşlevin ne yaptığını açıklar (aracının ne zaman kullanılacağına karar vermesine yardımcı olur)
- Dönüş değeri: Aracıya döndürülen (ve istemciye akışla aktarılan) sonuç
Birden Çok İşlev Aracı
Aracıya daha fazla özellik sunmak için birden çok araç sağlayabilirsiniz:
from typing import Any
from agent_framework import tool
@tool
def get_weather(
location: Annotated[str, Field(description="The city.")],
) -> str:
"""Get the current weather for a location."""
return f"The weather in {location} is sunny with a temperature of 22°C."
@tool
def get_forecast(
location: Annotated[str, Field(description="The city.")],
days: Annotated[int, Field(description="Number of days to forecast")] = 3,
) -> dict[str, Any]:
"""Get the weather forecast for a location."""
return {
"location": location,
"days": days,
"forecast": [
{"day": 1, "weather": "Sunny", "high": 24, "low": 18},
{"day": 2, "weather": "Partly cloudy", "high": 22, "low": 17},
{"day": 3, "weather": "Rainy", "high": 19, "low": 15},
],
}
İşlev Araçları ile AG-UI Sunucusu Oluşturma
İşlev araçlarıyla eksiksiz bir sunucu uygulaması aşağıdadır:
"""AG-UI server with backend tool rendering."""
import os
from typing import Annotated, Any
from agent_framework import Agent, tool
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
from azure.identity import AzureCliCredential
from fastapi import FastAPI
from pydantic import Field
# Define function tools
@tool
def get_weather(
location: Annotated[str, Field(description="The city")],
) -> str:
"""Get the current weather for a location."""
# Simulated weather data
return f"The weather in {location} is sunny with a temperature of 22°C."
@tool
def search_restaurants(
location: Annotated[str, Field(description="The city to search in")],
cuisine: Annotated[str, Field(description="Type of cuisine")] = "any",
) -> dict[str, Any]:
"""Search for restaurants in a location."""
# Simulated restaurant data
return {
"location": location,
"cuisine": cuisine,
"results": [
{"name": "The Golden Fork", "rating": 4.5, "price": "$$"},
{"name": "Bella Italia", "rating": 4.2, "price": "$$$"},
{"name": "Spice Garden", "rating": 4.7, "price": "$$"},
],
}
# Read required configuration
endpoint = os.environ.get("AZURE_OPENAI_ENDPOINT")
deployment_name = os.environ.get("AZURE_OPENAI_DEPLOYMENT_NAME")
if not endpoint:
raise ValueError("AZURE_OPENAI_ENDPOINT environment variable is required")
if not deployment_name:
raise ValueError("AZURE_OPENAI_DEPLOYMENT_NAME environment variable is required")
chat_client = AzureOpenAIChatClient(
credential=AzureCliCredential(),
endpoint=endpoint,
deployment_name=deployment_name,
)
# Create agent with tools
agent = Agent(
name="TravelAssistant",
instructions="You are a helpful travel assistant. Use the available tools to help users plan their trips.",
chat_client=chat_client,
tools=[get_weather, search_restaurants],
)
# Create FastAPI app
app = FastAPI(title="AG-UI Travel Assistant")
add_agent_framework_fastapi_endpoint(app, agent, "/")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8888)
Araç Olaylarını Anlama
Ajan bir aracı çalıştırdığında istemci birkaç olayı alır.
Araç Çağrı Olayları
# 1. TOOL_CALL_START - Tool execution begins
{
"type": "TOOL_CALL_START",
"toolCallId": "call_abc123",
"toolCallName": "get_weather"
}
# 2. TOOL_CALL_ARGS - Tool arguments (may stream in chunks)
{
"type": "TOOL_CALL_ARGS",
"toolCallId": "call_abc123",
"delta": "{\"location\": \"Paris, France\"}"
}
# 3. TOOL_CALL_END - Arguments complete
{
"type": "TOOL_CALL_END",
"toolCallId": "call_abc123"
}
# 4. TOOL_CALL_RESULT - Tool execution result
{
"type": "TOOL_CALL_RESULT",
"toolCallId": "call_abc123",
"content": "The weather in Paris, France is sunny with a temperature of 22°C."
}
Araç Olayları için Gelişmiş İstemci
Araç yürütmesini görüntüleyen gelişmiş bir istemci AGUIChatClient aşağıdadır:
"""AG-UI client with tool event handling."""
import asyncio
import os
from agent_framework import Agent, ToolCallContent, ToolResultContent
from agent_framework_ag_ui import AGUIChatClient
async def main():
"""Main client loop with tool event display."""
server_url = os.environ.get("AGUI_SERVER_URL", "http://127.0.0.1:8888/")
print(f"Connecting to AG-UI server at: {server_url}\n")
# Create AG-UI chat client
chat_client = AGUIChatClient(server_url=server_url)
# Create agent with the chat client
agent = Agent(
name="ClientAgent",
chat_client=chat_client,
instructions="You are a helpful assistant.",
)
# Get a thread for conversation continuity
thread = agent.create_session()
try:
while True:
message = input("\nUser (:q or quit to exit): ")
if not message.strip():
continue
if message.lower() in (":q", "quit"):
break
print("\nAssistant: ", end="", flush=True)
async for update in agent.run(message, session=thread, stream=True):
# Display text content
if update.text:
print(f"\033[96m{update.text}\033[0m", end="", flush=True)
# Display tool calls and results
for content in update.contents:
if isinstance(content, ToolCallContent):
print(f"\n\033[95m[Calling tool: {content.name}]\033[0m")
elif isinstance(content, ToolResultContent):
result_text = content.result if isinstance(content.result, str) else str(content.result)
print(f"\033[94m[Tool result: {result_text}]\033[0m")
print("\n")
except KeyboardInterrupt:
print("\n\nExiting...")
except Exception as e:
print(f"\n\033[91mError: {e}\033[0m")
if __name__ == "__main__":
asyncio.run(main())
Örnek Etkileşim
Güncellenmiş sunucu ve istemci çalışır durumdayken:
User (:q or quit to exit): What's the weather like in Paris and suggest some Italian restaurants?
[Run Started]
[Tool Call: get_weather]
[Tool Result: The weather in Paris, France is sunny with a temperature of 22°C.]
[Tool Call: search_restaurants]
[Tool Result: {"location": "Paris", "cuisine": "Italian", "results": [...]}]
Based on the current weather in Paris (sunny, 22°C) and your interest in Italian cuisine,
I'd recommend visiting Bella Italia, which has a 4.2 rating. The weather is perfect for
outdoor dining!
[Run Finished]
Araç Uygulama En İyi Yöntemleri
Hata İşleme
Araçlarınızda hataları zarif bir şekilde yönetin.
@tool
def get_weather(
location: Annotated[str, Field(description="The city.")],
) -> str:
"""Get the current weather for a location."""
try:
# Call weather API
result = call_weather_api(location)
return f"The weather in {location} is {result['condition']} with temperature {result['temp']}°C."
except Exception as e:
return f"Unable to retrieve weather for {location}. Error: {str(e)}"
Zengin Dönüş Türleri
Uygun olduğunda yapılandırılmış veriler döndürün:
@tool
def analyze_sentiment(
text: Annotated[str, Field(description="The text to analyze")],
) -> dict[str, Any]:
"""Analyze the sentiment of text."""
# Perform sentiment analysis
return {
"text": text,
"sentiment": "positive",
"confidence": 0.87,
"scores": {
"positive": 0.87,
"neutral": 0.10,
"negative": 0.03,
},
}
Açıklayıcı Belgeler
Temsilcinin araçları ne zaman kullanacağını anlamasına yardımcı olmak için net açıklamalar sağlayın.
@tool
def book_flight(
origin: Annotated[str, Field(description="Departure city and airport code, e.g., 'New York, JFK'")],
destination: Annotated[str, Field(description="Arrival city and airport code, e.g., 'London, LHR'")],
date: Annotated[str, Field(description="Departure date in YYYY-MM-DD format")],
passengers: Annotated[int, Field(description="Number of passengers")] = 1,
) -> dict[str, Any]:
"""
Book a flight for specified passengers from origin to destination.
This tool should be used when the user wants to book or reserve airline tickets.
Do not use this for searching flights - use search_flights instead.
"""
# Implementation
pass
Araçların Sınıflarla Düzenlenmesi
İlgili araçlar için bunları bir sınıfta düzenleyin:
from agent_framework import tool
class WeatherTools:
"""Collection of weather-related tools."""
def __init__(self, api_key: str):
self.api_key = api_key
@tool
def get_current_weather(
self,
location: Annotated[str, Field(description="The city.")],
) -> str:
"""Get current weather for a location."""
# Use self.api_key to call API
return f"Current weather in {location}: Sunny, 22°C"
@tool
def get_forecast(
self,
location: Annotated[str, Field(description="The city.")],
days: Annotated[int, Field(description="Number of days")] = 3,
) -> dict[str, Any]:
"""Get weather forecast for a location."""
# Use self.api_key to call API
return {"location": location, "forecast": [...]}
# Create tools instance
weather_tools = WeatherTools(api_key="your-api-key")
# Create agent with class-based tools
agent = Agent(
name="WeatherAgent",
instructions="You are a weather assistant.",
chat_client=AzureOpenAIChatClient(...),
tools=[
weather_tools.get_current_weather,
weather_tools.get_forecast,
],
)
Sonraki Adımlar
Arka plan aracı işleme sürecini anladığınıza göre şunları yapabilirsiniz:
- Gelişmiş Araçlar Oluşturma: Agent Framework ile işlev araçları oluşturma hakkında daha fazla bilgi edinin