Skip to content

API Reference

apatch(client, mode=Mode.FUNCTIONS)

No longer necessary, use patch instead.

Patch the client.chat.completions.create method

Enables the following features:

  • response_model parameter to parse the response from OpenAI's API
  • max_retries parameter to retry the function if the response is not valid
  • validation_context parameter to validate the response using the pydantic model
  • strict parameter to use strict json parsing
Source code in instructor/patch.py
def apatch(client: AsyncOpenAI, mode: Mode = Mode.FUNCTIONS):
    """
    No longer necessary, use `patch` instead.

    Patch the `client.chat.completions.create` method

    Enables the following features:

    - `response_model` parameter to parse the response from OpenAI's API
    - `max_retries` parameter to retry the function if the response is not valid
    - `validation_context` parameter to validate the response using the pydantic model
    - `strict` parameter to use strict json parsing
    """
    return patch(client, mode=mode)

dump_message(message)

Dumps a message to a dict, to be returned to the OpenAI API. Workaround for an issue with the OpenAI API, where the tool_calls field isn't allowed to be present in requests if it isn't used.

Source code in instructor/patch.py
def dump_message(message: ChatCompletionMessage) -> ChatCompletionMessageParam:
    """Dumps a message to a dict, to be returned to the OpenAI API.
    Workaround for an issue with the OpenAI API, where the `tool_calls` field isn't allowed to be present in requests
    if it isn't used.
    """
    ret: ChatCompletionMessageParam = {
        "role": message.role,
        "content": message.content or "",
    }
    if message.tool_calls is not None:
        ret["content"] += json.dumps(message.model_dump()["tool_calls"])
    if message.function_call is not None:
        ret["content"] += json.dumps(message.model_dump()["function_call"])
    return ret

is_async(func)

Returns true if the callable is async, accounting for wrapped callables

Source code in instructor/patch.py
def is_async(func: Callable) -> bool:
    """Returns true if the callable is async, accounting for wrapped callables"""
    return inspect.iscoroutinefunction(func) or (
        hasattr(func, "__wrapped__") and inspect.iscoroutinefunction(func.__wrapped__)
    )

patch(client, mode=Mode.FUNCTIONS)

Patch the client.chat.completions.create method

Enables the following features:

  • response_model parameter to parse the response from OpenAI's API
  • max_retries parameter to retry the function if the response is not valid
  • validation_context parameter to validate the response using the pydantic model
  • strict parameter to use strict json parsing
Source code in instructor/patch.py
def patch(client: Union[OpenAI, AsyncOpenAI], mode: Mode = Mode.FUNCTIONS):
    """
    Patch the `client.chat.completions.create` method

    Enables the following features:

    - `response_model` parameter to parse the response from OpenAI's API
    - `max_retries` parameter to retry the function if the response is not valid
    - `validation_context` parameter to validate the response using the pydantic model
    - `strict` parameter to use strict json parsing
    """

    logger.debug(f"Patching `client.chat.completions.create` with {mode=}")
    client.chat.completions.create = wrap_chatcompletion(
        client.chat.completions.create, mode=mode
    )
    return client

process_response(response, *, response_model, stream, validation_context=None, strict=None, mode=Mode.FUNCTIONS)

Processes a OpenAI response with the response model, if available. It can use validation_context and strict to validate the response via the pydantic model

Parameters:

Name Type Description Default
response ChatCompletion

The response from OpenAI's API

required
response_model BaseModel

The response model to use for parsing the response

required
stream bool

Whether the response is a stream

required
validation_context dict

The validation context to use for validating the response. Defaults to None.

None
strict bool

Whether to use strict json parsing. Defaults to None.

None
Source code in instructor/patch.py
def process_response(
    response,
    *,
    response_model: Type[BaseModel],
    stream: bool,
    validation_context: dict = None,
    strict=None,
    mode: Mode = Mode.FUNCTIONS,
):  # type: ignore
    """Processes a OpenAI response with the response model, if available.
    It can use `validation_context` and `strict` to validate the response
    via the pydantic model

    Args:
        response (ChatCompletion): The response from OpenAI's API
        response_model (BaseModel): The response model to use for parsing the response
        stream (bool): Whether the response is a stream
        validation_context (dict, optional): The validation context to use for validating the response. Defaults to None.
        strict (bool, optional): Whether to use strict json parsing. Defaults to None.
    """
    if response_model is not None:
        is_model_multitask = issubclass(response_model, MultiTaskBase)
        model = response_model.from_response(
            response,
            validation_context=validation_context,
            strict=strict,
            mode=mode,
            stream_multitask=stream and is_model_multitask,
        )
        if not stream:
            model._raw_response = response
            if is_model_multitask:
                return model.tasks
        return model
    return response

