Preparação para entrevista
RefatoraçãoMovendo controle

Trocar Regra de Prompt por Aresta de Grafo

Replace Prompt Rule with Graph Edge

Trocar Regra de Prompt por Aresta de Grafo (Replace Prompt Rule with Graph Edge) é uma refatoração de IA para sistemas com LLM, do grupo Movendo controle. Transformar um SE isso, faça aquilo escrito no prompt em uma transição explícita no código.

Elemento
08/35
Nível
Intermediário
Leitura
5 min
Atualizado
Nesta página 8
  1. 01Problema
  2. 02Solução
  3. 03Antes e depois
  4. 04Por que funciona
  5. 05Passo a passo seguro
  6. 06Riscos
  7. 07Desafio
  8. 08Teste seu entendimento
  9. ··Perguntas rápidas

Problema

O prompt descreve o fluxo (“primeiro peça X, depois Y; se Z, faça W”) e o modelo pula, repete ou inverte etapas. São os smells Pilha de Regras e Prompt Máquina de Estados.

O bot de trocas do marketplace pede o número do pedido, confere a janela de 30 dias, exige foto se o item for eletrônico e só então gera a etiqueta. Tudo isso está num parágrafo do system prompt. Na terça, um cliente escreveu “pedido 4521, fone chiando, foto anexa”. O modelo pulou a data de entrega, gerou a etiqueta e o produto já tinha 47 dias. A regra estava no texto. O texto não é um if.

A pergunta que esta refatoração responde: como fazer a etapa obrigatória acontecer sempre, sem transformar o prompt numa máquina de estados ilegível? O destino próximo é uma chain ou um roteamento em código.

Solução

Transforme cada “SE isto, faça aquilo” do prompt numa transição explícita em código: um estado, uma condição verificável e o próximo passo. O modelo continua fazendo o que só ele faz (entender e escrever), mas quem decide o caminho é o grafo.

Antes e depois

-SYSTEM = """Você atende pedidos de troca.
-Primeiro peça o número do pedido.
-Depois confirme se o pedido foi entregue há menos de 30 dias.
-Se passou de 30 dias, explique que não é possível trocar.
-Se o produto for eletrônico, peça foto do defeito antes de continuar.
-Só gere a etiqueta de devolução depois de tudo confirmado."""
+def next_step(state):
+    if not state.order_id:
+        return ask("order_id")                       # 1
+    order = orders.get(state.order_id)
+    if (today() - order.delivered_at).days > 30:
+        return reply("outside_window")               # 2
+    if order.category == "electronics" and not state.defect_photo:
+        return ask("defect_photo")                   # 3
+    return create_return_label(order)                # 4
+
+# o modelo só extrai dados da mensagem e escreve a pergunta de forma natural
+state.update(llm_parse(EXTRACT_PROMPT, message, schema=ExchangeFields))
+step = next_step(state)
+answer = llm(PHRASE_PROMPT, step)

Antes: o fluxo é um parágrafo que o modelo precisa seguir.

flowchart LR
  M(["1. Mensagem"]):::io --> P(["2. Prompt com o roteiro inteiro"]):::llm
  P --> R(["3. Resposta, com etapas puladas às vezes"]):::io

Depois: o fluxo é um grafo em código; o modelo entra nas pontas.

flowchart TD
  M(["Mensagem"]):::io --> X(["Extrair campos"]):::llm
  X --> S1{"1. Tem número do pedido?"}
  S1 -->|não| A1(["Pedir número"]):::llm
  S1 -->|sim| S2{"2. Dentro de 30 dias?"}
  S2 -->|não| A2(["Explicar que não é possível"]):::llm
  S2 -->|sim| S3{"3. Eletrônico sem foto?"}
  S3 -->|sim| A3(["Pedir foto"]):::llm
  S3 -->|não| L["4. Gerar etiqueta"]:::tool
  1. Sem o número do pedido, a única ação possível é pedir o número.
  2. A janela de 30 dias é calculada pelo código, com a data real de entrega.
  3. A exigência de foto para eletrônicos é uma aresta, não uma frase.
  4. A etiqueta só é gerada quando o código chega a este nó.

Exemplo trabalhado

A mensagem da terça: “pedido 4521, fone chiando, foto anexa”.

No antes, o modelo recebe o roteiro e a mensagem juntos. Às vezes extrai o 4521, aceita a foto e gera a etiqueta sem olhar delivered_at. Não há um teste que prove que a janela foi conferida: a conferência mora dentro do modelo.

No depois, o extrator devolve:

{ "order_id": "4521", "defect_photo": "cid:foto1", "symptom": "chiando" }

next_step busca o pedido, calcula 47 dias e devolve reply("outside_window"). O modelo de frase só explica, em tom cordial, que a janela fechou. A etiqueta não é uma ferramenta à disposição dele. Não há como pulá-la, porque o caminho até ela não existe quando a data estoura.

Um teste unitário cobre a aresta: pedido com 31 dias, foto presente, espera outside_window, nunca create_return_label. Esse teste não existia enquanto a regra era um parágrafo.

Checagem +20 XP de primeiraO cliente manda na primeira mensagem o número do pedido e a foto do defeito. O grafo ainda pergunta só o número. Qual é o erro?

Por que funciona

Um modelo segue instruções de fluxo na maioria das vezes, e a maioria das vezes não basta para etapas obrigatórias. Uma aresta em código não tem “às vezes”: se a condição não é verdadeira, o passo seguinte não acontece.

