diff --git a/docs/blog/index.md b/docs/blog/index.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/blog/posts/introduction.md b/docs/blog/posts/introduction.md new file mode 100644 index 0000000..03d44de --- /dev/null +++ b/docs/blog/posts/introduction.md @@ -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. \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 09928c7..5072e70 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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