Files
ia-microservice/app/services/document/evaluations_adapters.py
2026-03-31 20:00:04 -06:00

162 lines
5.9 KiB
Python

"""
Gateway de IA de Qualidot - Módulo de Adaptadores de Evaluación de Imágenes
Propósito:
Este módulo contiene funciones de adaptadores que permiten evaluar imágenes usando diferentes proveedores de IA.
Cada función de adaptador se encarga de interactuar con un proveedor específico (como OpenAI, AssemblyAI, Deepgram, etc.)
y de convertir la respuesta del proveedor al formato estándar de evaluación de imágenes de Qualidot.
"""
import json
import mimetypes
import mimetypes
import tempfile
import os
from fastapi import HTTPException
from matplotlib import image
from openai import OpenAI, AsyncOpenAI
import assemblyai as aai
from pyparsing.common import Any
from app.core.config import settings
from app.schemas.document_standard import DocumentRequestFile, StandardDocumentAnalysisResult
from app.core import config
from app.utilities.document_utilities import json_to_rubric, encode_document_from_bytes
from app.services.document.prompt_builder import build_document_evaluation_prompt
from anthropic import Anthropic
from app.utilities.image_utilities import encode_image_from_bytes
# Función de adaptador principal que infiere el proveedor y llama al adaptador específico
async def evaluate_document_with_provider(document_request: DocumentRequestFile) -> StandardDocumentAnalysisResult:
"""
Función de adaptador para evaluar documentos usando el proveedor de IA configurado.
"""
provider = document_request.provider.lower()
content = await document_request.rubric.read()
rubric_dict = json.loads(content)
rubric = json_to_rubric(rubric_dict)
prompt = build_document_evaluation_prompt(rubric)
match provider:
case "openai":
return await evaluate_with_openai(document_request, prompt)
case "claude":
return await evaluate_with_claude(document_request, prompt)
case "gemini":
return await evaluate_with_gemini(document_request, prompt)
case _:
raise ValueError(f"Proveedor de IA no soportado: {document_request.provider}")
# Función de adaptador para evaluar documentos usando OpenAI
async def evaluate_with_openai(document_request: DocumentRequestFile, prompt: str) -> StandardDocumentAnalysisResult:
"""
Función de adaptador para evaluar documentos usando OpenAI.
"""
client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY)
document_bytes = await document_request.file.read()
base64_document = encode_document_from_bytes(document_bytes)
media_type = document_request.file.content_type
try:
response = await client.chat.completions.create(
model=document_request.model,
messages=[
{"role": "user", "content": [
{"type": "text", "text": prompt},
{
"type": "file",
"file": {
"file_data": f"data:{media_type};base64,{base64_document}",
"filename": document_request.file.filename
}
}
]}
],
response_format={"type": "json_object"}
)
resultado = json.loads(response.choices[0].message.content)
return StandardDocumentAnalysisResult(
status="success",
original_filename=document_request.file.filename,
provider_used="openai",
model_used=document_request.model,
**resultado
)
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Error evaluando el documento: {str(e)}"
)
# Función de adaptador para evaluar documentos usando Claude
async def evaluate_with_claude(document_request: DocumentRequestFile, prompt: str) -> StandardDocumentAnalysisResult:
"""
Función de adaptador para evaluar documentos usando Claude.
"""
client = Anthropic(api_key=os.environ.get("ANTHROPIC_API_KEY"))
document_bytes = await document_request.file.read()
base64_document = encode_document_from_bytes(document_bytes)
media_type = document_request.file.content_type
if media_type not in ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"]:
raise ValueError(f"Tipo de documento no soportado por Anthropic: {media_type}")
try:
messages = [
{
"role": "user",
"content": [
{
"type": "document",
"source": {
"type": "base64",
"media_type": media_type,
"data": base64_document
},
},
{"type": "text", "text": prompt}
],
}
]
response = client.messages.create(
model=document_request.model,
max_tokens=4096,
messages=messages,
)
json_string = response.content[0].text
parsed_data = json.loads(json_string)
return StandardDocumentAnalysisResult(
status="success",
original_filename=document_request.file.filename,
provider_used="Claude",
model_used=document_request.model,
**parsed_data
)
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Error evaluando el documento: {str(e)}"
)
# Función de adaptador para evaluar documentos usando Gemini
async def evaluate_with_gemini(document_request: DocumentRequestFile, prompt: str) -> StandardDocumentAnalysisResult:
"""
Función de adaptador para evaluar documentos usando Gemini.
(Plantilla para futuras implementaciones)
"""
# Aquí iría la implementación específica para Gemini
pass