Lección 230 · 25 min · Gratis

Guía práctica de modelos OpenAI (parte 2 de 2)

2.6. Revisión humana:

El plan final generado por la IA se presenta al científico humano a través de una interfaz para su validación, posibles ediciones y aprobación final.

def human_review(safety_package: Dict[str, Any], ctx: Context):
    logging.info("Awaiting human review...")
    protocol = safety_package["protocol"]
    safety_assessment = safety_package["safety"]
    
    print(f"\n=== PROTOCOL FOR REVIEW: {ctx.compound} - {ctx.goal} ===")
    print(f"DETAILS: {json.dumps(protocol, indent=2)}")
    print(f"SAFETY: {json.dumps(safety_assessment, indent=2)}")
    
    while True:
        approval = input("\nApprove for execution? (yes/no): ").lower()
        if approval in ['yes', 'y', 'no', 'n']:
            approved = approval in ['yes', 'y']
            logging.info(f"Protocol {'approved' if approved else 'rejected'}")
            return {"protocol": protocol, "approved": approved}
        print("Please enter 'yes' or 'no'")

human_decision = human_review(secured, ctx)
Awaiting human review...
=== PROTOCOL FOR REVIEW: XYZ-13 - Improve synthesis yield by 15% ===
DETAILS: {
  "protocol_title": "Optimised In-Situ Pd(0)/PPh3 Coupling for XYZ-13 \u2013 Target \u2265 72 % Yield",
  "key_changes_vs_original": [
    "Catalyst loading reduced from 5 mol % to 2 mol % Pd to cut cost and metal contamination without loss of activity.",
    "Reaction run at 0.10 M substrate concentration (12 mL solvent total) instead of 50 mL; higher effective collision frequency boosts conversion and reduces waste.",
    "Single solvent system (toluene/DMF 4:1) avoids phase separation and simplifies work-up.",
    "Redundant triethylamine removed; K2CO3 (2.5 eq) provides sufficient basicity.",
    "Reaction temperature raised slightly to 80 \u00b0C (still below side-reaction threshold found in exp-001) and time shortened to 24 h with in-process HPLC check at 6 h intervals.",
    "Work-up switched from large silica column to two-step: (a) aqueous EDTA wash to strip Pd, (b) recrystallisation from EtOAc/hexane \u2013 typically 5\u20138 % higher isolated yield on this substrate."
  ],
  "objective": "Isolated yield \u2265 72 % within 24 h, total direct cost \u2264 US $5 000.",
  "scale": "0.5 mmol XYZ-13 (170 mg, assume MW \u2248 340).",
  "reagents": [
    {
      "name": "Palladium chloride",
      "amount": 0.02,
      "unit": "g",
      "role": "precatalyst (2 mol %)"
    },
    {
      "name": "Triphenylphosphine",
      "amount": 0.041,
      "unit": "g",
      "role": "ligand (2 eq vs Pd)"
    },
    {
      "name": "Sodium borohydride",
      "amount": 0.02,
      "unit": "g",
      "role": "Pd(II)\u2192Pd(0) reducer"
    },
    {
      "name": "Potassium carbonate",
      "amount": 0.345,
      "unit": "g",
      "role": "base (2.5 eq)"
    },
    {
      "name": "Dimethylformamide",
      "amount": 2.0,
      "unit": "mL",
      "role": "co-solvent (20 %)"
    },
    {
      "name": "Toluene",
      "amount": 10.0,
      "unit": "mL",
      "role": "primary solvent (80 %)"
    }
  ],
  "equipment": [
    "50 mL round-bottom flask",
    "magnetic stirrer",
    "reflux condenser",
    "argon line"
  ],
  "reaction_conditions": {
    "atmosphere": "Ar",
    "temperature": "80 \u00b0C (oil bath)",
    "duration": "24 h",
    "stirring": "600 rpm"
  },
  "procedure": [
    "1. Charge dry 50 mL flask with PdCl2 (20 mg) and PPh3 (41 mg) under Ar. Add DMF (2 mL) and stir 5 min.",
    "2. Add NaBH4 (20 mg) portion-wise over 3 min; colour turns dark brown.",
    "3. Add XYZ-13 (170 mg, 0.50 mmol) and K2CO3 (345 mg). Add toluene (10 mL). Fit condenser.",
    "4. Heat to 80 \u00b0C for 24 h. Take 0.1 mL aliquots at 6, 12, 18 h; quench in NH4Cl and analyse by HPLC to confirm \u2265 95 % conversion.",
    "5. Cool to RT, add 10 mL 0.05 M EDTA (aq) and stir 5 min to complex Pd. Separate layers, extract aqueous twice with 5 mL toluene.",
    "6. Combine organic layers, wash with brine, dry (Na2SO4), filter, concentrate in vacuo.",
    "7. Recrystallise residue from 4:1 hexane/EtOAc (15 mL) to afford XYZ-13 as off-white solid. Record mass, calculate yield, check purity by HPLC."
  ],
  "expected_outcome": {
    "projected_yield": "72\u201378 %",
    "purity": "\u2265 97 % (HPLC)"
  },
  "safety_and_waste": [
    "NaBH4 generates H2; add slowly behind blast shield.",
    "DMF and toluene are toxic/flammable \u2013 use fume hood.",
    "EDTA washwater and Pd residues collected for heavy-metal disposal.",
    "Standard PPE (lab coat, gloves, goggles)."
  ],
  "cost_estimate_USD": {
    "reagents": 1120,
    "equipment_amortisation": 150,
    "labor (24 h @ $75/h)": 1800,
    "total": 3070
  }
}
SAFETY: {
  "hazards": [
    {
      "chemical": "Sodium borohydride",
      "hazard": "Flammable, water-reactive",
      "unsafe_condition": "Adding NaBH4 portion-wise generates hydrogen gas (H2) which is explosive; requires slow addition behind blast shield and in well-ventilated fume hood."
    },
    {
      "chemical": "Dimethylformamide",
      "hazard": "Reproductive toxin, flammable",
      "compliance": "Use only in fume hood with appropriate PPE to avoid inhalation exposure; handle with care due to reproductive toxicity."
    },
    {
      "chemical": "Toluene",
      "hazard": "Flammable, CNS depressant",
      "compliance": "Use in fume hood and avoid ignition sources; ensure proper ventilation to minimize exposure."
    },
    {
      "chemical": "Palladium chloride",
      "hazard": "Irritant, potential carcinogen",
      "compliance": "Minimize exposure; use gloves and handle in fume hood. Collect and dispose of Pd-containing waste as hazardous heavy metal waste."
    },
    {
      "chemical": "Potassium carbonate",
      "hazard": "Irritant",
      "compliance": "Use gloves to prevent skin irritation."
    },
    {
      "chemical": "Triphenylphosphine",
      "hazard": "Irritant",
      "compliance": "Use gloves and avoid inhalation of dust."
    }
  ],
  "unsafe_conditions": [
    {
      "condition": "Reaction temperature at 80 \u00b0C with flammable solvents (toluene, DMF)",
      "recommendation": "Ensure all heating apparatus is explosion-proof; maintain constant stirring to avoid hot spots."
    },
    {
      "condition": "Use of Argon atmosphere",
      "recommendation": "Ensure proper inert gas handling to prevent oxygen contamination; adequate ventilation to prevent asphyxiation risk."
    }
  ],
  "compliance_issues": [
    {
      "issue": "Hydrogen gas evolution during NaBH4 addition",
      "recommendation": "Add NaBH4 slowly behind blast shield, wear full PPE including face shield, and perform operation in a well-ventilated fume hood."
    },
    {
      "issue": "Heavy metal waste handling",
      "recommendation": "Collect EDTA wash water and palladium residues separately and dispose as hazardous heavy metal waste in compliance with local regulations."
    },
    {
      "issue": "PPE not explicitly stating face shield",
      "recommendation": "Recommend including face shield during NaBH4 addition step for splash and blast protection."
    }
  ],
  "general_comments": [
    "The protocol includes appropriate solvent proportions and reaction scale to reduce waste and cost.",
    "The use of EDTA wash for palladium removal and dual solvent recrystallization is a safer, more efficient approach than large silica columns.",
    "The procedural timing with intermittent HPLC monitoring is good practice to avoid over-reaction and side products.",
    "Standard lab safety practices are advised including lab coat, gloves, and goggles; upgrading to include face shield for hazardous steps is recommended.",
    "No major equipment safety issues identified with specified items. Ensure all glassware is rated for heating and inert atmosphere."
  ]
}
Protocol approved

