Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create model GeneratesAttributes trait #3

Open
gregpriday opened this issue Jun 29, 2021 · 0 comments
Open

Create model GeneratesAttributes trait #3

gregpriday opened this issue Jun 29, 2021 · 0 comments

Comments

@gregpriday
Copy link
Member

Another incredibly useful feature of GPT-3 is its ability to generate model attributes. The most obvious example of this is auto-generating tags for a new item based on the tags from existing items. This functionality should work in a similar way as possible to #2

Attribute Generator Class

The first thing we need for this is an attribute generator class. This should be heavily inspired by the full model factory, with a similar interface.

class AttributeGenerator {
	protected Model $model;
	
	public function __construct(Model $model){}
	
	public function withSeed(Collection|Query $models){}
	public function withPrompt(string $text) {}
	public function withAttributes(array $fields){}
	public function withAttributeCast(string $field, Cast $cast){}
	public function withTitle(Closure|TitleCast|string|null $title){}
	public function withModelSeparator(string $separator="\n\n"){}
	public function withGpt3Options(array $options){}
	
	public function generateAttribute($name, $count=null){}
	public function completeAttribute($name, $append='', $count=null){}
}

The workflow will be quite similar, but how it interacts with GPT-3 will be different.

generateAttribute will generate a GPT-3 completion prompt that ends with it : after the required attribute name, and end with a "\n". completeAttribute will work in a similar way, except it'll include the existing value, and ask GPT-3 to add more content to it.

This is what the GPT-3 prompt text will look like with a single seed model, and

This is a list of articles along with their categories and tags:

Article Title - Article Sub Title
category: category 1
tags: tag1, tag2, tag3

Another Article Title - This Article's Sub Title
category: category 2
tags:[...]

Where the autocomplete starts at [...]. If we're calling completeAttribute, then the existing tags will be added (along with the append text afterward), which will prompt GPT-3 to complete the attribute. This would be useful, for example, if you already had a few tags and you wanted more added.

So calling completeAttribute('tags', ', ') would end with the following prompt.

tags: tag4, tag5, [...]

No matter which attributes are set using withAttributes, we should always place them in an order that results in the attribute we're generating coming last.

Generating Multiple Options

There are times that it would be useful to generate multiple options. For example, we could generate multiple options and then have a user select the best option for a field like a Post excerpt.

This would just call GPT-3 multiple times, using new seed data each time.

So calling generateAttribute('excerpt', 1) would return a single string, while calling generateAttribute('excerpt', 3) would return an array of 3 strings.

Model Trait

As a helper, we should have a model trait that gives a helper function to create a new attribute generator. The trait could be called generatesAttributes. It would be called as follows:

$post = Post::find(1);
$post->attributeGenerator()
	->withSeed(/*...*/)
	/* Rest of generator config */
	->generateAttribute('excerpt');

// Or, for generating multiple options
$excerpts = $post->attributeGenerator()->generateAttribute('excerpt', 3);
// This will be an array of 3 strings
var_dump($excerpts)

A model should also be able to define a function called configureAttributeGenerator. Something like this:

class MyModel extends Model {
	trait GeneratesAttributes;
	
	protected function configureAttributeGenerator(Generator $generator) {
		return $generator
			->withSeed(/* seed */)
			// Rest of generator config.
	}
}

The generator that's returned by this function, will also be returned by attributeGenerator() on the model, so it's a way to reuse the generator config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant