8000 replace tool call with new jsonschema responses · coder/labeler@4b959c5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4b959c5

Browse files
committed
replace tool call with new jsonschema responses
OpenAI was occasionally not adhering to the tool call schema causing false negatives. I'm not sure if response format will yield overall better performance but I'm curious to see.
1 parent b0dfb8f commit 4b959c5

File tree

4 files changed

+28
-46
lines changed

4 files changed

+28
-46
lines changed

‎ 8000 aicontext.go

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@ type aiContext struct {
1818
targetIssue *github.Issue
1919
}
2020

21-
func (c *aiContext) labelNames() []string {
22-
var labels []string
23-
for _, label := range c.allLabels {
24-
labels = append(labels, label.GetName())
25-
}
26-
return labels
27-
}
28-
2921
func issueToText(issue *github.Issue) string {
3022
var sb strings.Builder
3123
fmt.Fprintf(&sb, "=== ISSUE %v ===\n", issue.GetNumber())
@@ -49,7 +41,6 @@ func issueToText(issue *github.Issue) string {
4941
return sb.String()
5042
}
5143

52-
5344
func countTokens(msgs ...openai.ChatCompletionMessage) int {
5445
enc, err := tokenizer.Get(tokenizer.Cl100kBase)
5546
if err != nil {
@@ -92,23 +83,27 @@ func (c *aiContext) Request(
9283
LogProbs: true,
9384
// Want high determinism.
9485
Temperature: 0,
95-
Tools: []openai.Tool{
96-
{
97-
Type: openai.ToolTypeFunction,
98-
Function: &openai.FunctionDefinition{
99-
Name: labelFuncName,
100-
Description: `Label the GitHub issue with the given labels.`,
101-
Parameters: jsonschema.Definition{
102-
Type: jsonschema.Object,
103-
Properties: map[string]jsonschema.Definition{
104-
"labels": {
105-
Type: jsonschema.Array,
106-
Items: &jsonschema.Definition{Type: jsonschema.String},
107-
Enum: c.labelNames(),
108-
},
86+
ResponseFormat: &openai.ChatCompletionResponseFormat{
87+
Type: openai.ChatCompletionResponseFormatTypeJSONSchema,
88+
JSONSchema: &openai.ChatCompletionResponseFormatJSONSchema{
89+
Name: labelFuncName,
90+
Description: `Label the GitHub issue with the given labels.`,
91+
Schema: jsonschema.Definition{
92+
Type: jsonschema.Object,
93+
Properties: map[string]jsonschema.Definition{
94+
"reasoning": {
95+
Description: "The reasoning for the labels. Maximum of one sentence per label.",
96+
Type: jsonschema.String,
97+
},
98+
"labels": {
99+
Type: jsonschema.Array,
100+
Items: &jsonschema.Definition{Type: jsonschema.String},
109101
},
110102
},
103+
Required: []string{"reasoning", "labels"},
104+
AdditionalProperties: false,
111105
},
106+
Strict: true,
112107
},
113108
},
114109
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,6 @@ require (
9292
github.com/go-chi/chi/v5 v5.0.12
9393
github.com/go-playground/webhooks/v6 v6.3.0
9494
github.com/google/go-querystring v1.1.0 // indirect
95-
github.com/sashabaranov/go-openai v1.28.1
95+
github.com/sashabaranov/go-openai v1.28.2
9696
github.com/tiktoken-go/tokenizer v0.1.0
9797
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
158158
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
159159
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
160160
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
161-
github.com/sashabaranov/go-openai v1.28.1 h1:aREx6faUTeOZNMDTNGAY8B9vNmmN7qoGvDV0Ke2J1Mc=
162-
github.com/sashabaranov/go-openai v1.28.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
161+
github.com/sashabaranov/go-openai v1.28.2 h1:Q3pi34SuNYNN7YrqpHlHbpeYlf75ljgHOAVM/r1yun0=
162+
github.com/sashabaranov/go-openai v1.28.2/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
163163
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
164164
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
165165
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

webhook.go

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -232,36 +232,23 @@ retryAI:
232232
}
233233
return nil, fmt.Errorf("create chat completion: %w", err)
234234
}
235-
236235
if len(resp.Choices) != 1 {
237236
return nil, fmt.Errorf("expected one choice")
238237
}
239238

240239
choice := resp.Choices[0]
241240

242-
if len(choice.Message.ToolCalls) != 1 {
243-
return nil, fmt.Errorf("expected one tool call, got %d", len(choice.Message.ToolCalls))
244-
}
245-
246-
toolCall := choice.Message.ToolCalls[0]
241+
content := choice.Message.Content
247242
var setLabels struct {
248-
Labels []string `json:"labels"`
243+
Reasoning string `json:"reasoning"`
244+
Labels []string `json:"labels"`
249245
}
250-
err = json.Unmarshal([]byte(toolCall.Function.Arguments), &setLabels)
251-
if err != nil {
252-
var setLabelsStr struct {
253-
Labels string `json:"labels"`
254-
}
255246

256-
// Sometimes the labels are returned as a string.
257-
err2 := json.Unmarshal([]byte(toolCall.Function.Arguments), &setLabelsStr 8891 )
258-
if err2 != nil {
259-
return nil, errors.Join(
260-
fmt.Errorf("unmarshal setLabels: %w, toolCall: %+v", err, toolCall),
261-
err2,
262-
)
263-
}
247+
err = json.Unmarshal([]byte(content), &setLabels)
248+
if err != nil {
249+
return nil, fmt.Errorf("unmarshal setLabels: %w, content: %q", err, content)
264250
}
251+
s.Log.Info("set labels", "labels", setLabels.Labels, "reasoning", setLabels.Reasoning)
265252

266253
disabledLabels := make(map[string]struct{})
267254
for _, label := range labels {

0 commit comments

Comments
 (0)
0