AI Internals - Orquestração
Introduction
Em AI Internals - Tools & Agents, tratamos agent como um loop de controle com tool calls, budgets e regras de parada. Esse loop é útil, mas nem todo fluxo de produto deveria ser um planner decidindo o próximo passo em tempo real.
Orquestração é a parte em que você deixa o caminho explícito: classificar intent, recuperar evidência, chamar tools específicas e sintetizar uma resposta com limites claros. Você ainda usa o mesmo contrato de messages de Prompts & Context, mas agora o seu app manda na sequência.
Quando alguém diz "nosso agent está instável", muitas vezes o problema é falta de orquestração, não qualidade do modelo.
O que orquestração realmente significa
Em runtime, orquestração é política + ligação:
- Política: qual etapa roda primeiro, o que pode ramificar e o que nunca pode ser opcional.
- Ligação: como cada etapa lê entradas e produz saídas para a próxima.
Em vez de um loop aberto, você monta um pipeline limitado com checkpoints.
Esse formato traz duas vitórias práticas:
- Você testa cada estágio de forma independente.
- Você aplica guardrails antes dos side effects.
Blocos de construção de um pipeline
A maioria dos assistentes em produção usa um conjunto pequeno de etapas reutilizáveis:
- Classificação de intent: "Q&A", "ação de conta", "operação de escrita", "unknown".
- Retrieval: buscar docs ou registros de suporte só quando necessário.
- Execução de tools: chamar handlers em allowlist com args validados.
- Síntese: produzir texto para usuário ou saída estruturada.
- Pós-processamento: redigir segredos, normalizar tom, anexar citações.
O modelo pode aparecer em várias dessas etapas, mas ele não deveria decidir a existência das etapas.
Por exemplo, se intent=refund_request, seu código pode exigir:
- tool de policy check
- estado de confirmação do usuário
- idempotency key na tool de escrita
Nenhum truque de prompt deveria contornar isso.
Um esqueleto prático de orquestração
Abaixo está um esqueleto mínimo de pipeline com etapas fixas e um loop limitado para erros recuperáveis. O ponto não é a sintaxe do framework; o ponto é controle explícito.
type State struct {
UserInput string
Intent string
Evidence []string
ToolResults map[string]string
FinalAnswer string
Attempt int
}
func RunPipeline(s *State) error {
s.Intent = classifyIntent(s.UserInput)
if s.Intent == "unknown" {
s.FinalAnswer = "Can you clarify what you want to do?"
return nil
}
if needsRetrieval(s.Intent) {
s.Evidence = retrieveEvidence(s.UserInput)
}
if needsTools(s.Intent) {
// Tool args must be schema-validated before execution.
s.ToolResults = runAllowlistedTools(s.Intent, s.UserInput)
}
for s.Attempt = 1; s.Attempt <= 2; s.Attempt++ {
s.FinalAnswer = synthesizeAnswer(s)
if passesQualityGate(s.FinalAnswer) {
return nil
}
}
return fmt.Errorf("quality gate failed")
}Repare que o loop é limitado (<= 2) e só em volta da síntese. Retrieval e execução de tool de escrita ficam determinísticos.
Ramificações, fallbacks e condições de parada
Fluxos reais ramificam. A chave é ramificar no código com sinais explícitos:
- label do classificador
- status do resultado de tool
- threshold de confiança
- resultado de policy
Evite "se o modelo parecer incerto." Em vez disso, transforme incerteza em campo validável.
Um fallback forte vale mais do que uma corrente longa de retries. Duas tentativas mais um handoff limpo costumam ser melhores do que seis rounds de texto vago.
Orquestração vs loops de agent autônomo
Dá para pensar nisso como escolha de superfície de controle:
| Forma | Controle que você mantém | Perfil de custo / risco | Melhor encaixe |
|---|---|---|---|
| Orquestração explícita | Alto: etapas fixas, branches previsíveis | Menor variância, auditoria mais simples | Fluxos de produto com SLA e side effects |
| Agent loop limitado | Médio: modelo planeja dentro de budget limitado | Mais flexível, mais difícil de testar | Tarefas ambíguas com múltiplos passos |
| Agent aberto | Baixo: liberdade ampla de tools por horizonte longo | Alto gasto, risco de loop, complexidade de aprovação | Pesquisa interna com supervisão humana |
Comece por orquestração explícita e só adicione comportamento de agent onde branching estático falhar no tráfego real.
Observabilidade que torna orquestração depurável
Logue artefatos por estágio, não só a resposta final:
request_id,user_id,intent- IDs de chunks recuperados e scores
- nomes de tools, hash de args validados, latência, status
- nome do modelo, tokens de entrada/saída, estimativa de custo
- motivo de fallback
Assim você responde "por que esta resposta aconteceu?" sem tentar reproduzir no escuro a partir do texto do chat.
Conclusão
Orquestração é como transformar capacidade de modelo em caminho de produto confiável: etapas explícitas, branches com guardrails, retries limitados e resultados mensuráveis. Agents continuam importantes, mas devem viver dentro de um pipeline controlado, não substituir esse pipeline.
No próximo vamos para Harness — o que acontece quando esse pipeline roda dentro de uma sessão que dura horas: transcript durável, compactação, interrupção e retomada, e a sandbox onde as tools executam.