Clef da Cloudflare: modelos de decisão no seu backend Bun
Faz as contas de quantas chamadas de LLM no seu backend existem só para escolher uma opção numa lista. Classificar um ticket, decidir se um comentário é spam, escolher para qual fila uma tarefa vai. A Cloudflare anunciou o Clef, uma família de modelos de decisão com pesos abertos, junto com uma plataforma de fine-tuning por reforço (RL). A proposta mira exatamente esse tipo de chamada. Como meu backend do dia a dia roda em Bun, quero olhar o anúncio por esse ângulo: o que muda para quem escreve TypeScript e só quer que a decisão saia certa, rápida e barata.
O anúncio original está no blog da Cloudflare. Lá você encontra os detalhes de tamanho, licença e benchmarks. Aqui fica a minha leitura de dev.
O que a Cloudflare lançou com o Clef
São duas peças.
A primeira são os modelos. São open-weight, ou seja, você pode baixar os pesos e rodar onde quiser, sem depender da API de ninguém. O foco não é conversar nem escrever redação. O foco é tomar uma decisão a partir de uma entrada e de um conjunto de opções.
A segunda é a plataforma de fine-tuning por reforço. Em vez de você montar um dataset gigante com "entrada → resposta certa", você ensina o modelo dando nota para o que ele decidiu. Acertou, ganha recompensa. Errou, perde. Com o tempo o modelo se ajusta ao seu domínio.
A combinação é o que interessa. Modelo aberto sozinho já existe aos montes. Plataforma de RL sozinha é coisa de time de ML. As duas juntas, empacotadas para quem já usa Workers, viram uma ferramenta de produto.
O que é um modelo de decisão, na prática
Pensa num endpoint de triagem de suporte. Hoje muita gente resolve assim: manda o texto do ticket para um LLM grande com um prompt tipo "responda apenas com uma destas categorias: bug, billing, feature, spam". Aí faz parse da resposta, torce para não vir "Claro! A categoria é bug." e trata o caso em que o modelo inventa uma quinta categoria.
Funciona. Mas você está pagando um modelo que sabe escrever soneto para devolver uma palavra.
Um modelo de decisão inverte isso. Ele recebe a entrada e as opções e devolve uma escolha. A saída já nasce estruturada. Não tem parse de texto livre, não tem resposta criativa, não tem "como um modelo de linguagem...".
A maioria das chamadas de LLM em produção é uma decisão disfarçada de texto.
Essa é a minha opinião forte do dia. Se você abrir os logs do seu app e contar, aposto que mais da metade das chamadas termina num switch ou num if. Para esses casos, gerar texto é desperdício de latência, de token e de paciência.
Por que fine-tuning por RL interessa a quem não é de ML
Fine-tuning tradicional assusta porque pede dataset rotulado. Você precisa de milhares de exemplos com a resposta certa, limpos, balanceados. Quase nenhum time de produto tem isso pronto.
RL muda a pergunta. Você não precisa saber a resposta certa de antemão. Você precisa saber dizer, depois, se a decisão foi boa. E isso o seu sistema muitas vezes já sabe:
- O atendente moveu o ticket para outra fila? A decisão foi ruim.
- O usuário clicou na recomendação? Foi boa.
- O comentário marcado como spam foi restaurado por um moderador? Foi ruim.
Esse sinal já está no seu banco. Ele só não está sendo usado para treinar nada. Com uma plataforma de RL gerenciada, esse histórico vira matéria-prima. Para um dev full stack, isso é o ponto que faz a notícia sair do "legal, mais um modelo" para "ok, isso eu consigo usar".
Como isso entra num backend Bun
Vou mostrar o fluxo com um exemplo de triagem. O formato exato do payload e o nome do modelo estão na documentação da Cloudflare. Aqui o código é ilustrativo, para mostrar o encaixe.
Primeiro, a chamada. Do lado do Bun é só um fetch para a API REST do Workers AI:
// triage.ts
const options = ["bug", "billing", "feature", "spam"] as const
type Choice = (typeof options)[number]
const url = `https://api.cloudflare.com/client/v4/accounts/${Bun.env.CF_ACCOUNT}/ai/run/${Bun.env.DECISION_MODEL}`
export async function triage(ticket: string): Promise<Choice> {
const res = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${Bun.env.CF_TOKEN}` },
body: JSON.stringify({ input: ticket, options }), // formato ilustrativo
})
if (!res.ok) throw new Error(`decisão falhou: ${res.status}`)
const { result } = await res.json()
return result.choice
}
Repara que não tem regex para limpar resposta nem JSON.parse dentro de try rezando. O tipo Choice fecha o contrato.
Segundo, e é aqui que a maioria vai pular etapa: guardar a decisão e o resultado. Sem isso, o RL não tem o que aprender. Com o Bun.sql nativo e Postgres, fica curto:
import { sql } from "bun"
// quando decide
const [row] = await sql`
insert into decisions (input, choice, model)
values (${ticket}, ${choice}, ${Bun.env.DECISION_MODEL})
returning id
`
// quando um humano corrige (ou não) a fila
await sql`
update decisions
set reward = ${finalQueue === choice ? 1 : 0}
where id = ${row.id}
`
Duas tabelas a menos de planejamento do que parece. Uma coluna reward e você já tem o esqueleto de um ciclo de melhoria contínua. Daqui a um mês, esse histórico alimenta o fine-tuning, você troca o DECISION_MODEL pela versão ajustada e compara a taxa de acerto. Variável de ambiente, deploy, pronto.
E como os pesos são abertos, existe um plano B. Se um dia a Cloudflare mudar preço ou termos, você pega o modelo ajustado e roda em outro lugar. Isso não é detalhe. Já vi time reescrever metade do backend porque o provedor de IA mudou a API de um mês para o outro.
Onde eu ficaria com o pé atrás
Nem tudo é festa. Alguns pontos que eu checaria antes de colocar em produção:
Sinal de recompensa ruim gera modelo ruim. RL otimiza exatamente o que você mede. Se a sua recompensa for "o usuário clicou", o modelo aprende a gerar clique, não a gerar valor. Clássico. Pense duas vezes no que é "acertar" no seu domínio.
Volume importa. Se o seu endpoint toma 30 decisões por dia, o histórico vai demorar muito para ensinar alguma coisa. Para volume baixo, um prompt bem escrito num modelo genérico ainda resolve, e com menos peças móveis.
Lock-in disfarçado. Os pesos são abertos, mas a plataforma de RL é da Cloudflare. Se o seu pipeline de treino depende dela, a parte mais valiosa (o processo de melhoria) continua presa. Vale ver se dá para exportar o modelo ajustado e os dados de treino sem dor.
Decisão não é tudo. Se a tarefa pede explicação, resumo ou texto para o usuário final, modelo de decisão não serve. Ele é bisturi, não canivete suíço. E tudo bem, só não tente fazer ele escrever o e-mail de resposta ao cliente.
Vale a pena testar o Clef?
Para mim, vale, com um recorte claro. Pegue uma decisão do seu sistema que roda com volume decente e que já tem um sinal natural de certo ou errado. Triagem, moderação, roteamento. Coloque o modelo de decisão lado a lado com o que você usa hoje, logue tudo e compare acerto, latência e custo por mil chamadas durante duas semanas.
Se empatar no acerto e ganhar em latência e custo, você acabou de tirar um modelo gigante de um lugar onde ele nunca deveria ter estado. Se perder, você ganhou uma tabela decisions com dados reais, o que já é melhor do que o chute de antes.
O que eu mais gosto nesse anúncio é que ele empurra a conversa de IA para um lugar mais honesto. Menos "agente que faz tudo", mais "função que decide uma coisa bem". É o tipo de IA que cabe num backend de verdade, com tipo, teste e métrica. Se quiser ver como eu costumo estruturar esse tipo de integração em projetos reais, dá uma olhada nos meus projetos.
Resumo para o LinkedIn
A maioria das chamadas de LLM em produção é só uma decisão disfarçada de texto. Classificar um ticket, marcar spam, escolher uma fila. Pagamos um modelo que escreve soneto para devolver uma palavra. A Cloudflare lançou o Clef: modelos de decisão com pesos abertos e fine-tuning por reforço. A parte boa é que você não precisa de dataset rotulado. O sinal de acerto já está no seu banco: o ticket que mudou de fila, o comentário restaurado pelo moderador. No meu backend Bun, isso se resume a um fetch tipado e uma coluna reward no Postgres. Menos "agente que faz tudo", mais "função que decide uma coisa bem". Escrevi minha leitura completa no blog, com código e os pontos em que eu ficaria com o pé atrás. #Cloudflare #IA #TypeScript #Bun #Backend