mirror of
https://github.com/kennethreitz/instructor.git
synced 2026-06-05 22:50:18 +00:00
Rename to Instructor (#79)
This commit is contained in:
@@ -1,240 +1,252 @@
|
||||
# Pydantic is all you need, for openai function calls.
|
||||
# Instructor (openai_function_call)
|
||||
|
||||
Check out the [docs](https://openai-function-call.onrender.com/)!
|
||||
[](https://github.com/jxnl/instructor/stargazers)
|
||||
[](https://github.com/jxnl/instructor/network)
|
||||
[](https://github.com/jxnl/instructor/issues)
|
||||
[](https://github.com/jxnl/instructor/blob/main/LICENSE)
|
||||
[](https://link-to-your-documentation)
|
||||
[](https://www.buymeacoffee.com/jxnlco)
|
||||
[](https://twitter.com/jxnlco)
|
||||
|
||||
We try to provides a powerful and efficient approach to output parsing when interacting with OpenAI's Function Call API. One that is framework agnostic and minimizes any dependencies. It leverages the data validation capabilities of the Pydantic library to handle output parsing in a more structured and reliable manner.
|
||||
If you have any feedback, leave an issue or hit me up on [twitter](https://twitter.com/jxnlco).
|
||||
*Structured extraction in Python, powered by OpenAI's function calling api, designed for simplicity, transparency, and control.*
|
||||
|
||||
This repo also contains a range of examples I've used in experimentation and in production and I welcome new contributions for different types of schemas.
|
||||
This library is built to interact with openai's function call api from python code, with python structs / objects. It's designed to be intuitive, easy to use, but give great visibily in how we call openai.
|
||||
|
||||
## Support
|
||||
The approach of combining a human prompt and a "response schema" is not necessarily unique; however, it shows great promise. As we have been concentrating on translating user intent into structured data, we have discovered that Python with Pydantic is exceptionally well-suited for this task.
|
||||
|
||||
Follow me on twitter and consider helping pay for openai tokens!
|
||||
**OpenAISchema** is based on Python type annotations, and powered by Pydantic.
|
||||
|
||||
[](https://twitter.com/jxnlco) [](https://www.buymeacoffee.com/jxnl)
|
||||
The key features are:
|
||||
|
||||
## Installation
|
||||
* **Intuitive to write**: Great support for editors, completions. Spend less time debugging.
|
||||
* **Writing prompts as code**: Collocate docstrings and descriptions as part of your prompting.
|
||||
* **Extensible**: Bring your own kitchen sink without being weighted down by abstractions.
|
||||
|
||||
Ensure you have Python version 3.9 or above.
|
||||
## Structured Extraction with `openai`
|
||||
|
||||
```python
|
||||
pip install openai-function-call
|
||||
Welcome to the Quick Start Guide for OpenAI Function Call. This guide will walk you through the installation process and provide examples demonstrating the usage of function calls and schemas with OpenAI and Pydantic.
|
||||
|
||||
### Requirements
|
||||
|
||||
This library depends on **Pydantic** and **OpenAI** that's all.
|
||||
|
||||
### Installation
|
||||
|
||||
To get started with OpenAI Function Call, you need to install it using `pip`. Run the following command in your terminal:
|
||||
|
||||
!!! note Requirement
|
||||
Ensure you have Python version 3.9 or above.
|
||||
|
||||
```sh
|
||||
$ pip install instructor
|
||||
```
|
||||
|
||||
## Contributing
|
||||
## Quick Start with Patching ChatCompletion
|
||||
|
||||
To get started, clone the repository
|
||||
To simplify your work with OpenAI models and streamline the extraction of Pydantic objects from prompts, we offer a patching mechanism for the `ChatCompletion`` class. Here's a step-by-step guide:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/jxnl/openai_function_call.git
|
||||
```
|
||||
### Step 1: Import and Patch the Module
|
||||
|
||||
Next, install the necessary Python packages from the requirements.txt file:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Poetry
|
||||
|
||||
We also use poetry if you'd like
|
||||
|
||||
```bash
|
||||
poetry build
|
||||
```
|
||||
|
||||
Your contributions are welcome! If you have great examples or find neat patterns, clone the repo and add another example.
|
||||
Check out the issues for any ideas if you want to learn. The goal is to find great patterns and cool examples to highlight.
|
||||
|
||||
If you encounter any issues or want to provide feedback, you can create an issue in this repository. You can also reach out to me on Twitter at @jxnlco.
|
||||
|
||||
## Usage
|
||||
|
||||
This module simplifies the interaction with the OpenAI API, enabling a more structured and predictable conversation with the AI. Below are examples showcasing the use of function calls and schemas with OpenAI and Pydantic.
|
||||
|
||||
### Example 1: Function Calls
|
||||
First, import the required libraries and apply the patch function to the OpenAI module. This exposes new functionality with the response_model parameter.
|
||||
|
||||
```python
|
||||
import openai
|
||||
from openai_function_call import openai_function
|
||||
from pydantic import BaseModel
|
||||
from instructor import patch
|
||||
|
||||
@openai_function
|
||||
def sum(a:int, b:int) -> int:
|
||||
"""Sum description adds a + b"""
|
||||
return a + b
|
||||
|
||||
completion = openai.ChatCompletion.create(
|
||||
model="gpt-3.5-turbo-0613",
|
||||
temperature=0,
|
||||
functions=[sum.openai_schema],
|
||||
messages=[
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You must use the `sum` function instead of adding yourself.",
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "What is 6+3 use the `sum` function",
|
||||
},
|
||||
],
|
||||
)
|
||||
|
||||
result = sum.from_response(completion)
|
||||
print(result) # 9
|
||||
patch()
|
||||
```
|
||||
|
||||
### Example 2: Schema Extraction
|
||||
### Step 2: Define the Pydantic Model
|
||||
|
||||
Create a Pydantic model to define the structure of the data you want to extract. This model will map directly to the information in the prompt.
|
||||
|
||||
```python
|
||||
import openai
|
||||
from openai_function_call import OpenAISchema
|
||||
class UserDetail(BaseModel):
|
||||
name: str
|
||||
age: int
|
||||
```
|
||||
|
||||
### Step 3: Extract Data with ChatCompletion
|
||||
|
||||
Use the openai.ChatCompletion.create method to send a prompt and extract the data into the Pydantic object. The response_model parameter specifies the Pydantic model to use for extraction.
|
||||
|
||||
```python
|
||||
user: UserDetail = openai.ChatCompletion.create(
|
||||
model="gpt-3.5-turbo",
|
||||
response_model=UserDetail,
|
||||
messages=[
|
||||
{"role": "user", "content": "Extract Jason is 25 years old"},
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
### Step 4: Validate the Extracted Data
|
||||
|
||||
You can then validate the extracted data by asserting the expected values. By adding the type things you also get a bunch of nice benefits with your IDE like spell check and auto complete!
|
||||
|
||||
```python
|
||||
assert user.name == "Jason"
|
||||
assert user.age == 25
|
||||
```
|
||||
|
||||
## Introduction to `OpenAISchema`
|
||||
|
||||
If you want more control than just passing a single class we can use the `OpenAISchema` which extends `BaseModel`.
|
||||
|
||||
This quick start guide contains the follow sections:
|
||||
|
||||
1. Defining a schema
|
||||
2. Adding Additional Prompting
|
||||
3. Calling the ChatCompletion
|
||||
4. Deserializing back to the instance
|
||||
|
||||
OpenAI Function Call allows you to leverage OpenAI's powerful language models for function calls and schema extraction. This guide provides a quick start for using OpenAI Function Call.
|
||||
|
||||
### Section 1: Defining a Schema
|
||||
|
||||
To begin, let's define a schema using OpenAI Function Call. A schema describes the structure of the input and output data for a function. In this example, we'll define a simple schema for a `User` object:
|
||||
|
||||
```python
|
||||
from instructor import OpenAISchema
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
name: str
|
||||
age: int
|
||||
```
|
||||
|
||||
In this schema, we define a `UserDetails` class that extends `OpenAISchema`. We declare two fields, `name` and `age`, of type `str` and `int` respectively.
|
||||
|
||||
### Section 2: Adding Additional Prompting
|
||||
|
||||
To enhance the performance of the OpenAI language model, you can add additional prompting in the form of docstrings and field descriptions. They can provide context and guide the model on how to process the data.
|
||||
|
||||
!!! note Using `patch`
|
||||
these docstrings and fields descriptions are powered by `pydantic.BaseModel` so they'll work via the patching approach as well.
|
||||
|
||||
```python hl_lines="5 6"
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
"""User Details"""
|
||||
name: str = Field(..., description="User's name")
|
||||
age: int = Field(..., description="User's age")
|
||||
"Correctly extracted user information"
|
||||
name: str = Field(..., description="User's full name")
|
||||
age: int
|
||||
```
|
||||
|
||||
In this updated schema, we use the `Field` class from `pydantic` to add descriptions to the `name` field. The description provides information about the field, giving even more context to the language model.
|
||||
|
||||
|
||||
!!! note "Code, schema, and prompt"
|
||||
We can run `openai_schema` to see exactly what the API will see, notice how the docstrings, attributes, types, and field descriptions are now part of the schema. This describes on this library's core philosophies.
|
||||
|
||||
```python hl_lines="2 3"
|
||||
class UserDetails(OpenAISchema):
|
||||
"Correctly extracted user information"
|
||||
name: str = Field(..., description="User's full name")
|
||||
age: int
|
||||
|
||||
UserDetails.openai_schema
|
||||
```
|
||||
|
||||
```json hl_lines="3 8"
|
||||
{
|
||||
"name": "UserDetails",
|
||||
"description": "Correctly extracted user information",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "User's full name",
|
||||
"type": "string"
|
||||
},
|
||||
"age": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"age",
|
||||
"name"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Section 3: Calling the ChatCompletion
|
||||
|
||||
With the schema defined, let's proceed with calling the `ChatCompletion` API using the defined schema and messages.
|
||||
|
||||
```python hl_lines="11 12 15"
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
"Correctly extracted user information"
|
||||
name: str = Field(..., description="User's full name")
|
||||
age: int
|
||||
|
||||
completion = openai.ChatCompletion.create(
|
||||
model="gpt-3.5-turbo-0613",
|
||||
functions=[UserDetails.openai_schema],
|
||||
function_call={"name": UserDetails.openai_schema["name"]},
|
||||
messages=[
|
||||
{"role": "system", "content": "I'm going to ask for user details. Use UserDetails to parse this data."},
|
||||
{"role": "system", "content": "Extract user details from my requests"},
|
||||
{"role": "user", "content": "My name is John Doe and I'm 30 years old."},
|
||||
],
|
||||
)
|
||||
|
||||
user_details = UserDetails.from_response(completion)
|
||||
print(user_details) # UserDetails(name="John Doe", age=30)
|
||||
```
|
||||
|
||||
### Example 2.1: Using the Decorator
|
||||
In this example, we make a call to the `ChatCompletion` API by providing the model name (`gpt-3.5-turbo-0613`) and a list of messages. The messages consist of a system message and a user message. The system message sets the context by requesting user details, while the user message provides the input with the user's name and age.
|
||||
|
||||
The following will also work but we're having issues with propogating type hints
|
||||
so language services throw errors for methods like `.openai_schema`. We'd welcome a PR to fix this!
|
||||
Note that we have omitted the additional parameters that can be included in the API request, such as `temperature`, `max_tokens`, and `n`. These parameters can be customized according to your requirements.
|
||||
|
||||
### Section 4: Deserializing Back to the Instance
|
||||
|
||||
To deserialize the response from the `ChatCompletion` API back into an instance of the `UserDetails` class, we can use the `from_response` method.
|
||||
|
||||
```python hl_lines="1"
|
||||
user = UserDetails.from_response(completion)
|
||||
print(user.name) # Output: John Doe
|
||||
print(user.age) # Output: 30
|
||||
```
|
||||
|
||||
By calling `UserDetails.from_response`, we create an instance of the `UserDetails` class using the response from the API call. Subsequently, we can access the extracted user details through the `name` and `age` attributes of the `user` object.
|
||||
|
||||
## IDE Support
|
||||
|
||||
Everything is designed for you to get the best developer experience possible, with the best editor support.
|
||||
|
||||
Including **autocompletion**:
|
||||
|
||||

|
||||
|
||||
And even **inline errors**
|
||||
d
|
||||

|
||||
|
||||
## OpenAI Schema and Pydantic
|
||||
|
||||
This quick start guide provided you with a basic understanding of how to use OpenAI Function Call for schema extraction and function calls. You can now explore more advanced use cases and creative applications of this library.
|
||||
|
||||
Since `UserDetails` is a `OpenAISchems` and a `pydantic.BaseModel` you can use inheritance and nesting to create more complex emails while avoiding code duplication
|
||||
|
||||
```python
|
||||
from openai_function_call import openai_schema
|
||||
class UserDetails(OpenAISchema):
|
||||
name: str = Field(..., description="User's full name")
|
||||
age: int
|
||||
|
||||
@openai_schema
|
||||
class UserDetails(BaseModel):
|
||||
"""User Details"""
|
||||
name: str = Field(..., description="User's name")
|
||||
age: int = Field(..., description="User's age")
|
||||
class UserWithAddress(UserDetails):
|
||||
address: str
|
||||
|
||||
class UserWithFriends(UserDetails):
|
||||
best_friend: UserDetails
|
||||
friends: List[UserDetails]
|
||||
```
|
||||
|
||||
### Example 3: Using the DSL
|
||||
If you have any questions, feel free to leave an issue or reach out to the library's author on [Twitter](https://twitter.com/jxnlco). For a more comprehensive solution with additional features, consider checking out [MarvinAI](https://www.askmarvin.ai/).
|
||||
|
||||
```python
|
||||
from pprint import pprint
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from openai_function_call.dsl import ChatCompletion, MultiTask, messages as m
|
||||
from openai_function_call.dsl.messages import SystemIdentity, SystemTask, SystemStyle, SystemGuidelines, SystemTips
|
||||
|
||||
# Define a subtask you'd like to extract from then,
|
||||
# We'll use MultTask to easily map it to a List[Search]
|
||||
# so we can extract more than one
|
||||
class Search(OpenAISchema):
|
||||
id: int
|
||||
query: str
|
||||
|
||||
tasks = (
|
||||
ChatCompletion(name="Acme Inc Email Segmentation", model="gpt-3.5-turbo-0613")
|
||||
| SystemIdentity(identity="World class state of the art agent") # if no identity is provided, this is the default one
|
||||
| SystemTask(task="Segment emails into search queries")
|
||||
| SystemStyle(style="Professional, clear and concise")
|
||||
| SystemGuidelines(guidelines=[
|
||||
'You never swear',
|
||||
'You are polite',
|
||||
'You say please and thank you often.'
|
||||
])
|
||||
| SystemTips(tips=[
|
||||
"When unsure about the correct segmentation, try to think about the task as a whole",
|
||||
"If acronyms are used expand them to their full form",
|
||||
"Use multiple phrases to describe the same thing"]
|
||||
)
|
||||
| MultiTask(subtask_class=Search)
|
||||
| m.TaggedMessage(
|
||||
tag="email",
|
||||
content="Can you find the video I sent last week and also the post about dogs",
|
||||
)
|
||||
| m.ChainOfThought()
|
||||
)
|
||||
# Its important that this just builds you request,
|
||||
# all these | operators are overloaded and all we do is compile
|
||||
# it to the openai kwargs
|
||||
# Also note that the System components are combined sequentially
|
||||
# so the order matters!
|
||||
assert isinstance(tasks, ChatCompletion)
|
||||
pprint(tasks.kwargs, indent=3)
|
||||
"""
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are a world class state of the art agent.\n\nYour purpose is to correctly complete this task:
|
||||
`Segment emails into search queries`.\n\nYour style when answering is professional, clear and concise\n\n
|
||||
These are the guidelines you consider when completing your task:\n\n* You never swear\n* You are polite\n* You say please and thank you often.\n\nHere are some tips to help you complete the task:\n\n* When unsure about the correct segmentation, try to think about the task as a whole\n* If acronyms are used expand them to their full form\n* Use multiple phrases to describe the same thing"
|
||||
},
|
||||
...
|
||||
{
|
||||
"role": "user",
|
||||
"content": "<email>Can you find the video I sent last week and also the post about dogs</email>"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "Lets think step by step to get the correct answer:"
|
||||
}
|
||||
],
|
||||
"functions": [
|
||||
{
|
||||
"name": "MultiSearch",
|
||||
"description": "Correct segmentation of `Search` tasks",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tasks": {
|
||||
"description": "Correctly segmented list of `Search` tasks",
|
||||
"type": "array",
|
||||
"items": {"$ref": "#/definitions/Search"}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"Search": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {"type": "integer"},
|
||||
"query": {"type": "string"}
|
||||
},
|
||||
"required": ["id", "query"]
|
||||
}
|
||||
},
|
||||
"required": ["tasks"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"function_call": {"name": "MultiSearch"},
|
||||
"max_tokens": 1000,
|
||||
"temperature": 0.1,
|
||||
"model": "gpt-3.5-turbo-0613"
|
||||
"""
|
||||
|
||||
# Once we call .create we'll be returned with a multitask object that contains our list of task
|
||||
result = tasks.create()
|
||||
|
||||
for task in result.tasks:
|
||||
# We can now extract the list of tasks as we could normally
|
||||
assert isinstance(task, Search)
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
If you want to see more examples checkout the examples folder!
|
||||
To see more examples of how we can create interesting models check out some [examples.](examples/index.md)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the terms of the MIT license.
|
||||
|
||||
For more details, refer to the LICENSE file in the repository.
|
||||
This project is licensed under the terms of the MIT License.
|
||||
@@ -1,3 +1,3 @@
|
||||
# API: MultiTask
|
||||
|
||||
::: openai_function_call.dsl.multitask
|
||||
::: instructor.dsl.multitask
|
||||
@@ -6,16 +6,16 @@ To use the Prompt Pipeline in OpenAI Function Call, you need to instantiate a `C
|
||||
|
||||
The `ChatCompletion` object is the starting point for constructing your API call. It provides the necessary methods and attributes to define the conversation flow and include function calls.
|
||||
|
||||
::: openai_function_call.dsl.completion
|
||||
::: instructor.dsl.completion
|
||||
|
||||
## Messages Types
|
||||
|
||||
The basis of a message is defined as a `dataclass`. However, we provide helper functions and classes that provide additional functionality in the form of templates.
|
||||
|
||||
::: openai_function_call.dsl.messages.base
|
||||
::: instructor.dsl.messages.base
|
||||
|
||||
## Helper Messages / Templates
|
||||
|
||||
::: openai_function_call.dsl.messages.messages
|
||||
::: instructor.dsl.messages.messages
|
||||
|
||||
::: openai_function_call.dsl.messages.user
|
||||
::: instructor.dsl.messages.user
|
||||
@@ -10,7 +10,7 @@ In this example, we'll demonstrate how to convert a text into dataframes using O
|
||||
Let's start by defining the data structures required for this task: `RowData`, `Dataframe`, and `Database`.
|
||||
|
||||
```python
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
from typing import List, Any
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ Let's start by defining the data structures required for this task: `Fact` and `
|
||||
import openai
|
||||
from pydantic import Field, BaseModel
|
||||
from typing import List
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class Fact(BaseModel):
|
||||
|
||||
@@ -14,7 +14,7 @@ Let's start by defining the data structure of `File` and `Program`.
|
||||
```python
|
||||
from typing import List
|
||||
from pydantic import Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class File(OpenAISchema):
|
||||
@@ -173,7 +173,7 @@ This will be our definition for a change in our code base:
|
||||
|
||||
```python
|
||||
from pydantic import Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
class Diff(OpenAISchema):
|
||||
"""
|
||||
|
||||
@@ -23,7 +23,7 @@ import enum
|
||||
from typing import List
|
||||
|
||||
from pydantic import Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class QueryType(str, enum.Enum):
|
||||
@@ -140,7 +140,7 @@ In this example, we demonstrated how to use the OpenAI Function Call `ChatComple
|
||||
|
||||
If you want to see multiple versions of this style of code, please visit:
|
||||
|
||||
1. [query planning example](https://github.com/jxnl/openai_function_call/blob/main/examples/query_planner_execution/query_planner_execution.py)
|
||||
2. [task planning with topo sort](https://github.com/jxnl/openai_function_call/blob/main/examples/task_planner/task_planner_topological_sort.py)
|
||||
1. [query planning example](https://github.com/jxnl/instructor/blob/main/examples/query_planner_execution/query_planner_execution.py)
|
||||
2. [task planning with topo sort](https://github.com/jxnl/instructor/blob/main/examples/task_planner/task_planner_topological_sort.py)
|
||||
|
||||
Feel free to modify the code to fit your specific use case and explore other possibilities of using the OpenAI Function Call model to plan and execute complex workflows.
|
||||
@@ -13,7 +13,7 @@ We will use Pydantic to define the necessary data structures representing the di
|
||||
import enum
|
||||
from typing import List
|
||||
from pydantic import Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
class NodeType(str, enum.Enum):
|
||||
"""Enumeration representing the types of nodes in a filesystem."""
|
||||
|
||||
@@ -14,7 +14,7 @@ Let's model the problem as breaking down a search request into a list of search
|
||||
```python
|
||||
import enum
|
||||
from pydantic import Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
class SearchType(str, enum.Enum):
|
||||
"""Enumeration representing the types of searches that can be performed."""
|
||||
@@ -50,7 +50,7 @@ The `MultiSearch` class has a single attribute, `tasks`, which is a list of `Sea
|
||||
This pattern is so common that we've added a helper function `MultiTask` to makes this simpler
|
||||
|
||||
```python
|
||||
from openai_function_call.dsl import MultiTask
|
||||
from instructor.dsl import MultiTask
|
||||
|
||||
MultiSearch = MultiTask(Search)
|
||||
```
|
||||
|
||||
+15
-8
@@ -1,10 +1,17 @@
|
||||
# OpenAI Function Call
|
||||
# Instructor (openai_function_call)
|
||||
|
||||
*OpenAISchema, structured extraction in Python, powered by OpenAI, designed for simplicity, transparency, and control.*
|
||||
!!! note "Renaming from openai_function_call"
|
||||
This library used to be called `openai_function_call` simply change the import and you should be good to go!
|
||||
|
||||
```sh
|
||||
find /path/to/dir -type f -exec sed -i 's/openai_function_call/instructor/g' {} \;
|
||||
```
|
||||
|
||||
*Structured extraction in Python, powered by OpenAI's function calling api, designed for simplicity, transparency, and control.*
|
||||
|
||||
-----
|
||||
|
||||
This library is build to interact with openai's function call api from python code, with python objects. It's designed to be intuitive, easy to use, but give great visibily in how we call openai.
|
||||
This library is built to interact with openai's function call api from python code, with python structs / objects. It's designed to be intuitive, easy to use, but give great visibily in how we call openai.
|
||||
|
||||
The approach of combining a human prompt and a "response schema" is not necessarily unique; however, it shows great promise. As we have been concentrating on translating user intent into structured data, we have discovered that Python with Pydantic is exceptionally well-suited for this task.
|
||||
|
||||
@@ -32,7 +39,7 @@ To get started with OpenAI Function Call, you need to install it using `pip`. Ru
|
||||
Ensure you have Python version 3.9 or above.
|
||||
|
||||
```sh
|
||||
$ pip install openai_function_call
|
||||
$ pip install instructor
|
||||
```
|
||||
|
||||
## Quick Start with Patching ChatCompletion
|
||||
@@ -46,7 +53,7 @@ First, import the required libraries and apply the patch function to the OpenAI
|
||||
```python
|
||||
import openai
|
||||
from pydantic import BaseModel
|
||||
from openai_function_call import patch
|
||||
from instructor import patch
|
||||
|
||||
patch()
|
||||
```
|
||||
@@ -102,7 +109,7 @@ OpenAI Function Call allows you to leverage OpenAI's powerful language models fo
|
||||
To begin, let's define a schema using OpenAI Function Call. A schema describes the structure of the input and output data for a function. In this example, we'll define a simple schema for a `User` object:
|
||||
|
||||
```python
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
name: str
|
||||
@@ -119,7 +126,7 @@ To enhance the performance of the OpenAI language model, you can add additional
|
||||
these docstrings and fields descriptions are powered by `pydantic.BaseModel` so they'll work via the patching approach as well.
|
||||
|
||||
```python hl_lines="5 6"
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
@@ -171,7 +178,7 @@ In this updated schema, we use the `Field` class from `pydantic` to add descript
|
||||
With the schema defined, let's proceed with calling the `ChatCompletion` API using the defined schema and messages.
|
||||
|
||||
```python hl_lines="11 12 15"
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ Defining a task and creating a list of classes is a common enough pattern that w
|
||||
By using multitask you get a very convient class with prompts and names automatically defined. You get `from_response` just like any other `OpenAISchema` you're able to extract the list of objects data you want with `MultTask.tasks`.
|
||||
|
||||
```python hl_lines="13"
|
||||
from openai_function_call import OpenAISchema, MultiTask
|
||||
from instructor import OpenAISchema, MultiTask
|
||||
|
||||
class User(OpenAISchema):
|
||||
name: str
|
||||
|
||||
@@ -12,7 +12,7 @@ You can directly use the `OpenAISchema` class in your `openai` API create calls
|
||||
|
||||
```python
|
||||
import openai
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
|
||||
class UserDetails(OpenAISchema):
|
||||
@@ -38,7 +38,7 @@ You can also use the `@openai_schema` decorator to decorate `BaseModels`, but yo
|
||||
|
||||
```python
|
||||
import openai
|
||||
from openai_function_call import openai_schema
|
||||
from instructor import openai_schema
|
||||
from pydantic import Field, BaseModel
|
||||
|
||||
@openai_schema
|
||||
@@ -50,6 +50,6 @@ class UserDetails(BaseModel):
|
||||
|
||||
## Code Reference
|
||||
|
||||
For more information about the code, including the complete API reference, please refer to the `openai_function_call` documentation.
|
||||
For more information about the code, including the complete API reference, please refer to the `instructor` documentation.
|
||||
|
||||
::: openai_function_call.function_calls
|
||||
::: instructor.function_calls
|
||||
@@ -26,7 +26,7 @@ We will begin by defining a task to segment queries and add instructions using t
|
||||
First, let's design the schema for our task. In this example, we will have a `SearchQuery` schema with a single field called `query`. The `query` field will represent a detailed, comprehensive, and specific query to be used for semantic search.
|
||||
|
||||
```python
|
||||
from openai_function_call import OpenAISchema, dsl
|
||||
from instructor import OpenAISchema, dsl
|
||||
from pydantic import Field
|
||||
|
||||
class SearchQuery(OpenAISchema):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
from typing import List, Any
|
||||
import openai
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from pydantic import Field
|
||||
from typing import List, Any
|
||||
import openai
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import List
|
||||
import openai
|
||||
from pydantic import Field, BaseModel
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class Fact(BaseModel):
|
||||
|
||||
@@ -2,7 +2,7 @@ import json
|
||||
from typing import Iterable, List
|
||||
from fastapi import FastAPI, Request, HTTPException
|
||||
from fastapi.params import Depends
|
||||
from openai_function_call import MultiTask, OpenAISchema
|
||||
from instructor import MultiTask, OpenAISchema
|
||||
from pydantic import BaseModel, Field
|
||||
from starlette.responses import StreamingResponse
|
||||
|
||||
@@ -10,7 +10,7 @@ import os
|
||||
import openai
|
||||
import logging
|
||||
|
||||
from openai_function_call.dsl.multitask import MultiTaskBase
|
||||
from instructor.dsl.multitask import MultiTaskBase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import modal
|
||||
stub = modal.Stub("rag-citation")
|
||||
|
||||
image = modal.Image.debian_slim().pip_install(
|
||||
"fastapi", "openai_function_call>=0.2.1", "regex"
|
||||
"fastapi", "instructor>=0.2.1", "regex"
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@ fastapi
|
||||
uvicorn
|
||||
openai
|
||||
pydantic
|
||||
openai_function_call
|
||||
instructor
|
||||
regex
|
||||
@@ -1,9 +1,9 @@
|
||||
from fastapi import FastAPI
|
||||
from openai_function_call import OpenAISchema
|
||||
import openai_function_call.dsl as dsl
|
||||
from instructor import OpenAISchema
|
||||
import instructor.dsl as dsl
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
app = FastAPI(title="Example Application using openai_function_call")
|
||||
app = FastAPI(title="Example Application using instructor")
|
||||
|
||||
|
||||
class SearchRequest(BaseModel):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from openai_function_call import OpenAISchema, dsl
|
||||
from instructor import OpenAISchema, dsl
|
||||
from pydantic import Field
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import openai
|
||||
|
||||
from typing import List
|
||||
from pydantic import Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class File(OpenAISchema):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import openai
|
||||
|
||||
from pydantic import Field, parse_file_as
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
from generate import Program
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ from typing import List
|
||||
import openai
|
||||
from pydantic import Field
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class SearchType(str, enum.Enum):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import openai
|
||||
from pydantic import BaseModel
|
||||
from openai_function_call import patch
|
||||
from instructor import patch
|
||||
|
||||
# By default, the patch function will patch the ChatCompletion.create and ChatCompletion.acreate methods. to support response_model parameter
|
||||
patch()
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import List
|
||||
import openai
|
||||
from pydantic import Field
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class QueryType(str, enum.Enum):
|
||||
|
||||
@@ -5,7 +5,7 @@ import openai
|
||||
from pydantic import Field
|
||||
from tenacity import retry, stop_after_attempt
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class NodeType(str, enum.Enum):
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Any, List
|
||||
import openai
|
||||
from pydantic import Field
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class SQLTemplateType(str, enum.Enum):
|
||||
|
||||
@@ -2,7 +2,7 @@ from typing import Iterable
|
||||
import openai
|
||||
import time
|
||||
|
||||
from openai_function_call import MultiTask, OpenAISchema
|
||||
from instructor import MultiTask, OpenAISchema
|
||||
|
||||
|
||||
class User(OpenAISchema):
|
||||
|
||||
@@ -16,7 +16,7 @@ from typing import List, Generator
|
||||
import openai
|
||||
from pydantic import Field, BaseModel
|
||||
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class TaskResult(BaseModel):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import openai
|
||||
from typing import List, Union
|
||||
from pydantic import BaseModel, Field
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
from .messages import ChainOfThought, Message, MessageRole, SystemMessage
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from pydantic import BaseModel, create_model, Field
|
||||
from typing import Optional, List, Type, Union
|
||||
from openai_function_call import OpenAISchema
|
||||
from instructor import OpenAISchema
|
||||
|
||||
|
||||
class MultiTaskBase:
|
||||
@@ -4,7 +4,7 @@ import inspect
|
||||
from typing import Callable, Optional, Type, Union
|
||||
|
||||
from pydantic import BaseModel
|
||||
from openai_function_call import OpenAISchema, openai_schema
|
||||
from .function_calls import OpenAISchema, openai_schema
|
||||
|
||||
|
||||
def wrap_chatcompletion(func: Callable) -> Callable:
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
site_name: OpenAI Function Call Library
|
||||
site_name: Instructor (openai_function_call)
|
||||
site_description: Enhancing OpenAI function calling with Pydantic
|
||||
repo_name: openai_function_call
|
||||
repo_url: https://github.com/jxnl/openai_function_call
|
||||
site_url: https://openai-function-call.onrender.com/
|
||||
repo_name: instructor
|
||||
repo_url: https://github.com/jxnl/instructor
|
||||
site_url: https://jxnl.github.io/instructor
|
||||
theme:
|
||||
name: material
|
||||
icon:
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ description = "Helper functions that allow us to improve openai's function_call
|
||||
authors = ["Jason <jason@jxnl.co>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
packages = [{include = "openai_function_call"}]
|
||||
repository = "https://github.com/jxnl/openai_function_call"
|
||||
packages = [{include = "instructor"}]
|
||||
repository = "https://github.com/jxnl/instructor"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9"
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
from openai_function_call import OpenAISchema, MultiTask
|
||||
from openai_function_call.dsl import ChatCompletion
|
||||
from openai_function_call.dsl import messages as m
|
||||
from openai_function_call.dsl.messages import messages as s
|
||||
from instructor import OpenAISchema, MultiTask
|
||||
from instructor.dsl import ChatCompletion
|
||||
from instructor.dsl import messages as m
|
||||
from instructor.dsl.messages import messages as s
|
||||
|
||||
|
||||
def test_chatcompletion_has_kwargs():
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from openai_function_call import openai_schema, OpenAISchema
|
||||
from instructor import openai_schema, OpenAISchema
|
||||
|
||||
|
||||
def test_openai_schema():
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from openai_function_call.dsl import messages as m
|
||||
from openai_function_call.dsl.messages import messages as s
|
||||
from instructor.dsl import messages as m
|
||||
from instructor.dsl.messages import messages as s
|
||||
|
||||
|
||||
def test_create_message():
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from openai_function_call import OpenAISchema
|
||||
from openai_function_call.dsl import MultiTask
|
||||
from instructor import OpenAISchema
|
||||
from instructor.dsl import MultiTask
|
||||
|
||||
|
||||
def test_multi_task():
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
from pydantic import BaseModel
|
||||
import pytest
|
||||
import openai
|
||||
from openai_function_call import patch
|
||||
from instructor import patch
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="Needs openai call")
|
||||
|
||||
Reference in New Issue
Block a user