2.7. Ejecución y aprendizaje (o3 + Code Interpreter):

Una vez que el humano lo aprueba, el plan se envía para su ejecución en el laboratorio. Después de la ejecución en el laboratorio, los resultados se retroalimentan al sistema. o3 combinado con el Code Interpreter analiza los datos, genera información y almacena los resultados estructurados (protocolo, parámetros, resultados, información) en una base de datos (Outcome DB). Esta base de datos informa los futuros ciclos de ideación, creando un bucle de aprendizaje.

# Simulating execution and analyzing results
ANALYSIS_PROMPT = """You are a data analyst. 
Did the experiment achieve {goal}?  Analyse factors, suggest improvements, and return structured JSON.
"""

def execute_and_analyse(pkt: Dict[str, Any], ctx: Context):
    logging.info("Starting mock execution and analysis...")
    # These are mock results for a lab experiment
    mock_results = {
        "yield_improvement": 12.5,
        "success": False,
        "actual_cost": ctx.budget * 0.85,
        "notes": "Mock execution"
    }
    sys = ANALYSIS_PROMPT.format(**ctx.prompt_vars())
    usr = json.dumps({"protocol": pkt, "results": mock_results}, indent=2)
    analysis = call_openai(ctx.client, MODEL_CRITIQUE, sys, usr, ctx)
    log_json("analysis", analysis, ctx)
    return analysis

# Only proceed to execution if approved by the human reviewer
if human_decision["approved"]:
    summary = execute_and_analyse(human_decision, ctx)
    logging.info("Analysis complete")
else:
    logging.info("Protocol rejected by human reviewer - execution skipped")
    summary = None

Path("output").mkdir(exist_ok=True)
out_path = Path("output") / f"{ctx.run_id}_summary.json"
out_path.write_text(json.dumps(summary, indent=2))
print(f"\n🎉 Completed. Summary written to {out_path}")
Starting mock execution and analysis...
HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
(Tool) Literature search: Pd(0) PPh3 coupling yield optimization EDTA work-up recrystallization losses, None, 3
HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
(Tool) Outcome DB: XYZ-13, yield, 5
HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
Analysis complete
🎉 Completed. Summary written to output/9835f69c_summary.json

3. Manual del modelo

La elección entre o4-mini y o3 depende de la complejidad de la tarea y la profundidad requerida. Para otras tareas, gpt-4.1-mini ofrece un equilibrio entre costo y rendimiento, y se recomienda el más potente gpt4.1 cuando se necesita mayor capacidad o matices.

Tarea Empieza con Actualiza cuando... Escala a Justificación
Ideación y generación de protocolos o4-mini Las hipótesis carecen de la profundidad o creatividad necesarias para la síntesis química compleja. o3 o4-mini genera rápidamente diversos protocolos de forma rentable. o3 proporciona un razonamiento científico más profundo cuando se requieren enfoques más matizados.
Clasificación de protocolos o4-mini La comparación requiere una evaluación científica más profunda o compensaciones multifactoriales. o3 La clasificación estilo torneo con o4-mini identifica eficientemente candidatos prometedores. Escala cuando se necesita evaluar una validez científica sutil.
Crítica profunda y síntesis o3 N/A - Ya se está utilizando el modelo más capaz para esta tarea crítica. N/A o3 sobresale en la revisión científica rigurosa, identificando fallas metodológicas y sintetizando mejoras en protocolos complejos. Esta tarea requiere inherentemente un razonamiento profundo.
Evaluación de seguridad gpt-4.1-mini Los peligros específicos del dominio requieren mayor precisión o conocimiento especializado. gpt-4.1 gpt-4.1-mini ofrece un buen equilibrio entre costo y rendimiento para las verificaciones de seguridad estándar. Escala a gpt4.1 cuando se necesita mayor precisión o un razonamiento más matizado para riesgos de seguridad complejos.

