Melhores Práticas de Automação Tracecat
Para automações voltadas ao Slack, use /skill:tracecat-slackbot-best-practices. No Workspace Chat do Tracecat,
carregue /skill:tracecat-workspace-chat primeiro; o mapeamento de ferramentas específico do host substitui as
etapas MCP externas abaixo. Referências sob demanda: graph-shape,
expressions, run-python,
tables, trigger-inputs,
case-triggers, secrets,
agent-outputs, agent-presets,
workflow-editing.
Fluxo de Trabalho
Para uma conexão MCP Tracecat externa, comece pelo contexto ativo em vez de adivinhar:
- Descubra o workspace com
list_workspaces. - Leia
tracecat://platform/dsl-referencequando a sintaxe DSL ou exemplos forem necessários. - Use
get_workflow_authoring_contextpara esquemas de ação, variáveis e segredos. - Para workflows existentes, use
get_workflowe depois patches direcionados deedit_workflow— veja workflow-editing. Antes de adicionar ou editar qualquerrun_if,depends_onoujoin_strategy, chameget_workflow_graphonde o host o expõe e leia cada ação upstream e sua listagated_byprimeiro. - Valide com
validate_workflow, execute uma execução de rascunho ou publicada quando apropriado, depois inspecione falhas comlist_workflow_executionseget_workflow_execution.
Outros hosts podem expor uma superfície de ferramentas diferente. Siga o adaptador deles em vez de prefixar mecanicamente esses nomes MCP básicos.
Esclareça escolhas de produção que alteram o contrato do workflow: workspace, integração/provedor, origem do segredo, comportamento de publicação/execução, efeitos colaterais destrutivos, aprovações ou critérios de aceitação. Se a solicitação já for específica o suficiente, prossiga.
Formato do Grafo
Esboce o formato antes da criação e mantenha-o o mais próximo possível de uma linha, conforme o trabalho permitir. Prefira linear em vez de paralelo, e legível em vez de totalmente conectado: menos arestas é a métrica.
depends_oné ordem de execução, não roteamento de dados. Uma ação pode lerACTIONS.<ref>.resultde qualquer ancestral, não apenas de um pai direto — a validação verifica que a ref existe no workflow, não que seja um pai. Adicione uma aresta quando a ação precisar esperar, nunca para tornar um valor acessível.- Gate uma vez. Um
run_ifem uma ação também pula todas as ações abaixo dela na cadeia, então nunca repita-o downstream. Uma cadeia onde cada ação carrega a mesma guardaTRIGGER.enabled && ...está errada; apenas a primeira ação precisa dela. Uma ação downstream recebe seu própriorun_ifapenas para uma condição nova, escrita sozinha. A exceção é uma junção, e é uma armadilha: uma tarefa com vários pais não é forçada a pular enquanto um sobrevive, mas o padrãojoin_strategy: allentão exige que todo pai tenha sido visitado, então um ramo pulado torna a junção inalcançável e falha o workflow. Usejoin_strategy: any, ou repita a condição do ramo na junção para que ela se pule primeiro. - Padrão para uma única cadeia. Ramifique apenas para trabalho genuinamente independente que vale a pena executar concorrentemente, e reúna apenas quando uma ação posterior precisar de resultados de mais de um ramo.
- Um pai é a norma. Mais de um significa uma junção deliberada — escolha
join_strategyde propósito. - Mantenha cada
run_ifcurto: uma comparação legível para a única nova condição. Uma longa cadeia&&/||geralmente reafirma gates upstream ou pertence a uma transformação anterior. - Mantenha workflows comuns em torno de 20 nós ou menos e workflows agentivos em torno de 6 nós ou
menos. Prefira fluxos legíveis de cima para baixo ordenados da maneira que o processo lê, e
refs legíveis por humanos. O MCP Tracecat formata automaticamente a tela quando ações ou arestas mudam, então
omita
layoutem vez de posicionar nós manualmente.
Veja graph-shape para uma reescrita trabalhada de over-connected, estratégias de junção, arestas de erro, e por que scatter não é ramificação.
Prioridade de Ação
Escolha a ação mais específica que faz o trabalho:
- Ações de integração (
tools.<integration_slug>.*) para o produto sendo chamado. Pesquiselist_actionscom um substring curto do produto ou nome da ação (por exemploquery="okta"), ou navegue por um namespacetools.<integration_slug>conhecido, antes de escrever uma chamada de API. A pesquisa corresponde a substrings literais, não palavras-chave separadas. Siganext_cursorenquantohas_morefor verdadeiro quando a primeira página não tiver uma ação adequada. Inspecione candidatos comget_action_contexte compare suas credenciais e argumentos necessários. - Ações principais:
core.http_request/core.http_paginatepara produtos ou endpoints com nenhuma ação de integração,core.transform.*para modelagem, ecore.table.*/core.cases.*para dados da plataforma. core.script.run_pythonapenas para uma etapa autocontida que nenhuma ação cobre. Nunca chame uma API do Python quando uma ação de integração ou HTTP pode fazer a chamada.
Nunca invente nomes tools.*. Se uma solicitação genérica se encaixa em várias integrações, mostre os
candidatos primeiro.
Escolhendo entre um agente e Python
Decida pelo tipo de trabalho, e otimize o workflow inteiro para manutenibilidade e legibilidade — o menor número de ações e a menor quantidade de código que faz o trabalho.
- Trabalho agentivo → use um agente (
ai.agent/ai.preset_agent). Qualquer coisa que exija julgamento, investigação, roteamento, escolhas de enriquecimento, sumarização, composição de uma mensagem, ou postagem no Slack. Conceda as ferramentas na lista de permissão deactionsdo preset ou em um skillmetadata.tools, depois confie no agente com elas. Prefira agentes, prompts e skills — eles carregam o pensamento criativo com muito menos partes móveis do que um grafo de nós determinísticos. - Roteamento determinístico de dados → use Python (
core.script.run_python). Transformar, normalizar, redigir, unir e agrupar linhas em tabelas. É exatamente para isso que o Python serve — não é um cheiro. Uma açãorun_pythonclara é melhor do que espalhar o mesmo trabalho por muitos nós. Chamadas de API não são roteamento de dados: elas vão em ações de integração oucore.http_*(veja Prioridade de ação).
O cheiro é usar Python para a parte agentiva — por exemplo compor ou enviar a mensagem de Slack de um agente a partir de um script em vez de dar ao agente a ferramenta do Slack.
Barreira de tamanho do prompt: empurre o comportamento para o prompt até um tamanho razoável. Quando um único prompt cresce muito para permanecer legível, decomponha em subagentes ou um skill em vez de inflar um mega-prompt.
Automação Centrada em Agente
Quando o usuário pedir por um workflow agentivo, um preset de agente, ou disser para usar agentes, faça do
agente o proprietário principal do trabalho. Dê a ele as ferramentas necessárias e confie que ele investigue,
decida, roteie, componha mensagens e aja. Padrão para uma forma enxuta:
trigger -> reshape/redact -> upsert event record -> ai.agent (ou ai.preset_agent).
Persista o evento normalizado antes de o agente executar. Quando eventos se originam em um SIEM, plataforma de log, stream de webhook SaaS, trilha de auditoria ou serviço de nuvem, armazene o payload normalizado e o estado de revisão em uma tabela Tracecat primeiro, com um upsert determinístico. Isso dá às retentativas, webhooks duplicados e replay uma fonte durável de verdade. Aponte o agente para a linha salva, para que o workflow — não o agente — possua o primeiro registro durável do evento.
Um nó determinístico ganha seu lugar por ser enxuto, direto e fácil de auditar, e por fazer trabalho que o agente não deve possuir: redigir segredos antes de o agente ver dados, normalizar esquema, fazer upsert da linha do evento, proteger execuções caras de agente com uma verificação de deduplicação, preparar lotes limitados ou criar checkpoint de estado durável. Mantenha julgamento, roteamento, enriquecimento, composição de mensagem, decisões de aprovação suave e comportamento de notificação final no agente. Quando uma pergunta de aprovação em si precisa de julgamento, deixe o agente decidir ou redigir a solicitação.
Dois mecanismos diferentes cobrem risco, e eles não competem com ferramentas de propriedade do preset. Use um
portão determinístico para um efeito externo irreversível que o próprio workflow realiza —
o grafo decide se aquele nó executa ou não. Use tool_approvals por ferramenta no preset para
uma ferramenta arriscada que o agente possui: o agente mantém a ferramenta, e a execução pausa para um humano antes
de aquela chamada específica ser realizada.
Prefira um agente bem instruído ou preset reutilizável em vez de muitos nós determinísticos pequenos. As
ferramentas de um agente normalmente vivem na lista de permissão actions do preset, ou em um metadata.tools
de um skill anexado quando vários agentes compartilham o grupo. Dessa forma, o agente tem as mesmas ferramentas
no Workspace Chat e em todo workflow que o chama. As instruções carregam comportamento em vez de
permissões: contratos de saída, estilo Slack, regras de deduplicação, limites de inquilino e
efeitos colaterais permitidos vão nas instruções do preset, que o agente lê em vez de arquivos
de repositório. Quando o agente precisar de uma ferramenta, conceder a ferramenta estreita lá geralmente é melhor do que envolver
a mesma chamada em uma ação do workflow.
Um nó ai.preset_agent geralmente carrega apenas preset e user_prompt, mais um
apêndice instructions opcional para contexto específico da execução. Seu argumento actions substitui
as ferramentas de registro do preset e de seus skills para aquela execução, em vez de adicionar a elas — as ferramentas
MCP permanecem anexadas, e uma lista vazia é ignorada — então é adequado para testar um preset com um conjunto de
ferramentas diferente em um teste ou avaliação. Uma lista deixada lá em um workflow de produção também descarta
as ferramentas de registro que os skills do preset contribuem, o que raramente é o que o autor queria.
Escreva instruções de agente como metas, contexto e razões em vez de proibições. Uma regra
genérica pode cancelar uma ferramenta que o agente recebeu: um chamador anexou "Use apenas evidências fornecidas"
e o agente pulou a única consulta de política para a qual tinha recebido uma ferramenta. Reserve regras
rígidas para ações irreversíveis ou voltadas para o exterior, e coloque tool_approvals ou um portão
determinístico por trás delas em vez de confiar no texto de um prompt.
O tempo de execução de um preset tem mais capacidade do que list_actions mostra: um shell real e ferramentas de arquivo,
Python, curl, jq e DuckDB. Inspecione o contexto do preset/tempo de execução antes de adicionar um auxiliar
de workflow para compensar uma limitação presumida — veja
agent-presets.
Configurações Padrão de Criação
- Para workflows agentivos, empurre a maior parte do comportamento para o prompt/preset do agente. Para workflows orientados a eventos, uma única ação de remodelagem/redação/upsert antes do agente geralmente é o limite determinístico correto.
- Use
ai.agent/ai.preset_agentpara o trabalho agentivo; a açãotools.*do produto (oucore.http_requestquando nenhuma existe) para chamadas de API determinísticas;core.script.run_pythonpara trabalho de dados determinístico, depois que uma expressão inline,run_ifou uma açãocore.transform.*foram descartadas — veja expressions e run-python. - Para gravações em massa em tabelas, prefira uma ação nativa
core.table.insert_rowsquando as linhas já estão modeladas (até 1000 linhas por lote). Se modelagem, divisão em lotes ou gravações mistas de tabela/caso forem necessárias, usecore.script.run_pythoncom auxiliares importados e lotes limitados em vez de espalhar muitas ações apoiadas por banco de dados. - Não dê
core.http_requesta um agente a menos que o usuário aceite explicitamente a ampla capacidade de rede. Coloque HTTP determinístico no grafo do workflow ou em um subfluxo bem delimitado. - Divida em subfluxos apenas quando houver um limite de orquestração real, workflow filho
reutilizável, histórico de execução separado, aprovações, ações de longa duração ou
checkpointing independente. Use
core.workflow.executee prefiraworkflow_aliasem vez de IDs codificados. Padrões de subfluxo em massa:loop_strategy: batch,batch_size: 32,fail_strategy: isolated,wait_strategy: wait(usedetachapenas quando o pai não precisar dos resultados do filho). - Mantenha saídas de run-python e agente pequenas: linhas downstream, contagens de resumo, amostras de erro limitadas.
- Prefira um preset de agente reutilizável em vez de
ai.agentinline, e o objetomodelem vez do obsoletomodel_name/model_providerde nível superior — veja agent-presets.
Erros Comuns
- Usar Python para a parte agentiva — compor ou postar a mensagem de Slack de um agente, ou fazer chamadas de roteamento/julgamento em um script. O agente possui composição de mensagem, postagem (via uma ferramenta do Slack) e julgamento; o Python possui roteamento determinístico de dados.
- Conectar demais o grafo: uma aresta de cada produtor para cada consumidor. Leia de ancestrais e mantenha uma cadeia (veja graph-shape).
- Repetir um
run_ifpor uma cadeia, reafirmando uma condição que um ancestral já aplicou. O salto se propaga sozinho — gate uma vez no topo, e dê a uma ação downstream umrun_ifapenas para uma nova condição que ela mesma introduz (veja graph-shape). - Nomes de ações de workflow não são nomes de ferramentas MCP. Use ferramentas MCP como
create_workflowpara gerenciar workflows, e nomes de ação comocore.http_requestapenas dentro do YAML do workflow. - Inventar nomes de ação
tools.*. Descubra ações comlist_actions, depois inspecione esquemas exatos comget_action_context. - Chamar a API de um produto a partir de
core.script.run_python(requests,httpx) ou umcore.http_requestsimples quando uma açãotools.*adequada existe. Pesquise e navegue pelas páginas delist_actionspara o produto primeiro. - Usar
for_eachpara gerenciamento de loop comum, ou usar scatter/gather para agrupamento pesado de dados, filtragem, junções ou gravações em tabelas. Padrão para scatter para loops em nível de workflow; adicione gather apenas quando etapas downstream precisarem de resultados combinados e omita-o caso contrário. Tenha cuidado especial com >10 ações dispersas de tabela/caso apoiadas por banco de dados, que podem esgotar slots de conexão do PostgreSQL. O intervalo opcional do scatter pode escalonar o trabalho, mas não agrupa gravações de banco de dados; use uma açãocore.table.insert_
…
[truncado para tradução]