bokov.me
This is my website, which is a place for my hobby projects. Feel free to look around.
Article

GPT-3 experiments

The OpenAI API is a service, which allows you to generate text using OpenAI's GPT-3 model. This model is highly sophisticated, and excels at many tasks. On this page, I list some of my experiments with the technology.

Command extraction

One interesting way to use GPT-3 is to extract commands, and command parameters from text. This text may come from a speech-to-text API (such as Google's). The trick is to define some context for the model, which contains the available commands, and then prompt the machine to extract the commands into a Markdown table, along with a JSON object containing the parameters.

Example

You can issue the following commands:
- BUY
---- "item"
---- "store"
- TODO
---- "note"
- AGENDA
---- "date"
---- "time"
---- "note"
---- "location"

Interpret the following text, and extract the user's commands, along with their payloads.

# Text

I have to go to the doctor at 2 PM, and I also have to go shopping for groceries at around 5. I should buy milk, and water, it doesn't really matter where from. I should also buy some dog food from ALDI, because we are running low. Also remind me, that I should look at my homework when I get home, and that I should do some cleaning.

# Output

| Command | Payload JSON |
| --- | --- |
| AGENDA | `{ "date": "", "time": "2 PM", "note": "go to doctor", "location": "" }` |
| AGENDA | `{ "date": "", "time": "5 PM", "note": "go shopping for groceries", "location": "" }` |
| BUY | `{ "item": "milk", "store": "" }` |
| BUY | `{ "item": "water", "store": "" }` |
| BUY | `{ "item": "dog food", "store": "ALDI" }` |
| TODO | `{ "note": "look at homework" }` |
| TODO | `{ "note": "do some cleaning" }` |

text-davinci-002

JSON example generator

GPT-3 excells at dealing with code. One way to use this, is to include documentation of structures in the prompt, and expect the model to generate JSON examples, that use the fields defined in the documentation. Swagger, and similar tools usually generate placeholder content for fields, where examples are not available, such as "string", or 123 for numbers - by using GPT-3, we will get "domain-correct" data, since the model also interprets the meaning of the fields.

Example

Create a realistic JSON example for a JSON schema.

# Schema

## Example

* `firstName: String` - The person's first name.
* `lastName: String` - The person's last name.
* `age: Int` - Age in years which must be equal to or greater than zero.

## Product

* `id: String` - The product ID, an UUID.
* `name: String` - The product's name.
* `sku: String` - The product's SKU (aka. internal ID)
* `categoryId: String` - The id of the category this product belongs to (UUID)
* `images: Image[]` - Array of product images
* `manufacturer: ProductMan` - An object, which details the manufacturer of the product

`Image` elements have the following fields:

* `id: Int` - The ID of the image
* `url: String` - The URL of the image
* `thumbnailUrl: String` - The URL of the image thumbnail

`ProductMan` has the following fields:

* `name: String` - The name of the manufacturing company
* `seller: String` - The name of the selling company
* `supportUrl: String` - The link at which support can be reached for the product

# JSON Example

## Person

```json
{
    "firstName": "John",
    "lastName": "Doe",
    "age": 29
}
```

## Product

```json
{
    "id": "123456789",
    "name": "Product Name",
    "sku": "123456789",
    "categoryId": "123456789",
    "images": [
    {
    "id": 1,
    "url": "https://images.unsplash.com/photos/143627555-5dee8f8c-b5d5-4a27-bfa7-c2f2d2e2c4f1",
    "thumbnailUrl": "https://unsplash.com/photos/143627555-5dee8f8c-b5d5-4a27-bfa7-c2f2d2e2c4f1/320x180?size=l"
    }
    ],
    "manufacturer": {
    "name": "Manufacturer Name",
    "seller": "Seller Name",
    "supportUrl": "https://support.unsplash.com"
    }

}

text-curie-001

{
    "id": "123e4567-e89b-12d3-a456-426655440000",
    "name": "My Product",
    "sku": "ABC-123",
    "categoryId": "123e4567-e89b-12d3-a456-426655440000",
    "images": [
        {
            "id": 1,
            "url": "http://example.com/images/1.jpg",
            "thumbnailUrl": "http://example.com/images/1_thumb.jpg"
        },
        {
            "id": 2,
            "url": "http://example.com/images/2.jpg",
            "thumbnailUrl": "http://example.com/images/2_thumb.jpg"
        }
    ],
    "manufacturer": {
        "name": "Example Co.",
        "seller": "Example Seller",
        "supportUrl": "http://example.com/support"
    }
}
```

text-davinci-002

Generating Go code

In this experiment, I made GPT-3 generate boilerplate Go code, that contains standard API calls for predefined data structures. It performs well with smaller models too, such as text-curie-001.

Example

Turn specification into Go code. Generate structs, and client code for the types. Generate JSON annotations, use pascal-case for Go names, and lowercase snake-case for JSON names.

# Specification

## Example

Examples store an `id: int64`, and a `name`.

## Product

Products have an `id: string`, an `sku`, a `name`, and a `description`.

## Category

Categories have an `id: string`, a `name`, a `parentCategoryId`, and a `productIds` fields.

# Output

## Example

```go
type Example struct {
    Id int64 `json:"id"`
    Name string `json:"name"`
}
func NewExample() *Example {
    return new(Example)
}
func GetExample(id int64) (*Example, error) {
    resp, err := DoClientGet(fmt.Sprintf("/api/v1/example/%d", id))
    if err != nil {
        return nil, err
    }
    return resp.As(Example)
}
func CreateExample(input *Example) (*Example, error) {
    resp, err := DoClientPost("/api/v1/example", input)
    if err != nil {
        return nil, err
    }
    return resp.As(Example)
}
func UpdateExample(input *Example) (*Example, error) {
    resp, err := DoClientPost(fmt.Sprintf("/api/v1/example/%d", input.Id), input)
    if err != nil {
        return nil, err
    }
    return resp.As(Example)
}
func DeleteExample(id int64) error {
    resp, err := DoClientDelete(fmt.Sprintf("/api/v1/example/%d", id))
    return err
}
```

## Product

```go
type Product struct {
    Id string `json:"id"`
    Sku string `json:"sku"`
    Name string `json:"name"`
    Description string `json:"description"`
}
func NewProduct() *Product {
    return new(Product)
}
func GetProduct(id string) (*Product, error) {
    resp, err := DoClientGet(fmt.Sprintf("/api/v1/product/%s", id))
    if err != nil {
        return nil, err
    }
    return resp.As(Product)
}
func CreateProduct(input *Product) (*Product, error) {
    resp, err := DoClientPost("/api/v1/product", input)
    if err != nil {
        return nil, err
    }
    return resp.As(Product)
}
func UpdateProduct(input *Product) (*Product, error) {
    resp, err := DoClientPost(fmt.Sprintf("/api/v1/product/%s", input.Id), input)
    if err != nil {
        return nil, err
    }
    return resp.As(Product)
}
func DeleteProduct(id string) error {
    resp, err := DoClientDelete(fmt.Sprintf("/api/v1/product/%s", id))
    return err
}
```

## Category

```go

type Category struct {
    Id string `json:"id"`
    Name string `json:"name"`
    ParentCategoryId string `json:"parentCategoryId"`
    ProductIds []int64 `json:"productIds"`
}
func NewCategory() *Category {
    return new(Category)
}
func GetCategory(id string) (*Category, error) {
    resp, err := DoClientGet(fmt.Sprintf("/api/v1/category/%s", id))
    if err != nil {
        return nil, err
    }
    return resp.As(Category)
}
func CreateCategory(input *Category) (*Category, error) {
    resp, err := DoClientPost("/api/v1/category", input)
    if err != nil {
        return nil, err
    }
    return resp.As(Category)
}
func UpdateCategory(input *Category) (*Category, error) {
    resp, err := DoClientPost(fmt.Sprintf("/api/v1/category/%s", input.Id), input)
    if err != nil {
        return nil, err
    }
    return resp.As(Category)
}
func DeleteCategory(id string) error {
    resp, err := DoClientDelete(fmt.Sprintf("/api/v1/category/%s", id))
    return err
}
```

text-curie-001

About me and this site