diff --git a/README.md b/README.md
index ef1db98cc..da1a2804d 100644
--- a/README.md
+++ b/README.md
@@ -516,6 +516,66 @@ func main() {
```
+
+JSON Schema for function calling
+
+It is now possible for chat completion to choose to call a function for more information ([see developer docs here](https://platform.openai.com/docs/guides/gpt/function-calling)).
+
+In order to describe the type of functions that can be called, a JSON schema must be provided. Many JSON schema libraries exist and are more advanced than what we can offer in this library, however we have included a simple `jsonschema` package for those who want to use this feature without formatting their own JSON schema payload.
+
+The developer documents give this JSON schema definition as an example:
+
+```json
+{
+ "name":"get_current_weather",
+ "description":"Get the current weather in a given location",
+ "parameters":{
+ "type":"object",
+ "properties":{
+ "location":{
+ "type":"string",
+ "description":"The city and state, e.g. San Francisco, CA"
+ },
+ "unit":{
+ "type":"string",
+ "enum":[
+ "celsius",
+ "fahrenheit"
+ ]
+ }
+ },
+ "required":[
+ "location"
+ ]
+ }
+}
+```
+
+Using the `jsonschema` package, this schema could be created using structs as such:
+
+```go
+FunctionDefinition{
+ Name: "get_current_weather",
+ Parameters: jsonschema.Definition{
+ Type: jsonschema.Object,
+ Properties: map[string]jsonschema.Definition{
+ "location": {
+ Type: jsonschema.String,
+ Description: "The city and state, e.g. San Francisco, CA",
+ },
+ "unit": {
+ Type: jsonschema.String,
+ Enum: []string{"celcius", "fahrenheit"},
+ },
+ },
+ Required: []string{"location"},
+ },
+}
+```
+
+The `Parameters` field of a `FunctionDefinition` can accept either of the above styles, or even a nested struct from another library (as long as it can be marshalled into JSON).
+
+
Error handling
diff --git a/chat.go b/chat.go
index b74720d38..e4f23df07 100644
--- a/chat.go
+++ b/chat.go
@@ -62,47 +62,16 @@ type FunctionDefinition struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
// Parameters is an object describing the function.
- // You can pass a raw byte array describing the schema,
- // or you can pass in a struct which serializes to the proper JSONSchema.
- // The JSONSchemaDefinition struct is provided for convenience, but you should
- // consider another specialized library for more complex schemas.
+ // You can pass a []byte describing the schema,
+ // or you can pass in a struct which serializes to the proper JSON schema.
+ // The jsonschema package is provided for convenience, but you should
+ // consider another specialized library if you require more complex schemas.
Parameters any `json:"parameters"`
}
// Deprecated: use FunctionDefinition instead.
type FunctionDefine = FunctionDefinition
-type JSONSchemaType string
-
-const (
- JSONSchemaTypeObject JSONSchemaType = "object"
- JSONSchemaTypeNumber JSONSchemaType = "number"
- JSONSchemaTypeString JSONSchemaType = "string"
- JSONSchemaTypeArray JSONSchemaType = "array"
- JSONSchemaTypeNull JSONSchemaType = "null"
- JSONSchemaTypeBoolean JSONSchemaType = "boolean"
-)
-
-// JSONSchemaDefinition is a struct for JSON Schema.
-// It is fairly limited and you may have better luck using a third-party library.
-type JSONSchemaDefinition struct {
- // Type is a type of JSON Schema.
- Type JSONSchemaType `json:"type,omitempty"`
- // Description is a description of JSON Schema.
- Description string `json:"description,omitempty"`
- // Enum is a enum of JSON Schema. It used if Type is JSONSchemaTypeString.
- Enum []string `json:"enum,omitempty"`
- // Properties is a properties of JSON Schema. It used if Type is JSONSchemaTypeObject.
- Properties map[string]JSONSchemaDefinition `json:"properties,omitempty"`
- // Required is a required of JSON Schema. It used if Type is JSONSchemaTypeObject.
- Required []string `json:"required,omitempty"`
- // Items is a property of JSON Schema. It used if Type is JSONSchemaTypeArray.
- Items *JSONSchemaDefinition `json:"items,omitempty"`
-}
-
-// Deprecated: use JSONSchemaDefinition instead.
-type JSONSchemaDefine = JSONSchemaDefinition
-
type FinishReason string
const (
diff --git a/chat_test.go b/chat_test.go
index 3c759b310..d5879e60f 100644
--- a/chat_test.go
+++ b/chat_test.go
@@ -1,9 +1,6 @@
package openai_test
import (
- . "github.com/sashabaranov/go-openai"
- "github.com/sashabaranov/go-openai/internal/test/checks"
-
"context"
"encoding/json"
"fmt"
@@ -13,6 +10,10 @@ import (
"strings"
"testing"
"time"
+
+ . "github.com/sashabaranov/go-openai"
+ "github.com/sashabaranov/go-openai/internal/test/checks"
+ "github.com/sashabaranov/go-openai/jsonschema"
)
func TestChatCompletionsWrongModel(t *testing.T) {
@@ -128,22 +129,22 @@ func TestChatCompletionsFunctions(t *testing.T) {
},
Functions: []FunctionDefinition{{
Name: "test",
- Parameters: &JSONSchemaDefinition{
- Type: JSONSchemaTypeObject,
- Properties: map[string]JSONSchemaDefinition{
+ Parameters: &jsonschema.Definition{
+ Type: jsonschema.Object,
+ Properties: map[string]jsonschema.Definition{
"count": {
- Type: JSONSchemaTypeNumber,
+ Type: jsonschema.Number,
Description: "total number of words in sentence",
},
"words": {
- Type: JSONSchemaTypeArray,
+ Type: jsonschema.Array,
Description: "list of words in sentence",
- Items: &JSONSchemaDefinition{
- Type: JSONSchemaTypeString,
+ Items: &jsonschema.Definition{
+ Type: jsonschema.String,
},
},
"enumTest": {
- Type: JSONSchemaTypeString,
+ Type: jsonschema.String,
Enum: []string{"hello", "world"},
},
},
@@ -165,22 +166,22 @@ func TestChatCompletionsFunctions(t *testing.T) {
},
Functions: []FunctionDefine{{
Name: "test",
- Parameters: &JSONSchemaDefine{
- Type: JSONSchemaTypeObject,
- Properties: map[string]JSONSchemaDefine{
+ Parameters: &jsonschema.Definition{
+ Type: jsonschema.Object,
+ Properties: map[string]jsonschema.Definition{
"count": {
- Type: JSONSchemaTypeNumber,
+ Type: jsonschema.Number,
Description: "total number of words in sentence",
},
"words": {
- Type: JSONSchemaTypeArray,
+ Type: jsonschema.Array,
Description: "list of words in sentence",
- Items: &JSONSchemaDefine{
- Type: JSONSchemaTypeString,
+ Items: &jsonschema.Definition{
+ Type: jsonschema.String,
},
},
"enumTest": {
- Type: JSONSchemaTypeString,
+ Type: jsonschema.String,
Enum: []string{"hello", "world"},
},
},
diff --git a/jsonschema/json.go b/jsonschema/json.go
new file mode 100644
index 000000000..24af8584e
--- /dev/null
+++ b/jsonschema/json.go
@@ -0,0 +1,35 @@
+// Package jsonschema provides very simple functionality for representing a JSON schema as a
+// (nested) struct. This struct can be used with the chat completion "function call" feature.
+// For more complicated schemas, it is recommended to use a dedicated JSON schema library
+// and/or pass in the schema in []byte format.
+package jsonschema
+
+type DataType string
+
+const (
+ Object DataType = "object"
+ Number DataType = "number"
+ Integer DataType = "integer"
+ String DataType = "string"
+ Array DataType = "array"
+ Null DataType = "null"
+ Boolean DataType = "boolean"
+)
+
+// Definition is a struct for describing a JSON Schema.
+// It is fairly limited and you may have better luck using a third-party library.
+type Definition struct {
+ // Type specifies the data type of the schema.
+ Type DataType `json:"type,omitempty"`
+ // Description is the description of the schema.
+ Description string `json:"description,omitempty"`
+ // Enum is used to restrict a value to a fixed set of values. It must be an array with at least
+ // one element, where each element is unique. You will probably only use this with strings.
+ Enum []string `json:"enum,omitempty"`
+ // Properties describes the properties of an object, if the schema type is Object.
+ Properties map[string]Definition `json:"properties,omitempty"`
+ // Required specifies which properties are required, if the schema type is Object.
+ Required []string `json:"required,omitempty"`
+ // Items specifies which data type an array contains, if the schema type is Array.
+ Items *Definition `json:"items,omitempty"`
+}