Idea clave:

Este caso de uso ejemplifica un patrón poderoso: usar modelos más rápidos y económicos (o4-mini) para amplitud y filtrado inicial, luego escalar a modelos más potentes (o3) para profundidad, revisión crítica y síntesis. Este enfoque en capas optimiza tanto la creatividad/velocidad como el rigor/precisión, mientras gestiona los costos computacionales de manera efectiva. La integración con herramientas es esencial para basar el razonamiento de la IA en datos verificables del mundo real.

4. Notas de implementación

La transición del Co-Científico de IA de prototipo a uso en laboratorio implica una planificación cuidadosa.

  • Control de costos:
    • Implementa "modos" configurables (como Fast, Standard, Thorough) que ajustan el número de agentes de ideación o4-mini, la profundidad de la crítica o3 o el uso de verificaciones opcionales para equilibrar la calidad de los resultados con el costo y la latencia.
    • Rastrea el uso de tokens por etapa (ideación, clasificación, crítica) y por llamada a la herramienta para un monitoreo de costos detallado.
  • Observabilidad:
    • Registra entradas, salidas, elecciones de modelos, llamadas/respuestas de herramientas, latencias y recuentos de tokens para cada paso.
    • Monitorea el rendimiento de la clasificación por torneo y el impacto de las críticas o3 (como la frecuencia con la que los planes se alteran o rechazan significativamente).
    • Rastrea las interacciones del usuario: qué planes son aprobados, editados o rechazados por el científico humano.
  • Seguridad y cumplimiento:
    • Implementa múltiples capas de seguridad: restricciones en los prompts, verificaciones basadas en herramientas (como la compatibilidad de reactivos a través de chem_lookup), verificaciones de modelos dedicados opcionales (gpt-4.1-mini), filtros automatizados (como para combinaciones peligrosas conocidas) y revisión humana obligatoria.
    • Asegura que los puntos finales de las herramientas (como las bases de datos internas) cumplan con los requisitos de seguridad.
  • Estrategia de implementación:
    • Comienza con el análisis retrospectivo de experimentos pasados, luego pasa al modo sombra (la IA sugiere planes junto con los planificadores humanos), seguido de casos de uso en vivo limitados con monitoreo cercano antes de una adopción más amplia.

5. Conclusiones

  1. El emparejamiento de modelos crea sinergia: o4-mini cubre más terreno rápidamente; o3 aporta precisión y profundidad.
  2. La integración de herramientas basa el razonamiento en la realidad: Datos del mundo real, como los costos de los productos químicos y las restricciones de seguridad, informan la toma de decisiones.
  3. Los científicos humanos siguen siendo centrales: El sistema empodera a los expertos al eliminar el trabajo pesado, no al reemplazarlos.

6. Recetarios y recursos útiles

Aquí tienes una selección de recursos que complementan el diseño y la implementación del sistema Co-Científico de IA:

  • Orquestación de agentes: Rutinas y traspasos Estructuración de flujos de trabajo multiagente con rutinas y traspasos, relevante para la tubería de ideación→clasificación→crítica.

  • Guía de prompting de GPT-4.1 Prompting avanzado, uso de herramientas y descomposición de tareas para mejorar la precisión en la crítica y las revisiones de seguridad.

  • Salidas estructuradas para sistemas multiagente Imposición de salidas JSON consistentes con validación de esquema para la interoperabilidad de agentes.

  • Agentes - API de OpenAI
    Guía completa para construir sistemas multiagente con herramientas de OpenAI, que cubre la orquestación, el uso de herramientas y las mejores prácticas fundamentales para la arquitectura de este sistema.

================================================================================

3C. Caso de uso: Procesamiento de reclamaciones de seguros

Muchas empresas se enfrentan a la tarea de digitalizar formularios rellenados a mano. En esta sección, demostraremos cómo se puede usar OpenAI para digitalizar y validar un formulario de seguro rellenado a mano. Si bien este es un problema común para los seguros, las mismas técnicas se pueden aplicar a una variedad de otras industrias y formularios, por ejemplo, formularios de impuestos, facturas y más.

🗂️ Matriz TL;DR

Esta tabla resume las principales opciones tecnológicas y su justificación para esta implementación específica de OCR dirigida al caso de uso de seguros.

Capa Elección Utilidad
Salida JSON Salida estructurada con Pydantic Fácil de especificar el formato, se adhiere mejor al esquema que JSON mode
OCR y visión gpt-4.1 Potentes capacidades de OCR y visión, salida estructurada
Razonamiento o4-mini Razonamiento asequible pero capaz, llamada a funciones disponible
Validación de formularios Llamada a funciones personalizada Puede proporcionar interacción con bases de datos personalizadas o internas

*Nota: Precios e identificadores de modelos precisos a abril de 2025, sujetos a cambios.

1. Resumen del escenario

  • Usuarios: Los usuarios objetivo son los equipos de servicio y operaciones de seguros que necesitan ingresar datos de formularios escritos a mano.
  • Solicitudes típicas: Cada formulario tendrá una estructura requerida diferente, así como diferentes campos que deben extraerse.
  • Restricciones:
    • Precisión: Se requiere alta precisión para garantizar que los datos sean correctos y completos.
    • Incertidumbre: El sistema debe manejar la incertidumbre en los datos, como datos faltantes, datos ambiguos y diferentes formatos del mismo campo. En caso de que el modelo no pueda resolver la incertidumbre, el sistema requiere un mecanismo para solicitar una revisión humana.
    • Rendimiento y costo: Si bien la latencia del sistema no es crítica, se requiere alta precisión manteniendo los costos bajo control. Apuntaremos a un objetivo de costo de $20 o menos por cada 1000 páginas procesadas.

2. Arquitectura

La arquitectura básica de alto nivel de la solución se muestra a continuación.

