Tutorial: Configurar ganchos de agente (API) no Azure SRE Agent

Sugestão

Prefere a UI do portal? Agora pode criar e gerir hooks diretamente no portal sem usar a API REST. O portal disponibiliza um editor visual de formulários e código. Não são necessários curl comandos.

Neste tutorial, crias um agente personalizado com um gancho Stop que obriga o agente a adicionar um marcador de conclusão a cada resposta. Configuras o hook através da API REST e depois testas-no no playground do portal.

Tempo estimado: 15 minutos

Observação

Ganchos ao nível de agente vs. nível de agente personalizado: Este tutorial cria ganchos num agente personalizado (ganchos ao nível de agente personalizado). Esses ganchos só disparam quando esse agente personalizado específico é executado.

Para criar ganchos ao nível do agente que se aplicam a todo o agente (todos os tópicos, todos os agentes personalizados), usa os Ganchos de Construção> no portal.

Nível Como criar Scope
Nível de agente Portal: Gancho de Construtor > Aplica-se a todos os threads e agentes personalizados
Nível personalizado de agente API REST (este tutorial) ou Portal: Agent Canvas > Agente personalizado > Gerir Ganchos Aplica-se apenas a um agente de alfândega

Neste tutorial, aprenderás como:

  • Crie um agente personalizado com um gancho Stop usando a API REST
  • Comportamento do hook de teste na área de testes do portal
  • Adicionar um gancho PostToolUse para auditar a utilização de ferramentas
  • Bloquear comandos perigosos com um gancho de política

Pré-requisitos

  • Um agente SRE do Azure no estado Em execução
  • curl para chamar a API REST
  • Azure CLI iniciou sessão (az login) para obter um token de acesso

Compreenda o formato da API de gancho

Este tutorial utiliza a API REST v2 para criar ganchos num agente personalizado. A aba do editor YAML do portal mostra o formato v1 e não exibe hooks configurados via API, embora os hooks continuem ativos. Pode verificá-los na página Builder>Hooks ou no espaço de teste.

Sugestão

Quando usar a API vs o portal:

  • Portal (Builder > Hooks): Ideal para ganchos ao nível de agente em forma visual. Nenhum código é necessário.
  • API (este tutorial): Ideal para hooks ao nível de agente personalizado, pipelines CI/CD ou gestão programática.

Encontre o URL da API do seu agente

A URL base da API do seu agente segue este padrão:

https://{agent-name}--{hash}.{hash}.{region}.azuresre.ai

Para o encontrar:

  1. Abra sre.azure.com e escolha o seu agente.
  2. Na barra lateral esquerda, selecione Builder>Agent Canvas.
  3. Abra as Ferramentas de Desenvolvimento do seu navegador (F12 ou clique > direito em Inspecionar).
  4. Vá ao separador Rede , filtre por "api" e procure pedidos para uma URL que termine em .azuresre.ai.
  5. A URL base é tudo o que está antes de /api/....

Alternativamente, verifique o atributo src no separador Elements. Procure um <iframe> cujo src começa por https://{agent-name}--.

Obter um token de acesso

Execute o seguinte comando para obter um token de acesso para a API do SRE Agent:

TOKEN=$(az account get-access-token \
  --resource <RESOURCE_ID> \
  --query accessToken -o tsv)

Crie um agente personalizado com um gancho Stop

Esta etapa cria um agente personalizado chamado my_hooked_agent com um gancho Stop que verifica se a resposta termina em === RESPONSE COMPLETE ===. Caso o marcador esteja em falta, o sistema rejeita a resposta e informa o agente para adicionar o marcador.

AGENT_URL="https://your-agent--xxxxxxxx.yyyyyyyy.region.azuresre.ai"

curl -X PUT "${AGENT_URL}/api/v2/extendedAgent/agents/my_hooked_agent" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d @- << 'EOF'
{
  "name": "my_hooked_agent",
  "properties": {
    "instructions": "You are a helpful assistant. Be concise.",
    "handoffDescription": "",
    "handoffs": [],
    "enableVanillaMode": true,
    "hooks": {
      "Stop": [
        {
          "type": "prompt",
          "prompt": "Check the agent response below.\n\n$ARGUMENTS\n\nDoes it end with === RESPONSE COMPLETE ===?\nIf yes: {\"ok\": true}\nIf no: {\"ok\": false, \"reason\": \"Add === RESPONSE COMPLETE === at the end.\"}",
          "timeout": 30
        }
      ]
    }
  }
}
EOF

