-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdynamically_structured_output.py
More file actions
92 lines (73 loc) · 2.64 KB
/
dynamically_structured_output.py
File metadata and controls
92 lines (73 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import instructor
from pydantic import (
BaseModel,
Field,
create_model,
)
from dotenv import load_dotenv
from openai import OpenAI
from typing import List, Iterable, Literal
load_dotenv()
client = instructor.patch(OpenAI())
def extract_data_dynamically(context: str, schema_name: str) -> List[BaseModel]:
class Property(BaseModel):
"""property name and corresponding type"""
name: str = Field(..., description="must be snake case")
type: Literal["string", "integer", "boolean"]
def factory(schema: list[Property]) -> type[BaseModel]:
type_definition = {
"string": ("str", ""),
"integer": ("int", 0),
"boolean": ("bool", True),
}
field_definitions = {
attribute.name: (type_definition[attribute.type]) for attribute in schema
}
print(f"{field_definitions=}")
return create_model(
"DataModel",
**field_definitions,
__base__=BaseModel,
)
custom_properties = client.chat.completions.create(
# model="gpt-4",
model="gpt-3.5-turbo",
response_model=Iterable[Property],
max_retries=2,
messages=[
{
"role": "system",
"content": "You are a world class data structure extractor.",
},
{
"role": "user",
"content": f"""provide all necessary properties for a {schema_name} data class which captures all given information
about the {schema_name}s decribed in the context below.
context: {' '.join(context)}
""",
},
],
)
if not custom_properties:
raise ValueError("schema for dynamic data extraction is empty")
DataModel: BaseModel = factory(custom_properties)
def extract(Schema, context) -> List[DataModel]:
return client.chat.completions.create(
response_model=Iterable[Schema],
messages=[
{"role": "user", "content": f"parse the context: `{context}`"},
],
model="gpt-3.5-turbo",
temperature=0,
) # type: ignore
return extract(DataModel, context)
if __name__ == "__main__":
context = """
Brandon is 33 years old. He works as a solution architect.
Dominic is 45 years old. He is retired.
There onces was a prince, named Benny. He ruled for 10 years, which just ended. He started at 22.
Simon says, why are you 22 years old marvin?
"""
users = extract_data_dynamically(context, "user")
for user in users:
print(user.model_dump_json(indent=2))