Repository navigation
Expand file tree
/
Copy pathmain.go
More file actions
112 lines (99 loc) · 3.82 KB
/
Copy pathmain.go
File metadata and controls
112 lines (99 loc) · 3.82 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package main
import (
"context"
"encoding/json"
"fmt"
"github.com/invopop/jsonschema"
"github.com/openai/openai-go/examples/internal/errutil"
"github.com/openai/openai-go/v3"
"github.com/openai/openai-go/v3/responses"
)
// A struct that will be converted to a Structured Outputs response schema.
//
// NOTE: Avoid using `omitempty` in JSON tags for structured output schemas. The
// jsonschema library interprets `omitempty` as "optional", excluding the field
// from the schema's "required" array. This can cause the API to reject the
// schema (with Strict: true) or the model to silently skip populating those fields.
type HistoricalComputer struct {
Origin Origin `json:"origin" jsonschema_description:"The origin of the computer"`
Name string `json:"full_name" jsonschema_description:"The name of the device model"`
Legacy string `json:"legacy" jsonschema:"enum=positive,enum=neutral,enum=negative" jsonschema_description:"Its influence on the field of computing"`
NotableFacts []string `json:"notable_facts" jsonschema_description:"A few key facts about the computer"`
}
type Origin struct {
YearBuilt int64 `json:"year_of_construction" jsonschema_description:"The year it was made"`
Organization string `json:"organization" jsonschema_description:"The organization that was in charge of its development"`
}
func GenerateSchema[T any]() (map[string]any, error) {
// Structured Outputs uses a subset of JSON schema
// These flags are necessary to comply with the subset
reflector := jsonschema.Reflector{
AllowAdditionalProperties: false,
DoNotReference: true,
}
var v T
schema := reflector.Reflect(v)
data, err := json.Marshal(schema)
if err != nil {
return nil, fmt.Errorf("marshal JSON schema: %w", err)
}
// Preserve schema values as raw JSON so integer constraints are not rounded
// through float64 before the SDK serializes the request.
var rawSchema map[string]json.RawMessage
if err := json.Unmarshal(data, &rawSchema); err != nil {
return nil, fmt.Errorf("decode JSON schema: %w", err)
}
result := make(map[string]any, len(rawSchema))
for key, value := range rawSchema {
result[key] = value
}
return result, nil
}
func historicalComputerParams(question string, schema map[string]any) responses.ResponseNewParams {
return responses.ResponseNewParams{
Model: openai.ChatModelGPT5_2,
Input: responses.ResponseNewParamsInputUnion{
OfString: openai.String(question),
},
Text: responses.ResponseTextConfigParam{
Format: responses.ResponseFormatTextConfigUnionParam{
OfJSONSchema: &responses.ResponseFormatTextJSONSchemaConfigParam{
Name: "historical_computer",
Description: openai.String("Notable information about a computer"),
Schema: schema,
Strict: openai.Bool(true),
},
},
},
}
}
func main() {
client := openai.NewClient()
ctx := context.Background()
question := "What computer ran the first neural network?"
print("> ")
println(question)
schema, err := GenerateSchema[HistoricalComputer]()
if err != nil {
panic(errutil.Message(err))
}
response, err := client.Responses.New(ctx, historicalComputerParams(question, schema))
if err != nil {
panic(errutil.Message(err))
}
// The model responds with a JSON string, so parse it into a struct
var historicalComputer HistoricalComputer
err = json.Unmarshal([]byte(response.OutputText()), &historicalComputer)
if err != nil {
panic(errutil.Message(err))
}
// Use the model's structured response with a native Go struct
fmt.Printf("Name: %v\n", historicalComputer.Name)
fmt.Printf("Year: %v\n", historicalComputer.Origin.YearBuilt)
fmt.Printf("Org: %v\n", historicalComputer.Origin.Organization)
fmt.Printf("Legacy: %v\n", historicalComputer.Legacy)
fmt.Printf("Facts:\n")
for i, fact := range historicalComputer.NotableFacts {
fmt.Printf("%v. %v\n", i+1, fact)
}
}