Sistema de agentes autônomos para extração de questões de provas em PDF usando Cloudflare Agents SDK.
O sistema utiliza uma arquitetura de múltiplos agentes que trabalham de forma coordenada:
┌─────────────────────────────────────────────────────────────────┐
│ Upload PDF │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ OrchestratorAgent │
│ • Analisa estrutura do PDF │
│ • Identifica quantidade de questões │
│ • Extrai textos de apoio │
│ • Coordena agentes extratores │
└─────────────────────────────────────────────────────────────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Extractor │ │ Extractor │ │ Extractor │ ... (1 por questão)
│ Agent Q1 │ │ Agent Q2 │ │ Agent QN │
│ │ │ │ │ │
│ • Extrai │ │ • Extrai │ │ • Extrai │
│ enunciado │ │ enunciado │ │ enunciado │
│ • Extrai │ │ • Extrai │ │ • Extrai │
│ opções │ │ opções │ │ opções │
│ • Valida │ │ • Valida │ │ • Valida │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
└───────────┼───────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ ConsolidatorAgent │
│ • Recebe todas as questões extraídas │
│ • Valida consistência │
│ • Resolve referências cruzadas │
│ • Gera documento final (JSON + Markdown) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ R2 Storage │
│ • exam.json (estruturado) │
│ • exam.md (visualização) │
└─────────────────────────────────────────────────────────────────┘
- Cloudflare Workers - Runtime serverless
- Cloudflare Agents SDK - Framework para agentes autônomos
- Cloudflare Durable Objects - Estado persistente dos agentes
- Cloudflare Workers AI - Modelos de IA para extração
- Cloudflare R2 - Armazenamento de PDFs e resultados
- Hono - Framework web leve
- TypeScript - Tipagem estática
# Clonar o repositório
git clone https://github.com/seu-usuario/exam-question-extractor.git
cd exam-question-extractor
# Instalar dependências
npm install
# Configurar Wrangler (se ainda não configurado)
npx wrangler login
# Criar bucket R2
npx wrangler r2 bucket create exam-pdfsCrie um arquivo .dev.vars para desenvolvimento local:
OPENAI_API_KEY=sk-... # Opcional, para usar OpenAI ao invés de Workers AIO arquivo wrangler.jsonc já está configurado com:
- Bindings para os 3 agentes (Durable Objects)
- Binding para Workers AI
- Binding para R2 bucket
npm run devnpm run deployInicia a extração de um novo exame.
Request:
{
"pdfUrl": "https://exemplo.com/prova.pdf",
"filename": "prova.pdf"
}Ou com Base64:
{
"pdfBase64": "JVBERi0xLjQK...",
"filename": "prova.pdf"
}Response:
{
"examId": "exam-1704538800000-abc123",
"status": "processing",
"message": "Iniciada extração de 20 questões"
}Retorna o status da extração.
Response:
{
"examId": "exam-1704538800000-abc123",
"status": "extracting",
"progress": {
"total": 20,
"extracted": 15,
"percentage": 75
},
"errors": []
}Retorna o resultado da extração em JSON.
Response:
{
"examId": "exam-1704538800000-abc123",
"result": {
"examInfo": {
"title": "Prova de Estatística",
"year": 2019,
"institution": "SELECON",
"duration": "2h",
"totalQuestions": 20,
"subjects": [...]
},
"supportTexts": [...],
"questions": [...],
"extractedAt": "2024-01-06T12:00:00Z",
"totalProcessingTime": 45000,
"successRate": 0.95
}
}Retorna o resultado em formato Markdown.
Remove um exame e seus resultados.
Conexão direta com agentes via WebSocket:
ws://localhost:8787/agents/orchestrator-agent/{examId}
exam-question-extractor/
├── src/
│ ├── agents/
│ │ ├── OrchestratorAgent.ts # Agente coordenador
│ │ ├── QuestionExtractorAgent.ts # Agente extrator
│ │ └── ConsolidatorAgent.ts # Agente consolidador
│ ├── types/
│ │ └── index.ts # Definições de tipos
│ ├── utils/
│ │ ├── pdf.ts # Utilitários para PDF
│ │ └── formatting.ts # Formatação e validação
│ └── index.ts # Entry point e rotas
├── tests/
│ └── ... # Testes
├── docs/
│ └── ... # Documentação adicional
├── wrangler.jsonc # Configuração Cloudflare
├── tsconfig.json # Configuração TypeScript
├── package.json # Dependências
└── README.md # Este arquivo
{
"number": 1,
"subject": "Língua Portuguesa",
"supportTextId": "texto_1",
"statement": "O autor, para dar credibilidade às ideias expostas, faz uso de variados recursos...",
"options": [
{
"letter": "A",
"text": "citação de outro autor especializado na questão da saúde..."
},
{
"letter": "B",
"text": "abordagem de um problema comprovando sua gravidade..."
},
{
"letter": "C",
"text": "descrição impessoal, com neutralidade, puramente objetiva..."
},
{
"letter": "D",
"text": "predomínio da flexão dos verbos no pretérito do modo indicativo..."
}
],
"images": [],
"tables": [],
"formulas": [],
"pageNumber": 2,
"extractedAt": "2024-01-06T12:00:00Z",
"confidence": 0.95
}-
Extração de PDF: A extração de texto de PDFs complexos pode requerer serviços adicionais (OCR, Adobe PDF Services, etc.)
-
Imagens: Imagens dentro de questões são identificadas mas não extraídas automaticamente
-
Fórmulas Matemáticas: Conversão para LaTeX é baseada em heurísticas e pode não ser 100% precisa
-
Rate Limits: Workers AI tem limites de requisições que podem afetar provas muito grandes
- Integração com serviço de OCR para PDFs escaneados
- Suporte a mais formatos de prova
- Extração de imagens e diagramas
- Interface web para upload e visualização
- Exportação para formatos adicionais (DOCX, HTML)
- Detecção automática de gabarito
- Suporte a questões discursivas
- Fork o repositório
- Crie uma branch para sua feature (
git checkout -b feature/nova-feature) - Commit suas mudanças (
git commit -am 'Adiciona nova feature') - Push para a branch (
git push origin feature/nova-feature) - Abra um Pull Request
MIT License - veja LICENSE para detalhes.