Laravel 及 ChatGPT "函数调用" 的使用
最近,OpenAI 发布了一个 ChatGPT 更新,引入新特性,使开发者可以描述语言模型函数 - gpt-4-0613 和 gpt-3.5-turbo-0613。这些特性允许生成包含参数的 JSON 对象,以便根据用户输入运行这些函数。
让我们来探讨一下这个新功能的示例。您可以使用它来获取有关 IP 地址、以前的订单、常见问题解答中的信息、天气预报或任何其他所需信息。
为了演示它是如何工作的,我们将使用 openaiphp/client
库。首先,通过运行以下命令创建 Artisan 命令:
php artisan make:command ChatFunction
更新 ChatFunction
类如下:
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");
}
}
如果我们向 AI 询问有关特定 IP 地址的信息,它可能会回答说:“很抱歉,但我无法提供有关特定 IP 的信息。”
为了解决这个问题,让我们在请求中指定函数。
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" }
}
}
现在,我们已经准备好了数据,例如要调用的函数的名称及其参数。我认为执行此类任务的一个很好的解决方案是使用 Sajya 包,它简化了在控制台和作为 API 使用 JSON-RPC 的工作。因此,让我们使用这个包创建一个简单的类:
使用 Laravel 的 CLI 手动创建名为 “AboutIp” 的新过程的命令:
php artisan make:procedure AboutIp
现在,我们添加一个有用的 action:
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();
}
}
这个 “about_ip” 过程只接收一个 IP 地址,从另外一个 API 中获取信息,并返回给用户。
让我们回到控制台命令,添加一个方法来创建和调用远程过程调用(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);
}
如果我们只是通过名称和参数调用它,我们不会收到人类回应。要获得该信息,我们需要参考 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.
}
现在我们获得人类回应,并使用该 ChatGPT ”特性“去丰富实际信息。