Alejandro Rioja.
AI Agents

O Stack de Agentes que Uso para Rodar 30+ Agentes em Produção (Sem Python)

Alejandro Rioja
Alejandro Rioja
6 min de leitura
TL;DR

Rodo 30+ agentes de IA em produção usando TypeScript, Cloudflare Workers/Queues/KV e modelos Claude — sem Python, sem framework de agentes. O stack é deliberadamente simples: Workers lidam com scheduling e filas, KV armazena o estado, e o Anthropic SDK controla as chamadas ao modelo diretamente. A restrição que importa não é a camada de IA — é a infraestrutura ao redor.

Newsletter gratuita

Toda quarta-feira. 28.400+ operadores. Zero enrolação.

Índice

Atualizado maio 2026.

TL;DR: Rodo 30+ agentes de IA em produção usando TypeScript, Cloudflare Workers/Queues/KV e modelos Claude — sem Python, sem framework de agentes. O stack é deliberadamente simples: Workers lidam com scheduling e filas, KV armazena o estado, e o Anthropic SDK controla as chamadas ao modelo diretamente. A restrição que importa não é a camada de IA — é a infraestrutura ao redor.

[Perspectiva do operador] Gerencio dois negócios: uma marca de consultoria em IA e a Pickleland — uma instalação de pickleball em Pflugerville, TX. Entre os dois, tenho mais de 30 agentes rodando em produção hoje. Este é o stack real, não uma demo.

Por que sem Python

A resposta honesta: escrevo TypeScript todos os dias para meu trabalho em sites e produtos. Adicionar uma segunda linguagem para agentes significa dois runtimes, duas árvores de dependências, dois pipelines de deploy. O custo de produtividade não é teórico — paguei em projetos anteriores e decidi não repetir.

A segunda razão é o Cloudflare. Workers roda TypeScript nativamente no edge, com Queues, KV, Durable Objects e Cron Triggers embutidos. Toda a infraestrutura de agentes que preciso — scheduling, estado, processamento assíncrono de jobs — está a um wrangler deploy de distância. Não existe equivalente Python com a mesma simplicidade operacional.

A terceira razão: a maioria dos argumentos “Python-é-melhor-para-IA” realmente quer dizer “Python tem mais bibliotecas de ML.” Eu não treino modelos. Chamo APIs. O Anthropic SDK é TypeScript de primeira classe. LangChain e similares são complexidade que não quero. Quando você está implantando agentes, não pesquisando-os, a simplicidade vence.

A infraestrutura central: três primitivos Cloudflare

Todo agente que rodo toca pelo menos um desses três:

Cloudflare Workers — a camada de computação. Um Worker é o runtime do agente: recebe um trigger (cron, mensagem Queue, HTTP), executa as chamadas ao modelo e escreve outputs em algum lugar. Cold start abaixo de 5ms. Limite de execução de 30 segundos de tempo de CPU no plano gratuito, 15 minutos no pago. Quase tudo que construo cabe em 30 segundos; o que não cabe usa Queues para fan-out.

Cloudflare Queues — processamento assíncrono de jobs. Quando uma tarefa pode demorar mais que uma requisição, ou quando preciso de fan-out (gerar 12 traduções em paralelo), empurro mensagens para uma Queue e deixo consumers vinculados processá-las independentemente. Sem polling, sem hacks de setTimeout.

Cloudflare KV — estado leve. Histórico de execuções de agentes, últimos timestamps processados, respostas de API em cache. KV é eventualmente consistente, o que está bem para agentes — não estou executando transações. Me dá um store chave-valor simples que posso ler/escrever de qualquer Worker sem subir um banco de dados.

A camada do modelo: Anthropic SDK, dois modelos

Uso exatamente dois modelos Claude:

O Anthropic SDK em TypeScript é direto. Aqui está o padrão que uso para cada chamada ao modelo:

typescript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ apiKey: env.ANTHROPIC_API_KEY });

async function runAgent(prompt: string, systemPrompt: string): Promise<string> {
  const message = await client.messages.create({
    model: "claude-sonnet-4-6",
    max_tokens: 2048,
    system: systemPrompt,
    messages: [{ role: "user", content: prompt }],
  });

  const block = message.content[0];
  if (block.type !== "text") throw new Error("Unexpected content type");
  return block.text;
}

