Administración de estado con AG-UI

AG-UI define los eventos de estado y los campos de solicitud para compartir el estado de la aplicación entre un cliente y un punto de conexión del agente. Los patrones de estado admitidos y de implementación varían según el SDK de MAF.

Prerequisites

Antes de empezar, asegúrese de que comprende lo siguiente:

¿Qué es Administración de estado?

El estado de AG-UI puede proporcionar:

  • Estado compartido: tanto el cliente como el servidor mantienen una vista sincronizada del estado de la aplicación
  • Actualizaciones de cliente y servidor: las aplicaciones pueden enviar el estado en las solicitudes y emitir eventos de estado
  • Actualizaciones en tiempo real: los cambios se transmiten inmediatamente mediante eventos de estado
  • Actualizaciones predictivas: un SDK puede asignar el progreso de la llamada a la herramienta al estado optimista de la interfaz de usuario.
  • Datos estructurados: el estado sigue un esquema JSON para la validación

Casos de uso

La administración del estado es valiosa para:

  • Interfaz de usuario generativa: compilación de componentes de interfaz de usuario basados en el estado controlado por agente
  • Creación de formularios: el agente rellena los campos de formulario a medida que recopila información.
  • Seguimiento del progreso: mostrar el progreso en tiempo real de las operaciones de varios pasos
  • Paneles interactivos: mostrar datos que se actualizan a medida que el agente lo procesa
  • Edición colaborativa: varios usuarios ven actualizaciones de estado coherentes

El estado de AG-UI es un JSON visible para el cliente asociado a una ejecución. En .NET, la integración proporciona dos mecanismos explícitos:

  • Leer el estado proporcionado por el cliente desde el origen RunAgentInput.
  • Asocia las llamadas a herramientas o los resultados seleccionados a eventos de estado de AG-UI con AGUIStreamOptions.

La asignación de estado es opcional. Los resultados arbitrarios de la herramienta no se convierten automáticamente en estado compartido.

Leer el estado del cliente

MapAGUIServer almacena el origen RunAgentInput en ChatOptions. Un agente delegador o un middleware de cliente de chat puede recuperarlo con TryGetRunAgentInput:

using System.Text.Json;
using AGUI.Abstractions;
using AGUI.Server;
using Microsoft.Extensions.AI;

static bool TryGetClientState(ChatOptions options, out JsonElement state)
{
    if (options.TryGetRunAgentInput(out RunAgentInput? input) &&
        input.State is { ValueKind: not JsonValueKind.Undefined } value)
    {
        state = value;
        return true;
    }

    state = default;
    return false;
}

El estado del cliente corresponde a la entrada de la solicitud. Valide su forma y sus valores antes de usarlos en mensajes, enrutamiento o operaciones con privilegios.

Emisión de una instantánea de estado

Asigne el resultado de una herramienta a STATE_SNAPSHOT cuando la herramienta devuelva el estado completo:

using AGUI.Server;

AGUIStreamOptions streamOptions = new AGUIStreamOptions()
    .MapResultAsStateSnapshot("generate_recipe");

app.MapAGUIServer("/", agent).WithMetadata(streamOptions);

MapResultAsStateSnapshotrequiere que el FunctionResultContent.Result valor sea .JsonElement Serializa un POCO, un diccionario o una colección a JsonElement en la herramienta antes de devolverlo. A continuación, el resultado de generate_recipe se convierte en la instantánea y reemplaza el estado compartido actual del cliente.

Para otros tipos de resultados, use MapResult con un mapeador personalizado que construya el StateSnapshotEvent.

Emisión de deltas de estado

Asigna un resultado de una herramienta a STATE_DELTA cuando devuelve un RFC 6902 JSON Patch:

AGUIStreamOptions streamOptions = new AGUIStreamOptions()
    .MapResultAsStateSnapshot("create_plan")
    .MapResultAsStateDelta("update_plan_step");

app.MapAGUIServer("/", agent).WithMetadata(streamOptions);

Utilice una instantánea para inicializar o reemplazar el estado y los deltas para cambios incrementales.

MapResultAsStateDelta también requiere un JsonElement resultado. El elemento debe contener una matriz JSON Patch RFC 6902. Utiliza MapResult con un mapeador personalizado si la herramienta devuelve otra representación.

Asociar llamadas a herramientas con el estado

