Pular para conteúdo

Modificar um agente

Localização e caminho de execução

Agente Builder de prompt Estados relacionados
Triagem src/core/agents/triagem/system_prompt.pybuild_triagem_system_prompt TRIAGE
Qualificação src/core/agents/qualificacao/system_prompt.pybuild_qualificacao_system_prompt QUALIFYING
Coleta src/core/agents/coleta/system_prompt.pybuild_coleta_system_prompt DATA_COLLECT, CONFIRM

AgentInvokerImpl em src/core/agents/invoker.py escolhe o builder, insere packages, aplica override, acrescenta regras fixas e monta mensagens. O resultado do LLM retorna ao caso de uso; o agente não grava no banco ou envia WhatsApp diretamente.

1. Encontrar o prompt efetivo

Antes de editar, confira se há override ativo em VersionedResourceRepository. _apply_prompt_override() usa o arquivo como fallback, ou substitui {{default_prompt}} pelo conteúdo padrão quando esse marcador existe no override.

_with_runtime_guards() acrescenta identidade, contexto de instância/segmento/intenção, restrições de promessa de prazo e regras de mudança de assunto após o override. Em contexto de saúde humana, há restrições adicionais. Uma edição em um override não remove essas guardas.

Os overrides administrativos são validados estruturalmente por validate_resource_update() em admin_tools.py, mas a presença de {"s" ou {{default_prompt}} não comprova a qualidade nem a compatibilidade de todas as respostas possíveis. Trate alteração de conteúdo como uma mudança que precisa de regressão.

2. Preservar o contrato de saída

Toda saída precisa começar com {, conter JSON com s inteiro e ser seguida pelo texto destinado ao cliente quando o código pedir resposta. O parser não aceita cumprimento antes do JSON nem code fence envolvendo a resposta.

{"s":1}Qual é o tipo de amostra?
{"s":99,"context_needed":"SAMPLE_INSTRUCTIONS"}

s=99 pede um package; s=97 inicia a confirmação de mudança de assunto; s=98 é processado pelo fluxo de mudança de sessão. Não invente um código no prompt sem alterar os enums/validação, o dispatcher e os testes correspondentes. Códigos de ação descreve o significado por agente, pois o mesmo valor pode ter efeitos diferentes.

O caso de uso tem reparo de formato e fallback de handoff. Isso recupera algumas falhas; não transforma um prompt incompatível em uma mudança segura. Uma saída sintaticamente válida ainda pode ter campo desconhecido, serviço não reconhecido ou transição ilegal.

3. Respeitar histórico e contexto

invoke() filtra o histórico pelo session_id. Mensagens INBOUND viram user, OUTBOUND viram assistant, eventos SYSTEM não são reenviados e mensagens marcadas superseded são excluídas. O invocador evita acrescentar novamente o último texto de usuário quando já está no histórico.

Uma reinvocação no mesmo turno pode receber client_message=None. Os dados atualizados estão no histórico, na sessão ou nos packages injetados. Não escreva um prompt que dependa de sempre receber uma nova mensagem de usuário após cada resposta s=99.

O catálogo de descoberta contém descrições curtas, não toda a KB. O agente solicita conteúdo adicional somente quando necessário. Revisões de conhecimento devem manter coerência entre CONTENT, metadata de descoberta e os campos já qualificados/coletados.

4. Escolher a camada certa

Mudança desejada Camada
Clareza da pergunta, tom e concisão Prompt e src/core/agents/whatsapp_style.py
Novo campo obrigatório de um serviço domain/services.py, prompt e dispatcher
Nova ação ou estado Domínio + action_mapping.py + caso de uso + persistência
Novo modelo ou reasoning effort Settings/factory/SAM; cliente OpenAI
Novo conteúdo científico/comercial Package e fonte de conhecimento aprovada
Regra que nunca pode ser sobreposta por admin Guarda programática/runtime, com testes específicos

Não use o prompt para prometer uma validação que o código não implementa. Também não torne uma pergunta livre em escrita automática externa sem definir idempotência, estado e autorização do fluxo.

5. Validar antes da chamada real

python -m pytest tests/unit/agents/test_system_prompts.py tests/unit/agents/test_invoker.py -q
python -m pytest tests/unit/application/test_parser.py tests/unit/application/test_action_mapping.py -q
python -m pytest tests/unit/application/test_process_message_use_case.py -q
python -m pytest tests/integration/test_fixture_replay.py -q

Os testes de prompt verificam regras e conteúdo; os de invocador verificam montagem e encaminhamento. Parser/dispatcher/use case verificam o efeito do contrato, e replay verifica uma conversa roteirizada. Nenhum deles prova que uma nova versão do modelo vai sempre obedecer. O teste real marcado integration requer chave, custo e avaliação separada, conforme integração.

6. Criar uma fixture de regressão

Reduza o problema a uma conversa fictícia que exponha o erro. Inclua todos os llm_responses na ordem em que serão consumidos e os invariantes suportados pelo runner (state, segment, service_identified, handoff_reason, demands_recorded). Não use uma expectativa arbitrária que o runner ignore.

Para uma mudança de assunto, cubra a confirmação e a criação da nova sessão; para s=99, inclua o pedido de package e a resposta seguinte; para handoff, confira que o fluxo para de chamar agentes no atendimento humano. O guia de fixtures mostra o formato completo.

Rollback

Uma mudança em arquivo pode ser revertida no Git e implantada de novo. Uma versão dinâmica exige restaurar/desativar o recurso correto no repository administrativo. Verifique o prompt renderizado depois da restauração e mantenha o caso de regressão. Reverter um prompt não remove mensagens já enviadas nem desfaz alterações externas realizadas em turnos anteriores.

Fontes: src/core/agents/invoker.py, src/core/application/agent_invoker.py, src/core/application/parser.py, src/core/application/admin_tools.py, src/core/application/process_message_use_case.py, src/core/knowledge_base/repository.py e testes citados.