Eu construí meu próprio harness de IA num fim de semana (e foi assim que entendi por que não vale a pena)
Olá pessoALL, semana passada, numa reunião técnica com um cliente, um dev do time fez a pergunta que eu já tinha ouvido em três conversas diferentes no último mês. Se você trabalha com IA em time de engenharia, aposto que já ouviu também. Mas dessa vez ela veio com um argumento novo, e bem construído:
"Rafael, agora que o Copilot cobra AI Credits em cima da tarifa de API dos modelos, me explica uma coisa: por que eu pago Copilot em vez de chamar a API direto? É o mesmo modelo. É o mesmo preço de token. Eu escrevo meu loop de agente em C# num fim de semana."
E aqui vai a primeira confissão do post: eu não soube responder na hora. Falei alguma coisa genérica sobre integração e governança, daquelas que soam bem numa call e não convencem ninguém de verdade. Saí da reunião incomodado.
Então fui fazer o que ele disse. Passei o fim de semana construindo meu próprio harness. E foi a melhor forma que encontrei de responder a pergunta dele. Só que a resposta não é a que eu esperava quando abri o Visual Studio no sábado de manhã.
A conta que parece fechar
Vamos ser justos com o argumento antes de derrubar qualquer coisa. Porque ele é bom.
Desde 1º de junho, quando o GitHub virou a chave do billing por uso e enterrou as PRUs, o consumo do Copilot é calculado em cima de input, output e cached tokens, na tarifa oficial de API de cada modelo. Ou seja, aquele véu que existia antes ("quanto custa um premium request, afinal?") sumiu. Agora dá pra comparar diretamente.
E quando você compara direto, a primeira camada é essa:
| API direta do fornecedor | GitHub Copilot | |
|---|---|---|
| Preço por token | Tarifa oficial do modelo | Tarifa oficial do modelo |
Empate. Literalmente empate.
Se o token custa o mesmo, o argumento do dev se sustenta sozinho: por que pagar um intermediário? Você chama o endpoint, monta seu contexto, executa suas ferramentas, e fica com o controle total. Sem seat, sem plano, sem nada no meio.
A conta parece fechar. Mas ela só parece fechar porque está faltando linha na planilha. E eu só descobri quais linhas faltavam depois de tentar preenchê-las na mão.
Então eu fui construir o meu
Antes de contar como foi, preciso definir o termo que dá título ao post, porque ele ainda não caiu na boca do povo por aqui.
Harness, no contexto de IA, é toda a camada de software que fica entre você e o modelo. É quem decide quais arquivos entram no contexto, como as ferramentas são descritas pro modelo, o que fazer quando uma tool call vem malformada, quando comprimir o histórico da conversa, quando parar de iterar, quando pedir permissão pra rodar um comando destrutivo. O modelo é o cérebro. O harness é tudo que traduz "resolve esse bug" numa sequência de leituras, edições, execuções de teste e correções.
Guarda essa frase, porque ela vai voltar: o modelo pensa, mas o harness decide o que ele vê.
Meu experimento de sábado foi exatamente isso, na versão mais ingênua possível. Um loop em C# com function calling, três ferramentas (read_file, write_file, run_command) e um system prompt razoável. O esqueleto era mais ou menos assim:
var messages = new List<ChatMessage> { new SystemMessage(SYSTEM_PROMPT), new UserMessage(task) };
while (true)
{
var response = await client.CompleteAsync(messages, tools);
messages.Add(response);
if (response.ToolCalls.Count == 0) break;
foreach (var call in response.ToolCalls)
messages.Add(await ExecuteToolAsync(call));
}
Umas 200 linhas no total, contando as implementações das ferramentas. Rodei numa API .NET pequena, pedi pra corrigir um bug de validação, e ele corrigiu. Rodou o teste, o teste passou, ele parou.
Funcionou! Sério, funcionou. E eu fiquei genuinamente empolgado por uns quarenta minutos.
Mas funcionou uma vez, num repositório de 30 arquivos que eu conhecia de cor, numa tarefa que eu mesmo tinha escolhido. Basta trocar qualquer uma dessas três variáveis pra casa começar a cair.
Os problemas que aparecem depois da demo
Aqui é onde o fim de semana virou aula. Vou listar na ordem em que os problemas apareceram, porque a ordem importa: cada um só fica visível depois que você resolve o anterior.
O primeiro foi contexto. No repo de 30 arquivos, eu mandava a árvore inteira no prompt. Apontei o mesmo agente pra um repositório real de cliente, com 2.400 arquivos, e estourei a janela de contexto na primeira mensagem. Aí você precisa decidir: manda só a estrutura de pastas? Faz busca semântica? Deixa o modelo pedir arquivo por arquivo, queimando tokens em ida e volta? Cada escolha muda o custo e a taxa de acerto, e não existe resposta óbvia.
O segundo foram tool calls quebradas. O modelo às vezes devolve JSON com um caractere a mais, chama uma ferramenta que não existe, ou passa um caminho relativo quando você esperava absoluto. Meu loop simplesmente explodia. Tratar isso significa retry com feedback estruturado — e retry custa tokens.
O terceiro foi loop infinito. Duas vezes o agente ficou lendo e relendo os mesmos três arquivos, convencido de que ia entender melhor na quarta passada. Eu não tinha nenhum mecanismo de detecção. Só percebi olhando a fatura.
O quarto foi compactação de histórico. Numa tarefa longa, o histórico cresce e o custo por iteração cresce junto, porque você reenvia tudo. Compactar sem perder a informação que importa é um problema de engenharia sério, e a decisão de quando compactar é tão importante quanto o como.
O quinto foi permissão. No meu protótipo, run_command executava qualquer coisa. Na minha máquina, com o repo versionado, tudo bem. Em qualquer ambiente compartilhado, isso é irresponsável. E não adianta terceirizar pro modelo a decisão de "esse comando é perigoso?" — quem decide precisa ser o seu código.
O sexto doeu. Eu tinha calibrado tudo com um modelo da família GPT, troquei pra um Claude pra comparar, e a taxa de sucesso despencou. Não porque o Claude seja pior. É porque o formato das descrições de ferramenta, o estilo do system prompt e a forma de sinalizar "termine agora" respondem diferente em cada família de modelo. Eu não tinha construído um harness. Eu tinha construído um harness pra um modelo específico.
Lição aprendida: cada modelo novo que sai reabre todo esse trabalho. E hoje sai modelo novo a cada semana.
O dado que virou minha cabeça
Chegando no domingo à noite, eu tinha uma versão bem melhor. Tinha resolvido retry, tinha um limite de iterações, tinha um seletor de contexto menos burro. Rodei o benchmark improvisado que eu mesmo tinha montado (umas 12 tarefas em repositórios diferentes) e a taxa de acerto subiu de 7 para 9. Ótimo, né? Melhorei o agente em 17%.
Aparentemente. MAS (aqui entra um GRANDE MAS): eu tinha rodado uma vez.
Foi aí que eu esbarrei no estudo que o GitHub publicou em junho comparando o harness agêntico do Copilot com os harnesses dos próprios fornecedores de modelo. E o que me pegou não foi o resultado. Foi a metodologia.
Eles compararam o GitHub Copilot CLI contra o Claude Code (com Sonnet 4.6 e Opus 4.7) e contra o Codex CLI (com GPT-5.4 e GPT-5.5). Mesmo modelo dos dois lados. Mesma tarefa. Janela de contexto normalizada, mesmo reasoning effort, mesma seleção de ferramentas, mesmos MCP servers. Timeout de duas horas por execução. Cinco benchmarks: SWE-bench Verified (500 tarefas de bugfix validadas por humanos), SWE-bench Pro, SkillsBench, TerminalBench 2.0 e Win-Hill, esse último interno, rodando dentro de containers Windows.
E no TerminalBench 2.0, com 89 tarefas, eles rodaram cada combinação de agente e modelo no mínimo cinco vezes. Não pra ter média bonita. Pra medir a variância entre execuções.
Você entendeu onde eu quero chegar? Modelos são estocásticos. A mesma tarefa, com o mesmo prompt, no mesmo modelo, dá resultados diferentes em execuções diferentes. O gráfico deles mostra isso com elipses de ±1σ em volta de cada configuração, e as elipses são grandes.
Ou seja: minha "melhoria de 17%", medida em 12 tarefas com uma execução, provavelmente era ruído. Eu passei o domingo comemorando variância.
Não dá pra melhorar o que você não consegue medir. E medir harness de IA direito exige um volume de execução que, sinceramente, não cabe no orçamento de quase ninguém. Vou botar número nisso mais pra frente.
Antes disso, o resultado em si, e vou dar o dado honesto inclusive onde ele não favorece o Copilot: nos benchmarks, o harness do Copilot entregou taxa de resolução de tarefa em paridade com os harnesses dos fornecedores, consumindo menos tokens na maioria das configurações. Na maioria, não em todas. No SWE-bench Verified com GPT-5.4 e GPT-5.5, o Copilot CLI ficou 7% e 4% pior em eficiência de token, respectivamente. As diferenças de resolução, nos dois sentidos, ficam dentro da variância entre execuções.
Isso não é "o Copilot ganha de todo mundo". É uma afirmação bem mais modesta e bem mais útil: o mesmo modelo entrega resultado equivalente gastando menos token, e isso foi medido com rigor suficiente pra eu acreditar.
Comparando maçãs com maçãs: a conta real
Agora que sabemos quais linhas faltavam, dá pra montar a planilha inteira. Vou usar valores do mercado brasileiro e deixar claro o que é estimativa minha.
Camada 1, preço do token. Empate, como já vimos.
Camada 2, tokens consumidos por tarefa. Aqui a conta muda de dono. Se o harness resolve a mesma tarefa gastando menos token, a eficiência dele é desconto direto na sua fatura. E o meu harness caseiro, que reenviava histórico inteiro sem compactar e não tinha nenhuma estratégia de roteamento, gastava muito mais que isso. Não meço em percentual porque minha amostra é ruído, e eu acabei de dizer que isso não vale. Mas a direção é inequívoca.
Camada 3, custo de construir. Meu protótipo levou umas 14 horas entre sábado e domingo. Hora de dev sênior no Brasil não sai por menos de R$ 120 a R$ 180, então são uns R$ 2.000 pra chegar num agente que funciona numa demo controlada. Pra chegar em algo que roda em produção (com permissão, compactação, tratamento de erro decente, telemetria) some pelo menos mais um mês de trabalho. Chame de R$ 25.000, sendo otimista.
Camada 4, custo de manter. Modelo novo a cada semana. Cada um exige recalibrar prompt, formato de ferramenta e critério de parada. Isso não é projeto, é rotina. E rotina tem dono, e dono tem salário.
Camada 5, custo de avaliar. Essa é a linha que ninguém coloca no orçamento, e é a mais cara. Faz a conta comigo usando só o TerminalBench 2.0, que é o benchmark pequeno da lista: 89 tarefas, cinco execuções por configuração, quatro modelos, dois harnesses comparados. Dá 3.560 execuções de agente. A um custo conservador de US$ 1 por tarefa, são US$ 3.560 em tokens antes de você olhar pros outros quatro benchmarks, e o SWE-bench Verified sozinho tem 500 tarefas. Toda vez que mexer numa linha do seu seletor de contexto.
Você vai fazer isso? Eu não vou, e nenhum cliente meu vai.
Camada 6, governança e faturamento. Com API direta, cada dev tem uma chave. As chaves vão parar em .env, em script de CI, em variável de ambiente de máquina local. Você perde visibilidade de custo, perde controle de qual modelo está sendo usado, e ganha um problema de segurança. Chave de API é credencial de longa duração, e chave vazada em repositório é das formas mais comuns de incidente que eu vejo. Com Copilot em plano de organização, os AI Credits são pooled, o admin define budget e acompanha consumo no dashboard de billing, e a política de quais modelos ficam habilitados é decisão do enterprise, não de cada dev.
Juntando tudo:
| Fator | API direta (harness próprio) | GitHub Copilot |
|---|---|---|
| Preço do token | Tarifa oficial | Tarifa oficial |
| Tokens por tarefa | O que o seu código conseguir | Paridade de resolução com menos token na maioria das configurações |
| Construção | ~R$ 25.000 pra chegar em produção (estimativa minha) | Incluído |
| Manutenção por modelo novo | Recalibração recorrente | Incluído |
| Avaliação com rigor estatístico | Inviável pra maioria dos times | Feita e publicada |
| Chaves e credenciais | Espalhadas, longa duração | Centralizadas na organização |
| Visibilidade de custo | Você constrói | Dashboard de billing com budget |
| Escolha de modelo | Um por implementação | 20+ modelos no mesmo harness |
Repare na última linha, porque ela é contraintuitiva. Adotar uma plataforma parece lock-in. Mas o harness multi-modelo é exatamente o contrário: é a camada que te deixa trocar de modelo sem reescrever nada. Se amanhã sai um modelo melhor e mais barato, você muda um seletor. No harness que você construiu, você reabre os seis problemas que eu listei lá em cima.
E tem capacidade que só existe porque o harness é multi-modelo. O Rubber Duck, por exemplo: um modelo de uma família revisa o trabalho de outra família, justamente porque foram treinados com dados diferentes e têm pontos cegos diferentes. Um harness de fornecedor único não tem como oferecer isso. O seu, muito menos.
Quando a API crua é a resposta certa
Agora vamos ser equilibrados, porque eu detesto post que só defende um lado.
Existe um cenário em que chamar a API direto é a decisão certa, e não é raro: quando o agente é o seu produto, e não a sua ferramenta.
Se você está construindo uma feature dentro do seu software, uma plataforma interna de agentes, um pipeline de automação com trilha de auditoria própria, ou qualquer coisa em que o comportamento do agente é o diferencial que você vende, você precisa ser dono das primitivas. Prompts, retrieval, roteamento, retry, logs, modelo de segurança, billing. Nesse caso, o "custo de construir" que eu listei acima não é desperdício. É o seu roadmap de produto.
O critério que eu uso hoje com clientes é simples: o trabalho começa e termina dentro do fluxo de desenvolvimento de software? Issue, código, teste, pull request, review, deploy. Se sim, você quer o harness pronto. Construir o seu é reinventar uma roda que já foi medida contra cinco benchmarks e quatro modelos. Se o trabalho é um agente que lê um sistema interno, cria um change request num ITSM e grava evidência de compliance num formato que o seu auditor exige, aí você está construindo produto. Vai de API.
E tem um meio-termo que pouca gente conhece. São dois caminhos:
O Copilot SDK expõe exatamente o mesmo runtime de agente que roda no Copilot CLI. Você embute um harness já testado dentro da sua aplicação, em vez de escrever o seu. É a opção que eu teria escolhido se soubesse dela antes do meu fim de semana perdido.
E o BYOK (Bring Your Own Key), hoje em public preview, deixa você usar modelos do seu próprio contrato (Anthropic, AWS Bedrock, Google AI Studio, Microsoft Foundry, OpenAI, provedores compatíveis com OpenAI, xAI, e até modelos locais via Ollama no Copilot CLI) passando pelo harness e pelas integrações que o GitHub mantém. A conta do token vai pro seu fornecedor. A engenharia do harness continua sendo problema deles.
Na prática, se o seu argumento pra API direta era comercial ("já tenho compromisso de gasto com fornecedor X"), dá pra manter o contrato e não pagar o pedágio de construir o harness. Vale ressaltar que BYOK ainda é preview, então valide antes de amarrar decisão de arquitetura nisso.
Uma sequência pragmática pro seu time
Se essa discussão está acontecendo aí na sua empresa agora, é assim que eu conduziria:
- Separe as duas perguntas. "Qual modelo usar" e "qual harness usar" são decisões independentes, e misturar as duas é o que faz a discussão nunca terminar.
- Classifique cada caso de uso em "trabalho de desenvolvimento de software" ou "produto com comportamento de agente próprio". A resposta muda completamente entre os dois.
- Se for desenvolvimento, use o harness pronto e invista o tempo do time em
copilot-instructions.md, custom agents e MCP servers, que é onde o conhecimento do seu domínio realmente entra. O Burke Holland escreveu um post excelente argumentando que a maior parte do ganho vem de aprender bem o harness, não de instalar mais coisa em cima dele. Concordo integralmente. - Se for produto, comece pelo Copilot SDK antes de escrever seu próprio loop. Você pode descobrir que boa parte do que ia construir já está pronto.
- Nunca meça melhoria com uma execução só. Se for comparar qualquer coisa, rode no mínimo cinco vezes. Eu aprendi na marra.
- Centralize credencial. Chave de API espalhada em
.envde dev é dívida de segurança, não conveniência.
A lição que ficou
Voltando à pergunta daquele dev na reunião: "por que eu pago Copilot se é o mesmo modelo e o mesmo preço de token?"
A resposta que eu daria hoje, e que eu não tinha na semana passada: porque você não está pagando pelo modelo. O modelo pensa, mas o harness decide o que ele vê. E decidir o que ele vê é um problema de engenharia contínuo, com custo de construção, custo de manutenção a cada modelo novo, e um custo de avaliação estatística que praticamente nenhum time consegue bancar sozinho.
Eu construí o meu. Levou 14 horas pra funcionar numa demo e uns 20 minutos pra quebrar num repositório real. E a parte mais valiosa do experimento não foi o código. Foi descobrir que eu não tinha como saber se estava melhorando ou piorando.
Isso não é marketing. É o que aconteceu na minha máquina num fim de semana que eu poderia ter usado pra qualquer outra coisa.
E você, já tentou montar seu próprio loop de agente? Chegou até que problema antes de desistir, ou está rodando em produção e eu estou errado? Conta nos comentários, tenho curiosidade genuína de ouvir quem foi mais longe que eu.
Aqui na AzureBrasil.cloud a gente ajuda times brasileiros a fazer exatamente esse tipo de escolha: onde usar plataforma pronta, onde construir, e como faturar tudo isso dentro do contrato Azure em BRL. Se essa conversa está travada aí, fala com a gente.
[]s e até a próxima.
Referências
Artigos que motivaram este post
- Copilot vs. raw API access: What are you actually paying for? — GitHub Blog — Andrea Griffiths, o post que puxou o fio dessa discussão
- Evaluating performance and efficiency of the GitHub Copilot agentic harness across models and tasks — GitHub Blog — a metodologia e os números de benchmark citados aqui
- The harness is all you need (mostly) — GitHub Blog — Burke Holland, sobre extrair valor do harness sem empilhar ferramenta
Harness, SDK e escolha de modelo
- GitHub Copilot SDK — o mesmo runtime de agente do Copilot CLI, pra embutir na sua aplicação
- Auto model selection — GitHub Docs — como o Copilot escolhe modelo por intenção da tarefa e saúde do modelo
- Rubber Duck: crítica cruzada entre famílias de modelo — GitHub Blog — capacidade que só existe em harness multi-modelo
- Getting more from each token: context handling e model routing — GitHub Blog — as otimizações que explicam a diferença de consumo
BYOK e planos
- Use your own API keys with GitHub Copilot (enterprise) — GitHub Docs — BYOK no nível de organização, ainda em public preview
- Use BYOK models in Copilot CLI — GitHub Docs — incluindo endpoints compatíveis com OpenAI, Azure OpenAI e Ollama local
- GitHub Copilot plans e AI Credits — o que cada plano inclui
Posts relacionados aqui do blog
- A Conta Chegou: GitHub Anuncia AI Credits e Marca 1º de Junho como o Fim da Era PRU — o modelo de cobrança por token que torna essa comparação possível
- A IA Barata Está Acabando: Por Que GitHub Copilot Business é a Aposta Mais Segura Agora — previsibilidade contratual e governança em time
- GitHub Copilot CLI ACP Server: o "USB-C" para agentes de IA chegou ao terminal — como consumir o harness do Copilot de dentro das suas ferramentas
- GitHub Copilot Coding Agent: Como a IA Autônoma Está Transformando a Produtividade de Times de Desenvolvimento — o agente que trabalha a partir de issues