A divisão de trabalho também fica mais clara. O modelo é bom em entender mensagens bagunçadas (“o fone que comprei semana passada, pedido 4521, chegou chiando”) e em escrever perguntas naturais. O código é bom em comparar datas, checar categorias e garantir ordem. Cada um faz o que faz melhor.

E o fluxo vira algo que dá para ler, testar e desenhar. Cada aresta tem um teste unitário. O prompt que sobra fala de tom e formato, não de “primeiro” e “só quando”.

O post “Building effective agents” da Anthropic (dezembro de 2024) descreve workflows com passos definidos em código, em vez de deixar o modelo orquestrar tudo. Esta refatoração é esse movimento, aplicado a um parágrafo de regras.

Passo a passo seguro

  1. Meça. Monte um eval com conversas reais, incluindo respostas fora de ordem e tentativas de pular etapas. Registre a taxa de fluxos completados corretamente, e em especial a taxa de etapas obrigatórias puladas.
  2. Liste as regras de fluxo do prompt: toda frase com “primeiro”, “depois”, “se”, “só quando”.
  3. Desenhe o grafo: estados, condições e transições. Confira com quem é dono do processo. A janela de 30 dias é regra de negócio, não palpite de prompt.
  4. Defina o estado explícito (campos coletados, validados, pendentes).
  5. Escreva o extrator: uma chamada que lê a mensagem e preenche campos do estado em saída estruturada. Ele não decide o próximo passo.
  6. Implemente as transições em código, com testes para cada aresta, inclusive as que recusam (janela vencida, categoria sem foto).
  7. Reduza o prompt de resposta a tom e formato. O que perguntar vem do grafo.
  8. Meça de novo. Fluxos completados corretamente devem subir; etapas puladas devem ir a zero.

O que fica no prompt

Tom, vocabulário, idioma, como tratar o cliente irritado. Isso o grafo não faz bem. “Seja cordial e use o primeiro nome” permanece. “Só gere a etiqueta depois de tudo confirmado” sai.

Checagem +20 XP de primeiraA janela de troca está escrita no prompt: ‘confirme se a entrega foi há menos de 30 dias’. Em produção, um pedido com 31 dias ganhou etiqueta. O eval de tom está verde. O que a refatoração muda nesse caso?

Riscos

  • Conversa robótica. Um grafo rígido pode ignorar quando o cliente responde duas coisas de uma vez. Extraia todos os campos de cada mensagem, não só o que foi perguntado.
  • Casos fora do grafo. O cliente pergunta algo que nenhum estado prevê (“aceita Pix na devolução?”). Tenha um caminho para dúvidas gerais e para uma pessoa.
  • Grafo que cresce sem controle. Cada exceção vira uma aresta. Se o grafo ficar enorme, talvez o processo precise ser simplificado, não codificado.
  • Estado perdido. Conversas longas ou retomadas dias depois precisam de estado persistido. Veja Mover para Execução Durável.

Desafio

Quais regras deste prompt de agendamento devem virar arestas, e qual pode ficar no prompt?

Você agenda consultas.
Só ofereça horários dentro do horário de funcionamento (8h às 18h).
Sempre confirme o convênio antes de mostrar horários.
Se o convênio não for aceito, ofereça consulta particular.
Seja cordial e use o primeiro nome do paciente.
Ver solução

As três primeiras regras de fluxo viram código: horários vêm de uma consulta à agenda que já filtra o funcionamento; mostrar horários só acontece depois do estado convenio_confirmado; convênio não aceito leva a uma aresta para a oferta particular. A última regra é de tom e fica no prompt.

state: { paciente, convenio?, convenio_aceito?, horario? }
if not convenio: ask(convenio)
elif not convenio_aceito: offer(particular)
elif not horario: show(agenda.slots(open_hours_only=True))
else: confirm(horario)
prompt: "Seja cordial e use o primeiro nome do paciente."

Teste seu entendimento

Checagem +20 XP de primeiraQual destas frases do prompt de trocas deve continuar no prompt depois da refatoração?

Checagem +20 XP de primeiraO time desenhou 40 arestas para cobrir ‘todos os casos’ do marketplace, inclusive exceções que aparecem duas vezes por mês. O eval do extrator caiu. Qual é a leitura?

Checagem +20 XP de primeiraUma conversa de troca começa na segunda e o cliente volta na sexta com a foto. O estado estava só na memória do processo da segunda. O que acontece, e o que falta?

Checagem +20 XP de primeiraVocês mediram 8% de etiquetas geradas fora da janela de 30 dias. Depois da refatoração, esse número no eval deve ir a quanto, se a aresta estiver correta?

Perguntas rápidas

O que é Trocar Regra de Prompt por Aresta de Grafo?

Trocar Regra de Prompt por Aresta de Grafo (Replace Prompt Rule with Graph Edge) é uma refatoração de IA para sistemas com LLM, do grupo Movendo controle. Transformar um SE isso, faça aquilo escrito no prompt em uma transição explícita no código.

Que problema Trocar Regra de Prompt por Aresta de Grafo resolve?

Trata Pilha de Regras e Prompt Máquina de Estados.

Aonde Trocar Regra de Prompt por Aresta de Grafo leva?

Ao padrão de projeto Roteamento e Encadeamento de Prompts.

Para ir além

Relações

Buscar