Spaces:
Sleeping
Sleeping
Adzacam commited on
Commit 路
68485d3
1
Parent(s): 5f553ce
feat: integrate MLOps memory lookup and fuzzy matching into nlp analysis endpoint
Browse files
app.py
CHANGED
|
@@ -342,15 +342,48 @@ def procesar_registro_tabular(payload: ProcessSheetPayload, db: Session = Depend
|
|
| 342 |
raise HTTPException(status_code=500, detail=str(err))
|
| 343 |
|
| 344 |
@app.post("/api/v1/nlp/analyze")
|
| 345 |
-
def analyze_nlp_only(payload: ProcessSheetPayload):
|
| 346 |
"""
|
| 347 |
Fase 1: Solo ejecuta el modelo NLP (BETO) sobre el texto y devuelve las m茅tricas.
|
| 348 |
NO inserta en la base de datos. Usado para el Staging area en el Frontend.
|
| 349 |
"""
|
| 350 |
entidades = ner_engine.extract_entities(payload.texto_celda)
|
| 351 |
confianza_ia = sum([e["score"] for e in entidades]) / len(entidades) if entidades else 1.0
|
| 352 |
-
|
| 353 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 354 |
alertas_disparadas = []
|
| 355 |
if payload.nota_detectada <= 70.0:
|
| 356 |
alertas_disparadas.append("RIESGO_ACADEMICO_CRITICO")
|
|
@@ -361,7 +394,11 @@ def analyze_nlp_only(payload: ProcessSheetPayload):
|
|
| 361 |
"status": "analyzed",
|
| 362 |
"confianza_modelo_beto": round(confianza_ia, 4),
|
| 363 |
"requiere_auditoria_humana": forzar_revision,
|
| 364 |
-
"alertas_estrategicas": alertas_disparadas
|
|
|
|
|
|
|
|
|
|
|
|
|
| 365 |
}
|
| 366 |
|
| 367 |
@app.post("/api/v1/nlp/quality-check")
|
|
|
|
| 342 |
raise HTTPException(status_code=500, detail=str(err))
|
| 343 |
|
| 344 |
@app.post("/api/v1/nlp/analyze")
|
| 345 |
+
def analyze_nlp_only(payload: ProcessSheetPayload, db: Session = Depends(get_db)):
|
| 346 |
"""
|
| 347 |
Fase 1: Solo ejecuta el modelo NLP (BETO) sobre el texto y devuelve las m茅tricas.
|
| 348 |
NO inserta en la base de datos. Usado para el Staging area en el Frontend.
|
| 349 |
"""
|
| 350 |
entidades = ner_engine.extract_entities(payload.texto_celda)
|
| 351 |
confianza_ia = sum([e["score"] for e in entidades]) / len(entidades) if entidades else 1.0
|
| 352 |
+
nombre_resuelto = payload.texto_celda[:200].strip()
|
| 353 |
|
| 354 |
+
# 1. Consultar log_auditoria_nlp (MLOps Memory)
|
| 355 |
+
log_memoria = db.query(LogAuditoriaNlp).filter(
|
| 356 |
+
LogAuditoriaNlp.texto_original == nombre_resuelto
|
| 357 |
+
).order_by(LogAuditoriaNlp.created_at.desc()).first()
|
| 358 |
+
|
| 359 |
+
candidatos_difusos = []
|
| 360 |
+
regla_aplicada = False
|
| 361 |
+
|
| 362 |
+
if log_memoria:
|
| 363 |
+
# BETO "recuerda" la decisi贸n humana previa
|
| 364 |
+
nombre_resuelto = log_memoria.correccion_humana
|
| 365 |
+
confianza_ia = 1.0
|
| 366 |
+
forzar_revision = False
|
| 367 |
+
regla_aplicada = True
|
| 368 |
+
else:
|
| 369 |
+
# Fuzzy Matching
|
| 370 |
+
estudiantes_existentes = db.query(DimEstudiante).all()
|
| 371 |
+
best_match, score = find_best_match(nombre_resuelto, estudiantes_existentes)
|
| 372 |
+
|
| 373 |
+
# Generar Top 3 candidatos para el dropdown de resoluci贸n
|
| 374 |
+
from rapidfuzz import fuzz
|
| 375 |
+
for est in estudiantes_existentes:
|
| 376 |
+
s = fuzz.token_sort_ratio(nombre_resuelto.lower(), est.nombre_completo.lower()) / 100.0
|
| 377 |
+
if s > 0.4:
|
| 378 |
+
candidatos_difusos.append({"id": est.id_estudiante, "nombre": est.nombre_completo, "score": round(s, 2)})
|
| 379 |
+
|
| 380 |
+
candidatos_difusos = sorted(candidatos_difusos, key=lambda x: x["score"], reverse=True)[:3]
|
| 381 |
+
|
| 382 |
+
if score > 0.8:
|
| 383 |
+
confianza_ia = score
|
| 384 |
+
|
| 385 |
+
forzar_revision = confianza_ia < 0.60
|
| 386 |
+
|
| 387 |
alertas_disparadas = []
|
| 388 |
if payload.nota_detectada <= 70.0:
|
| 389 |
alertas_disparadas.append("RIESGO_ACADEMICO_CRITICO")
|
|
|
|
| 394 |
"status": "analyzed",
|
| 395 |
"confianza_modelo_beto": round(confianza_ia, 4),
|
| 396 |
"requiere_auditoria_humana": forzar_revision,
|
| 397 |
+
"alertas_estrategicas": alertas_disparadas,
|
| 398 |
+
"entidades_nlp": entidades,
|
| 399 |
+
"candidatos_difusos": candidatos_difusos,
|
| 400 |
+
"regla_memoria_aplicada": regla_aplicada,
|
| 401 |
+
"nombre_resuelto": nombre_resuelto
|
| 402 |
}
|
| 403 |
|
| 404 |
@app.post("/api/v1/nlp/quality-check")
|