Laravel

Cómo Implementar Inteligencia Artificial en Laravel usando Laravel AI SDK

16 septiembre, 2026
28 lecturas
Cómo analizar preguntas de opción múltiple con IA en Laravel: Tutorial

Imagina que tienes un banco de preguntas de opción múltiple —para un examen, un quiz educativo o una plataforma de e-learning— y quieres que, además de mostrar la respuesta correcta, el sistema explique el razonamiento detrás de ella. Hacerlo manualmente para cientos de preguntas es inviable. Aquí es donde entra el Laravel AI SDK: con pocas líneas de código puedes delegarle esa explicación pedagógica a un modelo de lenguaje.

En este tutorial construiremos, paso a paso, un endpoint en Laravel que recibe una pregunta, sus opciones y la alternativa correcta, y devuelve una explicación clara de por qué esa es la respuesta acertada.

¿Qué es el Laravel AI SDK?

El AI SDK oficial de Laravel (laravel/ai) es un paquete que unifica el acceso a distintos proveedores de inteligencia artificial —OpenAI, Anthropic, Gemini, Groq, Mistral, entre otros— bajo una sola API expresiva y "a la Laravel". Permite crear agentes con instrucciones propias, definir salidas estructuradas en JSON, manejar streaming, colas, failover entre proveedores y mucho más.

Instalación

bash

composer require laravel/ai

Publica la configuración y las migraciones:

bash

php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"
php artisan migrate

Define tu clave de API en .env (en este tutorial usaremos Gemini):

env

GEMINI_API_KEY=tu_api_key_aqui

Paso 1: el controlador base

Partimos de una estructura simple: un controlador con un método index, un agent() anónimo y un try/catch para manejar errores.

php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Laravel\Ai\Enums\Lab;
use function Laravel\Ai\agent;

class FrontController extends Controller
{
    public function index(Request $request)
    {
        $pregunta = $request->input('pregunta', '¿Cuál es la capital de Perú?');
        $opciones = $request->input('opciones', ['Lima', 'Cusco', 'Arequipa', 'Trujillo']);
        $correcta = $request->input('correcta', 'Lima');

        $prompt = <<<PROMPT
        Pregunta: {$pregunta}
        Opciones: {$this->listar($opciones)}
        Opción correcta: {$correcta}

        Explica de forma clara y breve por qué esa opción es la correcta.
        PROMPT;

        try {
            $response = agent(
                instructions: 'Actúa como un instructor experto que explica por qué una respuesta es correcta.',
            )->prompt(
                $prompt,
                provider: Lab::Gemini,
                model: 'gemini-2.5-flash',
            );

            $explicacion = (string) $response;

        } catch (\Throwable $e) {
            $explicacion = "Falló la respuesta de la IA";
        }

        return view('explicacion', [
            'explicacion' => $explicacion,
        ]);
    }

    private function listar(array $opciones): string
    {
        return implode(', ', $opciones);
    }
}

Errores comunes que evitamos aquí

Error frecuente Corrección Motivo
instruccions: (typo) instructions: Debe coincidir con la firma exacta del método agent()
Modelos inventados como gemeni-3.5-flash-lite gemini-2.5-flash Un nombre de modelo inválido produce error de la API
Prompt sin datos dinámicos Prompt armado con variables del Request Permite reutilizar el mismo endpoint para cualquier pregunta
Sin return return view(...) Sin retorno, Laravel no envía ninguna respuesta HTTP

Paso 2: registrando la ruta

php

use App\Http\Controllers\FrontController;

Route::post('/explicar-pregunta', [FrontController::class, 'index']);

Paso 3: mejorando con salida estructurada (JSON en vez de texto libre)

Un texto plano funciona para mostrarlo en una vista, pero si vas a consumir este endpoint desde una API o un frontend en React/Vue, conviene una respuesta estructurada. Para eso, en lugar del agente anónimo usamos una clase de Agente dedicada que implemente HasStructuredOutput:

bash

php artisan make:agent QuestionExplainer

