Pular para conteúdo

Schema de saída estruturada

Por que usar JSON

Texto livre é bom para leitura humana, mas ruim para sistemas. O SotuHire precisa exibir score, listas, alertas e mensagens de forma organizada. Por isso, a resposta da IA deve seguir um schema.

A Gemini API oferece suporte a saídas estruturadas, e a documentação oficial recomenda o SDK google-genai para Python. Consulte:

Schema inicial

{
  "match_score": 82,
  "recommendation": "Aplicar",
  "seniority_fit": "Estágio/Júnior",
  "summary": "Resumo curto da análise.",
  "strong_points": [
    "Engenharia da Computação",
    "Projetos com IA e automação"
  ],
  "weak_points": [
    "Falta experiência profissional direta com IA em produção"
  ],
  "missing_keywords": [
    "Power BI",
    "dashboards"
  ],
  "ats_notes": [
    "Currículo possui texto extraível",
    "Seção de projetos poderia destacar mais palavras-chave"
  ],
  "risk_flags": [
    "Vaga menciona inglês avançado"
  ],
  "recommended_actions": [
    "Destacar projetos de automação no currículo",
    "Adaptar resumo profissional para dados e IA"
  ],
  "recruiter_message": "Olá! Vi a oportunidade..."
}

Modelo Pydantic sugerido

from pydantic import BaseModel, Field
from typing import Literal

class MatchAnalysis(BaseModel):
    match_score: int = Field(ge=0, le=100)
    recommendation: Literal[
        "Aplicar",
        "Aplicar com cautela",
        "Revisar antes de aplicar",
        "Não aplicar",
    ]
    seniority_fit: str
    summary: str
    strong_points: list[str]
    weak_points: list[str]
    missing_keywords: list[str]
    ats_notes: list[str]
    risk_flags: list[str]
    recommended_actions: list[str]
    recruiter_message: str

Extensão futura do schema

Quando o SotuHire passar a usar Lattes, GitHub, LinkedIn e portais como fontes explícitas, o schema pode evoluir para:

{
  "resume_type_detected": "ats_resume",
  "source_profiles_used": ["pdf_resume", "lattes", "github"],
  "source_portal": "gupy",
  "portal_strategy": "manual_url_and_text",
  "ats_score": 78,
  "academic_score": 64,
  "portfolio_score": 82,
  "risk_score": 30,
  "lattes_relevant_items": [],
  "github_relevant_projects": [],
  "recommended_resume_version": "ats_resume_for_data_internship"
}

Esses campos ajudam a separar:

  • qualidade ATS;
  • aderência semântica;
  • relevância acadêmica;
  • força dos projetos;
  • risco da fonte/vaga;
  • recomendação de versão do currículo.

Validações

O sistema deve validar:

  • match_score entre 0 e 100;
  • listas sempre como listas;
  • mensagem não vazia;
  • recomendação dentro dos valores permitidos;
  • score coerente com recomendação.

Fallback

Se a IA retornar JSON inválido:

  1. tentar corrigir uma vez;
  2. se falhar, mostrar erro amigável;
  3. registrar o erro sem salvar dados sensíveis;
  4. permitir nova tentativa.

Combinação com regras determinísticas

O JSON da IA não deve ser autoridade absoluta. Exemplo:

  • IA retorna 82;
  • regra detecta sênior e 5+ anos;
  • sistema ajusta para 45 ou mostra alerta forte.

Isso evita score bonito para vaga incompatível.


Schema expandido de análise completa

{
  "match_score": 82,
  "ats_score": 76,
  "risk_score": 18,
  "linkedin_score": 70,
  "portfolio_score": 84,
  "lattes_score": null,
  "readiness_score": 79,
  "recommendation": "Aplicar com ajustes",
  "evidence": [],
  "strengths": [],
  "gaps": [],
  "missing_keywords": [],
  "best_projects_to_highlight": [],
  "linkedin_actions": [],
  "portfolio_actions": [],
  "message_to_recruiter": "",
  "next_follow_up_days": 5,
  "risk_flags": []
}

Regras para IA

  • Nunca inventar experiência.
  • Nunca alterar fatos do currículo.
  • Sempre separar evidência de sugestão.
  • Sempre indicar quando faltam dados.
  • Sempre devolver JSON válido.
  • Sempre permitir revisão humana antes de ação externa.

Atualização: Pydantic como contrato principal

O SotuHire deve usar Pydantic para validar toda saída de IA que tenha efeito no produto. Isso inclui análise de vaga, currículo direcionado, profile score e portfolio score.

Schemas novos:

  • JobAnalysisSchema
  • UserPreferences
  • ResumeTailorOutput
  • TailoredResumeSection
  • JSONResume
  • CareerEvidence

Regra:

Sem schema, a saída da IA é rascunho.
Com schema validado, a saída pode entrar no produto.

Referências:

Atualização: schemas por função

A v0.10.0 iniciou a separação de schemas por função, em vez de depender de um único schema de análise completa.

Schemas implementados nesta base:

  • ResumeExtractionOutput;
  • JobExtractionOutput;
  • DomainClassificationOutput.

Schemas ainda planejados:

  • ATSAnalysisOutput;
  • MatchEvidenceOutput;
  • ResumeTailorOutput;
  • GitHubRepoAnalysisOutput;
  • HiddenJobDetectionOutput.

Arquivos:

  • modules/ai/schemas/resume_extraction.py;
  • modules/ai/schemas/job_extraction.py;
  • modules/ai/schemas/domain_classification.py.

Regra de entrada no produto

Output de IA só pode entrar no produto se passar no schema.

Se falhar:

  1. tentar reparo de JSON;
  2. validar novamente;
  3. se falhar, mostrar erro revisável;
  4. não salvar como análise final;
  5. preservar fallback local.

Confidence por campo

Campos críticos devem ter confidence:

  • senioridade;
  • domínio profissional;
  • requisito obrigatório;
  • formação;
  • credencial;
  • registro profissional;
  • salário;
  • modalidade;
  • localidade;
  • evidência de experiência;
  • score sugerido.

Schema de requisito

{
  "text": "string",
  "normalized_name": "string",
  "category": "education | hard_skill | soft_skill | tool | software | equipment | certification | professional_license | language | experience | methodology | regulation | responsibility | availability | location | portfolio | other",
  "importance": "required | preferred | optional | unclear",
  "criticality": "low | medium | high | knockout",
  "evidence": "string",
  "confidence": 0.0
}

Schema de evidência

{
  "claim": "string",
  "source": "resume | job | github | portfolio | memory | tracker | user_input",
  "source_ref": "string | null",
  "evidence_type": "text | file | config | readme | workflow | project | experience | education | credential",
  "confidence": 0.0
}

Schema de confidence geral

{
  "overall": 0.0,
  "low_confidence_fields": ["string"],
  "needs_user_review": true,
  "reason": "string"
}

Relação com Prompt Catalog

Os detalhes completos de cada output ficam em Prompt Catalog.