Gemini API 是一个增强型 PHP API 客户端,允许您与 Gemini API 进行交互

1.0.5 2024-07-09 11:28 UTC

This package is not auto-updated.

Last update: 2024-09-17 12:21:11 UTC


README

Google Gemini PHP

Latest Version License

Gemini PHP 是一个社区维护的 PHP API 客户端,允许您与 Gemini AI API 进行交互。

目录

先决条件

要完成此快速入门,请确保您的开发环境满足以下要求

设置

安装

首先,使用 Composer 包管理器安装 Gemini

composer require google-gemini-php/client

确保允许 php-http/discovery Composer 插件运行或安装客户端,或者如果您的项目尚未集成 PSR-18 客户端,请手动安装客户端。

composer require guzzlehttp/guzzle

设置您的 API 密钥

要使用 Gemini API,您需要一个 API 密钥。如果您还没有,请在 Google AI Studio 中创建一个密钥。

获取 API 密钥

用法

与 Gemini 的 API 交互

$yourApiKey = getenv('YOUR_API_KEY');
$client = Gemini::client($yourApiKey);

$result = $client->geminiPro()->generateContent('Hello');

$result->text(); // Hello! How can I assist you today?

如果需要,可以配置和创建一个单独的客户端。

$yourApiKey = getenv('YOUR_API_KEY');

$client = Gemini::factory()
 ->withApiKey($yourApiKey)
 ->withBaseUrl('https://generativelanguage.example.com/v1') // default: https://generativelanguage.googleapis.com/v1/
 ->withHttpHeader('X-My-Header', 'foo')
 ->withQueryParam('my-param', 'bar')
 ->withHttpClient(new \GuzzleHttp\Client([]))  // default: HTTP client found using PSR-18 HTTP Client Discovery
 ->withStreamHandler(fn(RequestInterface $request): ResponseInterface => $client->send($request, [
   'stream' => true // Allows to provide a custom stream handler for the http client.
 ]))
 ->make();

聊天资源

仅文本输入

根据输入消息生成模型响应。如果输入只包含文本,请使用 gemini-pro 模型。

$yourApiKey = getenv('YOUR_API_KEY');
$client = Gemini::client($yourApiKey);

$result = $client->geminiPro()->generateContent('Hello');

$result->text(); // Hello! How can I assist you today?

文本和图像输入

如果输入包含文本和图像,请使用 gemini-pro-vision 模型。

$result = $client
 ->geminiProVision()
 ->generateContent([
  'What is this picture?',
  new Blob(
   mimeType: MimeType::IMAGE_JPEG,
   data: base64_encode(
    file_get_contents('https://storage.googleapis.com/generativeai-downloads/images/scones.jpg')
   )
  )
 ]);
 
$result->text(); //  The picture shows a table with a white tablecloth. On the table are two cups of coffee, a bowl of blueberries, a silver spoon, and some flowers. There are also some blueberry scones on the table.

多轮对话(聊天)

使用 Gemini,您可以在多个回合中构建自由形式的对话。

$chat = $client
 ->geminiPro()
 ->startChat(history: [
   Content::parse(part: 'The stories you write about what I have to say should be one line. Is that clear?'),
   Content::parse(part: 'Yes, I understand. The stories I write about your input should be one line long.', role: Role::MODEL)
 ]);

$response = $chat->sendMessage('Create a story set in a quiet village in 1600s France');
echo $response->text(); // Amidst rolling hills and winding cobblestone streets, the tranquil village of Beausoleil whispered tales of love, intrigue, and the magic of everyday life in 17th century France.

$response = $chat->sendMessage('Rewrite the same story in 1600s England');
echo $response->text(); // In the heart of England's lush countryside, amidst emerald fields and thatched-roof cottages, the village of Willowbrook unfolded a tapestry of love, mystery, and the enchantment of ordinary days in the 17th century.

对于文本和图像输入的 gemini-pro-vision 模型(多轮对话尚未优化)。请确保对于聊天用例使用 gemini-pro 和仅文本输入。

流生成内容

默认情况下,模型在完成整个生成过程后返回响应。您可以通过不等待整个结果,而是使用流处理部分结果来实现更快的交互。

$stream = $client
 ->geminiPro()
 ->streamGenerateContent('Write long a story about a magic backpack.');

foreach ($stream as $response) {
 echo $response->text();
}

计算标记数

在发送任何内容到模型之前,计算长提示中的标记数可能很有用。

$response = $client
 ->geminiPro()
 ->countTokens('Write a story about a magic backpack.');

echo $response->totalTokens; // 9

配置

您发送给模型的每个提示都包含控制模型如何生成响应的参数值。对于不同的参数值,模型可以生成不同的结果。了解更多关于 模型参数 的信息。

此外,您还可以使用安全设置来调整可能被认为有害的响应的可能性。默认情况下,安全设置阻止所有维度上中等和/或高概率的不安全内容。了解更多关于 安全设置 的信息。

use Gemini\Data\GenerationConfig;
use Gemini\Enums\HarmBlockThreshold;
use Gemini\Data\SafetySetting;
use Gemini\Enums\HarmCategory;

$safetySettingDangerousContent = new SafetySetting(
    category: HarmCategory::HARM_CATEGORY_DANGEROUS_CONTENT,
    threshold: HarmBlockThreshold::BLOCK_ONLY_HIGH
);

$safetySettingHateSpeech = new SafetySetting(
    category: HarmCategory::HARM_CATEGORY_HATE_SPEECH,
    threshold: HarmBlockThreshold::BLOCK_ONLY_HIGH
);

$generationConfig = new GenerationConfig(
    stopSequences: [
        'Title',
    ],
    maxOutputTokens: 800,
    temperature: 1,
    topP: 0.8,
    topK: 10
);

