Atualizei o RTK numa das máquinas, abri o Claude Code, e recebi isto:
✻ Connection refused — a firewall or proxy may be blocking it (ECONNREFUSED)
Nada de firewall, nada de proxy externo: o agente estava apontando para
http://127.0.0.1:8080, onde nada escutava. A mensagem do hook até dizia a
verdade, mas entre linhas: “launched the RTK proxy for http://127.0.0.1:8080
but it is not answering yet”. Só que não era questão de tempo. O binário do
daemon, pura e simplesmente, não existia na máquina.
Este post documenta o processo: uma introdução ao RTK para quem nunca usou, um mapa do que mudou no 1.0 (e mudou bastante), e ao final um guia de instalação e atualização de cada componente, porque hoje são três downloads distintos e o instalador oficial só cuida de um deles.
O que é o RTK
RTK (“Rust Token Killer”) é uma ferramenta de otimização de tokens agnóstica de agente: um binário único em Rust que intercepta os comandos de shell que seu agente de código executa e comprime a saída antes que ela chegue ao contexto do LLM. Compressão de saída de bash testada em batalha, até 90% menor no caso dos comandos mais verbosos, com menos de 10ms de overhead e mais de 100 comandos suportados: git, gh, cargo, npm, pnpm, pytest, ruff, go test, docker, kubectl, terraform, aws, e por aí vai.
A ideia central: quando o agente roda git log, ele não precisa de hash
completo, data formatada, corpo inteiro e autor com email. Basta hash curto,
autor e assunto. Quando roda a suíte de testes, precisa dos failures e de um
contador do que passou, não de mil linhas verdes. O RTK reescreve o comando no
hook (no Claude Code, um PreToolUse hook que transforma git status em
rtk git status de forma transparente) e aplica quatro estratégias por tipo de
comando: filtragem inteligente (remove ruído), agrupamento (agrega itens
similares), truncamento (corta redundância mantendo contexto) e deduplicação
(colapsa linhas repetidas com contadores).
Dois avisos honestos do próprio projeto, que vale repassar:
- O que o RTK mede é a saída de bash, uma das fontes de tokens de entrada. A
economia se dilui na conta total (prompt, system prompt, histórico, tokens de
saída). Os percentuais são confiáveis; os números absolutos são estimados em
bytes / 4, porque o RTK não embute tokenizer. - O hook só dispara em chamadas à ferramenta Bash. Ferramentas nativas como Read, Grep e Glob não passam por ele (por isso os comandos de shell continuam sendo o caminho para quem quer a economia completa).
São 18 ferramentas suportadas, de Claude Code, OpenCode, Codex e Gemini CLI a
Cursor, Windsurf, Cline, Droid e Trae. O rtk gain mostra o painel de economia
(por comando, por dia, com grafo de 30 dias e export em JSON), e o rtk discover aponta oportunidades perdidas. No meu setup, RTK é peça fixa global:
instalo uma vez por máquina e todos os agentes da casa herdam a compressão.
O que mudou no 1.0
A versão 1.0.0 saiu em 13 de outubro de 2026 (a 1.0.1, no dia seguinte), e não foi uma bump cosmética de número de versão. Foram três mudanças estruturais.
Um download virou três
Antes, você instalava “o rtk” e pronto. Agora existem três archives no release, com licenças diferentes:
rtk-<target>: a edição padrão, Apache-2.0 com um componente BUSL-1.1 (o motor de compressão,rtk-engine). Tem o núcleo de hooks, todos os filtros de comando e o motor.rtk-oss-<target>: edição 100% Apache-2.0, sem o motor. Hooks e filtros apenas.rtk-proxy-<target>: o daemon do RTK Proxy, BUSL-1.1, distribuído como archive próprio. Nunca vem empacotado com nenhum dos outros dois.
As duas edições do rtk instalam um binário com o mesmo nome, então são
mutuamente exclusivas: desinstale uma antes de instalar a outra. Uso em
produção é gratuito, engine e daemon incluídos; o que a licença BUSL não cobre
é oferecer o RTK (ou derivado) a terceiros como produto ou serviço comercial.
O motor de pipelines
Tudo que o RTK faz (quais comandos são reescritos, o que acontece com a saída
de cada ferramenta, o que o proxy comprime) virou configuração num arquivo
componível, o ~/.config/rtk/pipeline.toml, lido pelo novo motor. O
comportamento padrão não muda nada no upgrade: sem arquivo, você está no
rtk:default, mesmo hook, mesmo arquivo de awareness, seus filters.toml e
config.toml de sempre. Tudo além disso é opt-in, uma linha por vez:
[pipeline]
extends = ["rtk:posthook", "rtk:proxy"]
O daemon rtk-proxy
A novidade mais interessante (e a fonte do meu ECONNREFUSED): o RTK agora
pode estender a mesma compressão ao tráfego de API entre o agente e o
provedor. O rtk-proxy é um processo local em background que senta entre o
agente e o provedor LLM: comprime payloads, remove bytes que nenhum modelo
precisava, roteia chamadas para modelos mais baratos quando o pipeline pede
(e essas chamadas aparecem no rtk gain), e opcionalmente alinha breakpoints
de prompt cache.
São dois caminhos independentes de adoção, porque nem todo harness tem hook de sessão:
rtk init -goferece a configuração uma vez: escreve a base URL no settings, cria o pipelinertk:proxy, e pergunta como o daemon deve voltar após um reboot (hook de SessionStart, serviço de background, ou nenhum).rtk claudenão configura nada: sobe o daemon se preciso, aponta o harness pra ele e executa oclaudede dentro. É o caminho sem sistema de hooks, e a existência do subcomando é ela mesma a garantia de que o tráfego passa pelo daemon.
E aqui está o ponto que originou este artigo: o daemon é um binário separado,
sob licença separada, em archive separado. O install.sh oficial baixa só o
rtk.
Breaking changes da 1.0.0
Para quem vinha das versões 0.x:
rtk proxy <cmd>virourtk bypass <cmd>(o nome antigo segue como alias): roda um comando sem filtragem, ainda rastreado.--ultra-compactfoi removido.rtk gainexclui saídas oversized da taxa de destaque (headline rate).- A licença do binário padrão mudou (Apache-2.0 + BUSL-1.1), com a edição
rtk-ossApache-2.0 disponível ao lado.
A 1.0.1, um dia depois, trouxe duas correções: o RTK_PROXY_BIND passou a ser
respeitado no llm-proxy start e nos launchers de agente, e o gain só
sugere rtk pipeline share onde o comando existe.
O sintoma: ECONNREFUSED no Claude Code
O cenário completo, para quem cair aqui pelo erro:
curl -fsSL .../install.sh | shinstala ortk1.0.1 em~/.local/bin.rtk init -gregistra o hook, o RTK.md, e pergunta se você quer o proxy. Respondi que sim, escolhi o hook de SessionStart. Ele escreveu"ANTHROPIC_BASE_URL": "http://127.0.0.1:8080"no settings.json, criou opipeline.tomlcomextends = "rtk:proxy", e então:[warn] rtk-proxy not started: rtk-proxy not found.- O init foi honesto (“daemon NOT responding on 127.0.0.1:8080”), mas o settings.json ficou apontando para a porta 8080 de qualquer forma.
- Todo request do Claude Code morre com ECONNREFUSED, porque não há listener nenhum em 8080.
Ou seja: a configuração do agente é escrita mesmo quando o binário do daemon
não existe. O install.sh não baixa o rtk-proxy, e o init não o instala. A
mensagem de erro do RTK até explica o caminho (“The daemon ships as its own
release archive (rtk-proxy-
A correção é instalar o daemon manualmente. Daqui em diante, o guia.
Instalando e atualizando cada componente
rtk (edição padrão)
O caminho recomendado no Linux:
curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/refs/heads/master/install.sh | sh
O script detecta plataforma, baixa o archive certo, verifica o SHA-256 contra
o checksums.txt do release e instala em ~/.local/bin/rtk. Alternativas:
brew install rtk (macOS/Linux) e winget install rtk-ai.rtk (Windows).
Depois confira que pegou o pacote certo (existe outro projeto chamado “rtk” no crates.io):
rtk --version # qualquer versão recente
rtk gain # deve abrir o painel, não "command not found"
rtk-oss (edição Apache-2.0)
Mesmo instalador, variável de ambiente:
curl -fsSL .../install.sh | RTK_EDITION=oss sh
brew install rtk-ai/tap/rtk-oss
Lembre que as duas edições instalam um binário chamado rtk: troque uma pela
outra, não sobreponha.
rtk-proxy (o daemon)
Este é o componente que o instalador não cobria (na 1.0.1) e que precisa de
download manual. O procedimento resolve a última versão via API do GitHub,
verifica o checksum e instala ao lado do rtk:
set -euo pipefail
tmp=$(mktemp -d)
# resolve o target do seu sistema
case "$(uname -s)/$(uname -m)" in
Linux/x86_64) target=x86_64-unknown-linux-musl ;;
Linux/aarch64) target=aarch64-unknown-linux-gnu ;;
Darwin/arm64) target=aarch64-apple-darwin ;;
Darwin/x86_64) target=x86_64-apple-darwin ;;
*) echo "target não mapeado, confira a página de releases"; exit 1 ;;
esac
# última versão estável
ver=$(curl -fsSL https://api.github.com/repos/rtk-ai/rtk/releases/latest \
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' | head -1)
base="https://github.com/rtk-ai/rtk/releases/download/$ver"
curl -fsSL -o "$tmp/checksums.txt" "$base/checksums.txt"
curl -fsSL -o "$tmp/rtk-proxy.tar.gz" "$base/rtk-proxy-$target.tar.gz"
# verifica o SHA-256 contra o checksums.txt oficial
(cd "$tmp" && grep "rtk-proxy-$target" checksums.txt | sha256sum -c -)
tar xzf "$tmp/rtk-proxy.tar.gz" -C "$tmp" rtk-proxy
install -m 0755 "$tmp/rtk-proxy" ~/.local/bin/rtk-proxy
rm -rf "$tmp"
Em macOS, troque sha256sum -c por shasum -a 256 -c. Se prefere fixar
versão em vez de resolver a última, substitua a variável ver pela tag (por
exemplo ver=v1.0.1), que é o que eu faço quando quero as duas máquinas em
sincronia.
O daemon é procurado ao lado do binário rtk (no meu caso,
~/.local/bin/rtk-proxy).
Configuração por agente
Uma vez com os binários no lugar:
rtk init -g # Claude Code (padrão)
rtk init -g --opencode # Claude setup + plugin do OpenCode
rtk init -g --codex # Codex (OpenAI)
rtk init -g --gemini # Gemini CLI
rtk init -g --agent cursor # Cursor
Durante o init, quando ele perguntar sobre o proxy, as três opções de
retorno após reboot são: hook de SessionStart (sobe o daemon quando a sessão
começa, o que escolhi), serviço de background por usuário
(rtk llm-proxy service install), ou nenhum (só imprime a linha de export e
não toca no settings). Reinicie o agente depois e teste com git status: a
saída compactada aparece sem que o agente chame rtk explicitamente.
Quem não quiser configurar nada pode pular o init do proxy inteiro e usar só o launcher:
rtk claude # sobe o daemon se preciso e executa o claude através dele
Ciclo de vida do daemon
Os subcomandos do rtk llm-proxy:
rtk llm-proxy start # sobe o daemon (no-op se já estiver rodando)
rtk llm-proxy stop # pede o shutdown
rtk llm-proxy status # rodando ou não, endereço e versão
rtk llm-proxy stats # estatísticas de uso do daemon
rtk llm-proxy setup # o que pode ser apontado para o proxy nesta maquina
rtk llm-proxy service # gerencia o servico de background por usuario
Logs e banco do daemon ficam em ~/.config/rtk/llm-proxy/
(rtk-proxy.log e rtk-proxy.db).
Verificação
Três checagens, em ordem:
rtk llm-proxy status
# running at 127.0.0.1:8080 (edition local, v1.0.1)
curl -sS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/v1/messages \
-X POST -H 'content-type: application/json' -d '{}'
# 401: o daemon respondeu e rejeitou sem credencial, que é o esperado
rtk gain
# painel com filtragem de comandos e proxy lado a lado
O 404 na raiz (/) é normal: o proxy só serve as rotas da API. Um 401
sem chave no /v1/messages é a prova de vida. Se o Claude reclamar de
“connection refused” no primeiro request de uma sessão em que o daemon acabou
de subir, um retry resolve; persistente, é binário ausente ou porta errada.
Checklist de atualização
Para manter tudo são numa máquina, na ordem:
- Atualizar o
rtk: rodar oinstall.shde novo (é idempotente, substitui o binário) oubrew upgrade rtk. - Atualizar o
rtk-proxy: mesmo script do tutorial acima, com a tag nova. Eu mantenhortkertk-proxyna mesma versão por hábito; ortk llm-proxy statusmostra a versão do daemon para conferir. - Reiniciar o daemon:
rtk llm-proxy stop && rtk llm-proxy start(ou só esperar o hook de SessionStart subir na próxima sessão). - Conferir o settings do agente:
ANTHROPIC_BASE_URLapontando parahttp://127.0.0.1:8080e o hook registrado. - Rodar as três verificações (
status,curl,gain).
Notas finais
O RTK 1.0 é uma evolução legítima: o motor de pipelines e o proxy no nível de
request abrem possibilidades que a geração dos hooks puros não tinha. Mas a
divisão em três archives criou um vão entre “o instalador instala” e “o init
configura”: o rtk-proxy cai exatamente aí, e o usuário descobre pelo
ECONNREFUSED. Se você usa o proxy, o script de instalação manual do daemon
acima fecha o ciclo.
Dois registro finais de privacidade, porque importam: o RTK não coleta
conteúdo de comandos nem de arquivos, e a telemetria é anônima e desligada por
padrão (só envia algo após opt-in explícito com rtk telemetry enable).
Referências: repositório, guia de instalação, edições e licenciamento, RTK Proxy e BREAKING_CHANGES da 1.0.0.
