Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
O suporte ao fluxo de trabalho para a integração .NET AG-UI estará disponível em breve.
Este tutorial mostra como expor workflows do Agent Framework por meio de um endpoint AG-UI. Os fluxos de trabalho orquestram vários agentes e ferramentas em um grafo de execução definido e a integração AG-UI transmite eventos avançados de fluxo de trabalho – acompanhamento de etapas, instantâneos de atividade, interrupções e eventos personalizados – para clientes Web em tempo real.
Pré-requisitos
Antes de começar, verifique se você tem:
- Python 3.10 ou posterior
-
agent-framework-ag-uiInstalado - Familiaridade com o tutorial de Introdução
- Compreensão básica dos fluxos de trabalho do Agent Framework
Quando usar fluxos de trabalho com AG-UI
Use um fluxo de trabalho em vez de um único agente quando precisar:
- Orquestração de vários agentes: rotear tarefas entre agentes especializados (por exemplo, triagem → pedido de reembolso →)
-
Etapas de execução estruturadas: acompanhar o progresso por meio de estágios definidos com
STEP_STARTED/STEP_FINISHEDeventos - Interrupção/retomada de fluxos: pausar a execução para coletar aprovações ou entradas humanas e, em seguida, retomar
-
Streaming de eventos personalizados: emitir eventos específicos do domínio (
request_info,status,workflow_output) para o cliente
Encapsulando um fluxo de trabalho com AgentFrameworkWorkflow
AgentFrameworkWorkflow é um wrapper leve que adapta um nativo Workflow ao protocolo AG-UI. Você pode fornecer uma instância de fluxo de trabalho pré-criada ou uma fábrica que cria um novo fluxo de trabalho por thread.
Instância direta
Utilize uma instância direta quando um único objeto de processo de trabalho puder gerenciar com segurança todas as solicitações (por exemplo, pipelines sem estado):
from agent_framework import Workflow
from agent_framework.ag_ui import AgentFrameworkWorkflow
workflow = build_my_workflow() # returns a Workflow
ag_ui_workflow = AgentFrameworkWorkflow(
workflow=workflow,
name="my-workflow",
description="Single-instance workflow.",
)
Fábrica com escopo restrito a thread
Use workflow_factory quando cada tópico de conversa precisar de seu próprio estado de fluxo de trabalho. A fábrica recebe o thread_id e retorna um novo Workflow:
from agent_framework.ag_ui import AgentFrameworkWorkflow
ag_ui_workflow = AgentFrameworkWorkflow(
workflow_factory=lambda thread_id: build_my_workflow(),
name="my-workflow",
description="Thread-scoped workflow.",
)
Importante
Você deve passar ouworkflowouworkflow_factory, mas não ambos. O wrapper gera um ValueError se ambos forem fornecidos.
Registrando o ponto de extremidade
Registre o fluxo de trabalho com add_agent_framework_fastapi_endpoint da mesma forma que você registraria um agente único.
from fastapi import FastAPI
from agent_framework.ag_ui import (
AgentFrameworkWorkflow,
add_agent_framework_fastapi_endpoint,
)
app = FastAPI(title="Workflow AG-UI Server")
ag_ui_workflow = AgentFrameworkWorkflow(
workflow_factory=lambda thread_id: build_my_workflow(),
name="handoff-demo",
description="Multi-agent handoff workflow.",
)
add_agent_framework_fastapi_endpoint(
app=app,
agent=ag_ui_workflow,
path="/workflow",
)
Você também pode passar um simples Workflow diretamente - o endpoint o encapsula automaticamente em AgentFrameworkWorkflow:
add_agent_framework_fastapi_endpoint(app, my_workflow, "/workflow")
Eventos AG-UI Emitidos por Fluxos de Trabalho
As execuções de fluxo de trabalho emitem um conjunto mais avançado de eventos de AG-UI em comparação com execuções de agente único:
| Acontecimento | Quando emitido | Descrição |
|---|---|---|
RUN_STARTED |
Início da execução | Marca o início da execução do fluxo de trabalho |
STEP_STARTED |
Um executor ou superstep começa |
step_name identifica o agente ou a etapa (por exemplo, "triage_agent") |
TEXT_MESSAGE_* |
O agente produz texto | Eventos de texto de streaming padrão |
TOOL_CALL_* |
O agente invoca uma ferramenta | Eventos de chamada de ferramenta padrão |
STEP_FINISHED |
Um executor ou superstep é concluído | Fecha a etapa para acompanhamento de progresso da interface do usuário |
CUSTOM (status) |
Alterações de estado do fluxo de trabalho | Contém {"state": "<value>"} no valor do evento |
CUSTOM (request_info) |
O fluxo de trabalho solicita entrada humana | Contém a carga útil da solicitação para o cliente renderizar um prompt |
CUSTOM (workflow_output) |
O fluxo de trabalho produz resultado | Contém os dados de saída finais ou intermediários |
RUN_FINISHED |
Execução concluída | Pode incluir interrupts se o fluxo de trabalho estiver aguardando entrada |
Os clientes podem usar STEP_STARTED / STEP_FINISHED eventos para renderizar indicadores de progresso mostrando qual agente está ativo no momento.
Interromper e retomar
Os fluxos de trabalho podem pausar a execução para coletar entrada de humanos ou aprovações de ferramentas. A integração AG-UI lida com isso por meio do protocolo de interrupção/retomada.
Como as interrupções funcionam
Durante a execução, o fluxo de trabalho gera uma solicitação pendente (por exemplo, uma
HandoffAgentUserRequestsolicitação de mais detalhes ou uma ferramenta comapproval_mode="always_require").A ponte AG-UI emite um
CUSTOMevento comname="request_info"contendo os dados da solicitação.A execução é concluída com um
RUN_FINISHEDevento cujointerruptscampo contém uma lista de objetos de solicitação pendentes:{ "type": "RUN_FINISHED", "threadId": "abc123", "runId": "run_xyz", "interrupts": [ { "id": "request-id-1", "value": { "request_type": "HandoffAgentUserRequest", "data": "..." } } ] }O cliente renderiza a interface do usuário para que o usuário responda (uma entrada de texto, um botão de aprovação etc.).
Como o currículo funciona
O cliente envia uma nova solicitação com o resume conteúdo que contém as respostas do usuário chaveadas pela ID de interrupção:
{
"threadId": "abc123",
"messages": [],
"resume": {
"interrupts": [
{
"id": "request-id-1",
"value": "User's response text or approval decision"
}
]
}
}
O servidor converte o conteúdo do currículo em respostas de fluxo de trabalho e continua a execução de onde ele fez uma pausa.
Exemplo completo: fluxo de trabalho de repasse entre múltiplos agentes
Este exemplo mostra um fluxo de trabalho de suporte ao cliente com três agentes que entregam trabalho uns aos outros, usam ferramentas que exigem aprovação e solicitam entrada humana quando necessário.
Definir os agentes e as ferramentas
"""AG-UI workflow server with multi-agent handoff."""
import os
from agent_framework import Agent, Message, Workflow, tool
from agent_framework.ag_ui import (
AgentFrameworkWorkflow,
add_agent_framework_fastapi_endpoint,
)
from agent_framework.azure import AzureOpenAIResponsesClient
from agent_framework.orchestrations import HandoffBuilder
from azure.identity import AzureCliCredential
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
@tool(approval_mode="always_require")
def submit_refund(refund_description: str, amount: str, order_id: str) -> str:
"""Capture a refund request for manual review before processing."""
return f"Refund recorded for order {order_id} (amount: {amount}): {refund_description}"
@tool(approval_mode="always_require")
def submit_replacement(order_id: str, shipping_preference: str, replacement_note: str) -> str:
"""Capture a replacement request for manual review before processing."""
return f"Replacement recorded for order {order_id} (shipping: {shipping_preference}): {replacement_note}"
@tool(approval_mode="never_require")
def lookup_order_details(order_id: str) -> dict[str, str]:
"""Return order details for a given order ID."""
return {
"order_id": order_id,
"item_name": "Wireless Headphones",
"amount": "$129.99",
"status": "delivered",
}
Criar o fluxo de trabalho
def create_handoff_workflow() -> Workflow:
"""Build a handoff workflow with triage, refund, and order agents."""
client = AzureOpenAIResponsesClient(
project_endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
deployment_name=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
credential=AzureCliCredential(),
)
triage = Agent(id="triage_agent", name="triage_agent", instructions="...", client=client)
refund = Agent(id="refund_agent", name="refund_agent", instructions="...", client=client,
tools=[lookup_order_details, submit_refund])
order = Agent(id="order_agent", name="order_agent", instructions="...", client=client,
tools=[lookup_order_details, submit_replacement])
def termination_condition(conversation: list[Message]) -> bool:
for msg in reversed(conversation):
if msg.role == "assistant" and (msg.text or "").strip().lower().endswith("case complete."):
return True
return False
builder = HandoffBuilder(
name="support_workflow",
participants=[triage, refund, order],
termination_condition=termination_condition,
)
builder.add_handoff(triage, [refund], description="Route refund requests.")
builder.add_handoff(triage, [order], description="Route replacement requests.")
builder.add_handoff(refund, [order], description="Route to order after refund.")
builder.add_handoff(order, [triage], description="Route back after completion.")
return builder.with_start_agent(triage).build()
Criar o aplicativo FastAPI
app = FastAPI(title="Workflow AG-UI Demo")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
ag_ui_workflow = AgentFrameworkWorkflow(
workflow_factory=lambda _thread_id: create_handoff_workflow(),
name="support_workflow",
description="Customer support handoff workflow.",
)
add_agent_framework_fastapi_endpoint(
app=app,
agent=ag_ui_workflow,
path="/support",
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8888)
Sequência de eventos
Uma interação típica de vários turnos produz eventos como:
RUN_STARTED threadId=abc123
STEP_STARTED stepName=triage_agent
TEXT_MESSAGE_START role=assistant
TEXT_MESSAGE_CONTENT delta="I'll look into your refund..."
TEXT_MESSAGE_END
STEP_FINISHED stepName=triage_agent
STEP_STARTED stepName=refund_agent
TOOL_CALL_START toolCallName=lookup_order_details
TOOL_CALL_ARGS delta='{"order_id":"12345"}'
TOOL_CALL_END
TOOL_CALL_START toolCallName=submit_refund
TOOL_CALL_ARGS delta='{"order_id":"12345","amount":"$129.99",...}'
TOOL_CALL_END
RUN_FINISHED interrupts=[{id: "...", value: {function_approval_request}}]
Em seguida, o cliente pode exibir uma caixa de diálogo de aprovação e retomar com a decisão do usuário.