$generativeModel = $client
 ->geminiPro()
 ->withSafetySetting($safetySettingDangerousContent)
 ->withSafetySetting($safetySettingHateSpeech)
 ->withGenerationConfig($generationConfig)
 ->generateContent("Write a story about a magic backpack.");

嵌入资源

嵌入是将信息表示为浮点数数组的列表的技术。使用 Gemini,您可以将文本(单词、句子和文本块)表示为向量形式,使其更容易进行比较和对比嵌入。例如,具有相似主题或情感的两个文本应该具有相似的嵌入,这可以通过余弦相似度等数学比较技术来识别。

使用embedding-001模型,可以使用embedContentsbatchEmbedContents

$response = $client
 ->embeddingModel()
 ->embedContent("Write a story about a magic backpack.");

print_r($response->embedding->values);
//[
//    [0] => 0.008624583
//    [1] => -0.030451821
//    [2] => -0.042496547
//    [3] => -0.029230341
//    [4] => 0.05486475
//    [5] => 0.006694871
//    [6] => 0.004025645
//    [7] => -0.007294857
//    [8] => 0.0057651913
//    ...
//]

模型

列出模型

使用列表模型查看可用的Gemini模型。

$response = $client->models()->list();

$response->models;
//[
//    [0] => Gemini\Data\Model Object
//        (
//            [name] => models/gemini-pro
//            [version] => 001
//            [displayName] => Gemini Pro
//            [description] => The best model for scaling across a wide range of tasks
//            ...
//        )
//    [1] => Gemini\Data\Model Object
//        (
//            [name] => models/gemini-pro-vision
//            [version] => 001
//            [displayName] => Gemini Pro Vision
//            [description] => The best image understanding model to handle a broad range of applications
//            ...
//        )
//    [2] => Gemini\Data\Model Object
//        (
//            [name] => models/embedding-001
//            [version] => 001
//            [displayName] => Embedding 001
//            [description] => Obtain a distributed representation of a text.
//            ...
//        )
//]

获取模型

获取有关模型的信息,例如版本、显示名称、输入令牌限制等。

$response = $client->models()->retrieve(ModelType::GEMINI_PRO);

$response->model;
//Gemini\Data\Model Object
//(
//    [name] => models/gemini-pro
//    [version] => 001
//    [displayName] => Gemini Pro
//    [description] => The best model for scaling across a wide range of tasks
//    ...
//)

故障排除

超时

当向API发送请求时,可能会遇到超时。默认超时取决于所使用的HTTP客户端。

您可以通过配置HTTP客户端并将其传递给工厂来增加超时时间。

以下示例说明了如何使用Guzzle增加超时时间。

Gemini::factory()
    ->withApiKey($apiKey)
    ->withHttpClient(new \GuzzleHttp\Client(['timeout' => $timeout]))
    ->make();

测试

该包提供了一个假的Gemini\Client类实现,允许您模拟API响应。

为了测试您的代码,请确保在测试用例中将Gemini\Client类与Gemini\Testing\ClientFake类进行交换。

假响应将按照创建假客户端时提供的顺序返回。

所有响应都具有一个fake()方法,允许您通过仅提供与您的测试用例相关的参数来轻松创建响应对象。

use Gemini\Testing\ClientFake;
use Gemini\Responses\GenerativeModel\GenerateContentResponse;

$client = new ClientFake([
  GenerateContentResponse::fake([
    'candidates' => [
      [
        'content' => [
          'parts' => [
            [
              'text' => 'success',
            ],
          ],
        ],
      ],
    ],
  ]),
]);

$result = $fake->geminiPro()->generateContent('test');

expect($result->text())->toBe('success');

对于流式响应,您可以可选地提供一个包含假响应数据的资源。

use Gemini\Testing\ClientFake;
use Gemini\Responses\GenerativeModel\GenerateContentResponse;

$client = new ClientFake([
    GenerateContentResponse::fakeStream(),
]);

$result = $client->geminiPro()->streamGenerateContent('Hello');

expect($response->getIterator()->current())
    ->text()->toBe('In the bustling city of Aethelwood, where the cobblestone streets whispered');

在请求发送后,有各种方法可以确保发送了预期的请求。

// assert list models request was sent
$fake->models()->assertSent(callback: function ($method) {
    return $method === 'list';
});
// or
$fake->assertSent(resource: Models::class, callback: function ($method) {
    return $method === 'list';
});

$fake->geminiPro()->assertSent(function (string $method, array $parameters) {
    return $method === 'generateContent' &&
        $parameters[0] === 'Hello';
});
// or
$fake->assertSent(resource: GenerativeModel::class, model: ModelType::GEMINI_PRO, callback: function (string $method, array $parameters) {
    return $method === 'generateContent' &&
        $parameters[0] === 'Hello';
});


// assert 2 generative model requests were sent
$client->assertSent(resource: GenerativeModel::class, model: ModelType::GEMINI_PRO, callback: 2);
// or
$client->geminiPro()->assertSent(2);

// assert no generative model requests were sent
$client->assertNotSent(resource: GenerativeModel::class, model: ModelType::GEMINI_PRO);
// or
$client->geminiPro()->assertNotSent();

// assert no requests were sent
$client->assertNothingSent();

要编写期望API请求失败的测试,您可以将Throwable对象作为响应提供。

$client = new ClientFake([
    new ErrorException([
        'message' => 'The model `gemini-basic` does not exist',
        'status' => 'INVALID_ARGUMENT',
        'code' => 400,
    ]),
]);

// the `ErrorException` will be thrown
$client->geminiPro()->generateContent('test');