使用 Gemini 快速入門的範例商店

本教學課程將示範如何逐步建立少量樣本,並從樣本儲存庫動態擷取這些樣本,以便修正 LLM 的行為。在本教學課程中,您會使用 gemini-2.0-flash 模型。您將執行下列操作:

  • 建立 Example Store 例項 (ExampleStore)。

  • 根據 Gemini 的回覆撰寫範例,然後將這些範例上傳至 Example Store 執行個體。

  • 從樣本儲存庫動態擷取範例,引導 LLM 執行預期行為。

  • 清除所用資源。

事前準備

如要完成本教學課程中示範的步驟,您必須先設定專案和環境。

設定專案

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the Vertex AI API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the Vertex AI API.

    Enable the API

  8. 如果您選取了專案,請確認您具備該專案的 Vertex AI 使用者 (roles/aiplatform.user) IAM 角色。
  9. 驗證 Vertex AI

    如要在本機開發環境中使用本頁面上的 Python 範例,請先安裝並初始化 gcloud CLI,然後使用您的使用者憑證設定應用程式預設憑證。

  10. Install the Google Cloud CLI.

  11. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  12. To initialize the gcloud CLI, run the following command:

    gcloud init
  13. If you're using a local shell, then create local authentication credentials for your user account:

    gcloud auth application-default login

    You don't need to do this if you're using Cloud Shell.

    If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

  14. 詳情請參閱 Google Cloud 驗證說明文件中的「 為本機開發環境設定 ADC」。

    匯入程式庫

    1. 執行下列指令,安裝範例商店的 Vertex AI SDK for Python。

      pip install --upgrade google-cloud-aiplatform>=1.87.0
    2. 使用下列程式碼範例,匯入並初始化 Example Store 的 SDK。

      import vertexai
      from vertexai.preview import example_stores
      
      vertexai.init(
        project="PROJECT_ID",
        location="LOCATION"
      )
      

      更改下列內容:

      • PROJECT_ID:您的專案 ID。

      • LOCATION:您的區域。系統僅支援 us-central1

    建立範例商店執行個體

    使用下列程式碼範例,建立使用 text-embedding-005 嵌入模型的示例商店例項。

    example_store = example_stores.ExampleStore.create(
        example_store_config=example_stores.ExampleStoreConfig(
            vertex_embedding_model="text-embedding-005"
        )
    )
    

    請注意,建立範例商店需要幾分鐘的時間。

    如要進一步瞭解如何建立或重複使用範例商店執行個體,請參閱「建立範例商店執行個體」。

    將範例上傳至範例儲存庫執行個體

    請按照下列步驟,將範例編寫並上傳至 Example Store 執行個體。每個要求最多可上傳五個示例。

    1. 定義 get_current_weather 函式工具。您在後續步驟中建立的範例,會引導模型瞭解何時要叫用這個函式,以及要傳遞哪些引數給該函式。

      如要進一步瞭解範例如何改善函式呼叫成效和模型回應,請參閱「使用範例改善函式呼叫成效」。如要進一步瞭解如何建立函式呼叫應用程式,請參閱「函式呼叫簡介」。

      from google.genai import types as genai_types
      
      get_current_weather_func = genai_types.FunctionDeclaration(
        name="get_current_weather",
        description="Get the current weather in a given location",
        parameters={
          "type": "object",
          "properties": {
            "location": {
              "type": "string",
              "description": "The city name of the location for which to get the weather."
            }
          },
        },
      )
      
    2. 向 Gemini 傳送要求,請其使用 get_current_weather 函式產生內容。

      請參閱 Gen AI SDK 的建立用戶端

      from google import genai
      
      client = genai.Client(
          http_options=genai_types.HttpOptions(api_version="v1"),
          vertexai=True,
          project="PROJECT_ID",,
          location="LOCATION")
      
      user_content = genai_types.Content(
        role="user",
        parts=[Part(text="What is the weather like in Boston?")],
      )
      response = client.models.generate_content(
        model="gemini-2.0-flash",
        user_content,
        config=genai_types.GenerateContentConfig(
          tools=[
            genai_types.Tool(function_declarations=[get_current_weather_func])]
        )
      )
      
    3. 請執行下列任一操作,建立並上傳範例。

      • 如果 LLM 的回應顯示預期的行為,請使用下列程式碼範例,根據回應撰寫範例,然後上傳至範例商店。

        function_response = genai_types.Content(
          parts=[
            genai_types.Part(
              function_response={
                "name": "get_current_weather",
                "response": {
                  "location": "New York, NY", "temperature": 38,
                  "description": "Partly Cloudy",
                  "icon": "partly-cloudy", "humidity": 65,
                  "wind": { "speed": 10, "direction": "NW" }
                }
              }
            )
          ]
        )
        final_model_response = genai_types.Content(
          role="model",
          parts=[genai_types.Part(text="The weather in NYC is 38 degrees and partly cloudy.")],
        )
        example = {
          "contents_example": {
            "contents": [user_content.to_json_dict()],
            "expected_contents": [
              {"content": response.candidates[0].content.to_json_dict()},
              {"content": function_response.to_json_dict()},
              {"content": final_model_response.to_json_dict()},
            ],
          },
          "search_key": user_content.parts[0].text,
        }
        example_store.upsert_examples(examples=[example])
        
      • 或者,如果回覆內容未涵蓋您預期的所有函式或結果,或是您發現模型無法順利推理,請使用下列程式碼範例,編寫回覆內容來修正模型行為。

        expected_function_call = genai_types.Content(
          parts=[
            genai_types.Part(
              function_call={
                "name": "get_current_weather",
                "args": {"location": "New York, NY"}
              }
            )
          ]
        )
        function_response = genai_types.Content(
          parts=[
            genai_types.Part(
              function_response={
                "name": "get_current_weather",
                "response": {
                  "location": "New York, NY", "temperature": 38,
                  "description": "Partly Cloudy",
                  "icon": "partly-cloudy", "humidity": 65,
                  "wind": { "speed": 10, "direction": "NW" }
                }
              }
            )
          ]
        )
        final_model_response = genai_types.Content(
          role="model",
          parts=[genai_types.Part(text="The weather in NYC is 38 degrees and partly cloudy.")],
        )
        example = {
          "contents_example": {
            "contents": [user_content.to_json_dict()],
            "expected_contents": [
              {"content": expected_function_call.to_json_dict()},
              {"content": function_response.to_json_dict()},
              {"content": final_model_response.to_json_dict()},
            ],
          },
          "search_key": user_content.parts[0].text,
        }
        example_store.upsert_examples(examples=[example])
        
    4. 視需要重複執行步驟 2 和 3,編寫並上傳多個範例。如果模型出現非預期行為,或是上傳的範例未涵蓋您預期的所有函式、結果或推理,您可以上傳其他範例。如要進一步瞭解何時需要上傳其他範例,請參閱「上傳範例」。

    使用 Gemini 擷取及使用範例

    根據與提示的相似程度搜尋範例。接著,您可以在提示中加入這些範例,引導 LLM 執行預期的行為。

    定義輔助函式以設定範例格式

    請使用以下程式碼範例定義 ExampleStorePrompt 類別和輔助函式,讓您搜尋及擷取範例。

    import abc
    import jinja2
    import json
    
    from google.protobuf import json_format
    # --BOILERPLATE CODE FOR FORMATTING--
    
    EXAMPLES_PREAMBLE = """<EXAMPLES>
    The following are examples of user queries and model responses using the available python libraries.
    
    Begin few-shot
    """
    
    EXAMPLES_POSTAMBLE = """
    End few-shot
    
    Now, try to follow these examples and complete the following conversation:
    </EXAMPLES>
    """
    
    EXAMPLE_PREAMBLE = "EXAMPLE"
    
    TEMPLATE = """
    """
    
    class ExampleStorePrompt:
    
        def __init__(
              self, template = TEMPLATE, example_preamble = EXAMPLE_PREAMBLE,
              examples_preamble = EXAMPLES_PREAMBLE,
              examples_postamble = EXAMPLES_POSTAMBLE):
    
            self.template = jinja2.Template(template)
            self.example_preamble = example_preamble
            self.examples_preamble = examples_preamble
            self.examples_postamble = examples_postamble
    
        @abc.abstractmethod
        def process_function_response(self, function_response):
            return json.dumps(function_response)
    
        @abc.abstractmethod
        def process_function_call(self, function_call):
            args_list = []
            for key, value in function_call.get("args", []).items():
                if isinstance(value, str):
                    # Wrap strings in quotes.
                    value = f'"{value}"'
                if isinstance(value, list):
                    value = ', '.join(
                        f'"{item}"' if isinstance(item, str)
                        else str(item) for item in value)
                    value = f"[{value}]"
                if isinstance(value, dict):
                    value = json.dumps(value)
                args_list.append(f'{key}={value}')
            args = ", ".join(args_list)
            return f"```\n{function_call.get('name')}({args})\n```"
    
        @abc.abstractmethod
        def process_part(self, part):
            if "function_call" in part:
                return self.process_function_call(part["function_call"])
            if "text" in part:
                return part.get("text")
            if "function_response" in part:
                return self.process_function_response(part["function_response"])
    
        @abc.abstractmethod
        def process_content(self, content):
            response = []
            for part in content.get("parts", []):
                response.append(self.process_part(part))
            return [content.get("role"), response]
    
        @abc.abstractmethod
        def example_formatter(self, example: dict):
            response = []
            for content in example.get("contents", []):
                response.append(self.process_content(content))
            for content in example.get("expected_contents", []):
                content = content.get("content", {})
                response.append(self.process_content(content))
            return response
    
        def get_prompt(self, examples: list):
            if not examples:
              return ""
            contents_example = example.get("example", {}).get(
              "stored_contents_example", {}).get("contents_example", {})
            examples = [self.example_formatter(example) for example in examples]
            return self.template.render(
                examples=examples,
                example_preamble=self.example_preamble,
                examples_preamble=self.examples_preamble,
                examples_postamble=self.examples_postamble
            )
    

    搜尋相關範例

    使用下列程式碼範例,搜尋與 LLM 持續對話相關的範例。接著,您可以使用輔助函式,在提示中加入這些範例。

    query = "what's the fastest way to get to disney from lax"
    
    # Search for relevant examples.
    examples = example_store.search_examples(
      {"stored_contents_example_key": query}, top_k=3)
    
    prompt = ExampleStorePrompt().get_prompt(examples.get("results", []))
    
    model_response = client.models.generate_content(
        model="gemini-2.0-flash",
        contents="How do I get to LAX?",
        config=genai_types.GenerateContentConfig(
          system_instruction=prompt,
          tools=[
            genai_types.Tool(function_declarations=[track_flight_status_function])]
      )
    )
    

    反覆改善回覆品質

    如要使用零樣本示例改善 Gemini 的回應模式,請重複執行下列各節中的步驟:

    1. 將範例製作並上傳至範例商店執行個體。

    2. 使用 Gemini 擷取及使用範例

    清除所用資源

    如要清除此專案中使用的所有資源,您可以刪除用於入門導覽的 Google Cloud 專案

    或者,您也可以刪除在教學課程建立的個別資源,步驟如下:

    1. 使用下列程式碼範例刪除 Example Store 執行個體。

      example_store.delete()
      
    2. 刪除任何在本機建立的檔案。

    後續步驟