-
Notifications
You must be signed in to change notification settings - Fork 356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix function calling schema for pydantic v2 #616
Conversation
@CalebCourier can you add a test to repro the original failure? |
Another thing I still need to fix is the types used in llm_providers and the pydantic utils are wrong. The The obvious task here is to update those types, but in addition to that, if the type is a |
@ShreyaR I can show that the schema included in the This PR is also still in draft because I'm waiting the hear back on if this solved the issue the end user was experiencing. If it doesn't then there might be more to the problem. |
@ShreyaR I added tests that show the current behaviour as well as the empty schema issue I mention in the PR description. |
Ok, I was able to replicate the LLM returning an empty object when these changes are not in place (i.e. 0.4.1) if I remove the import guardrails as gd
import openai
from rich import print
from typing import List, Optional
from pydantic import BaseModel, Field
from guardrails.validators import ValidLength
openai.api_type = ""
openai.api_version = ""
openai.api_key = ""
openai.azure_endpoint = ""
class Founder(BaseModel):
first: str = Field(
description="First name of the founder"
)
last: str = Field(
description="last name of the founder"
)
class Customer(BaseModel):
customer_persona: Optional[str] = Field(
description="who is the customer that this organization is targeting (e.g. 'dental-practices', 'consumers', 'health plans')"
)
targets_healthcare_orgs: Optional[str] = Field(
description="Does this organization target healthcare providers or healthcare practices? Respond with 'True', 'False', or 'Unknown'"
)
targets_healthcare_reasoning: Optional[str] = Field(
description="Please provider a brief explanation of why you believe this organization does or does not target healthcare providers"
)
description: Optional[str] = Field(
description="Provider a brief description of the organizaiton in 80 characters or less",
validators=[ValidLength(min=0, max=10000)]
)
founders: Optional[List[Founder]] = Field(
description="List of all the founders of the organization"
)
organization_type: Optional[str] = Field(
description="What type of organization is this? (e.g. 'startup', 'consultancy', 'non-profit')"
)
prompt = """
I will provide you with some raw source data. I want you to read my instructions below and extract the information requested below.
**INSTRUCTIONS**
I am going to provide you with some information about an organization called Harbor Health.
I want you to read the information and fill out the responses to the best of your ability.
**SOURCE DATA**
Description: Harbor Health is a multi-specialy clinic group that providers smarter health care using technology. The company co-creates a health path that is dedicated to knowing individuals health goals with the guidance of specialist when needed. Harbor Health was foudned in 2022 and is based in Austin Texas.
Founders:
"""
# ${gr.complete_json_suffix}
instructions = """
You are a helpful assistant, able to express yourself purely through JSON, strictly and precisely adhering to the provided XML schemas.
When you return your response, do not wrap your answer in a code block such as or any other formatting such as '''json, or ''
If you do not know the answer, return an empty dictionary, '{}'
"""
guard = gd.Guard.from_pydantic(
output_class=Customer,
instructions=instructions,
prompt=prompt,
)
res = None
try:
res = guard(
openai.chat.completions.create,
# prompt_params=params,
# model=model.value,
model="gpt-3.5-turbo",
temperature=0,
)
except Exception as e:
# todo
print(e)
raise e
if guard.history.last is not None:
print(guard.history.last.tree) |
Hey, encountered the same issue on my end where OpenAI was returning an empt dict, can provide an example with the Also getting this error when trying with this branch: |
@edisontim if you could share your example where OpenAI returns empty dict that includes the complete_json_suffix that would be very helpful thank you! I'll try to track down the serializing error with validators on pydantic models. For that, which version of pydantic are you using? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
Hey! Sure here's the Models I'm using with pydantic v2.6.3
and using
and calling like such:
|
@edisontim I don't see any validators in your model. Would you mind sharing where the ValidRange validator is applied that caused the serialization error? |
My bad, updated in the original comment |
Ok, able to replicate the serialization issue with your example, thanks @edisontim. Think I have a path forward for resolution. |
@edisontim I just pushed a commit that should fix the serialization issue for pydantic 2.x. Note though, that pydantic 1.x is still broken. |
Pass the
model
instead oftype(model)
when reducing for function calling.The previous implementation yielded an empty dictionary for the annotation which some LLM's might take to mean they should return an empty object.