process_response_async(response, *, response_model, stream, validation_context=None, strict=None, mode=Mode.FUNCTIONS) async

Processes a OpenAI response with the response model, if available. It can use validation_context and strict to validate the response via the pydantic model

Parameters:

Name Type Description Default
response ChatCompletion

The response from OpenAI's API

required
response_model BaseModel

The response model to use for parsing the response

required
stream bool

Whether the response is a stream

required
validation_context dict

The validation context to use for validating the response. Defaults to None.

None
strict bool

Whether to use strict json parsing. Defaults to None.

None
Source code in instructor/patch.py
async def process_response_async(
    response,
    *,
    response_model: Type[BaseModel],
    stream: bool,
    validation_context: dict = None,
    strict=None,
    mode: Mode = Mode.FUNCTIONS,
):  # type: ignore
    """Processes a OpenAI response with the response model, if available.
    It can use `validation_context` and `strict` to validate the response
    via the pydantic model

    Args:
        response (ChatCompletion): The response from OpenAI's API
        response_model (BaseModel): The response model to use for parsing the response
        stream (bool): Whether the response is a stream
        validation_context (dict, optional): The validation context to use for validating the response. Defaults to None.
        strict (bool, optional): Whether to use strict json parsing. Defaults to None.
    """
    if response_model is not None:
        is_model_multitask = issubclass(response_model, MultiTaskBase)
        model = await response_model.from_response_async(
            response,
            validation_context=validation_context,
            strict=strict,
            mode=mode,
            stream_multitask=stream and is_model_multitask,
        )
        if not stream:
            model._raw_response = response
            if is_model_multitask:
                return model.tasks
        return model
    return response

Validator

Bases: OpenAISchema

Validate if an attribute is correct and if not, return a new value with an error message

Source code in instructor/dsl/validators.py
class Validator(OpenAISchema):
    """
    Validate if an attribute is correct and if not,
    return a new value with an error message
    """

    is_valid: bool = Field(
        default=True,
        description="Whether the attribute is valid based on the requirements",
    )
    reason: Optional[str] = Field(
        default=None,
        description="The error message if the attribute is not valid, otherwise None",
    )
    fixed_value: Optional[str] = Field(
        default=None,
        description="If the attribute is not valid, suggest a new value for the attribute",
    )

llm_validator(statement, allow_override=False, model='gpt-3.5-turbo', temperature=0, openai_client=None)

Create a validator that uses the LLM to validate an attribute

Usage

from instructor import llm_validator
from pydantic import BaseModel, Field, field_validator