AGUIStreamOptions.MapCall asocia un FunctionCallContent seleccionado a eventos adicionales de AG-UI emitidos después de los eventos normales de llamada de herramienta. Úselo cuando el estado derive de argumentos de herramienta en lugar del resultado de la herramienta:

AGUIStreamOptions streamOptions = new AGUIStreamOptions()
    .MapCall("write_document", call =>
    {
        if (call.Arguments?.TryGetValue("document", out object? document) is not true)
        {
            return [];
        }

        JsonElement snapshot = JsonSerializer.SerializeToElement(new { document });
        return [new StateSnapshotEvent { Snapshot = snapshot }];
    });

app.MapAGUIServer("/", agent).WithMetadata(streamOptions);

La aplicación controla el mapeo y la estructura del estado. MapCall no deduce el estado de los argumentos arbitrarios de la herramienta ni suprime la ejecución normal de la herramienta. Las actualizaciones incrementales requieren que el cliente del modelo subyacente exponga los argumentos de llamada a herramientas en streaming y que la aplicación configure la extracción correspondiente de esos argumentos.

Estado de recepción en un cliente de .NET

El cliente de AG-UI .NET muestra eventos de protocolo de estado a través de ChatResponseUpdate.RawRepresentation:

await foreach (AgentResponseUpdate update in agent.RunStreamingAsync(messages, session))
{
    if (update.AsChatResponseUpdate().RawRepresentation is StateSnapshotEvent snapshot)
    {
        JsonElement state = snapshot.Snapshot;
    }
    else if (update.AsChatResponseUpdate().RawRepresentation is StateDeltaEvent delta)
    {
        JsonElement changes = delta.Delta;
    }
}

El cliente es responsable de conservar y aplicar el estado compartido y, a continuación, enviar el estado actual en solicitudes posteriores cuando la aplicación lo requiera.

Pasos siguientes

Definir modelos de estado

En primer lugar, defina modelos pydantices para la estructura de estado. Esto garantiza la seguridad y validación de tipos:

from enum import Enum
from pydantic import BaseModel, Field


class SkillLevel(str, Enum):
    """The skill level required for the recipe."""
    BEGINNER = "Beginner"
    INTERMEDIATE = "Intermediate"
    ADVANCED = "Advanced"


class CookingTime(str, Enum):
    """The cooking time of the recipe."""
    FIVE_MIN = "5 min"
    FIFTEEN_MIN = "15 min"
    THIRTY_MIN = "30 min"
    FORTY_FIVE_MIN = "45 min"
    SIXTY_PLUS_MIN = "60+ min"


class Ingredient(BaseModel):
    """An ingredient with its details."""
    icon: str = Field(..., description="Emoji icon representing the ingredient (e.g., 🥕)")
    name: str = Field(..., description="Name of the ingredient")
    amount: str = Field(..., description="Amount or quantity of the ingredient")


class Recipe(BaseModel):
    """A complete recipe."""
    title: str = Field(..., description="The title of the recipe")
    skill_level: SkillLevel = Field(..., description="The skill level required")
    special_preferences: list[str] = Field(
        default_factory=list, description="Dietary preferences (e.g., Vegetarian, Gluten-free)"
    )
    cooking_time: CookingTime = Field(..., description="The estimated cooking time")
    ingredients: list[Ingredient] = Field(..., description="Complete list of ingredients")
    instructions: list[str] = Field(..., description="Step-by-step cooking instructions")

Esquema de estado

Defina un esquema de estado para especificar la estructura y los tipos de su estado:

state_schema = {
    "recipe": {"type": "object", "description": "The current recipe"},
}

Note

El esquema de estado usa un formato simple con type y opcional description. La estructura real se define mediante los modelos pydantices.

Actualizaciones de estado predictivo

Los argumentos de la herramienta se transmiten al estado predictivo a medida que los genera el LLM, permitiendo actualizaciones optimistas de la interfaz de usuario.

predict_state_config = {
    "recipe": {"tool": "update_recipe", "tool_argument": "recipe"},
}

Esta configuración asigna el recipe campo de estado al recipe argumento de la update_recipe herramienta. Cuando el agente invoca la herramienta, los argumentos se transmiten al estado en tiempo real a medida que el LLM los genera.

Definir herramienta de actualización de estado

Cree una función de utilidad que acepte su modelo Pydantic:

from agent_framework import tool