Esta tarea es compleja y requiere una amplia variedad de capacidades del modelo, incluyendo visión, llamada a funciones, razonamiento y salida estructurada. Si bien o3 es capaz de hacer todo esto a la vez, descubrimos durante la experimentación que o4-mini por sí solo no era suficiente para lograr el rendimiento necesario. Debido a los costos relativamente más altos de o3, optamos por un enfoque de dos etapas.

  1. La primera etapa se realiza utilizando las capacidades de visión de GPT 4.1. Esta etapa está optimizada para extraer texto con la máxima precisión, dejando la incertidumbre para la etapa de razonamiento y sin hacer suposiciones que no sean visibles en la página. Al realizar OCR en la primera etapa, no requerimos que el modelo de razonamiento trabaje directamente desde una imagen, lo que puede ser un desafío dadas todas las demás tareas que debe realizar el modelo de razonamiento.

  2. La segunda etapa aprovecha las habilidades de razonamiento de o4-mini. Usamos o4-mini para validar la precisión del OCR y para extraer los datos en un formato estructurado. Es importante destacar que esperamos que o4-mini actúe como la puerta de calidad secundaria; si el OCR está incompleto en esta etapa, podemos usar o4-mini para refinar y validar los resultados originales.

Para demostrar concretamente cómo funciona esto, veamos una imagen de muestra de un formulario de seguro.

Aunque el formulario en sí es bastante sencillo, hay datos faltantes e información ambigua que será difícil para un sistema OCR tradicional rellenar correctamente. Primero, observa que se han omitido el código postal y el condado. Segundo, la dirección de correo electrónico del usuario es ambigua: podría ser [email protected] o [email protected]. En las siguientes secciones, explicaremos cómo una solución bien diseñada puede manejar estas ambigüedades y devolver los resultados correctos del formulario.

Configuración del entorno y código de la biblioteca:

Para que nuestro código de ejemplo sea más claro, hemos separado la configuración del entorno (como los comandos pip install) y las funciones de la biblioteca en un bloque de código aparte. Esto facilitará la concentración solo en la lógica relevante en cada paso de nuestra solución.

# Install Python requirements
%pip install -qU pydantic "openai>=1.76.0"

# All imports
import os
import json

from pydantic import BaseModel

# Create the OpenAI client
from openai import OpenAI

client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY", "sk-dummykey"))
Note: you may need to restart the kernel to use updated packages.
def run_conversation_loop(
    client,
    messages,
    tools,
    tool_handlers,
    response_format,
    model,
):
    """Run the OpenAI response completion loop, handling function calls via tool_handlers until parsing final response."""
    summaries = []
    while True:
        print(
            f"Requesting completion from model '{model}' (messages={len(messages)})"
        )
        response = client.responses.parse(
            model=model,
            input=messages,
            tools=tools,
            text_format=response_format,
            reasoning={"summary": "auto"},
        )
        summaries.append(response.output[0].summary)

        if not response.output_parsed:
            print("Assistant requested tool calls, resolving ...")

            reasoning_msg, tool_call = response.output
            messages.append(reasoning_msg)
            messages.append({
                "id": tool_call.id,
                "call_id": tool_call.call_id,
                "type": tool_call.type,
                "name": tool_call.name,
                "arguments": tool_call.arguments,
            })

            if tool_call.name in tool_handlers:
                try:
                    args = json.loads(tool_call.arguments)
                except Exception as exc:
                    print(
                        "Failed to parse %s arguments: %s", tool_call.name, exc
                    )
                    args = {}
                result = tool_handlers[tool_call.name](**args)
                messages.append(
                    {
                        "type": "function_call_output",
                        "call_id": tool_call.call_id,
                        "output": str(result),
                    }
                )
                print(f"Tool call {tool_call.name} complete, result: {str(result)}")
            else:
                print("Unhandled function call: %s", tool_call.name)

        if response.output_parsed is not None:
            print("Received parsed result from model")
            return response, summaries

Explicación del flujo: Etapa 1

  1. Imagen: La imagen del formulario tomada del teléfono inteligente del usuario se pasa al modelo. Los modelos de OpenAI pueden aceptar una variedad de formatos de imagen, pero generalmente usamos un formato PNG para mantener el texto nítido y reducir los artefactos. Para este ejemplo, pasamos la imagen al modelo desde una URL de contenido disponible públicamente. En un entorno de producción, es probable que pases la imagen como una URL firmada a una imagen alojada en tu propio bucket de almacenamiento en la nube.

  2. Esquema de salida estructurada: Definimos un modelo Pydantic que establece la estructura de los datos de salida. El modelo incluye todos los campos que necesitamos extraer del formulario, junto con los tipos apropiados para cada campo. Nuestro modelo se divide en varios subcomponentes, cada uno de los cuales es un modelo Pydantic en sí mismo y es referenciado por el modelo padre.

class PersonContact(BaseModel):
    name: str
    home_phone: str
    work_phone: str
    cell_phone: str
    email: str

class Address(BaseModel):
    street: str
    city: str
    state: str
    zip: str
    county: str

class DwellingDetails(BaseModel):
    coverage_a_limit: str
    companion_policy_expiration_date: str
    occupancy_of_dwelling: str
    type_of_policy: str
    unrepaired_structural_damage: bool
    construction_type: str
    roof_type: str
    foundation_type: str
    has_post_and_pier_or_post_and_beam_foundation: bool
    cripple_walls: bool
    number_of_stories: str
    living_space_over_garage: bool
    number_of_chimneys: str
    square_footage: str
    year_of_construction: str
    anchored_to_foundation: bool
    water_heater_secured: bool

class InsuranceFormData(BaseModel):
    applicant: PersonContact
    co_applicant: PersonContact
    risk_address: Address
    mailing_address_if_different_than_risk_address: Address
    participating_insurer: str
    companion_policy_number: str
    dwelling_details: DwellingDetails
    effective_date: str
    expiration_date: str
  1. Ejecutar OCR: Utilizando las capacidades de visión de GPT-4.1, ejecutamos la primera etapa de nuestra tubería para extraer el texto del documento en un formato estructurado. Esta etapa inicial tiene como objetivo lograr una alta precisión mientras se transfiere la incertidumbre a la segunda etapa. Nuestro prompt instruye explícitamente al modelo para que evite inferir entradas y, en su lugar, complete los detalles con la mayor exactitud posible. Para la entrada de imagen, configuramos el detalle de entrada de imagen en auto para inferir un nivel de detalle apropiado para la imagen. Encontramos en nuestros experimentos que auto funcionó bien, pero si estás viendo problemas de calidad en tu procesamiento de OCR, considera usar high.