Essa é toda a interface do modelo. Sem abstrações acima. Quando preciso de tool use, adiciono um array tools. Quando preciso de streaming, troco messages.create por messages.stream. Nenhum framework gerencia isso por mim — e não quero que gerencie.

Um agente real: o pipeline de conteúdo

O agente mais complexo que rodo é o pipeline de conteúdo. Ele gera posts de blog, os traduz para 12 idiomas, renderiza SVGs de cards OG e redige promoções do LinkedIn — tudo como rascunhos, bloqueados atrás da minha revisão antes que qualquer coisa seja publicada.

O ponto de entrada do Worker se parece com isso:

typescript
// src/workers/content-pipeline.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const { topic, slug } = await request.json<{ topic: string; slug: string }>();

    // Passo 1: gerar post EN
    const enPost = await generatePost(topic, env);
    await env.CONTENT_KV.put(`draft:${slug}:en`, enPost);

    // Passo 2: fan-out de traduções via Queue
    const locales = ["ar", "de", "es", "fr", "hi", "it", "ja", "ko", "nl", "pt", "ru", "zh"];
    for (const locale of locales) {
      await env.TRANSLATION_QUEUE.send({ slug, locale, content: enPost });
    }

    return Response.json({ status: "queued", slug });
  },
};

Cada tradução roda em sua própria invocação Worker. Se uma falhar, a Queue a retenta automaticamente. Obtenho 12 traduções em paralelo sem gerenciar threads, promises ou rate-limit backoff eu mesmo.

Um agente real: o promotor de eventos

A Pickleland organiza eventos de pickleball. Construí um agente que escaneia a plataforma de reservas para eventos nos próximos 4 dias, redige posts para grupos do Facebook por evento e os apresenta para minha revisão antes que qualquer coisa saia.

O system prompt:

typescript
const systemPrompt = `You are a community manager for a pickleball facility.
Write Facebook group posts for upcoming events.
Rules:
- Max 150 words per post
- Lead with what's fun about the event, not the price
- Include the booking URL exactly as provided
- Do not use exclamation marks more than once per post
- Tone: friendly, local, not corporate`;

A restrição que importa aqui não é o modelo — é o workflow. O agente roda com um trigger cron às 8h diariamente. Os posts rascunho caem em uma fila de revisão. Eu aprovo ou edito, então um Worker de publicação separado dispara. Nenhum evento é postado sem que um humano o tenha visto.

Como gerencio 30+ agentes sem enlouquecer

O painel do Cloudflare é meu plano de controle. Cada Worker me mostra contagem de invocações, taxa de erros e tempo de CPU. Cada Queue mostra throughput de mensagens e falhas. KV mostra uso de armazenamento.

Além disso:

A disciplina não é técnica. É decidir o que um agente pode fazer autonomamente versus o que precisa da minha aprovação. Rascunhos de conteúdo: autônomo. Qualquer coisa que toque um cliente: revisão humana. Qualquer coisa que mova dinheiro: não é trabalho de agente.

O que mudaria se começasse hoje

Uma coisa: teria configurado outputs estruturados (modo JSON) desde o primeiro dia em vez de aplicá-los retroativamente em agentes já implantados. Parsear texto livre do Claude é um imposto. Quando você define um esquema Zod e o passa como forma de resposta esperada, obtém dados tipados de volta e os Workers downstream não precisam adivinhar.

typescript
import { z } from "zod";

const EventPostSchema = z.object({
  headline: z.string().max(80),
  body: z.string().max(600),
  bookingUrl: z.string().url(),
  suggestedPostTime: z.enum(["morning", "afternoon", "evening"]),
});

A conclusão do operador

O stack de agentes que funciona em produção é aquele que você consegue debugar às 22h quando algo quebra. Para mim, é TypeScript + Cloudflare + Anthropic SDK — não porque é a combinação mais glamorosa, mas porque cada camada é observável, implantável e substituível de forma independente. Frameworks são apostas em abstrações. Prefiro ser dono do encanamento.

Continue lendo

Receba o manual de IA na sua caixa de entrada

Toda quarta-feira. 28.400+ operadores. Zero enrolação.

↵ ver todos os resultados esc esc para fechar