@tool
def update_recipe(recipe: Recipe) -> str:
    """Update the recipe with new or modified content.

    You MUST write the complete recipe with ALL fields, even when changing only a few items.
    When modifying an existing recipe, include ALL existing ingredients and instructions plus your changes.
    NEVER delete existing data - only add or modify.

    Args:
        recipe: The complete recipe object with all details

    Returns:
        Confirmation that the recipe was updated
    """
    return "Recipe updated."

Importante

El nombre del parámetro de la función de la herramienta (recipe) debe coincidir con tool_argument en tu predict_state_config.

Crear el agente con administración de estado

Esta es una implementación completa del servidor con administración de estado:

"""AG-UI server with state management."""

from agent_framework import Agent
from agent_framework.openai import OpenAIChatCompletionClient
from agent_framework_ag_ui import (
    AgentFrameworkAgent,
    add_agent_framework_fastapi_endpoint,
)
from azure.identity import AzureCliCredential
from fastapi import FastAPI

# Create the chat agent with tools
agent = Agent(
    name="recipe_agent",
    instructions="""You are a helpful recipe assistant that creates and modifies recipes.

    CRITICAL RULES:
    1. You will receive the current recipe state in the system context
    2. To update the recipe, you MUST use the update_recipe tool
    3. When modifying a recipe, ALWAYS include ALL existing data plus your changes in the tool call
    4. NEVER delete existing ingredients or instructions - only add or modify
    5. After calling the tool, provide a brief conversational message (1-2 sentences)

    When creating a NEW recipe:
    - Provide all required fields: title, skill_level, cooking_time, ingredients, instructions
    - Use actual emojis for ingredient icons (🥕 🧄 🧅 🍅 🌿 🍗 🥩 🧀)
    - Leave special_preferences empty unless specified
    - Message: "Here's your recipe!" or similar

    When MODIFYING or IMPROVING an existing recipe:
    - Include ALL existing ingredients + any new ones
    - Include ALL existing instructions + any new/modified ones
    - Update other fields as needed
    - Message: Explain what you improved (e.g., "I upgraded the ingredients to premium quality")
    - When asked to "improve", enhance with:
      * Better ingredients (upgrade quality, add complementary flavors)
      * More detailed instructions
      * Professional techniques
      * Adjust skill_level if complexity changes
      * Add relevant special_preferences

    Example improvements:
    - Upgrade "chicken" → "organic free-range chicken breast"
    - Add herbs: basil, oregano, thyme
    - Add aromatics: garlic, shallots
    - Add finishing touches: lemon zest, fresh parsley
    - Make instructions more detailed and professional
    """,
    client=OpenAIChatCompletionClient(
        model=deployment_name,
        azure_endpoint=endpoint,
        api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
        credential=AzureCliCredential(),
    ),
    tools=[update_recipe],
)

# Wrap agent with state management
recipe_agent = AgentFrameworkAgent(
    agent=agent,
    name="RecipeAgent",
    description="Creates and modifies recipes with streaming state updates",
    state_schema={
        "recipe": {"type": "object", "description": "The current recipe"},
    },
    predict_state_config={
        "recipe": {"tool": "update_recipe", "tool_argument": "recipe"},
    },
)

# Create FastAPI app
app = FastAPI(title="AG-UI Recipe Assistant")
add_agent_framework_fastapi_endpoint(app, recipe_agent, "/")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="127.0.0.1", port=8888)

Conceptos clave

  • Modelos de Pydantic: definición del estado estructurado con seguridad y validación de tipos
  • Esquema de estado: formato simple que especifica tipos de campo de estado
  • Configuración de estado predictivo: asigna campos de estado a argumentos de herramienta para actualizaciones de streaming
  • Inyección de estado: el estado actual se inserta automáticamente como mensajes del sistema para proporcionar contexto
  • Actualizaciones completas: las herramientas deben escribir el estado completo, no solo deltas
  • Estrategia de confirmación: personalice los mensajes de aprobación para su dominio (receta, documento, planificación de tareas, etc.)

Comprender los eventos de estado

Evento de captura de estado

Instantánea completa del estado actual, emitida cuando se completa la herramienta:

