{"meta":{"title":"O ciclo do agente","intro":"Como a CLI do Copilot processa uma mensagem de usuário de ponta a ponta: do prompt ao session.idle.","product":"GitHub Copilot","breadcrumbs":[{"href":"/pt/copilot","title":"GitHub Copilot"},{"href":"/pt/copilot/how-tos","title":"Instruções"},{"href":"/pt/copilot/how-tos/copilot-sdk","title":"SDK do Copilot"},{"href":"/pt/copilot/how-tos/copilot-sdk/features","title":"Features"},{"href":"/pt/copilot/how-tos/copilot-sdk/features/agent-loop","title":"Loop de agente"}],"documentType":"article"},"body":"# O ciclo do agente\n\nComo a CLI do Copilot processa uma mensagem de usuário de ponta a ponta: do prompt ao session.idle.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n## Architecture\n\n![Diagrama: diagrama de grafo mostrando o processo descrito.](/assets/images/help/copilot/copilot-sdk/features-agent-loop-diagram-0.png)\n\nO **SDK** é uma camada de transporte — ele envia seu prompt para o **Copilot CLI** via JSON-RPC e retorna os eventos para o seu aplicativo. A **CLI** é o orquestrador que executa o ciclo de uso de ferramentas pelo agente, realizando uma ou mais chamadas à API de LLM até que a tarefa seja concluída.\n\n## O ciclo de uso de ferramentas\n\nQuando você chama `session.send({ prompt })`, a CLI insere um loop:\n\n![Diagrama: Fluxograma mostrando o processo descrito.](/assets/images/help/copilot/copilot-sdk/features-agent-loop-diagram-1.png)\n\nO modelo vê o **histórico completo da conversa** em cada chamada — prompt do sistema, mensagem do usuário e todas as chamadas e resultados de ferramentas anteriores.\n\n**Insight principal:** Cada iteração desse loop é exatamente uma chamada à API de LLM, visível no log de eventos como um par `assistant.turn_start` / `assistant.turn_end`. Não há chamadas ocultas.\n\n## Turnos – o que são\n\nUm **turno** é uma única chamada à API LLM e suas consequências:\n\n1. A CLI envia o histórico de conversas para o LLM\n2. O LLM responde (possivelmente com solicitações de ferramentas)\n3. Se as ferramentas foram solicitadas, a CLI as executa\n4. `assistant.turn_end` é emitido\n\nNormalmente, uma única mensagem de usuário resulta em **várias voltas**. Por exemplo, uma pergunta como \"como o X funciona nessa base de código?\" pode produzir:\n\n| Volta                  | O que o modelo faz                                          | toolRequests? |\n| ---------------------- | ----------------------------------------------------------- | ------------- |\n| 1                      | Chama `grep` e `glob` para pesquisar na base de código      |               |\n| ✅ Sim                  |                                                             |               |\n| 2                      | Lê arquivos específicos com base nos resultados da pesquisa |               |\n| ✅ Sim                  |                                                             |               |\n| 3                      | Lê mais arquivos para um contexto mais profundo             |               |\n| ✅ Sim                  |                                                             |               |\n| 4                      | Produz a resposta de texto final                            |               |\n| ❌ Não → o loop termina |                                                             |               |\n\nO modelo decide em cada turno se deseja solicitar mais ferramentas ou produzir uma resposta final. Cada chamada vê o **contexto acumulado completo** (todas as chamadas e resultados de ferramentas anteriores), para que possa tomar uma decisão informada sobre se ela tem informações suficientes.\n\n## Fluxo de eventos para uma interação de vários turnos\n\n![Diagrama: Fluxograma mostrando o processo descrito.](/assets/images/help/copilot/copilot-sdk/features-agent-loop-diagram-2.png)\n\n## Quem dispara cada turno?\n\n| Ator               | Responsabilidade                                                                                                 |\n| ------------------ | ---------------------------------------------------------------------------------------------------------------- |\n| **Seu aplicativo** | Envia o prompt inicial por meio de `session.send()`                                                              |\n| **Copilot CLI**    | Executa o ciclo de uso de ferramentas — executa as ferramentas e exibe os resultados ao LLM para o próximo turno |\n| **LLM**            | Decide se deve solicitar ferramentas (continuar o loop) ou produzir uma resposta final (interromper)             |\n| **SDK**            | Transmite eventos; não controla o loop                                                                           |\n\nA CLI é puramente mecânica: \"o modelo solicitou ferramentas → executá-las → chamar o modelo novamente.\" O **modelo** é o tomador de decisão para quando parar.\n\n## `session.idle` versus `session.task_complete`\n\nEstes são dois sinais de conclusão diferentes com garantias muito diferentes:\n\n### `session.idle`\n\n* **Sempre emitido** quando o loop de uso da ferramenta termina\n* **Efêmero**: não persistido em disco, não reexecutado na retomada da sessão\n* Significa: \"o agente parou de processar e está pronto para a próxima mensagem\"\n* **Use isso** como seu sinal confiável de \"concluído\"\n\nO método do `sendAndWait()` SDK aguarda este evento:\n\n```typescript\n// Blocks until session.idle fires\nconst response = await session.sendAndWait({ prompt: \"Fix the bug\" });\n```\n\n### `session.task_complete`\n\n* **Emitido opcionalmente**: requer que o modelo o indique explicitamente\n* **Persistido**: salvo no log de eventos da sessão em disco\n* Significa: \"o agente considera a tarefa geral atendida\"\n* Carrega um campo opcional `summary`\n\n```typescript\nsession.on(\"session.task_complete\", (event) => {\n    console.log(\"Task done:\", event.data.summary);\n});\n```\n\n### Modo Autopilot: as sugestões da CLI para `task_complete`\n\nNo **modo de piloto automático** (operação sem cabeça/autônoma), a CLI controla ativamente se o modelo chamou `task_complete`. Se o loop de uso da ferramenta terminar sem isso, a CLI injetará uma mensagem sintética de usuário para orientar o modelo:\n\n> *\"Você ainda não marcou a tarefa como concluída usando a ferramenta task\\_complete. Se você estava planejando, interrompa o planejamento e comece a implementar. Você não terminará até concluir totalmente a tarefa.\"*\n\nIsso reinicia efetivamente o loop de uso de ferramentas– o modelo vê o empurrão como uma nova mensagem de usuário e continua funcionando. A sugestão também instrui o modelo a **não** chamar `task_complete` prematuramente:\n\n* Não chame se você tiver perguntas abertas, tome decisões e continue trabalhando\n* Não a chame se encontrar um erro — tente resolvê-lo\n* Não chame se houver etapas restantes – conclua-as primeiro\n\nIsso cria um **mecanismo de conclusão de dois níveis** no piloto automático:\n\n1. O modelo chama `task_complete` com um resumo → CLI emite `session.task_complete` → concluído\n2. O modelo interrompe sem fazer a chamada → a CLI dá um aviso → o modelo continua ou chama `task_complete`\n\n### Por que `task_complete` talvez não apareça\n\nNo **modo interativo** (chat normal), a CLI não solicita `task_complete`. O modelo pode ignorá-lo completamente. Motivos comuns:\n\n* **Q\\&A de conversa**: o modelo responde a uma pergunta e simplesmente para — não há nenhuma \"tarefa\" discreta para concluir\n* **Critério do modelo**: o modelo produz uma resposta de texto final sem chamar o sinal de conclusão da tarefa\n* **Sessões interrompidas**: a sessão termina antes que o modelo atinja um ponto de conclusão\n\nA CLI emite `session.idle` independentemente, porque é um sinal mecânico (o loop terminou), não um semântico (o modelo acha que foi feito).\n\n### Qual você deve usar?\n\n| Caso de uso                                          | Sinal |\n| ---------------------------------------------------- | ----- |\n| \"Aguarde até que o agente conclua o processamento\"   |       |\n| `session.idle`                                       |       |\n| ✅                                                    |       |\n|                                                      |       |\n| \"Saiba quando uma tarefa de codificação é concluída\" |       |\n| `session.task_complete` (melhor esforço)             |       |\n| \"Tempo limite/tratamento de erros\"                   |       |\n| `session.idle`                                       |       |\n\n*\n\n`session.error`\n✅\n|\n\n## Contagem de chamadas ao LLM\n\nO número de pares `assistant.turn_start` / `assistant.turn_end` no log de eventos é igual ao número total de chamadas feitas à API LLM. Não há chamadas ocultas para planejamento, avaliação ou verificação de conclusão.\n\nPara inspecionar a contagem de turnos de uma sessão:\n\n```bash\n# Count turns in a session's event log\ngrep -c \"assistant.turn_start\" ~/.copilot/session-state/<sessionId>/events.jsonl\n```\n\n## Leitura adicional\n\n* [Eventos de sessão de streaming](/pt/copilot/how-tos/copilot-sdk/features/streaming-events): Referência completa no nível de campo para cada tipo de evento\n* [Retomada e persistência da sessão](/pt/copilot/how-tos/copilot-sdk/features/session-persistence): Como as sessões são salvas e retomadas\n* [Trabalhando com ganchos](/pt/copilot/how-tos/copilot-sdk/features/hooks): interceptar eventos no loop (permissões, ferramentas)"}