mirror of
https://github.com/kennethreitz/instructor.git
synced 2026-06-05 22:50:18 +00:00
blog
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
---
|
||||
draft: False
|
||||
date: 2023-09-11
|
||||
tags:
|
||||
- Introduction
|
||||
---
|
||||
|
||||
# Bridging Language Models with Python using Instructor, Pydantic, and OpenAI's Function Calls
|
||||
|
||||
Language models have seen significant growth. Using them effectively often requires complex frameworks. This post discusses how Instructor simplifies this process using Pydantic.
|
||||
|
||||
## The Problem with Existing LLM Frameworks
|
||||
|
||||
Current frameworks for Language Learning Models (LLMs) have complex setups. Developers find it hard to control interactions with language models. Some frameworks require complex JSON Schema setups.
|
||||
|
||||
## The OpenAI Function Calling Game-Changer
|
||||
|
||||
OpenAI's Function Calling feature provides a constrained interaction model. However, it has its own complexities, mostly around JSON Schema.
|
||||
|
||||
## Why Pydantic?
|
||||
|
||||
Instructor uses Pydantic to simplify the interaction between the programmer and the language model.
|
||||
|
||||
- **Widespread Adoption**: Pydantic is a popular tool among Python developers.
|
||||
- **Simplicity**: Pydantic allows model definition in Python.
|
||||
- **Framework Compatibility**: Many Python frameworks already use Pydantic.
|
||||
|
||||
```python
|
||||
import pydantic
|
||||
import instructor
|
||||
import openai
|
||||
|
||||
# Enables the response_model
|
||||
instructor.patch()
|
||||
|
||||
class UserDetail(pydantic.BaseModel):
|
||||
name: str
|
||||
age: int
|
||||
|
||||
def introduce(self):
|
||||
return f"Hello I'm {self.name} and I'm {self.age} years old"
|
||||
|
||||
user: UserDetail = openai.ChatCompletion.create(
|
||||
model="gpt-3.5-turbo",
|
||||
response_model=UserDetail,
|
||||
messages=[
|
||||
{"role": "user", "content": "Extract Jason is 25 years old"},
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Simplifying Validation Flow with Pydantic
|
||||
|
||||
Pydantic validators simplify features like re-asking or self-critique. This makes these tasks less complex compared to other frameworks.
|
||||
|
||||
```python
|
||||
from typing_extensions import Annotated
|
||||
from pydantic import BaseModel, BeforeValidator
|
||||
from instructor import llm_validator, patch
|
||||
|
||||
import openai
|
||||
|
||||
class QuestionAnswerNoEvil(BaseModel):
|
||||
question: str
|
||||
answer: Annotated[
|
||||
str,
|
||||
BeforeValidator(
|
||||
llm_validator("don't say objectionable things")
|
||||
),
|
||||
]
|
||||
```
|
||||
|
||||
## The Modular Approach
|
||||
|
||||
Pydantic allows for modular output schemas. This leads to more organized code.
|
||||
|
||||
### Composition of Schemas
|
||||
```python
|
||||
class UserDetails(BaseModel):
|
||||
name: str
|
||||
age: int
|
||||
|
||||
class UserWithAddress(UserDetails):
|
||||
address: str
|
||||
```
|
||||
|
||||
### Defining Relationships
|
||||
```python
|
||||
class UserDetail(BaseModel):
|
||||
id: int
|
||||
age: int
|
||||
name: str
|
||||
friends: List[int]
|
||||
|
||||
class UserRelationships(BaseModel):
|
||||
users: List[UserDetail]
|
||||
```
|
||||
|
||||
### Using Enums
|
||||
```python
|
||||
from enum import Enum, auto
|
||||
|
||||
class Role(Enum):
|
||||
PRINCIPAL = auto()
|
||||
TEACHER = auto()
|
||||
STUDENT = auto()
|
||||
OTHER = auto()
|
||||
|
||||
class UserDetail(BaseModel):
|
||||
age: int
|
||||
name: str
|
||||
role: Role
|
||||
```
|
||||
|
||||
### Flexible Schemas
|
||||
```python
|
||||
from typing import List
|
||||
|
||||
class Property(BaseModel):
|
||||
key: str
|
||||
value: str
|
||||
|
||||
class UserDetail(BaseModel):
|
||||
age: int
|
||||
name: str
|
||||
properties: List[Property]
|
||||
```
|
||||
|
||||
### Chain of Thought
|
||||
```python
|
||||
class TimeRange(BaseModel):
|
||||
chain_of_thought: str
|
||||
start_time: int
|
||||
end_time: int
|
||||
|
||||
class UserDetail(BaseModel):
|
||||
id: int
|
||||
age: int
|
||||
name: str
|
||||
work_time: TimeRange
|
||||
leisure_time: TimeRange
|
||||
```
|
||||
|
||||
## Language Models as Microservices
|
||||
|
||||
The architecture resembles FastAPI. Most code can be written as Python functions that use Pydantic objects. This eliminates the need for prompt chains.
|
||||
|
||||
### FastAPI Stub
|
||||
|
||||
```python
|
||||
app = FastAPI()
|
||||
|
||||
@app.get("/user/{user_id}", response_model=UserDetails)
|
||||
async def get_user(user_id: int) -> UserDetails:
|
||||
return UserDetails(...)
|
||||
```
|
||||
|
||||
### Using Instructor as a Function
|
||||
|
||||
```python
|
||||
def extract_user(str) -> UserDetails:
|
||||
return openai.ChatCompletion(
|
||||
response_model=UserDetails,
|
||||
messages=[...]
|
||||
)
|
||||
```
|
||||
|
||||
### Response Modeling
|
||||
```python
|
||||
class MaybeUser(BaseModel):
|
||||
result: Optional[UserDetail]
|
||||
error: bool
|
||||
message: Optional[str]
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
Instructor, with Pydantic, simplifies interaction with language models. It is usable for both experienced and new developers.
|
||||
+15
@@ -72,6 +72,21 @@ nav:
|
||||
- 'MultiTask': 'api_multitask.md'
|
||||
- "Introduction: Writing Prompts": "writing-prompts.md"
|
||||
- "Prompting Templates": "chat-completion.md"
|
||||
- Blog:
|
||||
- "blog/index.md"
|
||||
plugins:
|
||||
- group:
|
||||
enabled: !ENV CI
|
||||
plugins:
|
||||
- optimize
|
||||
- minify
|
||||
- blog:
|
||||
enabled: !ENV CI
|
||||
blog_dir: "blog"
|
||||
blog_toc: true
|
||||
post_dir: blog/posts
|
||||
post_date_format: yyyy/MM/dd
|
||||
post_url_format: "{date}/{slug}"
|
||||
extra:
|
||||
analytics:
|
||||
provider: google
|
||||
|
||||
Reference in New Issue
Block a user