php

<?php

namespace App\Ai\Agents;

use Illuminate\Contracts\JsonSchema\JsonSchema;
use Laravel\Ai\Attributes\Provider;
use Laravel\Ai\Contracts\Agent;
use Laravel\Ai\Contracts\HasStructuredOutput;
use Laravel\Ai\Enums\Lab;
use Laravel\Ai\Promptable;

#[Provider(Lab::Gemini)]
class QuestionExplainer implements Agent, HasStructuredOutput
{
    use Promptable;

    public function instructions(): string
    {
        return 'Eres un tutor experto. Recibirás una pregunta de opción múltiple, '
            . 'sus alternativas y cuál es la correcta. Explica por qué es correcta '
            . 'y, brevemente, por qué las demás no lo son.';
    }

    public function schema(JsonSchema $schema): array
    {
        return [
            'explicacion' => $schema->string()->required(),
            'razon_correcta' => $schema->string()->required(),
        ];
    }
}

Y el controlador queda así:

php

<?php

namespace App\Http\Controllers;

use App\Ai\Agents\QuestionExplainer;
use Illuminate\Http\Request;

class QuestionController extends Controller
{
    public function explain(Request $request)
    {
        $validated = $request->validate([
            'pregunta' => 'required|string',
            'opciones' => 'required|array|min:2',
            'correcta' => 'required|string',
        ]);

        $prompt = "Pregunta: {$validated['pregunta']}\n"
            . "Opciones: " . implode(', ', $validated['opciones']) . "\n"
            . "Opción correcta: {$validated['correcta']}\n"
            . "Explica por qué es la correcta.";

        try {
            $response = (new QuestionExplainer)->prompt($prompt);

            return response()->json([
                'explicacion' => $response['explicacion'],
                'razon_correcta' => $response['razon_correcta'],
            ]);
        } catch (\Throwable $e) {
            return response()->json(['error' => 'Falló la respuesta de la IA'], 500);
        }
    }
}

Ejemplo de petición

json

{
  "pregunta": "¿Cuál es la capital de Perú?",
  "opciones": ["Lima", "Cusco", "Arequipa", "Trujillo"],
  "correcta": "Lima"
}

Respuesta esperada

json

{
  "explicacion": "Lima es la capital de Perú porque es la sede del gobierno...",
  "razon_correcta": "Es la ciudad donde reside el poder ejecutivo y es la más poblada del país."
}

Paso 4: validando los datos de entrada

Nunca confíes en los datos que llegan del cliente. El uso de $request->validate() en el ejemplo anterior asegura que siempre recibas una pregunta, un arreglo de al menos dos opciones y una respuesta correcta antes de gastar una llamada a la API de IA.


Paso 5: buenas prácticas para producción

  1. Registra los errores reales con Log::error($e) en el catch, y muestra solo un mensaje genérico al usuario.
  2. Usa failover entre proveedores para mayor disponibilidad:

php

   provider: [Lab::Gemini, Lab::OpenAI, Lab::Anthropic],
  1. Procesa exámenes completos en cola (queue()) si necesitas explicar decenas de preguntas sin bloquear el request HTTP.
  2. Cachea instrucciones repetidas con #[CacheInstructions] si usas Anthropic, para reducir costos cuando el mismo agente se invoca muchas veces.
  3. Testea sin gastar créditos reales usando los fakes del SDK:

php

   QuestionExplainer::fake([
       ['explicacion' => 'Respuesta simulada', 'razon_correcta' => 'Motivo simulado'],
   ]);

Conclusión

Con el Laravel AI SDK puedes transformar un simple banco de preguntas en una herramienta pedagógica inteligente: basta con enviar la pregunta, las opciones y la respuesta correcta para obtener, en segundos, una explicación clara y bien fundamentada. La combinación de agentes dedicados, salida estructurada y manejo robusto de errores hace que este flujo sea fácil de mantener y escalar a producción.


Tutoriales Recomendados

Sigue explorando publicaciones de la misma categoría

Ver todos