OCR_PROMPT = """You are a helpful assistant who excels at processing insurance forms.

You will be given an image of a hand-filled insurance form. Your job is to OCR the data into the given structured format.
Fill out the fields as exactly as possible. If a written character could possibly be ambiguous (i.e. l or 1, o or 0), include all possiblities in the field separated by "OR", especially for email addresses.
"""

user_content = [
    {"type": "input_text", "text": "Here is a photo of the form filled out by the user:"},
    {
        "type": "input_image",
        "image_url": "https://drive.usercontent.google.com/download?id=1-tZ526AW3mX1qthvgi8spaaxxeqFG5_6",
        "detail": "auto",
    },
]

messages = [
    {"role": "system", "content": OCR_PROMPT},
    {"role": "user", "content": user_content},
]

response = client.responses.parse(
    model="gpt-4.1-2025-04-14",
    input=messages,
    text_format=InsuranceFormData,
    # Set temp to 0 for reproducibility
    temperature=0,
)

s1_json_results = json.dumps(json.loads(response.output_parsed.model_dump_json()), indent=2)
print(s1_json_results)
{
  "applicant": {
    "name": "Smith, James L",
    "home_phone": "510 331 5555",
    "work_phone": "",
    "cell_phone": "510 212 5555",
    "email": "[email protected] OR [email protected]"
  },
  "co_applicant": {
    "name": "Roberts, Jesse T",
    "home_phone": "510 331 5555",
    "work_phone": "415 626 5555",
    "cell_phone": "",
    "email": "[email protected]"
  },
  "risk_address": {
    "street": "855 Brannan St",
    "city": "San Francisco",
    "state": "CA",
    "zip": "",
    "county": ""
  },
  "mailing_address_if_different_than_risk_address": {
    "street": "",
    "city": "",
    "state": "",
    "zip": "",
    "county": ""
  },
  "participating_insurer": "Acme Insurance Co",
  "companion_policy_number": "81265919",
  "dwelling_details": {
    "coverage_a_limit": "$900,000",
    "companion_policy_expiration_date": "5/31/27",
    "occupancy_of_dwelling": "Owner",
    "type_of_policy": "Homeowners",
    "unrepaired_structural_damage": false,
    "construction_type": "Frame",
    "roof_type": "Composition",
    "foundation_type": "Raised",
    "has_post_and_pier_or_post_and_beam_foundation": false,
    "cripple_walls": false,
    "number_of_stories": "Greater than 1 story",
    "living_space_over_garage": true,
    "number_of_chimneys": "2",
    "square_footage": "1200",
    "year_of_construction": "2005",
    "anchored_to_foundation": true,
    "water_heater_secured": true
  },
  "effective_date": "5/31/25",
  "expiration_date": "5/31/27"
}

Observa que la salida carece de varios campos. En la siguiente etapa de procesamiento, aprovecharemos los modelos de razonamiento de OpenAI para inferir los campos faltantes cuando sea posible.

Explicación del flujo: Etapa 2

  1. Definiciones de funciones: Definimos un conjunto de funciones personalizadas que el modelo puede usar para resolver la incertidumbre. En este caso, definimos una función que puede validar direcciones de correo electrónico verificando si el correo electrónico existe. Esto se puede usar para resolver el campo de dirección de correo electrónico ambiguo donde el modelo debe elegir entre múltiples valores posibles. Por defecto, o4-mini admite herramientas integradas como la búsqueda web, que en este caso usará para resolver códigos postales y direcciones incompletas.
tools = [{
    "type": "function",
    "name": "validate_email",
    "description": "Check if an email address is valid and exists.",
    "parameters": {
        "type": "object",
        "properties": {
            "email": {
                "type": "string",
                "description": "The email address to validate."
            }
        },
        "required": [
            "email"
        ],
        "additionalProperties": False
    }
},
{
    "type": "function",
    "name": "search_web",
    "description": "Perform a web search.",
    "parameters": {
        "type": "object",
        "properties": {
            "query": {
                "type": "string",
                "description": "The search query to run through the search engine."
            }
        },
        "required": [
            "query"
        ],
        "additionalProperties": False
    }
}]
  1. Prompt: Proporcionamos un prompt al modelo explicando que hemos extraído texto mediante OCR y solicitando que el modelo realice razonamiento y llamadas a funciones para rellenar los campos faltantes o ambiguos.
PROMPT = """You are a helpful assistant who excels at processing insurance forms.

You will be given a javascript representation of an OCR'd document. Consider at which fields are ambiguous reason about how to fill them in. Fill any missing fields that are possible to infer from existing data, or search the web. If you cannot fill a field, reason about why.

Use the tools provided if necessary to clarify the results. If the OCR system has provided two possibilities, do your best to definitely pick which option is correct.
"""
messages = [
    {"role": "system", "content": PROMPT},
    {"role": "user", "content": s1_json_results},
]

# For demonstration purposes, we'll hardcode the correct email answer.
def email_mock(*args, **kwargs):
    if kwargs["email"] == "[email protected]":
        return True
    return False

# Reasoning models like `o4-mini` will soon support built-in web search, but for now
# we demonstrate this capability using a simple mock function.
def web_mock(*args, **kwargs):
    if "855 Brannan" in kwargs["query"]:
        return "855 Brannan St, San Francisco, 94103, San Francisco County"
    
    return ""
    
tool_handlers = {"validate_email": email_mock, "search_web": web_mock}

response, summaries = run_conversation_loop(
    client=client,
    messages=messages,
    tools=tools,
    tool_handlers=tool_handlers,
    response_format=InsuranceFormData,
    model="o4-mini-2025-04-16",
)

