Setup
Getting started with Instructor requires two things:
- Install the
cognesy/instructor-structpackage - Provide LLM provider credentials
Installation¶
Instructor requires PHP 8.3 or later.
Providing API Keys¶
Instructor reads provider credentials from environment variables. The simplest approach
is to set them in your shell or a .env file at the root of your project:
For other providers, set the corresponding variable:
Never commit API keys to version control. Add
.envto your.gitignorefile.
Preset-Based Setup¶
Presets are the fastest way to get started. A preset name maps to a provider configuration that reads credentials from the environment:
use Cognesy\Instructor\StructuredOutput;
$result = StructuredOutput::using('openai')
->with(
messages: 'What is the capital of France?',
responseModel: City::class,
)
->get();
You can switch providers by changing the preset name:
// Use Anthropic instead of OpenAI
$result = StructuredOutput::using('anthropic')
->with(
messages: 'What is the capital of France?',
responseModel: City::class,
)
->get();
Explicit Provider Configuration¶
When you need full control over the driver, model, API base URL, or other connection
parameters, use LLMConfig directly:
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$result = StructuredOutput::fromConfig(
LLMConfig::fromDsn('driver=openai,model=gpt-4o-mini')
)->with(
messages: 'What is the capital of France?',
responseModel: City::class,
)->get();
You can also construct LLMConfig from an array for more detailed configuration:
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$config = LLMConfig::fromArray([
'driver' => 'openai',
'model' => 'gpt-4o-mini',
'apiKey' => $_ENV['OPENAI_API_KEY'],
'apiUrl' => 'https://api.openai.com/v1',
'maxTokens' => 4096,
]);
$result = StructuredOutput::fromConfig($config)
->with(
messages: 'What is the capital of France?',
responseModel: City::class,
)
->get();
Runtime Configuration¶
StructuredOutput handles single requests. When you need to configure behavior that
applies across multiple requests -- retries, output mode, event listeners, or custom
pipeline extensions -- use StructuredOutputRuntime:
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Instructor\StructuredOutputRuntime;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$runtime = StructuredOutputRuntime::fromConfig(
LLMConfig::fromPreset('openai')
)->withMaxRetries(3);
$structured = (new StructuredOutput)->withRuntime($runtime);
$city = $structured
->with(
messages: 'What is the capital of France?',
responseModel: City::class,
)
->get();
What Belongs Where¶
Understanding the separation of concerns helps you structure your application:
| Layer | Responsibility | Examples |
|---|---|---|
LLMConfig |
Provider connection details | Driver, model, API key, base URL, max tokens |
StructuredOutputConfig |
Extraction behavior | Output mode, retry prompt template, schema naming |
StructuredOutputRuntime |
Runtime behavior | Max retries, event listeners, custom validators/transformers |
StructuredOutput |
Single request | Messages, response model, system prompt, examples |
Output Modes¶
Instructor supports multiple strategies for getting structured output from the LLM.
The default mode (Tools) uses the provider's function/tool calling API. You can switch
modes via the runtime:
use Cognesy\Instructor\Enums\OutputMode;
$runtime = StructuredOutputRuntime::fromConfig(
LLMConfig::fromPreset('openai')
)->withOutputMode(OutputMode::JsonSchema);
Available modes:
| Mode | Description |
|---|---|
OutputMode::Tools |
Uses the provider's tool/function calling API (default) |
OutputMode::Json |
Requests JSON output via the provider's JSON mode |
OutputMode::JsonSchema |
Sends a JSON Schema and requests strict conformance |
OutputMode::MdJson |
Asks the LLM to return JSON inside a Markdown code block |
OutputMode::Text |
Extracts JSON from unstructured text responses |
OutputMode::Unrestricted |
No output constraints; extraction is best-effort |
Event Listeners¶
The runtime exposes a full event system for monitoring and debugging:
use Cognesy\Instructor\Events\StructuredOutput\StructuredOutputRequestReceived;
$runtime = StructuredOutputRuntime::fromConfig(
LLMConfig::fromPreset('openai')
);
// Listen for a specific event
$runtime->onEvent(
StructuredOutputRequestReceived::class,
fn($event) => logger()->info('Request received', $event->toArray()),
);
// Or wiretap all events
$runtime->wiretap(
fn($event) => logger()->debug(get_class($event)),
);
Using a Local Model with Ollama¶
Instructor works with local models through Ollama. Install Ollama, pull a model, and point Instructor at the local endpoint:
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$result = StructuredOutput::fromConfig(
LLMConfig::fromDsn('driver=ollama,model=llama3.1')
)->with(
messages: 'What is the capital of France?',
responseModel: City::class,
)->get();
Framework Integration¶
Instructor is a standalone library that works in any PHP application. It does not require published config files, service providers, or framework-specific bindings.
For Laravel-specific installation, configuration, facades, events, and testing, use the dedicated Laravel package docs:
Next Steps¶
- Quickstart -- run your first extraction
- Usage -- the full request-building API
- Configuration -- advanced configuration options
- Modes -- output mode details and trade-offs
- LLM Providers -- supported providers and driver options