Welcome to the LaravelGPT package! LaravelGPT is a powerful and flexible package designed to integrate OpenAI's language model GPT (Generative Pretrained Transformer) into your Laravel project seamlessly. LaravelGPT is specifically tailored for developers, data scientists, and AI enthusiasts who are seeking to leverage the power of GPT models within a Laravel environment.
With LaravelGPT, you can easily analyze text for various purposes such as sentiment analysis, language translation, text summarization, and more. The package introduces two main concepts: GPTAction
and GPTChat
, which are designed to streamline the interaction between your application and the GPT model. GPTAction
is geared towards scenarios with a single input and task, while GPTChat
is suitable for handling more complex, conversational interactions.
Whether you're developing a chatbot, an AI-powered content creation tool, or any other application that needs natural language processing capabilities, LaravelGPT is here to simplify the process. This documentation will guide you through the installation and usage of the LaravelGPT package, along with providing you examples to help get you started. Happy coding!
::: tip Just getting started? If you are just getting started with the LaravelGPT package and want to get a feel for how it works, I recommend to check out the Basic Usage section. :::
You can install the package via composer:
composer require maltekuhr/laravel-gpt
Next you need to configure your OpenAI API Key and Organization ID. You can find both in the OpenAI Dashboard.
OPENAI_ORGANIZATION=YOUR_ORGANIZATION_ID
OPENAI_API_KEY=YOUR_API_KEY
You are now ready to use LaravelGPT!
You can publish the config file with:
php artisan vendor:publish --provider="MalteKuhr\LaravelGPT\Providers\GPTServiceProvider" --tag="config"
The published config file is located at config/laravel-gpt.php
.
In the following examples we are using LaravelGPT to determine the sentiment of a customer review. Both examples are delivering the same result, but the GPTChat
example is more complex and provides more flexibility.
GPTAction
is a feature provided by LaravelGPT designed to handle scenarios where you need to perform a single task based on a single input. This construct is most suitable for straightforward tasks that don't require back-and-forth or conversation-like interactions with the model.
A classic use-case for GPTAction
could be a sentiment analysis task, where the input is a customer review and the task is to determine the sentiment expressed in the review. In such a scenario, you define the task, and the function to execute once the model returns the sentiment.
To create a new GPTAction
class, you can use the following command. Adding the --clean
option removes the explanatory comments. If the class name doesn't end with GPTAction
, the package will automatically append it.
In this example, we're creating an action to determine the sentiment of a customer review:
php artisan make:gpt-action Sentiment
The GPTAction
is where you define the task for the model. Start by defining the systemMessage()
. This system message explains the task to the model. For more complex messages, it's recommended to use the BladePromptService
. You can read more about it in the BladePromptService section. Although it's possible to omit the systemMessage()
method, providing a system message helps guide the model.
Next, you define the function to be called by the model. Instead of being utilized for back-and-forth interactions, GPTAction
focuses on singular tasks. Consequently, the response generated by this method will only be dispatched to the point of invocation, not back to the model itself. Inside this function, you can define any operations you want. In this example, we determine the sentiment of a customer request and save it in the customer object. To reduce the risk of model-induced errors, the customer object is directly integrated into the GPTAction
through the constructor. This approach bypasses the need for the model to fill in the object as a parameter, thereby improving the accuracy and reliability of the process.
Finally, you define the rules()
for the function. LaravelGPT uses these to generate the function documentation and to validate the function call. Sometimes, it can be helpful to provide more rules than parameters in your function. For example, if you have a complex task and you want the model to provide a more precise answer, you could add additional rules for explaining the result. The arguments in the documentation will follow the order of the array returned by the rules()
method. Additional arguments will be validated but not passed to the function.
<?php
namespace App\GPT\Actions\Sentiment;
use MalteKuhr\LaravelGPT\GPTAction;
use Closure;
class SentimentGPTAction extends GPTAction
{
public function __construct(
protected Customer $customer,
) {}
public function systemMessage(): ?string
{
return 'Determine the sentiment of the customer review.';
}
public function function(): Closure
{
return function (string $sentiment): mixed {
$this->customer->sentiment = $sentiment;
$this->customer->save();
return [
'sentiment' => $sentiment
];
};
}
public function rules(): array
{
return [
'sentiment' => 'required|string|in:POSITIVE,NEGATIVE,NEUTRAL'
];
}
}
Finally, to call your GPTAction
, create a new instance using the make()
method, pass the arguments configured in your constructor (if any), and pass your message as a parameter into the send()
function. Wait a few seconds and the task will be executed.
echo $customer->sentiment; // null
echo SentimentGPTAction::make($customer)->send('I really like this product.'); // ['sentiment' => 'POSITIVE']
echo $customer->sentiment; // POSITIVE
GPTChat
is tailored for tasks that require a conversational or iterative interaction with the model. This component is especially effective for complex tasks that involve multiple steps.
A typical use-case for GPTChat
could be a customer support bot. In such a situation, you provide a system message that sets the task and maybe gives some context about the customer. You can also include several GPTFunction
s that the model might call to gather more information about the customer, previous similar requests, or even current pricing details. Once you start the GPTChat
, the model can either respond immediately or call one or more of the provided GPTFunction
s for more information. LaravelGPT automatically handles these function calls, which allows for a seamless integration, making the use of functions feel like magic, rather than a complexity that you have to take care of.
Creating a new GPTChat
class is as simple as running the following command. The --clean
option removes the explanatory comments, and if the class name doesn't end with GPTChat
, the package will append it automatically.
php artisan make:gpt-chat CustomerSupport
It is a good practice to create a GPTChat
for each specific use-case. In this context, CustomerSupportGPTChat
instructs the model to handle customer support requests using the available GPTFunction
s if needed, and will continue the conversation until the model provides a message rather than calling a function.
The systemMessage()
outlines the task for the model. For more complex messages, it's advised to use BladePromptService
. More details about it can be found in the BladePromptService section. Even though it's possible to remove the systemMessage()
method, having one can help guide the model effectively.
The functions()
method provides an array of GPTFunction
instances. These functions can be called by the model to gather more information about the customer or answer the request. The functionCall()
method can be used to force the model to respond with a message (return false
) or call a specific function (e.g. return BillingDetailsGPTFunction::class
). By default, the model decides the next step by itself.
class SentimentGPTChat extends GPTChat
{
public function __construct(
public Customer $customer,
public Ticket $ticket
) {}
public function systemMessage(): ?string
{
return 'You are a customer support agent for a software company and their software called "Awesome Software".';
}
public function functions(): ?array
{
return [
new KnowledgeBaseSearchGPTFunction(),
new BillingDetailsGPTFunction($this->customer)
];
}
public function functionCall(): string|bool|null
{
return null;
}
}
Finally, you need to define your GPTFunction
s. In this example, we will focus on KnowledgeBaseSearchGPTFunction
, as it provides a good understanding of how to use GPTFunction
s within a GPTChat
.
Creating a new GPTFunction
class is as straightforward as running the following command. This command also supports the --clean
option and will append GPTFunction
to the class name automatically if it's not included.
php artisan make:gpt-function KnowledgeBaseSearch
The example below shows KnowledgeBaseSearchGPTFunction
. The function()
method contains the function that the model will call. The rules()
method is used to set the validation rules for the function calls, and most importantly, to generate the function's documentation. The description()
method provides a description of the function to the model.
class KnowledgeBaseSearchGPTFunction extends GPTFunction
{
public function function(): Closure
{
return function (string $query): mixed {
$articles = KnowlegeBaseArticle::search($query)->take(3)->get();
return [
'results' => $articles->map(fn ($article) => [
'title' => $article->title,
'content' => $article->content
])
)
};
}
public function rules(): array
{
return [
'query' => 'required|string|max:255',
];
}
public function description(): string
{
return 'Search the knowledge base for the given query. Returns the three most relevant articles.';
}
}
Finally, you can put the CustomerSupportGPTChat
class into action as follows:
$chat = CustomerSupportGPTChat::make($customer, $ticket);
$chat->addMessage('I have a problem with your software.');
$chat->send();
return $chat->latestMessage()->content;
::: tip
This section of the documentation aims to explain the basic usage of LaravelGPT. For more detailed explanations of GPTChat
and more advanced examples, please visit the Advanced Usage section.
:::
LaravelGPT uses the validation rules defined in the rules()
method of GPTAction
and GPTFunction
classes to generate the documentation for the model. The rules are also used to validate the function calls. The validation rules are converted into a JSON schema and passed to the model. The model uses this schema to validate the function calls.
::: warning Important
LaravelGPT will validate the function call with all rules defined in the rules()
method. As of July 2023 LaravelGPT does not support all Laravel validation rules for conversion into the JSON schema provided to the model. If you experience poor results, please create an issue or a pull request. You can add support for custom and missing rules by extending the RuleConverter
class and adding the converter to the laravel-gpt
config file.
:::
LaravelGPT enables seamless integration of custom rules. To initiate a custom rule converter, execute the following command. Note that the --clean
option purges any explanatory comments, and if the class name doesn't include a RuleConverter
suffix, LaravelGPT will append it automatically.
php artisan make:rule-converter Example
This command generates a new ExampleRuleConverter
class under the App\GPT\RuleConverters
namespace. The priority()
method determines the execution order of the rule converters โ the higher the value, the sooner the rule converter gets triggered. The handle()
method is responsible for transforming the rule into a JSON schema. Here is an example of the ExampleRuleConverter
class:
<?php
namespace App\GPT\RuleConverters;
use MalteKuhr\LaravelGPT\Services\JsonSchemaService\Converters\AbstractRuleConverter;
class ExampleRuleConverter extends AbstractRuleConverter
{
public static function priority(): int
{
return 0;
}
public function handle(): void
{
// TODO: Implement handle() method.
}
}
To convert a rule into a JSON schema, the rule must first be identified and applied to the field. This can be done by filtering the $this->rules
array. You then need to convert the rules into a JSON Schema. It's recommended to familiarize yourself with the JSON Schema first. Once you've envisioned your desired outcome, you can manually adjust the $this->schema
array or use one of the methods supplied by the AbstractRuleConverter
class.
-
$this->addDescription(string $description)
: Appends a description to the current field. If a description already exists, the new description is added to it. To avoid appending the description, you can use thesetField()
method with a lower priority. -
$this->setType(string $type, bool $override = false)
: Determines the type of the current field. If a type already exists and$override
is set tofalse
, the method will throw aFieldSetException
. -
$this->setField(string $field, $value, bool $override = false)
: Establishes the value of a given field. If a value already exists and$override
isfalse
, the method will throw aFieldSetException
. -
$this->getType()
: Fetches the type of the current field. -
$this->getField(string $field)
: Retrieves the value of a specified field.
::: tip Note
The rule converter runs for every item in the GPTFunction
's or GPTAction
s rules()
array. The $this->rules
refer to the rules of the current field. The package employs explode()
if your original rules are separated by |
. The $this->field
represents the name of the current field, such as name
if your key was profile.key
.
:::
Last but not least, you need to register your custom rule converter in the laravel-gpt.php
config file. If you haven't published the config file yet, please follow the Instructions at the Publishing the Config File section.
We've introduced a custom validation rule for attaching descriptions to fields in the process of generating documentation with Laravel validation rules. You can easily apply the FieldDescription
to a field's validation rules by using the static set()
method. This method takes a string as an argument, which is then added as a description via the addDescription()
method from the AbstractRuleConverter
class.
public function rules(): array
{
return [
'id' => ['required', 'integer', FieldDescription::set('The ID of the user')],
];
}
In this example, the string 'The ID of the user'
is provided to the set()
method of FieldDescription
, establishing it as the field's description.