class User(BaseModel):
    name: str = Annotated[str, llm_validator("The name must be a full name all lowercase")
    age: int = Field(description="The age of the person")

try:
    user = User(name="Jason Liu", age=20)
except ValidationError as e:
    print(e)
1 validation error for User
name
  The name is valid but not all lowercase (type=value_error.llm_validator)

Note that there, the error message is written by the LLM, and the error type is value_error.llm_validator.

Parameters:

Name Type Description Default
statement str

The statement to validate

required
model str

The LLM to use for validation (default: "gpt-3.5-turbo-0613")

'gpt-3.5-turbo'
temperature float

The temperature to use for the LLM (default: 0)

0
openai_client OpenAI

The OpenAI client to use (default: None)

None
Source code in instructor/dsl/validators.py
def llm_validator(
    statement: str,
    allow_override: bool = False,
    model: str = "gpt-3.5-turbo",
    temperature: float = 0,
    openai_client: OpenAI = None,
):
    """
    Create a validator that uses the LLM to validate an attribute

    ## Usage

    ```python
    from instructor import llm_validator
    from pydantic import BaseModel, Field, field_validator

    class User(BaseModel):
        name: str = Annotated[str, llm_validator("The name must be a full name all lowercase")
        age: int = Field(description="The age of the person")

    try:
        user = User(name="Jason Liu", age=20)
    except ValidationError as e:
        print(e)
    ```

    ```
    1 validation error for User
    name
      The name is valid but not all lowercase (type=value_error.llm_validator)
    ```

    Note that there, the error message is written by the LLM, and the error type is `value_error.llm_validator`.

    Parameters:
        statement (str): The statement to validate
        model (str): The LLM to use for validation (default: "gpt-3.5-turbo-0613")
        temperature (float): The temperature to use for the LLM (default: 0)
        openai_client (OpenAI): The OpenAI client to use (default: None)
    """

    openai_client = openai_client or OpenAI()

    def llm(v):
        resp = openai_client.chat.completions.create(
            functions=[Validator.openai_schema],
            function_call={"name": Validator.openai_schema["name"]},
            messages=[
                {
                    "role": "system",
                    "content": "You are a world class validation model. Capable to determine if the following value is valid for the statement, if it is not, explain why and suggest a new value.",
                },
                {
                    "role": "user",
                    "content": f"Does `{v}` follow the rules: {statement}",
                },
            ],
            model=model,
            temperature=temperature,
        )  # type: ignore
        resp = Validator.from_response(resp)

        # If the response is  not valid, return the reason, this could be used in
        # the future to generate a better response, via reasking mechanism.
        assert resp.is_valid, resp.reason

        if allow_override and not resp.is_valid and resp.fixed_value is not None:
            # If the value is not valid, but we allow override, return the fixed value
            return resp.fixed_value
        return v

    return llm

openai_moderation(client=None)

Validates a message using OpenAI moderation model.

Should only be used for monitoring inputs and outputs of OpenAI APIs Other use cases are disallowed as per: https://platform.openai.com/docs/guides/moderation/overview

Example:

from instructor import OpenAIModeration

class Response(BaseModel):
    message: Annotated[str, AfterValidator(OpenAIModeration(openai_client=client))]

Response(message="I hate you")

 ValidationError: 1 validation error for Response
 message
Value error, `I hate you.` was flagged for ['harassment'] [type=value_error, input_value='I hate you.', input_type=str]

client (OpenAI): The OpenAI client to use, must be sync (default: None)

Source code in instructor/dsl/validators.py
def openai_moderation(client: OpenAI = None):
    """
    Validates a message using OpenAI moderation model.

    Should only be used for monitoring inputs and outputs of OpenAI APIs
    Other use cases are disallowed as per:
    https://platform.openai.com/docs/guides/moderation/overview

    Example:
    ```python
    from instructor import OpenAIModeration

    class Response(BaseModel):
        message: Annotated[str, AfterValidator(OpenAIModeration(openai_client=client))]

    Response(message="I hate you")
    ```

    ```
     ValidationError: 1 validation error for Response
     message
    Value error, `I hate you.` was flagged for ['harassment'] [type=value_error, input_value='I hate you.', input_type=str]
    ```

    client (OpenAI): The OpenAI client to use, must be sync (default: None)
    """

    client = client or OpenAI()

    def validate_message_with_openai_mod(v: str) -> str:
        response = client.moderations.create(input=v)
        out = response.results[0]
        cats = out.categories.model_dump()
        if out.flagged:
            raise ValueError(
                f"`{v}` was flagged for {', '.join(cat for cat in cats if cats[cat])}"
            )

        return v

    return validate_message_with_openai_mod

CitationMixin

Bases: BaseModel

Helpful mixing that can use validation_context={"context": context} in from_response to find the span of the substring_phrase in the context.

Usage

from pydantic import BaseModel, Field
from instructor import CitationMixin

class User(BaseModel):
    name: str = Field(description="The name of the person")
    age: int = Field(description="The age of the person")
    role: str = Field(description="The role of the person")


context = "Betty was a student. Jason was a student. Jason is 20 years old"

user = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {
            "role": "user",
            "content": "Extract jason from {context}",
        },
    response_model=User,
    validation_context={"context": context},
    ]
)

for quote in user.substring_quotes:
    assert quote in context

print(user.model_dump())

Result