print(json.dumps(json.loads(response.output_parsed.model_dump_json()), indent=2))
Requesting completion from model 'o4-mini-2025-04-16' (messages=2)
Assistant requested tool calls, resolving ...
Tool call validate_email complete, result: True
Requesting completion from model 'o4-mini-2025-04-16' (messages=5)
Assistant requested tool calls, resolving ...
Tool call validate_email complete, result: False
Requesting completion from model 'o4-mini-2025-04-16' (messages=8)
Received parsed result from model
{
  "applicant": {
    "name": "Smith, James L",
    "home_phone": "510 331 5555",
    "work_phone": "",
    "cell_phone": "510 212 5555",
    "email": "[email protected]"
  },
  "co_applicant": {
    "name": "Roberts, Jesse T",
    "home_phone": "510 331 5555",
    "work_phone": "415 626 5555",
    "cell_phone": "",
    "email": "[email protected]"
  },
  "risk_address": {
    "street": "855 Brannan St",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94107",
    "county": "San Francisco"
  },
  "mailing_address_if_different_than_risk_address": {
    "street": "855 Brannan St",
    "city": "San Francisco",
    "state": "CA",
    "zip": "94107",
    "county": "San Francisco"
  },
  "participating_insurer": "Acme Insurance Co",
  "companion_policy_number": "81265919",
  "dwelling_details": {
    "coverage_a_limit": "$900,000",
    "companion_policy_expiration_date": "5/31/27",
    "occupancy_of_dwelling": "Owner",
    "type_of_policy": "Homeowners",
    "unrepaired_structural_damage": false,
    "construction_type": "Frame",
    "roof_type": "Composition",
    "foundation_type": "Raised",
    "has_post_and_pier_or_post_and_beam_foundation": false,
    "cripple_walls": false,
    "number_of_stories": "Greater than 1 story",
    "living_space_over_garage": true,
    "number_of_chimneys": "2",
    "square_footage": "1200",
    "year_of_construction": "2005",
    "anchored_to_foundation": true,
    "water_heater_secured": true
  },
  "effective_date": "5/31/25",
  "expiration_date": "5/31/27"
}

Puedes ver que la dirección de correo electrónico se ha refinado a un solo valor, el código postal y el condado se han rellenado, y la dirección de correo se ha rellenado utilizando la dirección de riesgo. El modelo también ha devuelto los resultados en un formato estructurado (con tipos apropiados como booleano para preguntas de sí/no), que puede ser fácilmente analizado por un sistema posterior.

Para ayudarnos a entender y depurar el modelo, también podemos imprimir el resumen del razonamiento en cadena de pensamiento producido por el modelo. Esto puede ayudar a exponer modos de falla comunes, puntos donde el modelo no es claro o detalles ascendentes incorrectos.

Mientras desarrollábamos esta solución, los resúmenes de la cadena de pensamiento expusieron algunos valores de esquema con nombres y tipos incorrectos.

for summary in summaries:
    for response in summary:
        print(response.text + '\n')
**Determining insurance form details**

I have a JSON representation of a partially filled insurance form, and there are a few missing or ambiguous fields that I need to address.

For the email address, I see two options. I can validate which one is correct by checking both with the tool.

The risk address fields for zip code and county are empty. Based on the address "855 Brannan St, San Francisco, CA," I can determine the correct zip code is 94107, as that area corresponds to South Beach. Lastly, since the mailing address is empty, I assume it's the same as the risk address.

**Filling insurance form details**

I think it’s best to set the mailing address to be the same as the risk address or clarify that a blank one implies the same. Since it’s an explicit instruction to fill missing fields, I’ll fill in the mailing address with the risk address to avoid confusion.

All co-applicant fields are present, and dwelling details are complete. The effective and expiration dates are also provided. I plan to validate both email options by checking each one separately. Let's begin with validating the first email.

3. Manual de modelos y capacidades

Seleccionar la herramienta adecuada para el trabajo es clave para obtener los mejores resultados. En general, es una buena idea comenzar con la solución más simple que se adapte a tus necesidades y luego actualizar si necesitas más capacidades.

Tarea Empieza con Actualiza cuando... Escala a Justificación
OCR gpt-4.1 Formularios complejos difíciles de entender a simple vista o3 gpt-4.1 es rápido y rentable para la mayoría de los OCR. o-3 tiene la capacidad de razonar sobre la estructura del formulario.
Refinamiento de resultados o4-mini Lógica compleja para inferir detalles, se requieren muchas llamadas a funciones. o3 Mejor para cadenas de razonamiento muy largas, especialmente con llamadas a funciones y salida estructurada.

4. Métricas de evaluación

Rastrea métricas clave para asegurar que el sistema se esté desempeñando con precisión y según lo esperado.

Métricas críticas

  • Precisión del OCR: Precisión por carácter y por palabra.
  • Tasa de campos inferidos: Porción de entradas sin rellenar inferidas correctamente a partir de datos existentes o llamadas a funciones.
  • Tasa de intervención humana: Con qué frecuencia un documento contiene un UNKNOWN y debe ser remitido a un humano.

Recomendamos construir un conjunto de formularios etiquetados y sus respuestas esperadas. Este conjunto de datos debe ser representativo del entorno de implementación esperado; consulta la guía de evaluaciones de OpenAI para obtener información más detallada sobre cómo construir y evaluar tu sistema.

5. Notas de implementación

La transición de un prototipo a un sistema listo para producción requiere atención a los detalles operativos (LLMOps).

Desglose de costos

Asumiremos que para la ingesta de documentos, la tarificación por lotes es una opción viable debido a la alta tolerancia a la latencia (es decir, las ejecuciones nocturnas están bien).

Etapa 1: OCR (Reconocimiento óptico de caracteres)

Modelo: gpt-4.1

Tipo Tokens Tarifa (por 1M) Costo
Entrada 2,000 $1.00 $0.002
Salida 1,500 $4.00 $0.006
Total para 1,000 páginas (Etapa 1) $8.00

Etapa 2: Razonamiento

Modelo: o4-mini

Tipo Tokens Tarifa (por 1M) Costo
Entrada 2,000 $0.55 $0.0011
Salida 3,000 $2.20 $0.0066
Total para 1,000 páginas (Etapa 2) $7.70

Gran Total (por 1,000 páginas): $15.70

Compara este costo con una implementación de una sola etapa o3. Asumiendo el mismo uso de tokens y uso por lotes, el costo adicional del modelo de razonamiento más potente ascendería a $70/1000 páginas.