Recebes HTTP 202 Aceite com a configuração completa do agente no corpo da resposta.

O exemplo seguinte mostra a mesma configuração no formato YAML v2 para referência:

api_version: azuresre.ai/v2
kind: ExtendedAgent
metadata:
  name: my_hooked_agent
spec:
  instructions: |
    You are a helpful assistant. Be concise.
  handoffDescription: ""
  enableVanillaMode: true
  hooks:
    Stop:
      - type: prompt
        prompt: |
          Check the agent response below.

          $ARGUMENTS

          Does it end with === RESPONSE COMPLETE ===?
          If yes: {"ok": true}
          If no: {"ok": false, "reason": "Add === RESPONSE COMPLETE === at the end."}
        timeout: 30

Como funciona o gancho Stop

O gancho Stop avalia a resposta do agente antes de este regressar ao utilizador:

  • Substitui $ARGUMENTS pelo contexto do hook JSON, que inclui a resposta final do agente.
  • O LLM avalia o enunciado e devolve {"ok": true} ou {"ok": false, "reason": "..."}.
  • Se rejeitado, o agente continua a trabalhar depois de a razão ser injetada como mensagem de utilizador.
  • Após três rejeições (o padrão), o agente para.

Teste o gancho no portal

Siga estes passos para testar o gancho Stop:

  1. Vá ao seu agente no portal e selecione Builder>Agent Canvas.

  2. Selecione o botão de opção Test playground.

  3. Selecione o menu suspenso Subagente/Ferramenta, encontre my_hooked_agent e selecione Aplicar.

    Teste playground com o agente enganchado selecionado.

  4. Escreve What is 2+2? no chat e seleciona Enviar.

Vê o que acontece:

  • O agente responde primeiro com 4.
  • O gancho Stop avalia e rejeita a resposta (sem marcador de completação).
  • Aparece um passo do processo de pensamento onde o agente continua.
  • A resposta final aparece: 4 === RESPOSTA COMPLETA ===.

Resultado do gancho de parada que mostra que o agente adiciona o marcador RESPOSTA COMPLETA após a rejeição inicial.

O gancho funcionou. Isso obrigava o agente a adicionar o marcador antes de parar.

Adicionar um gancho PostToolUse para auditoria

Adicione um hook PostToolUse que registre todas as ferramentas que o agente utiliza. Atualize o mesmo agente enviando uma nova PUT solicitação com ambos os hooks:

curl -X PUT "${AGENT_URL}/api/v2/extendedAgent/agents/my_hooked_agent" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d @- << 'EOF'
{
  "name": "my_hooked_agent",
  "properties": {
    "instructions": "You are a helpful assistant. Be concise.",
    "handoffDescription": "",
    "handoffs": [],
    "enableVanillaMode": true,
    "hooks": {
      "Stop": [
        {
          "type": "prompt",
          "prompt": "Check the agent response below.\n\n$ARGUMENTS\n\nDoes it end with === RESPONSE COMPLETE ===?\nIf yes: {\"ok\": true}\nIf no: {\"ok\": false, \"reason\": \"Add === RESPONSE COMPLETE === at the end.\"}",
          "timeout": 30
        }
      ],
      "PostToolUse": [
        {
          "type": "command",
          "matcher": "*",
          "timeout": 30,
          "failMode": "allow",
          "script": "#!/usr/bin/env python3\nimport sys, json\ncontext = json.load(sys.stdin)\ntool = context.get('tool_name', 'unknown')\nprint(json.dumps({'decision': 'allow', 'hookSpecificOutput': {'additionalContext': f'[AUDIT] {tool} executed.'}}))"
        }
      ]
    }
  }
}
EOF