{
    "type": "STATE_SNAPSHOT",
    "snapshot": {
        "recipe": {
            "title": "Classic Pasta Carbonara",
            "skill_level": "Intermediate",
            "special_preferences": ["Authentic Italian"],
            "cooking_time": "30 min",
            "ingredients": [
                {"icon": "🍝", "name": "Spaghetti", "amount": "400g"},
                {"icon": "🥓", "name": "Guanciale or bacon", "amount": "200g"},
                {"icon": "🥚", "name": "Egg yolks", "amount": "4"},
                {"icon": "🧀", "name": "Pecorino Romano", "amount": "100g grated"},
                {"icon": "🧂", "name": "Black pepper", "amount": "To taste"}
            ],
            "instructions": [
                "Bring a large pot of salted water to boil",
                "Cut guanciale into small strips and fry until crispy",
                "Beat egg yolks with grated Pecorino and black pepper",
                "Cook spaghetti until al dente",
                "Reserve 1 cup pasta water, then drain pasta",
                "Remove pan from heat, add hot pasta to guanciale",
                "Quickly stir in egg mixture, adding pasta water to create creamy sauce",
                "Serve immediately with extra Pecorino and black pepper"
            ]
        }
    }
}

Evento Delta de estado

Actualizaciones de estado incrementales mediante el formato de parche JSON, emitidas como argumentos de la herramienta de transmisión LLM.

{
    "type": "STATE_DELTA",
    "delta": [
        {
            "op": "replace",
            "path": "/recipe",
            "value": {
                "title": "Classic Pasta Carbonara",
                "skill_level": "Intermediate",
                "cooking_time": "30 min",
                "ingredients": [
                    {"icon": "🍝", "name": "Spaghetti", "amount": "400g"}
                ],
                "instructions": ["Bring a large pot of salted water to boil"]
            }
        }
    ]
}

Note

Los eventos delta de estado se transmiten en tiempo real a medida que LLM genera los argumentos de la herramienta, lo que proporciona actualizaciones optimistas de la interfaz de usuario. La instantánea de estado final se genera cuando la herramienta completa la ejecución.

Implementación de cliente

El agent_framework_ag_ui paquete proporciona AGUIChatClient para conectarse a servidores AG-UI, lo que aporta la experiencia de cliente de Python a la paridad con .NET:

"""AG-UI client with state management."""

import asyncio
import json
import os
from typing import Any

from agent_framework import Agent, Message, Role
from agent_framework_ag_ui import AGUIChatClient


async def main():
    """Example client with state tracking."""
    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)

    # Wrap with Agent for convenient API
    agent = Agent(
        name="ClientAgent",
        client=chat_client,
        instructions="You are a helpful assistant.",
    )

    # Get a thread for conversation continuity
    thread = agent.create_session()

    # Track state locally
    state: dict[str, Any] = {}

    try:
        while True:
            message = input("\nUser (:q to quit, :state to show state): ")
            if not message.strip():
                continue

            if message.lower() in (":q", "quit"):
                break

            if message.lower() == ":state":
                print(f"\nCurrent state: {json.dumps(state, indent=2)}")
                continue

            print()
            # Stream the agent response with state
            async for update in agent.run(message, session=thread, stream=True):
                # Handle text content
                if update.text:
                    print(update.text, end="", flush=True)

                # Handle state updates surfaced through AG-UI events.
                for content in update.contents:
                    if content.type == "data" and getattr(content, "media_type", None) == "application/json":
                        print("\n[JSON state payload received]")

            print(f"\n\nCurrent state: {json.dumps(state, indent=2)}")
            print()

    except KeyboardInterrupt:
        print("\n\nExiting...")


if __name__ == "__main__":
    # Install dependencies: pip install agent-framework-ag-ui --pre
    asyncio.run(main())

Ventajas clave

AGUIChatClient proporciona:

  • Conexión simplificada: control automático de la comunicación HTTP/SSE
  • Administración de subprocesos: seguimiento del identificador de subproceso integrado para la continuidad de la conversación
  • Integración del agente: funciona perfectamente con Agent para una API conocida
  • Control de estado: análisis automático de eventos de estado desde el servidor
  • Paridad con .NET: experiencia consistente en todos los idiomas

Tip

Úselo AGUIChatClient con Agent para obtener la ventaja completa de las características del marco de agente, como el historial de conversaciones, la ejecución de herramientas y la compatibilidad con middleware.

Confirmación del estado previsto

Active require_confirmation=True en AgentFrameworkAgent cuando los cambios de estado previstos deban esperar la confirmación del cliente antes de aplicarse:

recipe_agent = AgentFrameworkAgent(
    agent=agent,
    state_schema={"recipe": {"type": "object", "description": "The current recipe"}},
    predict_state_config={"recipe": {"tool": "update_recipe", "tool_argument": "recipe"}},
    require_confirmation=True,
)

