DEV Community

Alexandr
Alexandr

Posted on • Edited on

Usage Laravel and ChatGPT "Function calling"

Recently, OpenAI released an update for ChatGPT, introducing new features that allow developers to describe language model functions - gpt-4-0613 and gpt-3.5-turbo-0613. These features enable the generation of JSON objects containing arguments to run these functions based on user input.

Let's explore an example of this new feature. You can use it to obtain information about an IP address, previous orders, information from your FAQ, weather forecast, or any other desired information.

To demonstrate how it works, we will use the openai-php/client library. Firstly, create an Artisan command by running the following command:

php artisan make:command ChatFunction
Enter fullscreen mode Exit fullscreen mode

Update the ChatFunction class as follows:

namespace App\Console\Commands;

use Illuminate\Console\Command;
use OpenAI\Client;

class ChatFunction extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:chat-function';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Invoke a chat function with OpenAI language model.';

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $client = new Client(config('openai.api_key'));

        $response = $client->chat()->create([
            'model'    => 'gpt-3.5-turbo-0613',
            'messages' => [
                ['role' => 'user', 'content' => 'What do you know about IP address 12.175.87.227?'],
            ],
        ]);

        $answer = $response->choices[0]->message->content;

        $this->info("OpenAI response: $answer");
    }
}
Enter fullscreen mode Exit fullscreen mode

If we ask AI for information about a specific IP address, it may respond with something like, "I'm sorry, but I cannot provide information about specific IP addresses."

To fix this, let's specify the function in our request.

namespace App\Console\Commands;

use Illuminate\Console\Command;

class ChatFunction extends Command
{
    public function handle()
    {
        $client = \OpenAI::factory()
            ->withApiKey(config('openai.api_key'))
            ->make();

        $response = $client->chat()->create([
            'model'     => 'gpt-3.5-turbo-0613',
            'messages'  => [
                ['role' => 'user', 'content' => 'What do you know about IP 12.175.87.227 ?'],
            ],
            'functions' => [
                [
                    'name'        => 'about_ip',
                    'description' => 'Get information about the IP address',
                    'parameters'  => [
                        'type'       => 'object',
                        'properties' => [
                            'ip' => [
                                'type'        => 'string',
                                'description' => 'IP address v4',
                            ],
                        ],
                        'required'   => ['ip'],
                    ],
                ],
            ],
        ]);

        // As we can see, we now have a proposal to call a function on our side and there are arguments:  
        $name = $response->choices[0]->message->functionCall->name; // ip_info  
        $arguments = $response->choices[0]->message->functionCall->arguments; // {\n "ip": "12.175.87.227" }  
    }
}
Enter fullscreen mode Exit fullscreen mode

Now we have prepared data such as the name of the function to be called and its arguments. I believe that an excellent solution for performing such tasks is to use the Sajya package, which simplifies working with JSON-RPC both in the console and as an API. Therefore, let's create a simple class using this package:

Command to create a new procedure called "AboutIp" using Laravel's artisan CLI:

php artisan make:procedure AboutIp
Enter fullscreen mode Exit fullscreen mode

Now, let's add a useful action to it:

namespace App\Http\Procedures;  

use Illuminate\Support\Collection;  
use Illuminate\Support\Facades\Http;  
use Sajya\Server\Procedure;  

class AboutIp extends Procedure  
{  
    /**  
     * The name of the procedure that is used for referencing.  
     * 
     * @var string  
     */  
    public static string $name = 'about';  

    /**  
     * Execute the procedure.  
     * 
     * @param string $ip  
     * @return Collection  
     */  
    public function ip(string $ip): Collection  
    {  
        return Http::get('http://ip-api.com/json/' . $ip)->collect();  
    }  
}
Enter fullscreen mode Exit fullscreen mode

This "about_ip" procedure will simply receive an IP address, fetch information from another API, and return it to the user.

Let's go back to the console command and add a method to create and call the Remote Procedure Call (RPC):

protected function callRPC(string $method, ?string $params = null): ?string
{
    $app = new App([
        \App\Http\Procedures\AboutIp::class,
    ], '_');

    $response = $app->terminate(json_encode([
        'jsonrpc' => '2.0',
        'method'  => $method,
        'params'  => json_decode($params, true),
        'id'      => 1,
    ]));

    return json_encode($response, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
}
Enter fullscreen mode Exit fullscreen mode

If we call it just by its name and arguments, we won't receive a human response. To obtain that, we need to refer back to ChatGPT:

/**
 * Execute the console command.
 */
public function handle()
{
    $client = \OpenAI::factory()
        ->withApiKey(config('openai.api_key'))
        ->make();

    $response = $client->chat()->create([
        'model'     => 'gpt-3.5-turbo-0613',
        'messages'  => [
            ['role' => 'user', 'content' => 'What do you know about IP 12.175.87.227 ?'],
        ],
        'functions' => [
            [
                'name'        => 'about_ip',
                'description' => 'Get information about the IP address',
                'parameters'  => [
                    'type'       => 'object',
                    'properties' => [
                        'ip' => [
                            'type'        => 'string',
                            'description' => 'IP address v4',
                        ],
                    ],
                    'required'   => ['ip'],
                ],
            ],
        ],
    ]);

    // As we can see, we now have a proposal to call a function on our side and there are arguments:
    $name = $response->choices[0]->message->functionCall->name; // ip_info
    $arguments = $response->choices[0]->message->functionCall->arguments; // {\n "ip": "12.175.87.227" }


    $functionResult = $this->callRPC($name, $arguments);

    // Again we turn to ChatGPT, but this time we add the response from the function:
    $response = $client->chat()->create([
        'model'     => 'gpt-3.5-turbo-0613',
        'messages'  => [
            ['role' => 'user', 'content' => 'What do you know about IP 12.175.87.227 ?'],
            ['role' => 'function', 'name' => $name, 'content' => $functionResult],
        ],
        'functions' => [
            [
                'name'        => 'about_ip',
                'description' => 'Get information about the IP address',
                'parameters'  => [
                    'type'       => 'object',
                    'properties' => [
                        'ip' => [
                            'type'        => 'string',
                            'description' => 'IP address v4',
                        ],
                    ],
                    'required'   => ['ip'],
                ],
            ],
        ],
    ]);

    $response->choices[0]->message->content;

    // The IP address 12.175.87.227 is located in San Diego, California, United States.
    // The postal code is 92110.
    // The latitude and longitude coordinates are 32.7616 and -117.2058 respectively.
    // The timezone of this location is America/Los_Angeles.
    // The ISP (Internet Service Provider) is AT&T Services, Inc.
    // The organization associated with this IP address is Coffman Specialties.
    // The Autonomous System (AS) number is AS7018 AT&T Services, Inc.
}
Enter fullscreen mode Exit fullscreen mode

Now we got a human response and used the ChatGPT "features" to enrich the actual information.

Top comments (1)

Collapse
 
makowskid profile image
Dawid Makowski

If you're into combining #Laravel and #AI then you must check my product SharpAPI.com and its Laravel package client github.com/sharpapi/sharpapi-larav... :-) It will save you countless programming hours and supercharge your app with AI capabilities in just 2 lines of code.