Integração OpenRouter AI

Configure a integração com OpenRouter para executar tarefas com modelos de IA de última geração

Nesta Página

Integração OpenRouter AI

O OpenRouter é o provedor de IA principal do Tarefa AI, permitindo acesso a dezenas de modelos de última geração incluindo GPT-4, Claude, Gemini e muito mais através de uma única API.

Visão Geral

A integração com OpenRouter permite que suas tarefas agendadas:

  • Executem prompts com diferentes modelos de IA
  • Processem textos, imagens e arquivos
  • Gerem conteúdo automaticamente
  • Realizem análises e classificações
  • Integrem capacidades de IA em workflows

Pré-requisitos

  • Conta no OpenRouter
  • Créditos disponíveis na conta OpenRouter
  • Variáveis de ambiente configuradas no projeto

Configuração Passo a Passo

1. Criar Conta no OpenRouter

  1. Acesse openrouter.ai
  2. Clique em Sign Up no canto superior direito
  3. Faça login com GitHub, Google ou email
  4. Confirme seu email se necessário

2. Obter API Key

  1. Após login, acesse Keys
  2. Clique em Create Key
  3. Dê um nome descritivo (ex: "Tarefa AI Production")
  4. Defina limites opcionais:
    • Rate Limit: Requisições por minuto
    • Credit Limit: Gasto máximo em dólares
  5. Clique em Create e copie a chave

3. Adicionar Créditos

  1. Acesse Credits
  2. Clique em Add Credits
  3. Escolha o valor (mínimo $5)
  4. Complete o pagamento via cartão ou criptomoeda
  5. Aguarde confirmação (geralmente instantâneo)

4. Configurar Variáveis de Ambiente

Desenvolvimento Local (.env.local)

# OpenRouter Configuration
OPENROUTER_API_KEY=sk-or-v1-sua-chave-aqui
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
 
# Optional: Default settings
OPENROUTER_DEFAULT_MODEL=anthropic/claude-3.5-sonnet
OPENROUTER_SITE_URL=http://localhost:3000
OPENROUTER_SITE_NAME=Tarefa AI Dev

Produção (Vercel/Railway/Render)

No dashboard da sua plataforma de deploy:

  1. Acesse Settings → Environment Variables
  2. Adicione as variáveis:
    • OPENROUTER_API_KEY: Sua chave API
    • OPENROUTER_BASE_URL: https://openrouter.ai/api/v1
  3. Salve e faça redeploy se necessário

Vercel CLI:

vercel env add OPENROUTER_API_KEY
# Cole sua chave quando solicitado

Railway CLI:

railway variables set OPENROUTER_API_KEY=sk-or-v1-sua-chave

Docker Compose:

# docker-compose.yml
environment:
  OPENROUTER_API_KEY: ${OPENROUTER_API_KEY}
  OPENROUTER_BASE_URL: https://openrouter.ai/api/v1

5. Verificar Instalação

Execute o script de verificação:

npm run test:openrouter

Ou teste manualmente:

// test-openrouter.ts
import { generateText } from 'ai';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
 
const openrouter = createOpenRouter({
  apiKey: process.env.OPENROUTER_API_KEY,
});
 
async function test() {
  const result = await generateText({
    model: openrouter('anthropic/claude-3.5-sonnet'),
    prompt: 'Diga olá em português',
  });
  console.log(result.text);
}
 
test();

Modelos Disponíveis

Recomendados para Produção

ModeloPreço (1M tokens)VelocidadeContextoUso Recomendado
Claude 3.5 Sonnet$3.00 / $15.00Rápido200KAnálise, escrita, código
GPT-4 Turbo$10.00 / $30.00Médio128KTarefas complexas
Gemini 2.0 Flash$0.075 / $0.30Muito Rápido1MProcessamento em massa
Llama 3.1 70B$0.35 / $0.40Rápido128KCusto-benefício

Modelos Especializados

// Análise de imagens
const visionModel = openrouter('anthropic/claude-3.5-sonnet');
 
// Geração de código
const codeModel = openrouter('anthropic/claude-3.5-sonnet');
 
// Tarefas rápidas e baratas
const fastModel = openrouter('google/gemini-2.0-flash-exp:free');
 
// Reasoning avançado
const reasoningModel = openrouter('deepseek/deepseek-r1');