Personalice el texto de confirmación en la interfaz de usuario de su cliente AG-UI al mostrar el evento de confirmación.

Interacción de ejemplo

Con el servidor y el cliente en ejecución:

User (:q to quit, :state to show state): I want to make a classic Italian pasta carbonara

[Run Started]
[Calling Tool: update_recipe]
[State Updated]
[State Updated]
[State Updated]
[Tool Result: Recipe updated.]
Here's your recipe!
[Run Finished]

============================================================
CURRENT STATE
============================================================

recipe:
  title: Classic Pasta Carbonara
  skill_level: Intermediate
  special_preferences: ['Authentic Italian']
  cooking_time: 30 min
  ingredients:
    - 🍝 Spaghetti: 400g
    - 🥓 Guanciale or bacon: 200g
    - 🥚 Egg yolks: 4
    - 🧀 Pecorino Romano: 100g grated
    - 🧂 Black pepper: To taste
  instructions:
    1. Bring a large pot of salted water to boil
    2. Cut guanciale into small strips and fry until crispy
    3. Beat egg yolks with grated Pecorino and black pepper
    4. Cook spaghetti until al dente
    5. Reserve 1 cup pasta water, then drain pasta
    6. Remove pan from heat, add hot pasta to guanciale
    7. Quickly stir in egg mixture, adding pasta water to create creamy sauce
    8. Serve immediately with extra Pecorino and black pepper

============================================================

Tip

Use el :state comando para ver el estado actual en cualquier momento durante la conversación.

Actualizaciones de estado predictivo en acción

Cuando se usan actualizaciones de estado predictivo con predict_state_config, el cliente recibe STATE_DELTA eventos a medida que LLM genera argumentos de herramienta en tiempo real, antes de que se ejecute la herramienta:

// Agent starts generating tool call for update_recipe
// Client receives STATE_DELTA events as the recipe argument streams:

// First delta - partial recipe with title
{
  "type": "STATE_DELTA",
  "delta": [{"op": "replace", "path": "/recipe", "value": {"title": "Classic Pasta"}}]
}

// Second delta - title complete with more fields
{
  "type": "STATE_DELTA",
  "delta": [{"op": "replace", "path": "/recipe", "value": {
    "title": "Classic Pasta Carbonara",
    "skill_level": "Intermediate"
  }}]
}

// Third delta - ingredients starting to appear
{
  "type": "STATE_DELTA",
  "delta": [{"op": "replace", "path": "/recipe", "value": {
    "title": "Classic Pasta Carbonara",
    "skill_level": "Intermediate",
    "cooking_time": "30 min",
    "ingredients": [
      {"icon": "🍝", "name": "Spaghetti", "amount": "400g"}
    ]
  }}]
}

// ... more deltas as the LLM generates the complete recipe

Esto permite al cliente mostrar las actualizaciones optimistas de la interfaz de usuario en tiempo real, ya que el agente está pensando, proporcionando comentarios inmediatos a los usuarios.

Estado con humano-en-el-bucle

Puede combinar la administración de estado con flujos de trabajo de aprobación estableciendo require_confirmation=True:

recipe_agent = AgentFrameworkAgent(
    agent=agent,
    state_schema={"recipe": {"type": "object", "description": "The current recipe"}},
    predict_state_config={"recipe": {"tool": "update_recipe", "tool_argument": "recipe"}},
    require_confirmation=True,  # Require approval for state changes
)

Cuando esté habilitado:

  1. Actualizaciones de estado del flujo mientras el agente genera parámetros de herramienta (actualizaciones predictivas a través de eventos STATE_DELTA)
  2. El agente hace una pausa antes de ejecutar la herramienta con una interrupción tool_call en RUN_FINISHED.outcome.interrupts
  3. Si se aprueba, la herramienta se ejecuta y se emite el estado final (a través STATE_SNAPSHOT del evento)
  4. Si se rechaza, se descartan los cambios de estado predictivo.

Patrones de estado avanzados

Estado complejo con varios campos

Puede administrar varios campos de estado con diferentes herramientas:

from pydantic import BaseModel


class TaskStep(BaseModel):
    """A single task step."""
    description: str
    status: str = "pending"
    estimated_duration: str = "5 min"


@tool
def generate_task_steps(steps: list[TaskStep]) -> str:
    """Generate task steps for a given task."""
    return f"Generated {len(steps)} steps."


