Skip to main content

Artisan Commands

The package registers three Artisan commands to help with installation, testing, and scaffolding. All commands are registered automatically when the application is running in console mode.

instructor:install

Sets up the Instructor package in your Laravel application. This is the recommended first step after installing the Composer package.
php artisan instructor:install
# @doctest id="086c"

What It Does

  1. Publishes the configuration file (config/instructor.php) using the instructor-config publish tag
  2. Checks for API key configuration by scanning your .env file for OPENAI_API_KEY or ANTHROPIC_API_KEY entries
  3. Displays next steps including how to create your first response model and test the installation
If no API keys are detected, the command displays a warning with instructions for adding them.

Options

OptionDescription
--forceOverwrite existing configuration files (passed through to vendor:publish)

Example Output

Installing Instructor for Laravel...

Publishing configuration... done
Checking API key configuration... done

Next steps:

  1. Configure your API keys in .env:
     OPENAI_API_KEY=your-key-here

  2. Create a response model:
     php artisan make:response-model PersonData

  3. Extract structured data:
     $person = StructuredOutput::with(
         messages: "John is 30 years old",
         responseModel: PersonData::class,
     )->get();

  4. Test your installation:
     php artisan instructor:test

Instructor installed successfully!
// @doctest id="e12e"

instructor:test

Tests your Instructor installation and API configuration by making a real API call. This verifies that your API key is valid, the network connection works, and the full extraction pipeline (or raw inference pipeline) is operational.
php artisan instructor:test
# @doctest id="5c72"

What It Does

  1. Displays current configuration — connection name, driver, model, and a masked version of the API key
  2. Makes a test API call — either a structured output extraction (default) or a raw inference call
  3. Verifies the response — confirms the result contains the expected data
For the structured output test, the command extracts a simple name-and-age pair from a test sentence. For the inference test, it sends “Reply with just the word ‘pong’” and checks the response.

Options

OptionDescription
--connection=Test a specific configured connection instead of the default
--inferenceTest raw inference instead of structured output extraction

Examples

# Test default connection
php artisan instructor:test

# Test specific connection
php artisan instructor:test --connection=anthropic

# Test raw inference
php artisan instructor:test --inference
# @doctest id="5b52"

Example Output

Testing Instructor installation...

Connection ......................................... openai
Driver ............................................. openai
Model .............................................. gpt-4o-mini
API Key ............................................ sk-a...xyz1 done

Testing structured output extraction... done

Structured output test completed!
// @doctest id="f855"
Use the -v flag for verbose output, which includes a full stack trace if the test fails.

make:response-model

Generates a new response model class with typed constructor properties, docblock descriptions, and the correct namespace. The generated class is ready to use with StructuredOutput::with(responseModel: ...) immediately.
php artisan make:response-model {name}
# @doctest id="a4c8"

Arguments

ArgumentDescription
nameThe name of the response model class (e.g., PersonData, InvoiceDetails)

Options

OptionDescription
--collection, -cCreate a collection response model with a parent class containing an array of child item objects
--nested, -nCreate a nested response model with child object properties (Contact, Address)
--description=, -dSet the class docblock description (defaults to a TODO placeholder)
--force, -fOverwrite an existing file

Examples

Basic Response Model

php artisan make:response-model PersonData
# @doctest id="e4d6"
Creates app/ResponseModels/PersonData.php:
<?php

declare(strict_types=1);

namespace App\ResponseModels;

/**
 * TODO: Add description for this response model
 */
final class PersonData
{
    public function __construct(
        /** The name of the person */
        public readonly string $name,

        /** The age of the person in years */
        public readonly int $age,

        /** Optional email address */
        public readonly ?string $email = null,
    ) {}
}
// @doctest id="a3aa"

Collection Response Model

php artisan make:response-model ProductList --collection
# @doctest id="ea5e"
Creates a model with an array of typed items, plus a companion item class in the same file:
final class ProductList
{
    public function __construct(
        /** List of extracted items */
        public readonly array $items,
    ) {}
}

final class ProductListItem
{
    public function __construct(
        public readonly string $name,
        public readonly ?string $description = null,
    ) {}
}
// @doctest id="9614"

Nested Objects Response Model

php artisan make:response-model CompanyProfile --nested
# @doctest id="3375"
Creates a model with nested Contact and Address objects:
final class CompanyProfile
{
    public function __construct(
        public readonly string $title,
        public readonly CompanyProfileContact $contact,
        public readonly ?CompanyProfileAddress $address = null,
    ) {}
}

final class CompanyProfileContact
{
    public function __construct(
        public readonly string $name,
        public readonly string $email,
        public readonly ?string $phone = null,
    ) {}
}

final class CompanyProfileAddress
{
    public function __construct(
        public readonly string $street,
        public readonly string $city,
        public readonly string $country,
        public readonly ?string $postalCode = null,
    ) {}
}
// @doctest id="f69e"

With Description

php artisan make:response-model Invoice --description="Represents an invoice extracted from PDF documents"
# @doctest id="bd5d"
Creates a model with the specified description replacing the TODO placeholder in the docblock.

Customizing Stubs

Publish the stubs to customize the templates used by make:response-model:
php artisan vendor:publish --tag=instructor-stubs
# @doctest id="7e17"
This copies stubs to stubs/instructor/ in your application root:
stubs/instructor/
+-- response-model.stub
+-- response-model.collection.stub
+-- response-model.nested.stub
// @doctest id="9ad3"
The command checks for published stubs first, falling back to the package defaults only when no custom stub is found.

Stub Placeholders

PlaceholderDescription
{{ namespace }}The fully qualified namespace for the class
{{ class }}The class name
{{ description }}The class description (from --description or the default TODO)

Creating Custom Commands

Build your own Artisan commands that use the facades for domain-specific extraction tasks:
// app/Console/Commands/ExtractInvoiceCommand.php
namespace App\Console\Commands;

use App\ResponseModels\InvoiceData;
use Cognesy\Instructor\Laravel\Facades\StructuredOutput;
use Illuminate\Console\Command;

class ExtractInvoiceCommand extends Command
{
    protected $signature = 'invoice:extract {file}';
    protected $description = 'Extract invoice data from a file';

    public function handle(): int
    {
        $content = file_get_contents($this->argument('file'));

        $invoice = StructuredOutput::with(
            messages: $content,
            responseModel: InvoiceData::class,
        )->get();

        $this->info("Invoice Number: {$invoice->number}");
        $this->info("Amount: \${$invoice->amount}");
        $this->info("Due Date: {$invoice->dueDate}");

        return self::SUCCESS;
    }
}
// @doctest id="7204"

Command Reference

CommandDescription
instructor:installInstall and configure the package
instructor:testTest API configuration with a real API call
make:response-modelGenerate a response model class