Acesse openrouter.ai/models para ver todos os 150+ modelos disponíveis com preços atualizados.


Exemplos Práticos

Exemplo 1: Tarefa de Resumo Diário

// src/lib/tasks/daily-summary.ts
import { generateText } from 'ai';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
 
const openrouter = createOpenRouter({
  apiKey: process.env.OPENROUTER_API_KEY,
});
 
export async function generateDailySummary(content: string) {
  try {
    const result = await generateText({
      model: openrouter('anthropic/claude-3.5-sonnet'),
      prompt: `Resuma o seguinte conteúdo em 3 pontos principais:\n\n${content}`,
      maxTokens: 500,
      temperature: 0.3,
    });
 
    return {
      success: true,
      summary: result.text,
      usage: result.usage,
    };
  } catch (error) {
    console.error('Erro ao gerar resumo:', error);
    return {
      success: false,
      error: error.message,
    };
  }
}

Exemplo 2: Análise de Sentimento

// src/lib/tasks/sentiment-analysis.ts
export async function analyzeSentiment(text: string) {
  const result = await generateObject({
    model: openrouter('anthropic/claude-3.5-sonnet'),
    schema: z.object({
      sentiment: z.enum(['positive', 'negative', 'neutral']),
      confidence: z.number().min(0).max(1),
      keywords: z.array(z.string()),
      summary: z.string(),
    }),
    prompt: `Analise o sentimento do seguinte texto: "${text}"`,
  });
 
  return result.object;
}
 
// Uso na tarefa agendada
const analysis = await analyzeSentiment('Este produto é incrível!');
console.log(analysis);
// {
//   sentiment: 'positive',
//   confidence: 0.95,
//   keywords: ['incrível', 'produto'],
//   summary: 'Avaliação extremamente positiva'
// }

Exemplo 3: Processamento de Imagens

// src/lib/tasks/image-analysis.ts
export async function analyzeImage(imageUrl: string) {
  const result = await generateText({
    model: openrouter('anthropic/claude-3.5-sonnet'),
    messages: [
      {
        role: 'user',
        content: [
          { type: 'text', text: 'Descreva esta imagem em detalhes' },
          { type: 'image', image: imageUrl },
        ],
      },
    ],
  });
 
  return result.text;
}

Exemplo 4: Geração de Conteúdo em Lote

// src/lib/tasks/batch-content.ts
export async function generateBatchContent(topics: string[]) {
  const results = await Promise.all(
    topics.map(async (topic) => {
      const result = await generateText({
        model: openrouter('google/gemini-2.0-flash-exp:free'), // Modelo rápido e barato
        prompt: `Escreva um parágrafo sobre: ${topic}`,
        maxTokens: 200,
      });
 
      return {
        topic,
        content: result.text,
        cost: result.usage,
      };
    })
  );
 
  return results;
}

Otimização e Boas Práticas

1. Controle de Custos

// src/lib/openrouter/cost-control.ts
const COST_LIMITS = {
  maxTokensPerRequest: 4000,
  maxCostPerDay: 10.0, // USD
  maxRequestsPerMinute: 60,
};
 
export async function executeWithCostControl(prompt: string) {
  // Verificar limite diário
  const todayCost = await getTodayCost();
  if (todayCost >= COST_LIMITS.maxCostPerDay) {
    throw new Error('Limite diário de custo atingido');
  }
 
  // Executar com limites
  const result = await generateText({
    model: openrouter('anthropic/claude-3.5-sonnet'),
    prompt,
    maxTokens: COST_LIMITS.maxTokensPerRequest,
  });
 
  // Registrar custo
  await logUsage(result.usage);
 
  return result;
}

2. Fallback de Modelos

// src/lib/openrouter/fallback.ts
const MODEL_PRIORITY = [
  'anthropic/claude-3.5-sonnet',
  'openai/gpt-4-turbo',
  'google/gemini-2.0-flash-exp:free',
];
 
export async function generateWithFallback(prompt: string) {
  for (const modelId of MODEL_PRIORITY) {
    try {
      const result = await generateText({
        model: openrouter(modelId),
        prompt,
      });
      return result;
    } catch (error) {
      console.warn(`Modelo ${modelId} falhou, tentando próximo...`);
      continue;
    }
  }
  throw new Error('Todos os modelos falharam');
}

3. Cache de Respostas

