Skip to main content

O ciclo do agente

Como a CLI do Copilot processa uma mensagem de usuário de ponta a ponta: do prompt ao session.idle.

Architecture

Diagrama: diagrama de grafo mostrando o processo descrito.

O 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.

O ciclo de uso de ferramentas

Quando você chama session.send({ prompt }), a CLI insere um loop:

Diagrama: Fluxograma mostrando o processo descrito.

O 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.

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.

Turnos – o que são

Uma curva é uma única chamada à API LLM e suas consequências:

  1. A CLI envia o histórico de conversas para o LLM
  2. O LLM responde (possivelmente com solicitações de ferramentas)
  3. Se as ferramentas foram solicitadas, a CLI as executa
  4. assistant.turn_end é emitido

Normalmente, 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:

VirarO que o modelo faztoolRequests?
1Chama grep e glob para pesquisar na base de código
✅ Sim
2Lê arquivos específicos com base nos resultados da pesquisa
✅ Sim
3Lê mais arquivos para um contexto mais profundo
✅ Sim
4Produz a resposta de texto final
❌ Não → o loop termina

O 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.

Fluxo de eventos para uma interação de vários turnos

Diagrama: Fluxograma mostrando o processo descrito.

Quem dispara cada turno?

AtorResponsabilidade
Seu aplicativoEnvia o prompt inicial por meio de session.send()
Copilot CLIExecuta o ciclo de uso de ferramentas — executa as ferramentas e retorna os resultados à LLM para a próxima interação
LLMDecide se deve solicitar ferramentas (continuar o loop) ou produzir uma resposta final (interromper)
SDKPassa eventos por meio; não controla o loop

A CLI é puramente mecânica: "o modelo solicitou ferramentas → executá-las → chamar o modelo novamente." O modelo é o tomador de decisão para quando parar.

session.idle versus session.task_complete

Estes são dois sinais de conclusão diferentes com garantias muito diferentes:

session.idle

  • Sempre emitido quando o loop de uso da ferramenta termina
  • Efêmero: não persistido em disco, não reexecutado na retomada da sessão
  • Significa: "o agente parou de processar e está pronto para a próxima mensagem"
  • Use isso como seu sinal confiável de "concluído"

O método do sendAndWait() SDK aguarda este evento:

// Blocks until session.idle fires
const response = await session.sendAndWait({ prompt: "Fix the bug" });

session.task_complete

  • Emitido opcionalmente: requer que o modelo o indique explicitamente
  • Persistido: salvo no log de eventos da sessão em disco
  • Significa: "o agente considera a tarefa geral atendida"
  • Carrega um campo opcional summary
session.on("session.task_complete", (event) => {
    console.log("Task done:", event.data.summary);
});

Modo de piloto automático: os empurrãoes da CLI para task_complete

No 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:

"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."

Isso reinicia efetivamente o loop de uso de ferramentas– o modelo vê o empurrão como uma nova mensagem de usuário e continua funcionando. O empurrão também instrui o modelo a não chamar task_complete prematuramente:

  • Não chame se você tiver perguntas abertas, tome decisões e continue trabalhando
  • Não a chame se encontrar um erro — tente resolvê-lo
  • Não chame se houver etapas restantes – conclua-as primeiro

Isso cria um mecanismo de conclusão de dois níveis no piloto automático:

  1. O modelo chama task_complete com um resumo → CLI emite session.task_complete → concluído
  2. O modelo interrompe sem fazer a chamada → a CLI dá um aviso → o modelo continua ou chama task_complete

Por que task_complete talvez não apareça

No modo interativo (chat normal), a CLI não solicita task_complete. O modelo pode ignorá-lo completamente. Motivos comuns:

  • Q&A de conversa: o modelo responde a uma pergunta e simplesmente para — não há nenhuma "tarefa" discreta para concluir
  • Critério do modelo: o modelo produz uma resposta de texto final sem chamar o sinal de conclusão da tarefa
  • Sessões interrompidas: a sessão termina antes que o modelo atinja um ponto de conclusão

A CLI emite session.idle independentemente, porque é um sinal mecânico (o loop terminou), não um semântico (o modelo acha que foi feito).

Qual você deve usar?

Caso de usoSinal
"Aguarde até que o agente conclua o processamento"
session.idle
"Saiba quando uma tarefa de codificação é concluída"
session.task_complete (melhor esforço)
"Tempo limite/tratamento de erros"
session.idle

session.error ✅ |

Contagem de chamadas LLM

O 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.

Para inspecionar a contagem de turnos de uma sessão:

# Count turns in a session's event log
grep -c "assistant.turn_start" ~/.copilot/session-state/<sessionId>/events.jsonl

Leitura adicional