@tool
def update_preferences(preferences: dict[str, Any]) -> str:
    """Update user preferences."""
    return "Preferences updated."


# Configure with multiple state fields
agent_with_multiple_state = AgentFrameworkAgent(
    agent=agent,
    state_schema={
        "steps": {"type": "array", "description": "List of task steps"},
        "preferences": {"type": "object", "description": "User preferences"},
    },
    predict_state_config={
        "steps": {"tool": "generate_task_steps", "tool_argument": "steps"},
        "preferences": {"tool": "update_preferences", "tool_argument": "preferences"},
    },
)

Uso de argumentos de la herramienta comodín

Cuando una herramienta devuelve datos anidados complejos, use "*" para asignar todos los argumentos de la herramienta al estado:

@tool
def create_document(title: str, content: str, metadata: dict[str, Any]) -> str:
    """Create a document with title, content, and metadata."""
    return "Document created."


# Map all tool arguments to document state
predict_state_config = {
    "document": {"tool": "create_document", "tool_argument": "*"}
}

Esto asigna toda la llamada de herramienta (todos los argumentos) al document campo de estado.

Prácticas recomendadas

Uso de modelos de Pydantic

Definir modelos estructurados para la seguridad de tipos:

class Recipe(BaseModel):
    """Use Pydantic models for structured, validated state."""
    title: str
    skill_level: SkillLevel
    ingredients: list[Ingredient]
    instructions: list[str]

Ventajas:

  • Seguridad de Tipos: validación automática de tipos de datos
  • Documentación: las descripciones de campo sirven como documentación
  • Compatibilidad con IDE: finalización automática y comprobación de tipos
  • Serialización: Conversión automática de JSON

Actualizaciones de estado completas

Escriba siempre el estado completo, no solo deltas:

@tool
def update_recipe(recipe: Recipe) -> str:
    """
    You MUST write the complete recipe with ALL fields.
    When modifying a recipe, include ALL existing ingredients and
    instructions plus your changes. NEVER delete existing data.
    """
    return "Recipe updated."

Esto garantiza la coherencia de estado y las actualizaciones predictivas adecuadas.

Concordar nombres de parámetros

Asegúrese de que los nombres de parámetros de la herramienta coincidan con tool_argument la configuración:

# Tool parameter name
def update_recipe(recipe: Recipe) -> str:  # Parameter name: 'recipe'
    ...

# Must match in predict_state_config
predict_state_config = {
    "recipe": {"tool": "update_recipe", "tool_argument": "recipe"}  # Same name
}

Proporcionar contexto en instrucciones

Incluya instrucciones claras sobre la administración de estado:

agent = Agent(
    instructions="""
    CRITICAL RULES:
    1. You will receive the current recipe state in the system context
    2. To update the recipe, you MUST use the update_recipe tool
    3. When modifying a recipe, ALWAYS include ALL existing data plus your changes
    4. NEVER delete existing ingredients or instructions - only add or modify
    """,
    ...
)

Personalización de la interfaz de usuario de confirmación

Personalice los mensajes de aprobación y confirmación de estado en el cliente de AG-UI al representar eventos de confirmación desde el servidor.

Pasos siguientes

Ahora ha aprendido todas las características principales de AG-UI. A continuación, puede:

  • Exploración de la documentación de Agent Framework
  • Crear una aplicación completa que combine todas las características de AG-UI
  • Implementación del servicio AG-UI en producción

Recursos adicionales

La administración de estado de Go AG-UI se puede implementar con middleware que emite actualizaciones estructuradas message.DataContent junto con las actualizaciones normales de texto.

stateSnapshotMiddleware := agent.MiddlewareFunc(func(next agent.RunFunc, ctx context.Context, messages []*message.Message, opts ...agent.Option) iter.Seq2[*agent.ResponseUpdate, error] {
    return func(yield func(*agent.ResponseUpdate, error) bool) {
        for update, err := range next(ctx, messages, opts...) {
            if err != nil {
                yield(nil, err)
                return
            }
            if update != nil {
                // Inspect update contents and yield DataContent snapshots as needed.
            }
            if !yield(update, nil) {
                return
            }
        }
    }
})

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Config: agent.Config{
        Middlewares: []agent.Middleware{stateSnapshotMiddleware},
    },
})

Tip

Consulte el ejemplo de administración de estado deAG-UI para ver un ejemplo completo de ejecución.