Toda equipe tem aquele conjunto de tarefas chatas que ninguém gosta de fazer, mas que precisam ser feitas sempre do mesmo jeito: abrir PR com o título no padrão, nomear a branch certo, montar o changelog, linkar o work item. São tarefas de baixo valor intelectual e alto custo de atenção — e, pior, qualquer desvio do padrão vira ruído na revisão.

Resolvi atacar isso de uma forma diferente: em vez de escrever mais um script bash gigante, montei agentes de IA especializados que encapsulam esses fluxos. Neste artigo mostro como estruturei esse setup usando o Kiro CLI, com um padrão que separa claramente configuração, conhecimento e regras de segurança.

Vou usar meus próprios agentes como exemplo — abstraindo nomes internos — mas o padrão serve para qualquer time.

O problema

No meu dia a dia eu repetia, várias vezes por dia, dois fluxos:

  1. Abrir um Pull Request: criar a branch no padrão, commitar com a convenção certa, inferir a branch de destino, abrir o PR com título e descrição padronizados e linkar o work item.
  2. Fechar um pacote de release: buscar os PRs já concluídos de uma demanda, gerar o changelog, commitar e abrir um PR de release para a branch certa.

Nenhum desses passos é difícil. O problema é que todos eles têm detalhes — e detalhe esquecido é retrabalho. Automatizar com um script puro seria frágil, porque boa parte das decisões depende de contexto (qual branch, qual título, qual destino).

Agente de IA é bom justamente nessa zona cinzenta: segue regras, mas interpreta contexto.

A ideia central: separar configuração, conhecimento e regras

O que mais me ajudou foi não jogar tudo em um prompt gigante. Em vez disso, dividi cada agente em quatro camadas, cada uma em um arquivo próprio:

.kiro/ ├── agents/ # Configuração: quais ferramentas o agente pode usar ├── prompts/ # Identidade: quem o agente é e seu contexto fixo ├── steering/ # Guardrails: o que ele NUNCA pode fazer ├── skills/ # Conhecimento: o passo a passo de cada tarefa └── settings/ # Integração com ferramentas externas (via MCP) 

A sacada é que cada camada tem uma responsabilidade única:

  • Agent = o contrato (ferramentas permitidas, atalho, mensagem de boas-vindas)
  • Prompt = a identidade (contexto que nunca muda)
  • Steering = os limites (proibições inegociáveis)
  • Skill = o manual (como executar cada passo, com exemplos)

Separar assim traz um benefício enorme: as skills viram reutilizáveis entre agentes. A skill de "criar commit" é a mesma para o agente que abre PR e para o que fecha release.

Camada 1 — O agente (configuração)

O arquivo de configuração do agente é enxuto. Ele diz o que o agente pode fazer, não como. Veja um exemplo (abstraído):

{ "name": "open-pr", "description": "Agente que abre Pull Requests: cria branch, commita, abre o PR e linka o work item.", "prompt": "file://./prompts/open-pr.md", "includeMcpJson": true, "tools": ["shell", "read", "write", "grep", "glob", "@git-provider"], "allowedTools": [ "shell", "read", "write", "@git-provider/create_pull_request", "@git-provider/create_branch", "@git-provider/link_work_item" ], "resources": [ "skill://.kiro/skills/commit/SKILL.md", "skill://.kiro/skills/create-branch/SKILL.md", "skill://.kiro/skills/open-pr/SKILL.md" ], "keyboardShortcut": "ctrl+shift+p", "welcomeMessage": "Me diga o ID da demanda ou descreva a feature. Eu cuido do resto." } 

Dois pontos importantes aqui:

  • allowedTools é uma allowlist explícita. O agente só consegue chamar exatamente as ferramentas que eu listei. Isso é segurança por design: ele não vai, por engano, chamar uma ferramenta destrutiva que eu nunca autorizei.
  • resources injeta as skills. O agente carrega as instruções detalhadas sob demanda, em vez de carregar tudo o tempo todo.

Camada 2 — O prompt (identidade e contexto fixo)

O prompt define quem o agente é e qual contexto nunca muda. É aqui que eu "ancoro" o agente para ele não ficar perguntando o óbvio toda vez.

Você é um agente especializado em abrir Pull Requests para o repositório da equipe. ## Contexto Fixo - Provedor de git: <configurado via MCP> - Projeto / repositório: <fixos, injetados pela configuração> - Branch de origem padrão: `main` ## Regras de Operação - SEMPRE usar o projeto e repositório fixos — NUNCA perguntar ao usuário - Inferir a branch de destino a partir do contexto da demanda - Seguir as convenções de branch e commit definidas nas skills ## O que NÃO fazer - NÃO perguntar projeto ou repositório — são fixos - NÃO fazer push direto para branches protegidas 

Repare no padrão "Regras" + "O que NÃO fazer". Dizer ao agente o que não fazer é tão importante quanto dizer o que fazer. Isso reduz muito o comportamento imprevisível.

Dica: dados que não devem vazar (IDs internos, GUIDs, URLs) ficam fora do artigo/documentação pública e são injetados via configuração ou MCP. Nunca coloque isso no corpo de uma skill que vai pro repositório aberto.

Camada 3 — Steering (guardrails inegociáveis)

Essa é a camada que me deixa dormir tranquilo. O steering lista proibições absolutas, independentes de qualquer instrução que o agente receba.

