Instructor Package Cheatsheet¶
Code-verified quick reference for packages/instructor.
Core Flow¶
use Cognesy\Instructor\StructuredOutput;
class User {
public string $name;
public int $age;
}
$user = (new StructuredOutput)
->with(
messages: 'Jason is 28 years old.',
responseModel: User::class,
)
->get();
Create StructuredOutput¶
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$so = new StructuredOutput();
$so = StructuredOutput::using('openai');
$so = StructuredOutput::using('openai', '/custom/config/path');
$so = StructuredOutput::fromConfig(LLMConfig::fromArray(['driver' => 'openai']));
Request Configuration (StructuredOutput)¶
$so = (new StructuredOutput)
->withMessages($messages)
->withInput($input)
->withRequest($request)
->withResponseModel(User::class)
->withResponseClass(User::class)
->withResponseObject(new User())
->withResponseJsonSchema($jsonSchema)
->withSystem('You are a precise extractor') // string|\Stringable
->withPrompt('Extract user profile') // string|\Stringable
->withExamples($examples)
->withModel('gpt-4o-mini')
->withOptions(['temperature' => 0])
->withOption('max_tokens', 1200)
->withStreaming(true);
Single-call variant:
$so = (new StructuredOutput)->with(
messages: $messages,
responseModel: User::class,
system: '...', // string|\Stringable|null
prompt: '...', // string|\Stringable|null
examples: $examples,
model: 'gpt-4o-mini',
options: ['temperature' => 0],
);
Runtime / Provider Setup¶
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Instructor\StructuredOutputRuntime;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
use Cognesy\Instructor\Enums\OutputMode;
$so = StructuredOutput::fromConfig(LLMConfig::fromArray(['driver' => 'openai']));
$runtime = StructuredOutputRuntime::fromConfig(LLMConfig::fromDsn('driver=openai,model=gpt-4o-mini'))
->withOutputMode(OutputMode::Json)
->withMaxRetries(2);
// Create from LLMProvider
$runtime = StructuredOutputRuntime::fromProvider(LLMProvider::new());
// Configure with StructuredOutputConfig
$runtime = $runtime->withConfig(StructuredOutputConfig::fromArray([...]));
$runtime = $runtime->withConfig(StructuredOutputConfig::fromDsn('outputMode=json,maxRetries=2'));
$runtime = $runtime->withRequestMaterializer($customMaterializer);
$so = (new StructuredOutput)->withRuntime($runtime);
OutputMode Enum¶
use Cognesy\Instructor\Enums\OutputMode;
OutputMode::Tools; // 'tool_call' — default, uses tool/function calling
OutputMode::Json; // 'json' — JSON mode
OutputMode::JsonSchema; // 'json_schema' — structured outputs / JSON schema mode
OutputMode::MdJson; // 'md_json' — extract JSON from Markdown code blocks
OutputMode::Text; // 'text' — plain text extraction
OutputMode::Unrestricted; // 'unrestricted' — no constraints on output format
Pipeline Overrides¶
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Instructor\StructuredOutputRuntime;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$runtime = StructuredOutputRuntime::fromConfig(LLMConfig::fromDsn('driver=openai,model=gpt-4o-mini'))
->withValidator($validator)
->withTransformer($transformer)
->withDeserializer($deserializer)
->withExtractor($extractor);
$so = (new StructuredOutput)->withRuntime($runtime);
Execution¶
$result = $so->get(); // parsed value
$response = $so->response(); // StructuredOutputResponse
$raw = $so->inferenceResponse(); // InferenceResponse
$stream = $so->stream(); // StructuredOutputStream
$pending = $so->create();
$result = $pending->get();
$response = $pending->response();
$raw = $pending->inferenceResponse();
$stream = $pending->stream();
$array = $pending->toArray();
$json = $pending->toJson();
$jsonObject = $pending->toJsonObject();
$execution = $pending->execution();
PendingStructuredOutput is a lazy handle:
- no provider call happens until one of the read methods above is used
- get(), response(), inferenceResponse(), and stream() coordinate one execution
- mutable lifecycle bookkeeping sits behind the internal execution session, not on the facade-facing handle
- long-lived streaming state stays in the dedicated stream/state objects
Type helpers (available on StructuredOutput and PendingStructuredOutput):
$so->getString();
$so->getInt();
$so->getFloat();
$so->getBoolean();
$so->getObject();
$so->getArray();
Additional type helper (only on PendingStructuredOutput):
Streaming (StructuredOutputStream)¶
$stream = $so->withStreaming()->stream();
foreach ($stream->partials() as $partial) {
// every parsed partial update
}
foreach ($stream->sequence() as $sequenceUpdate) {
// one update per completed sequence item (Sequence responses only)
}
foreach ($stream->responses() as $responseUpdate) {
// StructuredOutputResponse, partial or final
}
foreach ($stream->getIterator() as $rawUpdate) {
// raw emitted StructuredOutputResponse snapshots
}
$latestValue = $stream->lastUpdate();
$latestResponse = $stream->lastResponse();
$usage = $stream->usage();
$finalValue = $stream->finalValue();
$finalResponse = $stream->finalResponse();
$finalRaw = $stream->finalInferenceResponse();
lastResponse() / finalResponse() return StructuredOutputResponse.
Use ->inferenceResponse() when you need the nested raw InferenceResponse.
Response Model Helpers¶
Sequence¶
use Cognesy\Instructor\Extras\Sequence\Sequence;
$people = (new StructuredOutput)
->with(
messages: $text,
responseModel: Sequence::of(Person::class),
)
->get();
$count = $people->count();
$first = $people->first();
$last = $people->last();
$item = $people->get(0);
$all = $people->all();
Scalar¶
use Cognesy\Instructor\Extras\Scalar\Scalar;
$name = (new StructuredOutput)
->with(messages: $text, responseModel: Scalar::string('name'))
->get();
$age = (new StructuredOutput)
->with(messages: $text, responseModel: Scalar::integer('age'))
->get();
$isAdult = (new StructuredOutput)
->with(messages: $text, responseModel: Scalar::boolean('isAdult'))
->get();
$sentiment = (new StructuredOutput)
->with(messages: $text, responseModel: Scalar::enum(Sentiment::class, 'sentiment'))
->get();
Maybe¶
use Cognesy\Instructor\Extras\Maybe\Maybe;
$maybeUser = (new StructuredOutput)
->with(messages: $text, responseModel: Maybe::is(User::class))
->get();
if ($maybeUser->hasValue()) {
$user = $maybeUser->get();
}
$error = $maybeUser->error();
Output Controls¶
use Cognesy\Instructor\Extras\Scalar\Scalar;
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Instructor\StructuredOutputRuntime;
use Cognesy\Instructor\Enums\OutputMode;
use Cognesy\Polyglot\Inference\Config\LLMConfig;
$runtime = StructuredOutputRuntime::fromConfig(LLMConfig::fromDsn('driver=openai,model=gpt-4o-mini'))
->withOutputMode(OutputMode::Json)
->withMaxRetries(3)
->withDefaultToStdClass(true);
$so = (new StructuredOutput)->withRuntime($runtime);
$asArray = (new StructuredOutput)->intoArray();
$asClass = (new StructuredOutput)->intoInstanceOf(User::class);
$asObject = (new StructuredOutput)->intoObject(Scalar::integer('rating'));
Cached Context¶
$result = (new StructuredOutput)
->withCachedContext(
messages: $longContext,
system: 'You know the full context',
)
->with(
prompt: 'Extract only contact details',
responseModel: Contact::class,
)
->get();
Examples API¶
use Cognesy\Instructor\Extras\Example\Example;
$result = (new StructuredOutput)
->withExamples([
Example::fromText(
'John Doe, john@example.com',
['name' => 'John Doe', 'email' => 'john@example.com'],
),
])
->with(messages: $text, responseModel: Contact::class)
->get();
Events¶
use Cognesy\Instructor\StructuredOutput;
use Cognesy\Instructor\StructuredOutputRuntime;
use Cognesy\Instructor\Events\StructuredOutput\StructuredOutputRequestReceived;
use Cognesy\Polyglot\Inference\LLMProvider;
$runtime = StructuredOutputRuntime::fromProvider(LLMProvider::new())
->onEvent(StructuredOutputRequestReceived::class, function (object $event): void {
// handle selected event
})
->wiretap(function (object $event): void {
// handle all events
});
$result = (new StructuredOutput)
->withRuntime($runtime)
->with(messages: $text, responseModel: User::class)
->get();
Testing¶
Deterministic test seams:
Tests\Support\FakeInferenceDriver- queue sync
InferenceResponsefixtures or streamingPartialInferenceDeltabatches - best for most unit and regression tests inside
packages/instructor Tests\MockHttp- builds an HTTP client around
MockHttpDriver - use when provider adapter and HTTP response shape still matter
Tests\Integration\Support\ProbeStreamDriver- observation helper for streaming immediacy and call-count assertions
Tests\Support\ProbeIterator- explicit iterator helper for controlled delta emission in integration tests