Skip to content

qcx/perseval

Repository files navigation

Perseval

Sistema de agentes autônomos para extração de questões de provas em PDF usando Cloudflare Agents SDK.

Arquitetura

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)                                        │
└─────────────────────────────────────────────────────────────────┘

Tecnologias

  • 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

Instalação

# 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-pdfs

Configuração

Variáveis de Ambiente

Crie um arquivo .dev.vars para desenvolvimento local:

OPENAI_API_KEY=sk-... # Opcional, para usar OpenAI ao invés de Workers AI

Wrangler

O arquivo wrangler.jsonc já está configurado com:

  • Bindings para os 3 agentes (Durable Objects)
  • Binding para Workers AI
  • Binding para R2 bucket

Uso

Desenvolvimento Local

npm run dev

Deploy

npm run deploy

API

Endpoints

POST /api/exams

Inicia 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"
}

GET /api/exams/:examId/status

Retorna o status da extração.

Response:

{
  "examId": "exam-1704538800000-abc123",
  "status": "extracting",
  "progress": {
    "total": 20,
    "extracted": 15,
    "percentage": 75
  },
  "errors": []
}

GET /api/exams/:examId/result

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
  }
}

GET /api/exams/:examId/markdown

Retorna o resultado em formato Markdown.

DELETE /api/exams/:examId

Remove um exame e seus resultados.

WebSocket (Agentes)

Conexão direta com agentes via WebSocket:

ws://localhost:8787/agents/orchestrator-agent/{examId}

Estrutura do Projeto

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

Formato de Saída

Questão Extraída

{
  "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
}

Limitações Conhecidas

  1. Extração de PDF: A extração de texto de PDFs complexos pode requerer serviços adicionais (OCR, Adobe PDF Services, etc.)

  2. Imagens: Imagens dentro de questões são identificadas mas não extraídas automaticamente

  3. Fórmulas Matemáticas: Conversão para LaTeX é baseada em heurísticas e pode não ser 100% precisa

  4. Rate Limits: Workers AI tem limites de requisições que podem afetar provas muito grandes

Melhorias Futuras

  • 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

Contribuindo

  1. Fork o repositório
  2. Crie uma branch para sua feature (git checkout -b feature/nova-feature)
  3. Commit suas mudanças (git commit -am 'Adiciona nova feature')
  4. Push para a branch (git push origin feature/nova-feature)
  5. Abra um Pull Request

Licença

MIT License - veja LICENSE para detalhes.

About

Autonomous agents for exam question extraction - Cloudflare Agents SDK

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published