{
    "name": "Jason Liu",
    "age": 20,
    "role": "student",
    "substring_quotes": [
        "Jason was a student",
        "Jason is 20 years old",
    ]
}
Source code in instructor/dsl/citation.py
class CitationMixin(BaseModel):
    """
    Helpful mixing that can use `validation_context={"context": context}` in `from_response` to find the span of the substring_phrase in the context.

    ## Usage

    ```python
    from pydantic import BaseModel, Field
    from instructor import CitationMixin

    class User(BaseModel):
        name: str = Field(description="The name of the person")
        age: int = Field(description="The age of the person")
        role: str = Field(description="The role of the person")


    context = "Betty was a student. Jason was a student. Jason is 20 years old"

    user = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[
            {
                "role": "user",
                "content": "Extract jason from {context}",
            },
        response_model=User,
        validation_context={"context": context},
        ]
    )

    for quote in user.substring_quotes:
        assert quote in context

    print(user.model_dump())
    ```

    ## Result
    ```
    {
        "name": "Jason Liu",
        "age": 20,
        "role": "student",
        "substring_quotes": [
            "Jason was a student",
            "Jason is 20 years old",
        ]
    }
    ```

    """

    substring_quotes: List[str] = Field(
        description="List of unique and specific substrings of the quote that was used to answer the question.",
    )

    @model_validator(mode="after")
    def validate_sources(self, info: FieldValidationInfo) -> "CitationMixin":
        """
        For each substring_phrase, find the span of the substring_phrase in the context.
        If the span is not found, remove the substring_phrase from the list.
        """
        if info.context is None:
            return self

        # Get the context from the info
        text_chunks = info.context.get("context", None)

        # Get the spans of the substring_phrase in the context
        spans = list(self.get_spans(text_chunks))
        # Replace the substring_phrase with the actual substring
        self.substring_quotes = [text_chunks[span[0] : span[1]] for span in spans]
        return self

    def _get_span(self, quote, context, errs=5):
        import regex

        minor = quote
        major = context

        errs_ = 0
        s = regex.search(f"({minor}){{e<={errs_}}}", major)
        while s is None and errs_ <= errs:
            errs_ += 1
            s = regex.search(f"({minor}){{e<={errs_}}}", major)

        if s is not None:
            yield from s.spans()

    def get_spans(self, context):
        for quote in self.substring_quotes:
            yield from self._get_span(quote, context)

validate_sources(info)

For each substring_phrase, find the span of the substring_phrase in the context. If the span is not found, remove the substring_phrase from the list.

Source code in instructor/dsl/citation.py
@model_validator(mode="after")
def validate_sources(self, info: FieldValidationInfo) -> "CitationMixin":
    """
    For each substring_phrase, find the span of the substring_phrase in the context.
    If the span is not found, remove the substring_phrase from the list.
    """
    if info.context is None:
        return self

    # Get the context from the info
    text_chunks = info.context.get("context", None)

    # Get the spans of the substring_phrase in the context
    spans = list(self.get_spans(text_chunks))
    # Replace the substring_phrase with the actual substring
    self.substring_quotes = [text_chunks[span[0] : span[1]] for span in spans]
    return self

MultiTask(subtask_class, name=None, description=None)

Dynamically create a MultiTask OpenAISchema that can be used to segment multiple tasks given a base class. This creates class that can be used to create a toolkit for a specific task, names and descriptions are automatically generated. However they can be overridden.

Usage

from pydantic import BaseModel, Field
from instructor import MultiTask

class User(BaseModel):
    name: str = Field(description="The name of the person")
    age: int = Field(description="The age of the person")
    role: str = Field(description="The role of the person")

MultiUser = MultiTask(User)

Result

class MultiUser(OpenAISchema, MultiTaskBase):
    tasks: List[User] = Field(
        default_factory=list,
        repr=False,
        description="Correctly segmented list of `User` tasks",
    )

    @classmethod
    def from_streaming_response(cls, completion) -> Generator[User]:
        '''
        Parse the streaming response from OpenAI and yield a `User` object
        for each task in the response
        '''
        json_chunks = cls.extract_json(completion)
        yield from cls.tasks_from_chunks(json_chunks)

Parameters:

Name Type Description Default
subtask_class Type[OpenAISchema]

The base class to use for the MultiTask

required
name Optional[str]

The name of the MultiTask class, if None then the name of the subtask class is used as Multi{subtask_class.__name__}

None
description Optional[str]

The description of the MultiTask class, if None then the description is set to Correct segmentation of{subtask_class.name}tasks

None

Returns:

Name Type Description
schema OpenAISchema