// src/lib/openrouter/cache.ts
import { Redis } from '@upstash/redis';
 
const redis = new Redis({
  url: process.env.UPSTASH_REDIS_URL!,
  token: process.env.UPSTASH_REDIS_TOKEN!,
});
 
export async function generateWithCache(prompt: string, ttl = 3600) {
  // Gerar hash do prompt
  const cacheKey = `openrouter:${hashPrompt(prompt)}`;
 
  // Verificar cache
  const cached = await redis.get(cacheKey);
  if (cached) return JSON.parse(cached as string);
 
  // Gerar se não existir
  const result = await generateText({
    model: openrouter('anthropic/claude-3.5-sonnet'),
    prompt,
  });
 
  // Armazenar em cache
  await redis.setex(cacheKey, ttl, JSON.stringify(result));
 
  return result;
}

4. Monitoramento de Uso

// src/lib/openrouter/monitoring.ts
export async function trackUsage(result: any) {
  await prisma.aiUsage.create({
    data: {
      model: result.model,
      promptTokens: result.usage.promptTokens,
      completionTokens: result.usage.completionTokens,
      totalCost: calculateCost(result),
      timestamp: new Date(),
    },
  });
}
 
// Dashboard de uso
export async function getUsageStats(days = 7) {
  const stats = await prisma.aiUsage.groupBy({
    by: ['model'],
    where: {
      timestamp: {
        gte: new Date(Date.now() - days * 24 * 60 * 60 * 1000),
      },
    },
    _sum: {
      promptTokens: true,
      completionTokens: true,
      totalCost: true,
    },
  });
 
  return stats;
}

Troubleshooting

Erro: "Invalid API Key"

Causa: Chave API incorreta ou expirada

Solução:

# Verificar se a variável está definida
echo $OPENROUTER_API_KEY
 
# Deve começar com sk-or-v1-
# Se não estiver definida, adicione ao .env.local

Erro: "Insufficient credits"

Causa: Créditos insuficientes na conta OpenRouter

Solução:

  1. Acesse openrouter.ai/credits
  2. Adicione mais créditos
  3. Aguarde confirmação (1-2 minutos)

Erro: "Rate limit exceeded"

Causa: Muitas requisições em curto período

Solução:

// Implementar rate limiting
import { Ratelimit } from '@upstash/ratelimit';
 
const ratelimit = new Ratelimit({
  redis,
  limiter: Ratelimit.slidingWindow(10, '1 m'), // 10 por minuto
});
 
export async function executeWithRateLimit(userId: string) {
  const { success } = await ratelimit.limit(userId);
  if (!success) {
    throw new Error('Rate limit excedido. Aguarde 1 minuto.');
  }
  // Continuar execução...
}

Erro: "Context length exceeded"

Causa: Prompt muito longo para o modelo

Solução:

// Truncar prompt
function truncatePrompt(text: string, maxTokens = 100000) {
  // Aproximadamente 4 caracteres = 1 token
  const maxChars = maxTokens * 4;
  if (text.length <= maxChars) return text;
 
  return text.slice(0, maxChars) + '\n\n[...truncado]';
}

Respostas Lentas

Causa: Modelo complexo ou prompt grande

Solução:

// Usar modelo mais rápido
const fastModel = openrouter('google/gemini-2.0-flash-exp:free');
 
// Ou usar streaming
const stream = await streamText({
  model: openrouter('anthropic/claude-3.5-sonnet'),
  prompt: 'Escreva um artigo longo...',
});
 
for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}

Monitoramento e Analytics

Dashboard do OpenRouter

Acesse openrouter.ai/activity para ver:

  • Requisições em tempo real
  • Gasto por modelo
  • Erros e latência
  • Uso por aplicação

Alertas Personalizados

Configure alertas no OpenRouter:

  1. Acesse Settings → Alerts
  2. Configure limites:
    • Gasto diário > $X
    • Taxa de erro > Y%
    • Créditos < $Z
  3. Adicione email ou webhook

Screenshot Placeholder

[INSERIR SCREENSHOT: Dashboard do OpenRouter mostrando gráficos de uso e custos]

Recursos Adicionais

Documentação Oficial

Comunidade

Suporte


Próximos Passos

Agora que você configurou o OpenRouter, explore:

Precisa de ajuda?

Consulte nosso guia completo de troubleshooting

Learn more