# Open PR — Guardrails ## Proibições - NUNCA fazer force push - NUNCA push direto em branches protegidas - NUNCA criar PR sem pelo menos 1 commit na branch - NUNCA prosseguir se o git mostrar conflitos não resolvidos ## Confirmações Obrigatórias - SEMPRE mostrar o resumo (branch, commits, destino, título) antes de abrir o PR - SEMPRE confirmar se houver dúvida sobre a branch de destino ## Comportamento em Falha - Se o push falhar → mostrar o erro e sugerir ação (nunca forçar) - Se a branch de destino não existir → perguntar ao usuário 

A diferença entre prompt e steering é intencional: o prompt é a personalidade (pode ter nuance), o steering é a lei (não tem exceção). Mesmo que o usuário peça "faz um force push aí", o guardrail segura.

Camada 4 — Skills (o conhecimento reutilizável)

As skills são o coração do setup. Cada uma é um documento curto que ensina um procedimento, com formato e exemplos. A skill de commit, por exemplo, define a convenção completa:

# Responsabilidade Criar commits padronizados. ## Formato <type>(<scope>): <emoji> <descrição curta> ## Procedimento 1. Rodar `git status --short` 2. Analisar os caminhos para determinar tipo e escopo 3. Agrupar em commits lógicos 4. Fazer staging seletivo (nunca `git add .`) 5. Commitar com a mensagem formatada ## Exemplos feat(module-a): ✨ add product tag component fix(module-b): 🐛 correct price display refactor(shared): 🔨 simplify item props 

O ponto forte: a mesma skill de commit é usada pelo agente de PR e pelo agente de release. Escrevi uma vez, reaproveitei em todos. Quando a convenção muda, altero um arquivo só.

Meu segundo agente — o de fechar release — é basicamente uma orquestração de skills:

Recebe o ID da demanda → busca os PRs já concluídos → troca para a branch certa → gera o changelog → usa a skill de commit → usa a skill de open-pr para abrir o PR de release → linka o work item 

Ou seja: um agente complexo nasce da composição de skills simples. Isso é muito mais fácil de manter do que um prompt monolítico.

Camada 5 — Integração via MCP

Para o agente conseguir realmente abrir PRs e buscar demandas, ele precisa falar com o provedor de git. Eu faço isso via MCP (Model Context Protocol), que expõe as operações externas como ferramentas que o agente pode chamar.

{ "mcpServers": { "git-provider": { "command": "npx", "args": ["-y", "<pacote-mcp-do-provedor>", "--arg", "valor"], "env": { "PROVIDER_ORG_URL": "<url-da-organizacao>", "PROVIDER_DEFAULT_PROJECT": "<projeto>", "PROVIDER_DEFAULT_REPOSITORY": "<repo>" } } } } 

O MCP é o que conecta o "cérebro" (o agente) às "mãos" (as operações no provedor de git). E, combinado com a allowlist lá do agente, eu controlo exatamente quais dessas operações ficam disponíveis.

Camada 6 — Docs de onboarding

Por último, mantenho um doc curto por agente explicando o que ele é e como invocar. É o que eu passo pra qualquer pessoa nova do time:

# Agente `open-pr` ## Como invocar - Atalho: Ctrl+Shift+P - Ou: "Abre um PR para a demanda 123" / "Commita e abre PR" ## Fluxo Usuário informa demanda → busca contexto → cria branch → commit → push → abre PR → linka work item → retorna o link ## Onde vivem as regras | Assunto | Arquivo | |----------------------|-----------------------------| | Convenção de branch | skills/create-branch | | Convenção de commit | skills/commit | | Regras de PR | skills/open-pr | | Guardrails | steering/open-pr | 

O resultado na prática

Depois que esse setup entrou no fluxo, abrir um PR virou uma frase: "abre um PR pra demanda X". O agente infere a branch, commita no padrão, abre o PR com título e descrição corretos e linka o work item — sempre do mesmo jeito, sem eu precisar lembrar de cada detalhe.

E, olhando o histórico de commits do repositório, dá pra ver a convenção sendo seguida de forma consistente: tipo, escopo, emoji e descrição curta em inglês, commit após commit. Essa consistência é exatamente o que eu queria — e ela não depende mais da minha memória num dia cansado.

O que eu levaria pra qualquer projeto

Se eu fosse resumir o aprendizado em princípios reaproveitáveis:

  1. Separe configuração de conhecimento. O agente diz o que pode; a skill diz como fazer.
  2. Guardrails são uma camada à parte. Proibições não deveriam estar misturadas com instruções normais.
  3. Skills pequenas e reutilizáveis. Um agente complexo é composição de skills simples.
  4. Allowlist de ferramentas sempre. Segurança por design, não por confiança.
  5. Diga o que NÃO fazer. Isso reduz comportamento imprevisível mais do que qualquer instrução positiva.
  6. Mantenha dados sensíveis fora das skills. Injete por configuração/MCP, nunca no texto versionado.

No fim, não automatizei só tarefas — padronizei decisões. E isso, mais do que o tempo economizado, foi o que mudou meu fluxo de trabalho.

Se você também vive repetindo os mesmos passos de Git, vale experimentar esse padrão. Comece com uma skill só, como a de commit, e vá compondo a partir daí.

🇺🇸 English version: How I turned repetitive Git chores into AI agents with the Kiro CLI