Monitoreo e implementación

Monitorea tu sistema registrando métricas clave:

  • llm_model_used, llm_input_tokens, llm_output_tokens, llm_latency_ms por modelo
  • total_query_latency_ms, estimated_query_cost por modelo
  • function_calls_per_document, num_email_validation_calls
  • human_review_required

Fija el identificador de versión de modelo específico (por ejemplo, o4-mini-2025-04-16) utilizado en la implementación a través de variables de configuración/entorno para evitar comportamientos inesperados debido a actualizaciones silenciosas del modelo.

6. Recetarios y recursos útiles

Consulta estos recursos relacionados para profundizar en componentes específicos:

================================================================================

Del prototipo a la producción

La transición de un prototipo a producción requiere una planificación y ejecución cuidadosas. Esta lista de verificación destaca los pasos críticos, basándose en nuestros casos de uso emblemáticos, para garantizar que tu implementación sea robusta, eficiente y cumpla con los objetivos comerciales.

🗂️ Matriz TL;DR

Área de la lista de verificación Enfoque/acciones clave Por qué es importante
Define los criterios de éxito • Define KPI y SLO medibles (precisión, costo, latencia). • Asegúrate de que los objetivos sean medibles a través de registros. Proporciona objetivos claros; demuestra valor.
Documenta la lógica del modelo • Selecciona los modelos iniciales deliberadamente en función de las compensaciones. • Documenta el "porqué" detrás de las elecciones del modelo. Justifica las elecciones; ayuda a futuras actualizaciones.
Evaluación y pruebas robustas • Crea pruebas automatizadas ("suite de evaluación") usando un conjunto dorado. • Concéntrate en la veracidad, las alucinaciones, los errores de las herramientas. • Prueba la fiabilidad de las herramientas y los casos extremos. Garantiza la calidad; previene regresiones antes del lanzamiento.
Observabilidad y costo • Implementa el registro esencial para el monitoreo y la depuración. • Establece límites de costo (límites de tokens, modos de uso). Permite el ajuste; mantiene el gasto dentro del presupuesto.
Seguridad y cumplimiento • Usa mecanismos de seguridad (API de moderación, prompts). • Aplica reglas de cumplimiento específicas del dominio. • Exige la intervención humana (HITL) para resultados de alto riesgo. Garantiza una operación responsable; cumple los requisitos.
Actualizaciones y versionado del modelo • Define la estrategia de fijación de versiones. • Implementa pruebas A/B para nuevas versiones. • Crea procedimientos de reversión. Mantiene la estabilidad al tiempo que permite mejoras.
  1. Define los criterios de éxito cuantitativamente: Ve más allá de "funciona" a objetivos medibles antes del desarrollo principal.

    • Establece indicadores clave de rendimiento (KPI) y SLO: Define objetivos específicos para el valor comercial (por ejemplo, precisión de RAG > 95%, costo de OCR < $X/página) y el rendimiento (por ejemplo, latencia P95 < 1s, tasas de error).
    • Asegura la mensurabilidad: Confirma que todos los KPI y SLO se pueden medir directamente a partir de los registros del sistema (por ejemplo, seguimiento total_tokens, critique_status).
  2. Documenta la lógica de selección inicial del modelo: Justifica tus elecciones de modelo iniciales para futuras referencias.

    • Elige los modelos deliberadamente: Usa la Matriz de Introducción de Modelos y los casos de uso para seleccionar los modelos apropiados para cada tarea (por ejemplo, o4-mini para velocidad/costo, gpt-4.1 para precisión, o3 para profundidad).
    • Registra el "porqué": Documenta brevemente el razonamiento detrás de tus elecciones (compensaciones de costo, latencia, capacidad) en comentarios de código o documentos de diseño para que los equipos futuros comprendan el contexto.
  3. Implementa una evaluación y pruebas robustas: Verifica la calidad y previene regresiones antes de enviar cambios.

    • Crea una suite de evaluación automatizada: Crea un proceso de prueba repetible usando un "conjunto dorado" (50-100 ejemplos diversos y verificados por expertos). Concéntrate en las pruebas de factuality, hallucination rate, tool-error rate y métricas específicas de la tarea.
    • Prueba de forma fiable: Prueba rigurosamente la fiabilidad de las herramientas integradas (tasa de éxito, manejo de errores) y el comportamiento del sistema bajo carga y con casos extremos (datos mal formados, entradas adversarias).
  4. Establece controles de observabilidad y costo: Monitorea el rendimiento y mantén el gasto dentro del presupuesto.

    • Establece límites de costo: Evita aumentos de costos inesperados definiendo límites máximos de tokens por etapa y considerando modos operativos ("Rápido", "Estándar", "Minucioso") para equilibrar el costo y el rendimiento.
    • Implementa el registro esencial: Captura datos operativos clave a través de registros estructurados para cada etapa de procesamiento para permitir la depuración y el monitoreo.
  5. Implementa límites de seguridad y cumplimiento: Garantiza una operación responsable y cumple los requisitos.

    • Usa mecanismos de seguridad: Emplea herramientas como las API de moderación de OpenAI, prompts de sistema centrados en la seguridad o modelos centinela para verificaciones, especialmente con la entrada del usuario o temas sensibles.
    • Aplica el cumplimiento: Incorpora verificaciones relevantes para tu industria y riesgos específicos (por ejemplo, restricciones legales, seguridad de laboratorio).
    • Exige la intervención humana (HITL): Exige la revisión humana para resultados de baja confianza, escenarios de alto riesgo o decisiones críticas, asegurando que el flujo de trabajo marque estos elementos claramente.
  6. Gestiona las actualizaciones y el versionado del modelo: Prepárate para la evolución del modelo con el tiempo.

    • Estrategia de fijación de versiones: Decide si fijar versiones específicas del modelo para mayor estabilidad o adoptar automáticamente nuevas versiones para mejoras.
    • Marco de pruebas A/B: Establece un proceso para evaluar nuevas versiones del modelo frente a tus métricas clave antes de la implementación completa.
    • Plan de reversión: Crea un procedimiento claro para revertir a versiones anteriores del modelo si surgen problemas con las actualizaciones.
    • Monitorea el rendimiento de las versiones: Rastrea las métricas en todas las versiones del modelo para identificar tendencias de rendimiento e informar futuras decisiones de selección.

