Por Dentro de uma CLI de Coding Agent: Loops, Contexto, Permissões
O que faz uma CLI de coding agent funcionar de verdade? Loops de tool calls, gestão de contexto, permissões e design cliente/servidor.

O modelo é a parte fácil. Pelo menos essa é a tese, e depois de acompanhar uma dúzia de CLIs de coding agents surgirem, bifurcarem e tropeçarem nos últimos anos, acho que ela se sustenta: uma CLI de coding agent tem sucesso ou fracasso pelo seu harness, não pelo seu modelo. O lançamento do OpenCode 2.0 — um agente de programação open-source, baseado em terminal, que ganhou tração séria esta semana — é um bom motivo para dizer isso em voz alta. As coisas interessantes desse lançamento não são novas integrações de modelos. São uma separação cliente/servidor, plugins com hot-reload, tarefas que rodam em segundo plano e um loop de agente re-arquitetado. Encanamento, em outras palavras. O encanamento é o produto.
Sou ex-engenheiro de ML, então essa conclusão me incomodou. Eu queria que a qualidade do modelo fosse o diferencial. Mas, quando olho para o motivo de continuar ou abandonar essas ferramentas, a resposta nunca é "o modelo ficou mais inteligente". É "a ferramenta parou de me pedir para aprovar cada comando", ou "finalmente recarrega a configuração sem reiniciar", ou "consigo conectar uma interface gráfica a uma sessão rodando numa máquina remota". Vamos desmontar os três subsistemas que de fato determinam se um coding agent é útil: o loop de tool calls, a gestão de contexto e o modelo de permissões. Depois, vou admitir onde a tese contrária falha.
O Loop de Tool Calls é um Sistema Distribuído
Tirando o marketing, todo coding agent é o mesmo programa: chamar o modelo com um prompt e uma lista de ferramentas, receber texto ou uma tool call, executar a ferramenta, anexar o resultado e repetir. Esse loop parece trivial. Não é, e as ferramentas que o tratam como trivial parecem capengas em cinco minutos de uso real.
Pense no que o loop realmente precisa lidar. Execuções de ferramentas falham: o compilador dá erro, a suíte de testes trava, o arquivo não existe naquele caminho porque o modelo alucinou. O modelo emite JSON malformado nos argumentos da ferramenta. Uma tool call leva quarenta segundos e o usuário aperta Escape no meio da execução. Duas tool calls chegam no mesmo turno e uma delas não pode rodar se a outra falhar. A janela de contexto enche no meio da tarefa e alguma coisa precisa ceder. Cada um desses casos é um problema de concorrência e falhas, não de inteligência. Já defendi antes que agentes LLM são apenas sistemas distribuídos, e a CLI de coding é o exemplo mais puro disso: você tem um componente remoto não confiável e não determinístico (o modelo) coordenando com componentes locais com efeitos colaterais (shell, sistema de arquivos, LSP), e o loop é o protocolo de consenso entre eles.
Por isso importa que o OpenCode 2.0 tenha, segundo relatos, reconstruído seu loop em torno do Effect, um framework TypeScript para concorrência estruturada e erros tipados. Essa escolha indica que a equipe deixou de pensar no loop como "um while com fetch dentro" e passou a tratá-lo pelo que ele é: um sistema de efeitos interrompíveis, componíveis e reexecutáveis, com canais de erro explícitos. Quando seu loop de agente tem semântica de cancelamento real, "o usuário aperta Escape" vira um evento de primeira classe em vez de estado corrompido. Quando os resultados das ferramentas são tipados, você pode validar a saída do modelo antes de executá-la, o que combina bem com técnicas como decodificação restrita, em que você limita o espaço de saída do modelo para que tool calls malformadas se tornem impossíveis em vez de apenas detectadas.
Cliente/Servidor é o Recurso que Ninguém Vende
Uma das decisões de design mais consequentes de uma CLI de coding é se o agente é um processo ou um serviço. O design ingênuo — um processo, um terminal, a sessão morre quando o terminal morre — é como a maioria dessas ferramentas começou, e é um teto. O modelo cliente/servidor do OpenCode (em que um servidor de longa duração é dono das sessões e qualquer número de clientes — TUI, aplicativo desktop, interface web — se conecta a ele) remove esse teto. Na prática, isso significa: sua sessão sobrevive ao fechamento do terminal, você pode rodar o agente numa máquina de desenvolvimento remota e controlá-lo a partir de um app nativo no seu notebook, e várias interfaces podem observar a mesma sessão.
Se você já tentou rodar um agente numa VM via SSH e perdeu a sessão em uma reconexão, sabe que isso não é um detalhe. É a diferença entre um brinquedo e infraestrutura. Agentes de longa duração pertencem à mesma categoria de builds e suítes de teste: coisas que você inicia, deixa rodando e verifica depois. As tarefas em segundo plano do OpenCode 2.0 vão na mesma direção: o agente deixa de ser uma conversa síncrona e se torna um executor de jobs com interface de chat.
Agora, a ressalva, porque sustento essa opinião de forma consistente: arquitetura de servidor não significa daemon permanente. Vários comentaristas notaram com desconfiança que todo harness de agente de repente quer um processo de background persistente na máquina. Essa desconfiança está correta. Já escrevi que ferramentas de linha de comando não deveriam instalar daemons em segundo plano por padrão, e mantenho isso. Existe um meio-termo limpo: iniciar o servidor sob demanda, restrito ao diretório do projeto, e encerrá-lo quando o último cliente desconectar. Você ganha persistência de sessão e múltiplos clientes conectados sem um processo sempre ativo na sua máquina. O fato de o OpenCode carregar a configuração a partir da pasta da sessão, e não do diretório de trabalho do servidor — outra mudança da 2.0 —, sugere que a equipe entende que o servidor deve seguir o projeto, e não o contrário.
A Gestão de Contexto é Onde Mora a Qualidade
Pergunte a qualquer praticante por que um agente "ficou burro" depois de uma hora de trabalho, e a resposta quase nunca é regressão do modelo. É apodrecimento de contexto. A janela se encheu de saídas antigas de ferramentas, becos sem saída e o texto completo de arquivos que eram relevantes quarenta turnos atrás. O modelo agora toma decisões sobre um palheiro, e a capacidade de encontrar a agulha degrada muito antes de você chegar ao limite nominal de tokens.
Um bom harness trata o contexto como um orçamento com política de alocação, e não como um cano. Concretamente, isso significa várias coisas funcionando juntas:
- Truncamento de saída de ferramentas com saídas de escape para recuperação. Um log de testes de 5.000 linhas deve entrar no contexto como as quarenta linhas que falharam, mais uma nota dizendo que o log completo está em um caminho que o modelo pode reler. O harness decide o que é relevante; o modelo decide quando precisa de mais.
- Sub-sessões e sub-agentes. "Vá explorar como a autenticação funciona neste repositório e volte com um resumo" deve rodar em um contexto isolado que devolve um digest, e não a transcrição inteira da exploração. A melhoria na comunicação entre sub-sessões do OpenCode 2.0 é exatamente essa ideia.
- Compactação que preserva a intenção. Quando a janela enche, algo precisa resumir a conversa até ali. Um harness que resume de forma ingênua perde as restrições do usuário ("não mexa no módulo de cobrança") junto com o ruído. Uma boa compactação mantém decisões e restrições literalmente e comprime apenas a narrativa.
- Configuração e skills como contexto, não como código. Instruções em nível de projeto, ferramentas definidas por plugins e arquivos de skills consomem janela. O hot-reload deles — outra correção da 2.0 — importa porque editar o contexto do seu agente sem reiniciar a sessão é como você itera sobre o próprio comportamento do agente.
Nada disso é inteligência do modelo. Tudo isso determina o quanto o modelo parece inteligente. Um modelo de fronteira com uma política de contexto desleixada vai perder para um modelo mais barato atrás de uma política disciplinada em qualquer tarefa que dure mais de vinte minutos.