A new class that can be used to segment multiple tasks

Source code in instructor/dsl/multitask.py
def MultiTask(
    subtask_class: Type[BaseModel],
    name: Optional[str] = None,
    description: Optional[str] = None,
):
    """
    Dynamically create a MultiTask OpenAISchema that can be used to segment multiple
    tasks given a base class. This creates class that can be used to create a toolkit
    for a specific task, names and descriptions are automatically generated. However
    they can be overridden.

    ## Usage

    ```python
    from pydantic import BaseModel, Field
    from instructor import MultiTask

    class User(BaseModel):
        name: str = Field(description="The name of the person")
        age: int = Field(description="The age of the person")
        role: str = Field(description="The role of the person")

    MultiUser = MultiTask(User)
    ```

    ## Result

    ```python
    class MultiUser(OpenAISchema, MultiTaskBase):
        tasks: List[User] = Field(
            default_factory=list,
            repr=False,
            description="Correctly segmented list of `User` tasks",
        )

        @classmethod
        def from_streaming_response(cls, completion) -> Generator[User]:
            '''
            Parse the streaming response from OpenAI and yield a `User` object
            for each task in the response
            '''
            json_chunks = cls.extract_json(completion)
            yield from cls.tasks_from_chunks(json_chunks)
    ```

    Parameters:
        subtask_class (Type[OpenAISchema]): The base class to use for the MultiTask
        name (Optional[str]): The name of the MultiTask class, if None then the name
            of the subtask class is used as `Multi{subtask_class.__name__}`
        description (Optional[str]): The description of the MultiTask class, if None
            then the description is set to `Correct segmentation of `{subtask_class.__name__}` tasks`

    Returns:
        schema (OpenAISchema): A new class that can be used to segment multiple tasks
    """
    task_name = subtask_class.__name__ if name is None else name

    name = f"Multi{task_name}"

    list_tasks = (
        List[subtask_class],
        Field(
            default_factory=list,
            repr=False,
            description=f"Correctly segmented list of `{task_name}` tasks",
        ),
    )

    new_cls = create_model(
        name,
        tasks=list_tasks,
        __base__=(OpenAISchema, MultiTaskBase),  # type: ignore
    )
    # set the class constructor BaseModel
    new_cls.task_type = subtask_class

    new_cls.__doc__ = (
        f"Correct segmentation of `{task_name}` tasks"
        if description is None
        else description
    )

    return new_cls

MaybeBase

Bases: BaseModel

Extract a result from a model, if any, otherwise set the error and message fields.

Source code in instructor/dsl/maybe.py
class MaybeBase(BaseModel):
    """
    Extract a result from a model, if any, otherwise set the error and message fields.
    """

    result: Optional[BaseModel]
    error: bool = Field(default=False)
    message: Optional[str]

    def __bool__(self):
        return self.result is not None  # type: ignore

Maybe(model)

Create a Maybe model for a given Pydantic model. This allows you to return a model that includes fields for result, error, and message for sitatations where the data may not be present in the context.

Usage

from pydantic import BaseModel, Field
from instructor import Maybe

class User(BaseModel):
    name: str = Field(description="The name of the person")
    age: int = Field(description="The age of the person")
    role: str = Field(description="The role of the person")

MaybeUser = Maybe(User)

Result

class MaybeUser(BaseModel):
    result: Optional[User]
    error: bool = Field(default=False)
    message: Optional[str]

    def __bool__(self):
        return self.result is not None

Parameters:

Name Type Description Default
model Type[BaseModel]

The Pydantic model to wrap with Maybe.

required

Returns:

Name Type Description
MaybeModel Type[BaseModel]

A new Pydantic model that includes fields for result, error, and message.

