Weergave van back-endhulpprogramma's met AG-UI

Back-endhulpprogramma's maken gebruik van de normale MAF-hulpprogrammapijplijn. AG-UI transport gebeurtenissen toevoegt zodat een client de oproep en het resultaat kan observeren; het introduceert geen afzonderlijke abstractie van hulpprogramma's.

Een back-endhulpprogramma toevoegen

Definieer en registreer het hulpprogramma zoals u zou doen voor elke MAF-agent:

using System.ComponentModel;
using Microsoft.Extensions.AI;

[Description("Get the weather for a location.")]
static string GetWeather(
    [Description("The city to look up.")] string location) =>
    $"The weather in {location} is sunny.";

AITool getWeather = AIFunctionFactory.Create(GetWeather, name: "get_weather");
AIAgent agent = chatClient.AsAIAgent(tools: [getWeather]);

app.MapAGUIServer("/", agent);

Voor complexe aanvraag- of antwoordtypen configureert u hetzelfde JsonSerializerOptions voor ASP.NET Core en AIFunctionFactory.Create.

Tip

Zie het voorbeeld van .NET back-endhulpprogramma's voor een volledige implementatie.

Zie Functiehulpmiddelen gebruiken met een agent voor toolschema’s, dependency-injectie, foutafhandeling en algemeen toolontwerp.

AG-UI gebeurtenistoewijzing

Wanneer de agent het hulpprogramma aanroept:

  • FunctionCallContent wordt verzonden als AG-UI TOOL_CALL_START, TOOL_CALL_ARGSen TOOL_CALL_END gebeurtenissen.
  • FunctionResultContent wordt verzonden als een TOOL_CALL_RESULT gebeurtenis.
  • Tekst en andere agentinhoud worden nog steeds normaal gestreamd.

Een .NET client ontvangt de vertaalde inhoud als FunctionCallContent enFunctionResultContent:

await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, session))
{
    foreach (AIContent content in update.Contents)
    {
        if (content is FunctionCallContent call)
        {
            Console.WriteLine($"Calling {call.Name}");
        }
        else if (content is FunctionResultContent result)
        {
            Console.WriteLine($"Result: {result.Result}");
        }
    }
}

Resultaten van tools zijn waarden voor het model die AG-UI ook aan de client beschikbaar stelt. Als u de status van de gedeelde gebruikersinterface wilt verzenden naast een resultaat van een hulpprogramma, gebruikt u de expliciete toewijzingen die worden beschreven in Statusbeheer.

Volgende stappen 

In deze handleiding leert u hoe u functietools toevoegt aan uw AG-UI-agents. Functiehulpprogramma's zijn aangepaste Python-functies die de agent kan aanroepen om specifieke taken uit te voeren, zoals het ophalen van gegevens, het uitvoeren van berekeningen of interactie met externe systemen. Met AG-UI worden deze hulpprogramma's uitgevoerd op de back-end en worden hun resultaten automatisch naar de client gestreamd.

Prerequisites

Voordat u begint, moet u ervoor zorgen dat u de zelfstudie Aan de slag hebt voltooid en dat u het volgende hebt gedaan:

  • Python 3.10 of hoger
  • agent-framework-ag-ui Geïnstalleerd
  • Azure OpenAI-service geconfigureerd
  • Basiskennis van AG-UI server- en clientinstallatie

Opmerking

Deze voorbeelden gebruiken DefaultAzureCredential voor verificatie. Zorg ervoor dat u bent geverifieerd met Azure (bijvoorbeeld via az login). Zie de Documentatie voor Azure Identity voor meer informatie.

Wat is Rendering van back-endhulpprogramma's?

Rendering van back-endhulpprogramma's betekent:

  • Functiehulpprogramma's worden gedefinieerd op de server
  • De AI-agent bepaalt wanneer deze hulpprogramma's moeten worden aangeroepen
  • Hulpprogramma's worden uitgevoerd op de back-end (serverzijde)
  • Aanroepgebeurtenissen en resultaten van hulpprogramma's worden in realtime naar de client gestreamd
  • De client ontvangt updates over de voortgang van de uitvoering van het hulpprogramma

Deze aanpak biedt:

  • Beveiliging: Gevoelige bewerkingen blijven op de server staan
  • Consistentie: Alle clients gebruiken dezelfde hulpprogramma-implementaties
  • Transparantie: Clients kunnen voortgang van de uitvoering van hulpprogramma's weergeven
  • Flexibiliteit: Hulpprogramma's bijwerken zonder clientcode te wijzigen