matcher: "*" significa que este hook executa para cada chamada de ferramenta. O script regista o nome da ferramenta e injeta uma [AUDIT] mensagem na conversa.

Para testar o gancho, faça ao agente uma pergunta que desencadeie uma ferramenta (por exemplo, "Executar echo hello").

Bloquear comandos perigosos

Adicione um segundo gancho PostToolUse que bloqueie rm -rf, sudo, e chmod 777:

PostToolUse:
  # Audit hook (runs for all tools)
  - type: command
    matcher: "*"
    timeout: 30
    failMode: allow
    script: |
      #!/usr/bin/env python3
      import sys, json
      context = json.load(sys.stdin)
      tool = context.get('tool_name', 'unknown')
      print(json.dumps({"decision": "allow",
        "hookSpecificOutput": {"additionalContext": f"[AUDIT] {tool} executed."}}))

  # Policy hook (only for shell tools)
  - type: command
    matcher: "Bash|ExecuteShellCommand"
    timeout: 30
    failMode: block
    script: |
      #!/usr/bin/env python3
      import sys, json, re
      context = json.load(sys.stdin)
      command = context.get('tool_input', {}).get('command', '')
      for pattern in [r'\brm\s+-rf\b', r'\bsudo\b', r'\bchmod\s+777\b']:
          if re.search(pattern, command):
              print(json.dumps({"decision": "block", "reason": f"Blocked: {pattern}"}))
              sys.exit(0)
      print(json.dumps({"decision": "allow"}))

Principais diferenças em relação ao gancho de auditoria:

  • matcher: "Bash|ExecuteShellCommand" só é executado para ferramentas de shell (o padrão está fixado como ^(Bash|ExecuteShellCommand)$).
  • failMode: block bloqueia o resultado da ferramenta se o próprio script falhar (modo rigoroso).
  • Regressa "block" com uma razão quando se encontra um padrão perigoso.

Formatos de resposta de hook

Ganchos de prompt e ganchos de comando usam formatos de resposta diferentes.

Ganchos de prompt

Ganchos de prompt retornam JSON simples:

{"ok": true}
{"ok": false, "reason": "Please fix X."}

Ganchos de comando

Ganchos de comando retornam JSON expandido:

{"decision": "allow"}
{"decision": "block", "reason": "Dangerous command."}
{"decision": "allow", "hookSpecificOutput": {"additionalContext": "Audit note."}}

Os hooks de comando também podem usar códigos de saída em vez de JSON:

Código de saída Comportamento
0 sem saída Allow
0 com JSON Analise o JSON
2 Bloqueio (o STDERR torna-se a razão)
Outros Volta a failMode

Atenção

Uma rejeição sem motivo é tratada como aprovação. Inclua reason sempre ao rejeitar.

Verificar

Depois de configurar e testar os ganchos, confirme as seguintes condições:

  • Configurar hooks personalizados ao nível de agente usando a API REST v2. Aplicam-se apenas a esse agente alfandegário.
  • Cria-se ganchos ao nível de agente nos Builder > Hooks. Aplicam-se a todo o agente.
  • O gancho de parada faz com que o agente adicione o === RESPONSE COMPLETE === marcador antes de parar.
  • O gancho de auditoria PostToolUse regista [AUDIT] mensagens para chamadas de ferramenta.
  • O gancho de política bloqueia comandos perigosos como rm -rf e sudo.

Troubleshooting

A tabela seguinte lista problemas comuns e soluções para ganchos de agente.

Problema Solução
Ganchos não visíveis no separador YAML do portal Esperado – a aba YAML mostra apenas v1. Hooks personalizados ao nível de agente criados através da API estão ativos e visíveis nos Builder>Hooks ou no playground.
Unsupported kind: ExtendedAgent Utilize o endpoint v2: PUT /api/v2/extendedAgent/agents/{name}.
Handoffs cannot be null Adicione "handoffs": [] ao payload JSON.
O gancho não tem efeito Inclua um reason campo ao rejeitar. Sem isso, a rejeição é tratada como aprovação.
"Agente entra em loop infinito" Reduzir maxRejections (padrão: 3, intervalo: 1-25).

Próximo passo