Source code in instructor/dsl/maybe.py
def Maybe(model: Type[BaseModel]) -> MaybeBase:
    """
    Create a Maybe model for a given Pydantic model. This allows you to return a model that includes fields for `result`, `error`, and `message` for sitatations where the data may not be present in the context.

    ## Usage

    ```python
    from pydantic import BaseModel, Field
    from instructor import Maybe

    class User(BaseModel):
        name: str = Field(description="The name of the person")
        age: int = Field(description="The age of the person")
        role: str = Field(description="The role of the person")

    MaybeUser = Maybe(User)
    ```

    ## Result

    ```python
    class MaybeUser(BaseModel):
        result: Optional[User]
        error: bool = Field(default=False)
        message: Optional[str]

        def __bool__(self):
            return self.result is not None
    ```

    Parameters:
        model (Type[BaseModel]): The Pydantic model to wrap with Maybe.

    Returns:
        MaybeModel (Type[BaseModel]): A new Pydantic model that includes fields for `result`, `error`, and `message`.
    """

    class MaybeBase(BaseModel):
        def __bool__(self):
            return self.result is not None  # type: ignore

    fields = {
        "result": (
            Optional[model],
            Field(
                default=None,
                description="Correctly extracted result from the model, if any, otherwise None",
            ),
        ),
        "error": (bool, Field(default=False)),
        "message": (
            Optional[str],
            Field(
                default=None,
                description="Error message if no result was found, should be short and concise",
            ),
        ),
    }

    MaybeModel = create_model(f"Maybe{model.__name__}", __base__=MaybeBase, **fields)

    return MaybeModel  # type: ignore

Mode

Bases: Enum

The mode to use for patching the client

Source code in instructor/function_calls.py
class Mode(enum.Enum):
    """The mode to use for patching the client"""

    FUNCTIONS: str = "function_call"
    TOOLS: str = "tool_call"
    JSON: str = "json_mode"
    MD_JSON: str = "markdown_json_mode"

OpenAISchema

Bases: BaseModel

Augments a Pydantic model with OpenAI's schema for function calling

This class augments a Pydantic model with OpenAI's schema for function calling. The schema is generated from the model's signature and docstring. The schema can be used to validate the response from OpenAI's API and extract the function call.

Usage

from instructor import OpenAISchema

class User(OpenAISchema):
    name: str
    age: int

completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[{
        "content": "Jason is 20 years old",
        "role": "user"
    }],
    functions=[User.openai_schema],
    function_call={"name": User.openai_schema["name"]},
)

user = User.from_response(completion)

print(user.model_dump())

Result

