google-gemini-php / client
Gemini API 是一个增强型 PHP API 客户端,允许您与 Gemini API 进行交互
Requires
- php: ^8.1.0
- php-http/discovery: ^1.19.2
Requires (Dev)
- guzzlehttp/guzzle: ^7.8.1
- guzzlehttp/psr7: ^2.6.2
- laravel/pint: ^1.13.10
- mockery/mockery: ^1.6.7
- pestphp/pest: ^2.30
- phpstan/phpstan: ^1.10
README
Gemini PHP 是一个社区维护的 PHP API 客户端,允许您与 Gemini AI API 进行交互。
- Fatih AYDIN github.com/aydinfatih
目录
先决条件
要完成此快速入门,请确保您的开发环境满足以下要求
- 需要 PHP 8.1+
设置
安装
首先,使用 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 中创建一个密钥。
用法
与 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
模型,可以使用embedContents
或batchEmbedContents
。
$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');