Pular para o conteúdo
OpENEMdocs

DocumentaçãoPara quem hospeda

Inteligência artificial

Como ligar um provedor de IA no OpENEM, o que usa IA (comentário de questão e classificação de assunto) e como limitar o custo com cotas.

A IA é opcional. Sem nenhum provedor configurado, o app funciona normalmente e só os recursos desta página ficam indisponíveis. As chamadas são pagas pela chave de quem hospeda a instância, por isso vale ler a parte de cotas antes de ligar.

O que usa IA

Comentário de questão sob demanda

As provas oficiais chegam sem comentário. Depois de responder, o aluno vê o botão Ver comentário. Na primeira vez que alguém pede, a API (POST /api/v1/questions/:id/explanation) gera o comentário, grava no banco e o devolve; os alunos seguintes recebem o texto gravado, sem nova chamada. O app avisa que o comentário foi gerado por IA e pode conter erros, e o prompt manda a IA nunca contradizer o gabarito oficial.

Sem provedor, o botão responde que a questão ainda não tem comentário. Esse recurso usa AI_PROVIDER e AI_EXPLANATION_MODEL, gasta a cota AI_EXPLANATION_DAILY_LIMIT e tem um limite próprio de 10 pedidos por minuto por aluno.

Classificação de assunto

O import entrega as questões oficiais só com a área. Revisão espaçada, mapa de calor e recomendação trabalham por assunto, então a questão sem assunto fica de fora deles. A classificação por palavra-chave, que roda sem IA no bootstrap, resolve parte do banco; o script de IA cuida do resto. Ele não roda pelo app: quem hospeda executa pelo terminal.

docker compose exec backend node dist-scripts/prisma/classify-questions.js --limit=50 --dry-run
docker compose exec backend node dist-scripts/prisma/classify-questions.js

Opções: --dry-run mostra as decisões sem gravar, --limit e --area restringem o lote, e --min-confidence (padrão 0.6) define a confiança mínima para gravar o assunto. O script usa AI_PROVIDER e AI_CLASSIFY_MODEL. Ele percorre milhares de questões, então prefira um modelo barato. Como AI_CLASSIFY_MODEL não passa pelo compose, informe-o na própria chamada:

docker compose exec -e AI_CLASSIFY_MODEL=<modelo barato do seu provedor> backend node dist-scripts/prisma/classify-questions.js

O script não passa pelas cotas por aluno.

Provedores

ProvedorLigado porModelo padrão
anthropicANTHROPIC_API_KEYANTHROPIC_MODEL, senão claude-opus-4-8
openaiOPENAI_API_KEYOPENAI_MODEL, senão gpt-4o
geminiGEMINI_API_KEY (ou GOOGLE_API_KEY)GEMINI_MODEL, senão gemini-2.5-flash
openai-compatibleOPENAI_BASE_URLOPENAI_MODEL, senão llama3.1

O provedor openai-compatible atende servidores que imitam a API da OpenAI, como Ollama, Groq, OpenRouter, LM Studio e vLLM. A chave é opcional, porque servidores locais não pedem autenticação. Como nem todo servidor aceita schema estrito de JSON, nesse modo a API pede só um objeto JSON e descreve o formato no prompt.

Como o provedor é escolhido

  1. O comentário de questão e a classificação usam AI_PROVIDER.
  2. Sem variável, vale o primeiro provedor configurado nesta ordem: anthropic, openai, gemini, openai-compatible.

Um provedor escolhido por variável mas sem chave não cai em outro: o recurso fica indisponível.

No Docker Compose

Coloque a chave e o modelo no .env da raiz:

ANTHROPIC_API_KEY=<sua chave>
ANTHROPIC_MODEL=claude-opus-4-8
AI_DAILY_LIMIT=500
  • Defina sempre o modelo do provedor (ANTHROPIC_MODEL, OPENAI_MODEL ou GEMINI_MODEL). Sem ele no .env, o compose repassa a variável vazia e o backend usa o modelo vazio em vez do padrão.
  • O compose repassa AI_PROVIDER, as chaves, os modelos, OPENAI_BASE_URL e as cotas. AI_EXPLANATION_MODEL, AI_CLASSIFY_MODEL e GOOGLE_API_KEY não chegam ao container; use um docker-compose.override.yml, como em Variáveis de ambiente.
  • Dentro do container, localhost é o próprio container. Um OPENAI_BASE_URL apontando para http://localhost:11434/v1 não alcança um Ollama rodando no host.

Depois de mudar o .env, recrie o backend com docker compose up -d.

Cotas e custo

O rate limiting não segura custo: o cadastro é livre, e cada conta nova teria o próprio limite. Por isso as chamadas pagas passam por uma cota por aluno, guardada no banco (tabela AiUsage), numa janela móvel de 24 horas, e por um teto global opcional.

VariávelPadrãoConta
AI_EXPLANATION_DAILY_LIMIT30comentários gerados por aluno
AI_DAILY_LIMIT0 (sem teto)todas as chamadas de todos os alunos
  • 0 desliga o limite correspondente.
  • Quem passa do limite recebe HTTP 429.
  • A cota é reservada antes da chamada ao provedor: uma chamada que falha também conta.
  • Abrir um comentário já gravado não gasta cota. Se dois alunos pedem o mesmo comentário ao mesmo tempo, a API faz uma chamada só (também entre instâncias, com uma trava no Redis), mas o pedido conta na cota de cada um.
Sugerir uma correção nesta página