{
    "name": "Jason Liu",
    "age": 20,
}
Source code in instructor/function_calls.py
class OpenAISchema(BaseModel):
    """
    Augments a Pydantic model with OpenAI's schema for function calling

    This class augments a Pydantic model with OpenAI's schema for function calling. The schema is generated from the model's signature and docstring. The schema can be used to validate the response from OpenAI's API and extract the function call.

    ## Usage

    ```python
    from instructor import OpenAISchema

    class User(OpenAISchema):
        name: str
        age: int

    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{
            "content": "Jason is 20 years old",
            "role": "user"
        }],
        functions=[User.openai_schema],
        function_call={"name": User.openai_schema["name"]},
    )

    user = User.from_response(completion)

    print(user.model_dump())
    ```
    ## Result

    ```
    {
        "name": "Jason Liu",
        "age": 20,
    }
    ```


    """

    @classmethod
    @property
    def openai_schema(cls):
        """
        Return the schema in the format of OpenAI's schema as jsonschema

        Note:
            Its important to add a docstring to describe how to best use this class, it will be included in the description attribute and be part of the prompt.

        Returns:
            model_json_schema (dict): A dictionary in the format of OpenAI's schema as jsonschema
        """
        schema = cls.model_json_schema()
        docstring = parse(cls.__doc__ or "")
        parameters = {
            k: v for k, v in schema.items() if k not in ("title", "description")
        }
        for param in docstring.params:
            if (name := param.arg_name) in parameters["properties"] and (
                description := param.description
            ):
                if "description" not in parameters["properties"][name]:
                    parameters["properties"][name]["description"] = description

        parameters["required"] = sorted(
            k for k, v in parameters["properties"].items() if "default" not in v
        )

        if "description" not in schema:
            if docstring.short_description:
                schema["description"] = docstring.short_description
            else:
                schema["description"] = (
                    f"Correctly extracted `{cls.__name__}` with all "
                    f"the required parameters with correct types"
                )

        return {
            "name": schema["title"],
            "description": schema["description"],
            "parameters": parameters,
        }

    @classmethod
    def from_response(
        cls,
        completion,
        validation_context=None,
        strict: bool = None,
        mode: Mode = Mode.FUNCTIONS,
        stream_multitask: bool = False,
    ):
        """Execute the function from the response of an openai chat completion

        Parameters:
            completion (openai.ChatCompletion): The response from an openai chat completion
            throw_error (bool): Whether to throw an error if the function call is not detected
            validation_context (dict): The validation context to use for validating the response
            strict (bool): Whether to use strict json parsing
            mode (Mode): The openai completion mode
            stream_multitask (bool): Whether to stream a multitask response

        Returns:
            cls (OpenAISchema): An instance of the class
        """
        if stream_multitask:
            return cls.from_streaming_response(completion, mode)

        message = completion.choices[0].message

        if mode == Mode.FUNCTIONS:
            assert (
                message.function_call.name == cls.openai_schema["name"]
            ), "Function name does not match"
            return cls.model_validate_json(
                message.function_call.arguments,
                context=validation_context,
                strict=strict,
            )
        elif mode == Mode.TOOLS:
            assert (
                len(message.tool_calls) == 1
            ), "Instructor does not support multiple tool calls, use List[Model] instead."
            tool_call = message.tool_calls[0]
            assert (
                tool_call.function.name == cls.openai_schema["name"]
            ), "Tool name does not match"
            return cls.model_validate_json(
                tool_call.function.arguments,
                context=validation_context,
                strict=strict,
            )
        elif mode == Mode.JSON:
            return cls.model_validate_json(
                message.content,
                context=validation_context,
                strict=strict,
            )
        elif mode == Mode.MD_JSON:
            return cls.model_validate_json(
                message.content,
                context=validation_context,
                strict=strict,
            )
        else:
            raise ValueError(f"Invalid patch mode: {mode}")

    @classmethod
    async def from_response_async(
        cls,
        completion,
        validation_context=None,
        strict: bool = None,
        mode: Mode = Mode.FUNCTIONS,
        stream_multitask: bool = False,
    ):
        """Execute the function from the response of an openai chat completion

        Parameters:
            completion (openai.ChatCompletion): The response from an openai chat completion
            throw_error (bool): Whether to throw an error if the function call is not detected
            validation_context (dict): The validation context to use for validating the response
            strict (bool): Whether to use strict json parsing
            mode (Mode): The openai completion mode
            stream_multitask (bool): Whether to stream a multitask response

        Returns:
            cls (OpenAISchema): An instance of the class
        """
        if stream_multitask:
            return await cls.from_streaming_response_async(completion, mode)

        message = completion.choices[0].message

        if mode == Mode.FUNCTIONS:
            assert (
                message.function_call.name == cls.openai_schema["name"]
            ), "Function name does not match"
            return cls.model_validate_json(
                message.function_call.arguments,
                context=validation_context,
                strict=strict,
            )
        elif mode == Mode.TOOLS:
            assert (
                len(message.tool_calls) == 1
            ), "Instructor does not support multiple tool calls, use List[Model] instead."
            tool_call = message.tool_calls[0]
            assert (
                tool_call.function.name == cls.openai_schema["name"]
            ), "Tool name does not match"
            return cls.model_validate_json(
                tool_call.function.arguments,
                context=validation_context,
                strict=strict,
            )
        elif mode == Mode.JSON:
            return cls.model_validate_json(
                message.content,
                context=validation_context,
                strict=strict,
            )
        elif mode == Mode.MD_JSON:
            return cls.model_validate_json(
                message.content,
                context=validation_context,
                strict=strict,
            )
        else:
            raise ValueError(f"Invalid patch mode: {mode}")

openai_schema classmethod property

Return the schema in the format of OpenAI's schema as jsonschema

Note

Its important to add a docstring to describe how to best use this class, it will be included in the description attribute and be part of the prompt.

Returns:

Name Type Description
model_json_schema dict

A dictionary in the format of OpenAI's schema as jsonschema

from_response(completion, validation_context=None, strict=None, mode=Mode.FUNCTIONS, stream_multitask=False) classmethod

Execute the function from the response of an openai chat completion

Parameters:

Name Type Description Default
completion ChatCompletion

The response from an openai chat completion

required
throw_error bool

Whether to throw an error if the function call is not detected

required
validation_context dict

The validation context to use for validating the response

None
strict bool

Whether to use strict json parsing

None
mode Mode

The openai completion mode

FUNCTIONS
stream_multitask bool

Whether to stream a multitask response

False

Returns:

Name Type Description
cls OpenAISchema

An instance of the class