Functiehulpprogramma's maken

Eenvoudig functiehulpmiddel

U kunt elke Python-functie omzetten in een hulpprogramma met behulp van de @tool decorator:

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."

Belangrijkste concepten

  • @tool decorator: Markeert een functie als beschikbaar voor de agent
  • Typeaantekeningen: Geef typegegevens op voor parameters
  • Annotated en Field: Beschrijvingen toevoegen om de agent te helpen parameters te begrijpen
  • Docstring: Beschrijft wat de functie doet (helpt de agent te bepalen wanneer deze moet worden gebruikt)
  • Retourwaarde: het resultaat dat wordt geretourneerd naar de agent (en naar de client gestreamd)

Hulpprogramma's voor meerdere functies

U kunt meerdere hulpprogramma's opgeven om de agent meer mogelijkheden te bieden:

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},
        ],
    }

Een AG-UI Server maken met Functiehulpprogramma's

Hier volgt een volledige server-implementatie met functiehulpprogramma's:

"""AG-UI server with backend tool rendering."""

import os
from typing import Annotated, Any

from agent_framework import Agent, tool
from agent_framework.openai import OpenAIChatCompletionClient
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_CHAT_COMPLETION_MODEL")

if not endpoint:
    raise ValueError("AZURE_OPENAI_ENDPOINT environment variable is required")
if not deployment_name:
    raise ValueError("AZURE_OPENAI_CHAT_COMPLETION_MODEL environment variable is required")

chat_client = OpenAIChatCompletionClient(
    model=deployment_name,
    azure_endpoint=endpoint,
    api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
    credential=AzureCliCredential(),
)

# 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.",
    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)

Inzicht in tool-gebeurtenissen

Wanneer de agent een hulpprogramma aanroept, ontvangt de client verschillende gebeurtenissen:

Gebeurtenissen voor het oproepen van tools

# 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."
}

Geoptimaliseerde client voor tool-activiteiten

Hier is een verbeterde client die gebruikmaakt van AGUIChatClient om de uitvoering van hulpprogramma's weer te geven.

"""AG-UI client with tool event handling."""

import asyncio
import os

from agent_framework import Agent
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(endpoint=server_url)

    # Create agent with the chat client
    agent = Agent(
        name="ClientAgent",
        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 content.type == "function_call":
                        print(f"\n\033[95m[Calling tool: {content.name}]\033[0m")
                    elif content.type == "function_result":
                        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())

Voorbeeldinteractie

Nu de verbeterde server en client worden uitgevoerd:

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]

Best practices voor hulpprogramma-implementatie

Foutafhandeling

Fouten probleemloos verwerken in uw hulpprogramma's:

@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)}"

Uitgebreide retourtypen

Retourneer gestructureerde gegevens indien van toepassing:

@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,
        },
    }

Beschrijvende documentatie

Geef duidelijke beschrijvingen op om de agent te helpen begrijpen wanneer u hulpprogramma's gebruikt:

@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

Organisatie van hulpprogramma's met klassen

Voor gerelateerde hulpprogramma's ordent u deze in een klas:

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.",
    client=OpenAIChatCompletionClient(...),
    tools=[
        weather_tools.get_current_weather,
        weather_tools.get_forecast,
    ],
)

Volgende stappen

Nu u inzicht hebt in de rendering van back-endhulpprogramma's, kunt u het volgende doen:

Aanvullende bronnen

Go AG-UI servers kunnen normale hulpprogramma's voor Agent Framework-functies beschikbaar maken. Maak hulpprogramma's met tool/functool, koppel ze aan de gehoste agent en serveer de agent met aguiprovider.NewJSONHTTPHandler.

searchRestaurants := functool.MustNew(functool.Config{
    Name:        "search_restaurants",
    Description: "Search for restaurants in a location.",
}, func(ctx context.Context, in restaurantSearchRequest) (restaurantSearchResponse, error) {
    return restaurantSearchResponse{
        Location: in.Location,
        Cuisine:  in.Cuisine,
        Results:  []restaurantInfo{{Name: "The Golden Fork", Cuisine: in.Cuisine}},
    }, nil
})

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Config: agent.Config{
        Tools: []tool.Tool{searchRestaurants},
    },
})

Tip

Zie het voorbeeld van AG-UI-back-end-hulpprogramma's voor een volledig, uitvoerbaar voorbeeld.