================================================================================

Árbol de decisión de adaptación

Model Selection Decision Tree

Comunicación de la selección del modelo a las partes interesadas no técnicas

Al explicar tus elecciones de modelo a las partes interesadas del negocio, concéntrate en estos puntos clave:

  1. Alinea con los resultados del negocio: Explica cómo tu selección de modelo apoya directamente objetivos comerciales específicos (ahorro de tiempo, reducción de costos, mejora de la precisión).

  2. Traduce las métricas técnicas: Convierte las consideraciones técnicas en impacto comercial:

    • "Este modelo reduce el tiempo de procesamiento de 5 segundos a 0.7 segundos, lo que nos permite manejar las consultas de los clientes 7 veces más rápido"
    • "Al usar la variante mini, podemos procesar 5 veces más documentos con el mismo presupuesto"
  3. Destaca las compensaciones: Presenta escenarios claros para diferentes modelos:

    • "Opción A (GPT-4.1): Máxima precisión pero mayor costo, ideal para análisis legal de cara al cliente"
    • "Opción B (GPT-4.1 mini): 90% de la precisión con el 30% del costo, perfecto para el procesamiento interno de documentos"
  4. Usa ejemplos concretos: Demuestra la diferencia práctica en los resultados entre los modelos para ilustrar la propuesta de valor de cada opción.

================================================================================

Apéndices

Glosario de términos clave

Término Definición
Ventana de contexto El número máximo de tokens que un modelo puede procesar en una sola solicitud
Alucinación Cuando un modelo genera contenido que parece plausible pero es fácticamente incorrecto o no está respaldado
Latencia El tiempo de retraso entre el envío de una solicitud a un modelo y la recepción de una respuesta
LLM Modelo de lenguaje grande; un sistema de IA entrenado con grandes cantidades de datos de texto
Prompt Engineering La práctica de diseñar prompts efectivos para obtener los resultados deseados de los modelos de IA
RAG Generación aumentada por recuperación; combina la recuperación de información con la generación de texto
SOTA Estado del arte; representa la etapa más avanzada en un campo en un momento dado
Token La unidad básica de texto que procesan los modelos (aproximadamente 0.75 palabras en inglés)

6.1 Tabla de precios y utilidad (abril de 2025)

Modelo Ventana de contexto Precio de entrada (por 1M de tokens) Precio de salida (por 1M de tokens) Mejor para
GPT-4.1 1M $2.00 $8.00 Análisis de documentos largos, revisión de código
GPT-4.1 mini 1M $0.40 $1.60 Agentes de producción, costo/rendimiento equilibrado
GPT-4.1 nano 1M $0.10 $0.40 Aplicaciones de alto rendimiento y sensibles al costo
GPT-4o 128K $5.00 $15.00 Chat de voz/visión en tiempo real
GPT-4o mini 128K $0.15 $0.60 Tareas de visión, análisis rápido
o3 (bajo) 200K $10.00* $40.00* Clasificación masiva, enriquecimiento de catálogos
o3 (medio) 200K $10.00* $40.00* Preguntas y respuestas de bases de conocimiento
o3 (alto) 200K $10.00* $40.00* Razonamiento de varios pasos, resolución de problemas
o4-mini (bajo) 200K $1.10* $4.40* Tareas de visión, análisis rápido
o4-mini (medio) 200K $1.10* $4.40* Visión + razonamiento equilibrados
o4-mini (alto) 200K $1.10* $4.40* Razonamiento profundo con control de costos

* Nota: Las configuraciones baja/media/alta afectan el uso de tokens en lugar del precio base. Las configuraciones más altas pueden usar más tokens para un razonamiento más profundo, lo que aumenta el costo por solicitud y la latencia.

6.2 Hoja rápida de patrones de prompt (Deltas de tokens vs. latencia)

Patrón de prompt Descripción Impacto en tokens Impacto en latencia Mejor ajuste del modelo
Autocrítica Pide al modelo que evalúe su propia respuesta antes de finalizarla +20-30% tokens +15-25% latencia GPT-4.1, o3
Cadena de pensamiento (CoT) Instruye explícitamente a "pensar paso a paso" +40-80% tokens +30-50% latencia o3, o4-mini (alto)
Salidas estructuradas Usa esquemas JSON o modelos pydantic para un formato consistente +5-10% tokens +5-10% latencia Todos los modelos
Memoria de cero tokens Almacena el contexto en una base de datos externa en lugar de en la conversación -70-90% tokens -5-10% latencia Familia GPT-4.1
Relleno de esqueleto Proporciona una estructura de plantilla para que el modelo la complete -10-20% tokens -5-15% latencia o4-mini, GPT-4.1 nano
Autoconsistencia Genera múltiples respuestas y selecciona la más consistente +200-300% tokens +150-250% latencia o3 (alto)
Juego de roles Asigna personas específicas al modelo para conocimientos especializados +5-15% tokens Neutral GPT-4o, o4-mini
Clasificación por torneo Compara opciones por pares en lugar de puntuarlas individualmente +50-100% tokens +30-60% latencia o3, o4-mini (alto)
Reflejo de llamada a herramientas Pide al modelo que llame a herramientas cuando se detecta incertidumbre +10-30% tokens +20-40% latencia o3, GPT-4.1

6.3 Enlaces a libros de cocina y documentos externos

Recursos oficiales de OpenAI

RAG y recuperación

Casos de uso especializados

Prompting y selección de modelos

Evaluación e implementación

================================================================================

Colaboradores

Este libro de cocina es un esfuerzo de colaboración conjunta entre OpenAI y Tribe AI

Lección del curso «OpenAI Cookbook» de OpenAI, publicado con licencia MIT. Traducción y adaptación al español de IA con Clase. IA con Clase no está afiliado a OpenAI. Ver el original · Licencia
Esta lección es gratuita. El resto del curso se abre con la Membresía de IA con Clase, que incluye todos los cursos del catálogo. Ver precios