Source code in instructor/function_calls.py
@classmethod
def from_response(
    cls,
    completion,
    validation_context=None,
    strict: bool = None,
    mode: Mode = Mode.FUNCTIONS,
    stream_multitask: bool = False,
):
    """Execute the function from the response of an openai chat completion

    Parameters:
        completion (openai.ChatCompletion): The response from an openai chat completion
        throw_error (bool): Whether to throw an error if the function call is not detected
        validation_context (dict): The validation context to use for validating the response
        strict (bool): Whether to use strict json parsing
        mode (Mode): The openai completion mode
        stream_multitask (bool): Whether to stream a multitask response

    Returns:
        cls (OpenAISchema): An instance of the class
    """
    if stream_multitask:
        return cls.from_streaming_response(completion, mode)

    message = completion.choices[0].message

    if mode == Mode.FUNCTIONS:
        assert (
            message.function_call.name == cls.openai_schema["name"]
        ), "Function name does not match"
        return cls.model_validate_json(
            message.function_call.arguments,
            context=validation_context,
            strict=strict,
        )
    elif mode == Mode.TOOLS:
        assert (
            len(message.tool_calls) == 1
        ), "Instructor does not support multiple tool calls, use List[Model] instead."
        tool_call = message.tool_calls[0]
        assert (
            tool_call.function.name == cls.openai_schema["name"]
        ), "Tool name does not match"
        return cls.model_validate_json(
            tool_call.function.arguments,
            context=validation_context,
            strict=strict,
        )
    elif mode == Mode.JSON:
        return cls.model_validate_json(
            message.content,
            context=validation_context,
            strict=strict,
        )
    elif mode == Mode.MD_JSON:
        return cls.model_validate_json(
            message.content,
            context=validation_context,
            strict=strict,
        )
    else:
        raise ValueError(f"Invalid patch mode: {mode}")

from_response_async(completion, validation_context=None, strict=None, mode=Mode.FUNCTIONS, stream_multitask=False) async classmethod

Execute the function from the response of an openai chat completion

Parameters:

Name Type Description Default
completion ChatCompletion

The response from an openai chat completion

required
throw_error bool

Whether to throw an error if the function call is not detected

required
validation_context dict

The validation context to use for validating the response

None
strict bool

Whether to use strict json parsing

None
mode Mode

The openai completion mode

FUNCTIONS
stream_multitask bool

Whether to stream a multitask response

False

Returns:

Name Type Description
cls OpenAISchema

An instance of the class

Source code in instructor/function_calls.py
@classmethod
async def from_response_async(
    cls,
    completion,
    validation_context=None,
    strict: bool = None,
    mode: Mode = Mode.FUNCTIONS,
    stream_multitask: bool = False,
):
    """Execute the function from the response of an openai chat completion

    Parameters:
        completion (openai.ChatCompletion): The response from an openai chat completion
        throw_error (bool): Whether to throw an error if the function call is not detected
        validation_context (dict): The validation context to use for validating the response
        strict (bool): Whether to use strict json parsing
        mode (Mode): The openai completion mode
        stream_multitask (bool): Whether to stream a multitask response

    Returns:
        cls (OpenAISchema): An instance of the class
    """
    if stream_multitask:
        return await cls.from_streaming_response_async(completion, mode)

    message = completion.choices[0].message

    if mode == Mode.FUNCTIONS:
        assert (
            message.function_call.name == cls.openai_schema["name"]
        ), "Function name does not match"
        return cls.model_validate_json(
            message.function_call.arguments,
            context=validation_context,
            strict=strict,
        )
    elif mode == Mode.TOOLS:
        assert (
            len(message.tool_calls) == 1
        ), "Instructor does not support multiple tool calls, use List[Model] instead."
        tool_call = message.tool_calls[0]
        assert (
            tool_call.function.name == cls.openai_schema["name"]
        ), "Tool name does not match"
        return cls.model_validate_json(
            tool_call.function.arguments,
            context=validation_context,
            strict=strict,
        )
    elif mode == Mode.JSON:
        return cls.model_validate_json(
            message.content,
            context=validation_context,
            strict=strict,
        )
    elif mode == Mode.MD_JSON:
        return cls.model_validate_json(
            message.content,
            context=validation_context,
            strict=strict,
        )
    else:
        raise ValueError(f"Invalid patch mode: {mode}")