Modelos de Permissão: a Funcionalidade Chata que Decide a Adoção
Aqui vai uma pergunta da discussão no HN que considero a questão de produto mais importante deste espaço: existe algo entre "aprovar cada comando" e "modo yolo"? A aprovação automática total é genuinamente perigosa — um coding agent com acesso ao shell pode executar rm -rf, git push --force e exfiltrar suas variáveis de ambiente em um único turno. A aprovação manual total é genuinamente inutilizável — aprovar oitenta comandos por hora significa que você não está supervisionando o agente, está sendo um teclado humano lento de interrupção. A ferramenta que acerta o meio-termo conquista os pragmáticos.
O meio-termo é um modelo de permissões graduado, e seu espaço de design é mais bem compreendido do que as pessoas imaginam:
- Somente leitura vs. escrita vs. execução. Leituras são quase gratuitas; escritas devem ficar restritas à árvore do projeto; a execução é onde a política mais importa.
- Listas de permissão sensíveis a argumentos.
git statusé aprovado automaticamente;git pushpede confirmação. Ferramentas ingênuas comparam apenas o nome do binário; boas ferramentas comparam verbo e flags, porquenpm testenpm publishsão o mesmo binário com raios de impacto totalmente diferentes. - Concessões com escopo de sessão. "Sempre permitir este comando nesta sessão" é o recurso de permissão de maior valor que existe. Ele transforma setenta pedidos em um só.
- Contenção para o irreversível. Acesso à rede, qualquer coisa fora do diretório do projeto e qualquer coisa que toque em credenciais devem ser restringidos estruturalmente, e não apenas gerar um pedido de confirmação.
Esse último item é a parte em que a maioria dos harnesses investe pouco, porque pedir confirmação é fácil e conter é difícil. Mas um prompt é uma pergunta que o modelo espera que você responda corretamente às 18h de uma sexta-feira. Isolar a árvore de processos do agente — rede restrita, montagens de arquivos com escopo — torna classes inteiras de falhas impossíveis, independentemente do que o modelo ou o usuário façam. Detalhei esse trade-off em contenção versus monitoramento para agentes de IA; a versão curta é que prompts são monitoramento, sandboxing é contenção, e você quer contenção para qualquer coisa irreversível. O ecossistema de CLIs está aprendendo isso devagar. As que aprenderem mais rápido vão conquistar a confiança que permite aos usuários ativar a aprovação automática para os 90% tediosos.
Extensibilidade e o Problema do Modelo Self-Hosted
Duas lições menores da discussão sobre a 2.0 merecem atenção. Primeira: "tudo é plugin" está vencendo. Usuários estão criando skills, editores de configuração e hooks de fluxo de trabalho sobre esses harnesses, e o harness que torna plugins de primeira classe — com hot-reload, capazes de observar sessões e de modificar comportamento — multiplica o esforço da comunidade em vez de brigar com ele. O sinal de que o OpenCode leva isso a sério é que o app do GitHub deles faz a triagem de relatórios de bugs reproduzindo o problema e comentando os achados, basicamente usando o agente para manter o próprio agente. Essa é a "autoconsciência" que os usuários elogiaram, e é um resultado da arquitetura de plugins, não do modelo.
Segunda: a independência de modelo é mais difícil do que parece, e é um problema de formato de contexto. Um usuário tentou um modelo local excelente, treinado para emitir comandos em bash, enquanto o harness insistia em tool calls no estilo JavaScript, e os dois simplesmente não conseguiam se entender. Esse é o acoplamento escondido em todo harness de agente: o formato das tool calls, as suposições do system prompt e a distribuição de treinamento do modelo precisam estar alinhados. Um harness que fixa as convenções de uma família de modelos não é agnóstico de modelo, na melhor das hipóteses é tolerante a modelos. Se modelos locais forem importar para coding agents — e por razões de custo e privacidade deveriam —, os harnesses precisam de dialetos de tool calls plugáveis, e não apenas endpoints de API plugáveis.
Onde a Tese Contrária Falha
Eu disse que o modelo é a parte fácil. Chegou a hora de admitir as bordas. A tese vale para o design do harness — loops, contexto, permissões —, mas há lugares em que o modelo é genuinamente o gargalo. A confiabilidade no uso de ferramentas é treinada dentro dos modelos; um modelo que não consegue emitir chamadas de função válidas faz qualquer harness parecer quebrado, e nenhuma quantidade de concorrência estruturada baseada em Effect conserta um modelo que briga com o próprio schema. O planejamento de múltiplas etapas em horizontes longos ainda separa as faixas de modelos de formas que você sente dentro de uma única sessão. E o enquadramento harness-versus-modelo tem prazo de validade: à medida que os modelos absorvem comportamento agêntico no treinamento (uso nativo de ferramentas, planejamento nativo de longo prazo), capacidades migram do harness para os pesos, e o recurso engenhoso de hoje vira esforço desperdiçado amanhã. Equipes que constroem harnesses devem presumir que estão construindo andaimes que os modelos vão eventualmente tornar obsoletos — o que, honestamente, é um argumento a favor de harnesses open-source com ecossistemas de plugins, porque eles sobrevivem pela comunidade, e não por uma lacuna temporária de capacidade.
Há também um piso de UX que nenhuma arquitetura justifica. Alguns usuários testaram o OpenCode 2.0 e ainda o acharam desajeitado; outros reclamaram de inicialização lenta e de um banco de dados de histórico de chat morto que só cresce. Não são problemas profundos, mas são os que fazem as pessoas desistirem da ferramenta nos primeiros dez minutos, antes que o elegante loop do agente tenha chance de brilhar. Polimento também é funcionalidade, e é justamente o que projetos open-source mais costumam deixar sem verba.
O modelo escreve o código, mas o harness decide se você confia nele o bastante para deixá-lo agir.
Então, meu conselho pragmático, de quem acompanhou essa categoria girar: escolha seu coding agent como escolheria um banco de dados, e não pelo vencedor do benchmark de modelos. Olhe o tratamento de falhas do loop, a política de contexto, a granularidade das permissões e se as sessões sobrevivem ao fechamento do terminal. São essas as partes que continuarão importando depois que o próximo lançamento de modelo deixar todo mundo igualmente inteligente.


