Feed on
Posts
Comments
Email訂閱

This Post is under 軟體開發
在前文使用 PHP 呼叫 Google Gemini API 生成內容,是以模型既有的知識來回答。而模型既有的知識受限於訓練所餵給的資料。即使是最新的模型,其知識內容涵蓋的範圍大概會落後現在年代一、兩年以上。譬如現在是2025年,若你問 gemini-2.5-flash-preview-04-17 模型(2025-04-17),Gemini會回答:「現任美國總統是 **喬·拜登(Joe Biden)**。他是民主黨的成員。」顯然這不符合現實,因此生成式AI工具都發展出從網路抓取即時資訊來統整再回答,這就是所謂的「以 Google 搜尋建立基準(Grounding with Google Search)」,這樣生成式AI的回答就會比較即使與準備。

不過有些模型需要是付費帳戶才能使用基於Google搜尋的回應功能,且可能會有使用次數的限制。目前試過gemini-2.0-flash,現在還可以免費帳戶使用這項功能。你可以在底下的範例中,改變不同的模型,看看各個模型對這項功能的支援情形,或是驗證Gemini的回答是否能讓你滿意。於是在”基於Google搜尋”勾選的狀態在問一次gemini-2.0-flash,答案會變成:「根據目前時間(2025年5月12日),美國現任總統是唐納·川普。 他於2025年1月20日宣誓就職。」


以下是在網站伺服器端呼叫 Google Gemini 基於Google搜尋生成內容的程式碼,以 php curl 來實作,參考:Grounding with Google Search,新增的程式碼以粗體字表示。根據文件, Google 搜尋擷取功能(google_search_retrieval)僅支援 Gemini 1.5 模型。在 Gemini 2.0 模型,應將搜尋功能(google_search)視為工具。因此以下根據模型版本的不同來設定tools。

值得一提的是,在 Gemini 1.5 模型設定 google_search_retrieval參數或是在 Gemini 2.0 模型設定 google_search參數時,就算沒有參數也不能省略(除了dynamic_threshold有預設值0.3,可省略不給),否則會出現類似「 Unknown name google_search_retrieval at tools」的錯誤訊息,但是google_search其實是沒有參數的,如果傳進空的陣列或是null都不是正確的做法。試了好久,原來是要將空陣列先轉成 object 型態,這樣在 json_encode就會將之變成符合rest api文件的寫法 “google_search”: {} 了。

<?php

$model = isset($_REQUEST['m']) ? $_REQUEST['m'] : "";
$geminiQuery = isset($_REQUEST['q']) ? $_REQUEST['q'] : "";
$grounding = isset($_REQUEST['grounding']);

$api_key = "YOUR_GEMINI_KEY";

$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$api_key}";

$data = array(
    "contents" => array(
        array(
            "role" => "user",
            "parts" => array(
                array(
                    "text" => $geminiQuery
                )
            )
        )
    )
);

if($grounding) {
    $modelParts = explode("-", $model);
    
    $data["tools"] = ($modelParts[1]) == "1.5" ? 
        array(
            "google_search_retrieval" => array(
                "dynamic_retrieval_config" => array(
                        "mode"=> "MODE_DYNAMIC",
//                        "dynamic_threshold"=> 0.3
                    )
            )
        ) :
        array(
            "google_search" => (object)[]
        );
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$response = curl_exec($ch);

curl_close($ch);

header('Content-type: application/json');

if (curl_errno($ch)) {

    die("{ 'error': '" . curl_error($ch) . "'}");
}

echo $response;

 

留言區