Partials
Streaming lets you receive partial updates as the LLM generates its response, rather than waiting for the complete result. This is useful for improving perceived latency in user interfaces -- you can render data progressively as it arrives.
Basic Streaming¶
Call stream() instead of get() to receive a StructuredOutputStream. The partials() method yields parsed partial objects as the response is built.
use Cognesy\Instructor\StructuredOutput;
$stream = (new StructuredOutput)
->with(messages: $text, responseModel: Person::class)
->stream();
foreach ($stream->partials() as $partial) {
// $partial is a Person object with fields populated so far
updateUI($partial);
}
Instructor is smart about updates. It calculates and compares hashes of the previous and newly deserialized version of the model, so your callback only fires when a property actually changes -- not on every token received.
Partial updates are deserialized but not validated. Only the final result returned by finalValue() is fully validated, making it safe to persist or process further.
Explicit Streaming Control¶
You can also enable streaming with withStreaming() and then call get(), which internally drains the stream and returns the final value.
$person = (new StructuredOutput)
->withResponseClass(Person::class)
->withStreaming()
->with(messages: $text)
->get();
StructuredOutputStream Methods¶
The StructuredOutputStream class provides several ways to consume the stream.
Iteration Methods¶
| Method | Description |
|---|---|
partials() |
Yields parsed partial values. Only the final update is validated; earlier partials are only deserialized. |
sequence() |
For Sequence response models -- yields only completed items. See Sequences. |
responses() |
Yields StructuredOutputResponse snapshots as they arrive. |
Result Access Methods¶
| Method | Description |
|---|---|
finalValue() |
Drains the stream and returns the final parsed, validated result. |
finalResponse() |
Drains the stream and returns the final StructuredOutputResponse. |
lastUpdate() |
Returns the most recently received parsed value. |
lastResponse() |
Returns the most recently received StructuredOutputResponse. |
Utility Methods¶
| Method | Description |
|---|---|
usage() |
Returns the latest token usage data from the stream. |
Example: Streaming with Final Retrieval¶
A common pattern is to stream partials for UI updates, then use the final validated value for persistence.
$stream = (new StructuredOutput)->with(
messages: "His name is Jason, he is 28 years old.",
responseModel: Person::class,
)->stream();
foreach ($stream->partials() as $update) {
$view->updateView($update);
}
// Final validated object
$person = $stream->finalValue();
$db->savePerson($person);
Example: Streaming Sequence Items¶
When using a Sequence response model, you can stream completed items individually rather than waiting for the entire list.
use Cognesy\Instructor\Extras\Sequence\Sequence;
$stream = (new StructuredOutput)
->with(
messages: "Jason is 28. Amanda is 26. John is 40.",
responseModel: Sequence::of(Person::class),
)
->stream();
foreach ($stream->sequence() as $person) {
$view->appendPerson($person);
}
$people = $stream->finalValue();
$db->savePeople($people->toArray());
Streaming with Output Formats¶
Streaming works with all output formats. During streaming, partials are always objects regardless of your chosen output format. The final value respects the format you specified. See Output Formats for details.