TL;DR: RTK é um proxy de CLI que comprime o output dos seus comandos antes de jogar pro contexto do Claude Code (ou qualquer AI assistant no terminal). Você instala, roda rtk init -g, e a partir daí o hook intercepta automaticamente todos os comandos bash — sem precisar ficar digitando rtk na frente de nada. Em 612 comandos, economizei 5,3 milhões de tokens — 92,6% do que teria sido consumido.
Faz alguns meses que eu uso Claude Code no meu fluxo diário de desenvolvimento. Rodava testes, lia arquivos, listava branches — tudo direto pelo assistant. Funcionava bem. O que eu não estava vendo é que cada um desses comandos jogava o output inteiro pro contexto do modelo.
Pensa assim: é como se você pedisse pra um colega revisar um PR e mandasse o log completo de build pra ele — 800 linhas de compilação, timing por pacote, status de cada função. Ele vai achar o que importa, mas vai gastar tempo filtrando. O Claude faz a mesma coisa, só que em tokens.
Um ./gradlew test num projeto Android de tamanho médio gera facilmente 2,6 milhões de tokens de output bruto. Eu rodei uma vez. Foram 2,6M tokens que entraram no contexto sem eu precisar de 99,8% daquilo.
Aí eu descobri o RTK.
O que é o RTK
RTK é um proxy de CLI open-source escrito em Rust que senta entre seus comandos e o AI assistant. Ele executa o comando normalmente, captura o output, filtra o ruído, e entrega um resumo estruturado pro contexto do modelo.
O projeto tem 47k+ stars no GitHub e suporta 100+ comandos com overhead de menos de 10ms.
Funciona assim:
# Sem RTK — output bruto vai inteiro pro contexto
./gradlew test
# Com RTK — output filtrado, preservando o que importa
rtk ./gradlew test
O RTK não esconde nada crítico. Falhas de teste aparecem. Stack traces aparecem. O que some é o ruído: cada linha de compilação quando tudo passou, timings por método individual, logs repetitivos que o modelo não precisa processar palavra por palavra.
É como a diferença entre receber um relatório de 200 páginas ou um sumário executivo de 3. O conteúdo importante está nos dois — mas num deles você chega no ponto muito mais rápido.
Instalação
Bora colocar a mão na massa. Tem três formas de instalar:
Homebrew (recomendado para Mac):
brew install rtk
Linux/macOS via curl:
curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh
Instala em
~/.local/bin. Se precisar adicionar ao PATH:echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
Cargo:
cargo install --git https://github.com/rtk-ai/rtk
⚠️ Existe outro pacote chamado "rtk" no crates.io (Rust Type Kit). Se
rtk gainfalhar, você instalou o errado. Use sempre o--gitno cargo.
Para verificar:
rtk --version # rtk 0.x.x
rtk gain # mostra as estatísticas de economia
O hook: você não precisa digitar rtk em nada
Essa é a parte que muda tudo, e que eu não deixei claro antes.
Você não fica chamando rtk go test, rtk git status, rtk read manualmente. O RTK instala um hook no Claude Code que intercepta todos os comandos bash automaticamente, antes de executar. O Claude digita git status, o hook reescreve pra rtk git status, e o output que chega no contexto já vem filtrado.
Para instalar o hook:
rtk init -g
Depois disso, reinicie o Claude Code. Pronto. A partir daí, 100% dos comandos bash passam pelo RTK sem você fazer nada.
# Você digita:
git status
# O hook transforma em:
rtk git status
# E o Claude recebe o output já filtrado
Um caveat importante: o hook só funciona em chamadas via ferramenta Bash. As ferramentas nativas do Claude Code (Read, Grep, Glob) não passam pelo hook. Se quiser RTK nesses fluxos, use os equivalentes em shell: cat, rg, find — ou chame rtk read, rtk grep diretamente.
Por debaixo dos panos
Essa parte é pra quem quer entender o que acontece de verdade, não só "instala e usa".
O RTK é um binário Rust de ~4.1MB. O overhead fica entre 5 e 15ms por comando. Mas o que acontece nesse intervalo?
Quando você roda rtk git status, o comando passa por seis fases antes de imprimir qualquer coisa:
1. Parse: o Clap (biblioteca de CLI do Rust) identifica o comando e extrai os argumentos. Commands::Git com args ["status"].
2. Route: direciona para o módulo correspondente. O RTK tem mais de 60 módulos organizados por ecossistema: git/, go/, rust/, python/, js/, cloud/, system/.
3. Execute: o comando real é executado via std::process::Command. O output é capturado inteiro em memória — stderr e stdout separados.
4. Filter: aqui mora o trabalho. O RTK aplica uma estratégia específica por tipo de comando. O output filtrado pode ter 100% de redução (quando nada é relevante) ou 0% (quando tudo é sinal).
5. Print: output filtrado vai pro stdout. Passando -v, -vv ou -vvv você vê progressivamente mais detalhe — inclusive o output bruto antes de filtrar, útil pra debugar.
6. Track: um INSERT no SQLite em ~/.local/share/rtk/history.db, gravando tokens de input, output, percentual salvo e tempo de execução. É desse banco que o rtk gain lê.
Como o RTK conta tokens
A estimativa usa uma heurística simples:
fn estimate_tokens(text: &str) -> usize {
(text.len() as f64 / 4.0).ceil() as usize
}
Quatro caracteres por token, alinhado com o modelo de tokenização do GPT. Não é exato, mas é consistente e rápido. Em texto técnico com muitos símbolos, a heurística tende a subestimar um pouco, então os números reais de economia costumam ser maiores do que o reportado.
As estratégias de filtragem
O README fala em quatro estratégias. Na prática, são doze. Cada uma otimizada pra um tipo de output:
Stats Extraction (git status, git log, git diff): em vez de listar cada arquivo linha por linha, extrai contagens e agrega. "3 files changed, +142/-89" no lugar de 30 linhas detalhadas.
Failure Focus (go test, cargo test, pytest, vitest): quando os testes passam, o output é descartado. Zero tokens. O modelo não precisa ler ok TestAuth 0.003s pra saber que funcionou. Falhas aparecem inteiras, com stack trace. É por isso que rtk go test ./... chega a 100% de economia nas rodadas limpas.
NDJSON Streaming (go test com -json): o go test -json emite uma linha de JSON por evento de teste. O RTK parseia linha a linha usando serde_json, agrega por pacote, e entrega algo como "2 packages, 3 failures (pkg1::TestAuth, pkg2::TestParse)". Cada linha processada em sequência, sem carregar o output inteiro em memória.
State Machine (pytest): o pytest emite texto, não JSON. O RTK implementa um state machine que rastreia IDLE → TEST_START → PASSED/FAILED → SUMMARY, extrai só as falhas e o resumo final, descartando tudo no meio.
Code Filtering (rtk read): leitura de arquivos tem três níveis configuráveis: none (mantém tudo), minimal (remove comentários, redução de 20-40%) e aggressive (remove corpo das funções, redução de 60-90%). O RTK detecta a linguagem pela extensão e aplica a regex correta. Rust, Python, Go, Java, JavaScript e TypeScript têm suporte nativo.
Deduplication (docker logs, kubectl logs, arquivos de log): colapsa linhas repetidas com contagem. [ERROR] Connection refused (×50) no lugar de 50 linhas idênticas.
Tree Compression (ls, tree): converte uma lista flat de 50 arquivos numa hierarquia com contagem de itens por diretório. src/ ├── lib/ (12 files) no lugar de 12 linhas.
O mecanismo de tee
Quando um comando falha, o RTK salva o output bruto completo num arquivo temporário:
FAILED: 2/15 tests
[full output: ~/.local/share/rtk/tee/1707753600_cargo_test.log]
O modelo pode ler esse arquivo se precisar de mais contexto sem re-executar o comando. A ideia é: filtra por padrão, mas nunca esconde dados de diagnóstico quando algo quebrou.
Fail-safe
Se o filtro do RTK falhar por qualquer motivo (output num formato inesperado, erro de parse), o comportamento padrão é devolver o output original sem filtrar. Você nunca fica sem informação. O overhead de tokens piora, mas o comando continua funcionando.
Os números depois de 612 comandos
Rodei rtk gain pra ver o acumulado:
Os cinco comandos com maior impacto:
1. rtk ./gradlew test — 1 execução, 2,6M tokens economizados, 99,8%.
Uma rodada só. Projetos Android e backend Java são os casos mais extremos porque o output do Gradle é verboso por padrão. Esse único comando representa mais da metade de toda a economia acumulada.
2. rtk read — 57 execuções, 1,2M tokens economizados, 26,4% de média.
Toda vez que o Claude lia um arquivo grande, o RTK filtrava o que era relevante pro contexto atual. A média de 26,4% parece baixa até você multiplicar por 57 execuções.
3. rtk go test ./... — 8 execuções, 810K tokens economizados, 100%.
O output de testes passando é descartado porque não acrescenta nada ao contexto. Falhas e detalhes de erro continuam aparecendo integralmente.
4. rtk go test ./pkg/app... — 2 execuções, 146K tokens, 100%.
5. rtk git branch -a — 2 execuções, 79K tokens, 99%.
Porque listar 40 branches remotas quando você quer saber as 3 ativas é desperdício puro.
Por que token não é só custo
A conta mais óbvia é financeira. Menos tokens consumidos, menos gasto. Mas o impacto mais importante é outro: contexto.
Quanto mais ruído no contexto, mais o modelo tem que filtrar pra encontrar o sinal. Em janelas de contexto longas — que é exatamente onde você usa Claude Code no dia a dia — isso afeta a qualidade das respostas. O modelo "lembra" de menos do que importa porque está processando muito do que não importa.
É como tentar se concentrar numa reunião onde metade das pessoas está falando ao mesmo tempo sobre assuntos não relacionados. Tecnicamente você ouviu tudo. Na prática, ficou com muito menos.
Checklist de início rápido
# 1. Instala
brew install rtk
# 2. Ativa o hook no Claude Code
rtk init -g
# 3. Reinicia o Claude Code
# 4. Depois de uma semana, vê o resultado
rtk gain
Uma coisa importante: o RTK não resolve prompt ruim nem contexto mal estruturado. Ele remove desperdício. Se o seu problema é outro, o RTK não é a solução — mas provavelmente faz sentido ter ele rodando de qualquer forma.
O repositório completo está em github.com/rtk-ai/rtk.
É isso galera! Se tiver alguma dúvida ou quiser compartilhar o número que apareceu no seu rtk gain, deixa nos comentários. Happy coding! 👨🏼💻

Top comments (0)