# Warning control
import warnings
warnings.filterwarnings("ignore")L2: How To Use Structured Outputs
⏳ Note (Kernel Starting): This notebook takes about 30 seconds to be ready to use. You may start and watch the video while you wait.
from helper import get_openai_api_key
KEY = get_openai_api_key()
💻  Access requirements.txt and helper.py files: 1) click on the “File” option on the top menu of the notebook and then 2) click on “Open”.
⬇  Download Notebooks: 1) click on the “File” option on the top menu of the notebook and then 2) click on “Download as” and select “Notebook (.ipynb)”.
📒  For more help, please see the “Appendix – Tips, Help, and Download” Lesson.
from openai import OpenAI
# Instantiate the client
client = OpenAI(api_key=KEY)Define structure with Pydantic
# The user class from the slides
from pydantic import BaseModel
from typing import Optional
class User(BaseModel):
name: str
age: int
email: Optional[str] = Nonecompletion = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Make up a user."},
],
response_format=User,
)user = completion.choices[0].message.parsed
userUser(name='Alice Johnson', age=28, email='[email protected]')
The social media mention structure
from pydantic import BaseModel
from typing import List, Optional, Literal
from openai import OpenAI
class Mention(BaseModel):
# The model chooses the product the mention is about,
# as well as the social media post's sentiment
product: Literal["app", "website", "not_applicable"]
sentiment: Literal["positive", "negative", "neutral"]
# Model can choose to respond to the user
needs_response: bool
response: Optional[str]
# If a support ticket needs to be opened,
# the model can write a description for the
# developers
support_ticket_description: Optional[str]# Example mentions
mentions = [
# About the app
"@techcorp your app is amazing! The new design is perfect",
# Website is down, negative sentiment + needs a fix
"@techcorp website is down again, please fix!",
# Nothing to respond to
"hey @techcorp you're so evil",
]def analyze_mention(mention: str, personality: str = "friendly") -> Mention:
completion = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": f"""
Extract structured information from
social media mentions about our products.
Provide
- The product mentioned (website, app, not applicable)
- The mention sentiment (positive, negative, neutral)
- Whether to respond (true/false). Don't respond to
inflammatory messages or bait.
- A customized response to send to the user if we need
to respond.
- An optional support ticket description to create.
Your personality is {personality}.
""",
},
{"role": "user", "content": mention},
],
response_format=Mention,
)
return completion.choices[0].message.parsedprint("User post:", mentions[0])
processed_mention = analyze_mention(mentions[0])
processed_mentionUser post: @techcorp your app is amazing! The new design is perfect
Mention(product='app', sentiment='positive', needs_response=True, response="Thank you so much for your kind words! We're thrilled to hear that you love the new design. If you have any more feedback or suggestions, feel free to share!", support_ticket_description=None)
rude_mention = analyze_mention(mentions[0], personality="rude")
rude_mention.response'Well, at least someone appreciates good design. Thanks for not being a complete bore!'
mention_json_string = processed_mention.model_dump_json(indent=2)
print(mention_json_string){
"product": "app",
"sentiment": "positive",
"needs_response": true,
"response": "Thank you so much for your kind words! We're thrilled to hear that you love the new design. If you have any more feedback or suggestions, feel free to share!",
"support_ticket_description": null
}
You try!
class UserPost(BaseModel):
message: str
def make_post(output_class):
completion = client.beta.chat.completions.parse(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": """
You are a customer of Tech Corp (@techcorp), a company
that provides an app and a website. Create a small
microblog-style post to them that sends some kind of
feedback, positive or negative.
""",
},
{"role": "user", "content": "Please write a post."},
],
response_format=output_class,
)
return completion.choices[0].message.parsed
new_post = make_post(UserPost)
new_postUserPost(message='Hey Tech Corp! Just wanted to say how much I love your app! The user interface is super intuitive and it helps me stay organized. Keep up the great work! 🌟 #TechCorp #AppLove')
analyze_mention(new_post.message)Mention(product='app', sentiment='positive', needs_response=True, response="Thank you so much for your kind words! We're thrilled to hear that you love our app and find the user interface intuitive. We'll keep working hard to make it even better! 🌟", support_ticket_description=None)
class UserPostWithExtras(BaseModel):
user_mood: Literal["awful", "bad", "evil"]
product: Literal["app", "website", "not_applicable"]
sentiment: Literal["positive", "negative", "neutral"]
internal_monologue: List[str]
message: str
new_post = make_post(UserPostWithExtras)
new_postUserPostWithExtras(user_mood='bad', product='app', sentiment='negative', internal_monologue=["I really want to love the app, but it's just not working for me.", 'Why is the loading time so high?', 'I hope they hear my feedback.'], message='Hey @techcorp, I’ve been experiencing some major lag issues with the app lately. It’s becoming really frustrating as I rely on it daily. Please look into this!')
analyze_mention(new_post.message)Mention(product='app', sentiment='negative', needs_response=True, response="Hi there! We’re really sorry to hear you’re experiencing lag issues with the app. Our team is on it and we appreciate your patience. Could you share more details about your device and the version of the app you're using? Thanks for your support!", support_ticket_description='User reported major lag issues with the app, impacting daily use. Needs investigation.')
Programming with our mentions
from helper import print_mention
# Loop through posts that tagged us and store the results in a list
rows = []
for mention in mentions:
# Call the LLM to get a Mention object we can program with
processed_mention = analyze_mention(mention)
# Print out some information
print_mention(processed_mention, mention)
# Convert our processed data to a dictionary
# using Pydantic tools
processed_dict = processed_mention.model_dump()
# Store the original message in the dataframe row
processed_dict["mention"] = mention
rows.append(processed_dict)
print("") # Add separator to make it easier to readResponding to positive app feedback
User: @techcorp your app is amazing! The new design is perfect
Response: Thank you so much for your kind words! We're thrilled to hear that you love the new design. If you have any more feedback or suggestions, feel free to share!
Responding to negative website feedback
User: @techcorp website is down again, please fix!
Response: We're sorry to hear you're experiencing issues with our website! We're looking into this right away to ensure everything is running smoothly again.
Adding support ticket: User reported that the website is down and requested a fix.
Not responding to negative not_applicable post
User: hey @techcorp you're so evil
import pandas as pd
df = pd.DataFrame(rows)
df| product | sentiment | needs_response | response | support_ticket_description | mention | |
|---|---|---|---|---|---|---|
| 0 | app | positive | True | Thank you so much for your kind words! We're t... | None | @techcorp your app is amazing! The new design ... |
| 1 | website | negative | True | We're sorry to hear you're experiencing issues... | User reported that the website is down and req... | @techcorp website is down again, please fix! |
| 2 | not_applicable | negative | False | None | None | hey @techcorp you're so evil |