7.1 KiB
title, description
| title | description |
|---|---|
| Iterable Extraction with Instructor - Stream Multiple Objects | Use Iterable types to extract and stream multiple structured objects from LLM responses. Perfect for entity extraction and multi-task outputs. |
Multi-Task and Streaming
Using an Iterable lets you extract multiple structured objects from a single LLM call, streaming them as they arrive. This is useful for entity extraction, multi-task outputs, and more.
We recommend using the create_iterable method for most use cases. It's simpler and less error-prone than manually specifying Iterable[...] and stream=True.
Here's a simple example showing how to extract multiple users from a single sentence. You can use either the recommended create_iterable method or the create method with Iterable[User]:
=== "Using create_iterable (recommended)"
```python
import instructor
from pydantic import BaseModel
client = instructor.from_provider("openai/gpt-4.1-mini")
class User(BaseModel):
name: str
age: int
resp = client.create_iterable(
messages=[
{
"role": "user",
"content": "Ivan is 28, lives in Moscow and his friends are Alex, John and Mary who are 25, 30 and 27 respectively",
}
],
response_model=User,
)
for user in resp:
print(user)
#> name='Ivan' age=28
#> name='Alex' age=25
#> name='John' age=30
#> name='Mary' age=27
```
_Recommended for most use cases. Handles streaming and iteration for you._
=== "Using create with Iterable[User]"
```python
import instructor
from pydantic import BaseModel
from typing import Iterable
client = instructor.from_provider("openai/gpt-4.1-mini")
class User(BaseModel):
name: str
age: int
resp = client.create(
messages=[
{
"role": "user",
"content": "Ivan is 28, lives in Moscow and his friends are Alex, John and Mary who are 25, 30 and 27 respectively",
}
],
response_model=Iterable[User],
)
for user in resp:
print(user)
#> name='Ivan' age=28
#> name='Alex' age=25
#> name='John' age=30
#> name='Mary' age=27
```
_Use this if you need more manual control or compatibility with legacy code._
We also support more complex extraction patterns such as Unions as you'll see below out of the box.
???+ warning
Unions don't work with Gemini because the AnyOf is not supported in the current response schema.
Synchronous Usage
=== "Using create"
```python
import instructor
from typing import Iterable, Union, Literal
from pydantic import BaseModel
class Weather(BaseModel):
location: str
units: Literal["imperial", "metric"]
class GoogleSearch(BaseModel):
query: str
client = instructor.from_provider("openai/gpt-4.1-mini", mode=instructor.Mode.TOOLS)
results = client.create(
messages=[
{"role": "system", "content": "You must always use tools"},
{
"role": "user",
"content": "What is the weather in toronto and dallas and who won the super bowl?",
},
],
response_model=Iterable[Union[Weather, GoogleSearch]],
stream=True,
)
for item in results:
print(item)
#> location='Toronto' units='metric'
#> location='Dallas' units='imperial'
#> query='Super Bowl winner'
```
=== "Using create_iterable (recommended)"
```python
import instructor
from typing import Union, Literal
from pydantic import BaseModel
class Weather(BaseModel):
location: str
units: Literal["imperial", "metric"]
class GoogleSearch(BaseModel):
query: str
client = instructor.from_provider("openai/gpt-4.1-mini", mode=instructor.Mode.TOOLS)
results = client.create_iterable(
messages=[
{"role": "system", "content": "You must always use tools"},
{
"role": "user",
"content": "What is the weather in toronto and dallas and who won the super bowl?",
},
],
response_model=Union[Weather, GoogleSearch],
)
for item in results:
print(item)
#> location='Toronto' units='metric'
#> location='Dallas' units='imperial'
#> query='Super Bowl winner'
```
See Also
- Streaming Lists - Similar functionality with different API
- Streaming Partial - Stream partially completed objects
- List Extraction Tutorial - Step-by-step guide
- Streaming Basics - Introduction to streaming
Asynchronous Usage
=== "Using create"
```python
import instructor
from typing import Iterable, Union, Literal
from pydantic import BaseModel
import asyncio
class Weather(BaseModel):
location: str
units: Literal["imperial", "metric"]
class GoogleSearch(BaseModel):
query: str
aclient = instructor.from_provider(
"openai/gpt-4.1-mini", async_client=True, mode=instructor.Mode.TOOLS
)
async def main():
results = await aclient.create(
messages=[
{"role": "system", "content": "You must always use tools"},
{
"role": "user",
"content": "What is the weather in toronto and dallas and who won the super bowl?",
},
],
response_model=Iterable[Union[Weather, GoogleSearch]],
stream=True,
)
async for item in results:
print(item)
#> location='Toronto' units='metric'
#> location='Dallas' units='imperial'
#> query='Super Bowl winner'
asyncio.run(main())
```
=== "Using create_iterable (recommended)"
```python
import asyncio
from typing import Literal, Union
import instructor
from pydantic import BaseModel
class Weather(BaseModel):
location: str
units: Literal["imperial", "metric"]
class GoogleSearch(BaseModel):
query: str
aclient = instructor.from_provider(
"openai/gpt-4.1-mini", async_client=True, mode=instructor.Mode.TOOLS
)
async def iter_results():
async for item in aclient.create_iterable(
messages=[
{"role": "system", "content": "You must always use tools"},
{
"role": "user",
"content": "What is the weather in toronto and dallas and who won the super bowl?",
},
],
response_model=Union[Weather, GoogleSearch],
):
yield item
async def main():
async for item in iter_results():
print(item)
#> location='Toronto' units='metric'
#> location='Dallas' units='imperial'
#> query='Super Bowl winner'
asyncio.run(main())
```