Używanie Vertex AI Search w przypadku plików PDF (nieuporządkowanych danych) w Cloud Storage z usługi Cloud Run

1. Wprowadzenie

Przegląd

Vertex AI Search and Conversation (wcześniej znana jako Generative AI App Builder) umożliwia deweloperom korzystanie z potęgi modeli podstawowych Google, wiedzy specjalistycznej w zakresie wyszukiwania i technologii konwersacyjnej AI do tworzenia aplikacji generatywnej AI klasy korporacyjnej. To ćwiczenie skupia się na korzystaniu z Vertex AI Search, gdzie możesz utworzyć aplikację do wyszukiwania o jakości Google na podstawie własnych danych i umieścić pasek wyszukiwania na stronach internetowych lub w aplikacji.

Cloud Run to zarządzana platforma obliczeniowa, która umożliwia uruchamianie kontenerów bezpośrednio w skalowalnej infrastrukturze Google. W Cloud Run możesz wdrożyć kod napisany w dowolnym języku programowania (który można umieścić w kontenerze) za pomocą opcji wdrażania na podstawie kodu źródłowego.

W tym ćwiczeniu utworzysz usługę Cloud Run, która będzie korzystać z wdrażania na podstawie kodu źródłowego, aby pobierać wyniki wyszukiwania nieustrukturyzowanych treści w plikach PDF w zasobniku Cloud Storage. Więcej informacji o przetwarzaniu treści nieustrukturyzowanych znajdziesz tutaj.

Czego się nauczysz

  • Jak utworzyć aplikację Vertex AI Search do wyszukiwania nieuporządkowanych danych w postaci plików PDF pozyskanych z zasobnika Cloud Storage
  • Jak utworzyć punkt końcowy HTTP za pomocą wdrożenia opartego na źródle w Cloud Run
  • Jak utworzyć konto usługi zgodnie z zasadą jak najmniejszych uprawnień, aby usługa Cloud Run mogła używać go do wysyłania zapytań do aplikacji Vertex AI Search
  • Jak wywołać usługę Cloud Run, aby wysłać zapytanie do aplikacji Vertex AI Search

2. Konfiguracja i wymagania

Wymagania wstępne

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni z opisem tego środowiska. Jeśli pojawił się ekran pośredni, kliknij Dalej.

d95252b003979716.png

Uzyskanie dostępu do środowiska Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

7833d5e1c5d18f54.png

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Większość zadań w tym ćwiczeniu, a być może wszystkie, możesz wykonać w przeglądarce.

Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu.

  1. Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list

Wynik polecenia

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project

Wynik polecenia

[core]
project = <PROJECT_ID>

Jeśli nie, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Wynik polecenia

Updated property [core/project].

3. Włącz interfejsy API

Zanim zaczniesz korzystać z Vertex AI Search, musisz włączyć kilka interfejsów API.

Po pierwsze, to ćwiczenie wymaga użycia interfejsów Vertex AI Search and Conversation, BigQuery i Cloud Storage API. Możesz włączyć te interfejsy API tutaj.

Następnie wykonaj te czynności, aby włączyć interfejs Vertex AI Search and Conversation API:

  1. W konsoli Google Cloud otwórz konsolę Vertex AI Search and Conversation.
  2. Przeczytaj i zaakceptuj Warunki korzystania z usługi, a następnie kliknij Przejdź dalej i aktywuj API.

4. Tworzenie aplikacji do wyszukiwania nieuporządkowanych danych z Cloud Storage

  1. W konsoli Google Cloud otwórz stronę Search & Conversation. Kliknij Nowa aplikacja.
  2. W panelu Wybierz typ aplikacji kliknij Wyszukiwanie.
  3. Sprawdź, czy Funkcje wersji Enterprisewłączone, aby otrzymywać odpowiedzi wyodrębniane dosłownie z dokumentów.
  4. Aby otrzymywać podsumowania wyszukiwania, upewnij się, że opcja Zaawansowane funkcje LLM jest włączona.
  5. W polu Nazwa aplikacji wpisz nazwę aplikacji. Pod nią pojawi się identyfikator aplikacji.
  6. Jako lokalizację aplikacji wybierz lokalizację globalną (Cały świat) i kliknij Dalej.
  7. W panelu Magazyny danych kliknij Utwórz nowy magazyn danych.
  8. W panelu Wybierz źródło danych kliknij Cloud Storage.
  9. W panelu Zaimportuj dane z GCS upewnij się, że wybrano Folder.
  10. W polu gs:// wpisz tę wartość: cloud-samples-data/gen-app-builder/search/stanford-cs-224 Ten zasobnik Cloud Storage zawiera pliki PDF z publicznie dostępnego folderu Cloud Storage do celów testowych.
  11. Wybierz Dokumenty nieuporządkowane i kliknij Dalej.
  12. W panelu Skonfiguruj magazyn danych jako lokalizację magazynu danych wybierz lokalizację globalną (Cały świat).
  13. Wpisz nazwę magazynu danych. Użyjesz tej nazwy w dalszej części tego ćwiczenia podczas wdrażania usługi Cloud Run. Kliknij Utwórz.
  14. W panelu Magazyny danych wybierz swój nowy magazyn danych i kliknij Utwórz.
  15. Na stronie Dane magazynu danych kliknij kartę Aktywność, aby sprawdzić stan pozyskiwania danych. Po zakończeniu procesu importowania w kolumnie Stan pojawi się komunikat Import zakończony.
  16. Kliknij kartę Dokumenty, aby zobaczyć liczbę zaimportowanych dokumentów.
  17. Aby przetestować aplikację do wyszukiwania, w menu nawigacyjnym kliknij Podgląd.
  18. Na pasku wyszukiwania wpisz final lab due date, a następnie naciśnij Enter, aby wyświetlić wyniki.

5. Tworzenie usługi Cloud Run

W tej sekcji utworzysz usługę Cloud Run, która akceptuje ciąg zapytania z wyszukiwanymi hasłami. Ta usługa będzie korzystać z bibliotek klienta Pythona dla interfejsu Discovery Engine API. Listę innych obsługiwanych środowisk wykonawczych znajdziesz tutaj.

Tworzenie kodu źródłowego funkcji

Najpierw utwórz katalog i przejdź do niego.

mkdir docs-search-service-python && cd $_

Następnie utwórz plik requirements.txt o tej treści:

blinker==1.6.3
cachetools==5.3.1
certifi==2023.7.22
charset-normalizer==3.3.0
click==8.1.7
Flask==3.0.0
google-api-core==2.12.0
google-auth==2.23.3
google-cloud-discoveryengine==0.11.2
googleapis-common-protos==1.61.0
grpcio==1.59.0
grpcio-status==1.59.0
idna==3.4
importlib-metadata==6.8.0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
numpy==1.26.1
proto-plus==1.22.3
protobuf==4.24.4
pyasn1==0.5.0
pyasn1-modules==0.3.0
requests==2.31.0
rsa==4.9
urllib3==2.0.7
Werkzeug==3.0.1
zipp==3.17.0

Następnie utwórz plik źródłowy main.py o tej treści:

from typing import List
import json
import os
from flask import Flask
from flask import request

app = Flask(__name__)

from google.api_core.client_options import ClientOptions
from google.cloud import discoveryengine_v1 as discoveryengine

project_id = os.environ.get('PROJECT_ID')
location = "global"  # Values: "global", "us", "eu"
data_store_id = os.environ.get('SEARCH_ENGINE_ID')

print(project_id)
print(data_store_id)

@app.route("/")
def search_storage():

    search_query = request.args.get("searchQuery")

    result = search_sample(project_id, location, data_store_id, search_query)
    return result

def search_sample(
    project_id: str,
    location: str,
    data_store_id: str,
    search_query: str,
) -> str:
    #  For more information, refer to:
    # https://cloud.google.com/generative-ai-app-builder/docs/locations#specify_a_multi-region_for_your_data_store
    client_options = (
        ClientOptions(api_endpoint=f"{location}-discoveryengine.googleapis.com")
        if location != "global"
        else None
    )

    # Create a client
    client = discoveryengine.SearchServiceClient(client_options=client_options)

    # The full resource name of the search engine serving config
    # e.g. projects/{project_id}/locations/{location}/dataStores/{data_store_id}/servingConfigs/{serving_config_id}
    serving_config = client.serving_config_path(
        project=project_id,
        location=location,
        data_store=data_store_id,
        serving_config="default_config",
    )

    # Optional: Configuration options for search
    # Refer to the `ContentSearchSpec` reference for all supported fields:
    # https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine_v1.types.SearchRequest.ContentSearchSpec
    content_search_spec = discoveryengine.SearchRequest.ContentSearchSpec(
        # For information about snippets, refer to:
        # https://cloud.google.com/generative-ai-app-builder/docs/snippets
        snippet_spec=discoveryengine.SearchRequest.ContentSearchSpec.SnippetSpec(
            return_snippet=True
        ),
        # For information about search summaries, refer to:
        # https://cloud.google.com/generative-ai-app-builder/docs/get-search-summaries
        summary_spec=discoveryengine.SearchRequest.ContentSearchSpec.SummarySpec(
            summary_result_count=5,
            include_citations=True,
            ignore_adversarial_query=True,
            ignore_non_summary_seeking_query=True,
        ),
    )


    # Refer to the `SearchRequest` reference for all supported fields:
    # https://cloud.google.com/python/docs/reference/discoveryengine/latest/google.cloud.discoveryengine_v1.types.SearchRequest
    request = discoveryengine.SearchRequest(
        serving_config=serving_config,
        query=search_query,
        page_size=10,
        content_search_spec=content_search_spec,
        query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
            condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.AUTO,
        ),
        spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
            mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
        ),
    )

    response = client.search(request)

    return response.summary.summary_text

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0", port=int(os.environ.get("PORT", 8080)))

Konfigurowanie zmiennych środowiskowych

W tym kodzie utworzysz kilka zmiennych środowiskowych, aby zwiększyć czytelność poleceń gcloud używanych w tym ćwiczeniu.

PROJECT_ID=$(gcloud config get-value project)

SERVICE_NAME="search-storage-pdfs-python"
SERVICE_REGION="us-central1"

# update with your data store name
SEARCH_ENGINE_ID=<your-data-store-name>

Tworzenie konta usługi

To ćwiczenie pokazuje, jak utworzyć konto usługi, które będzie używane przez usługę Cloud Run do uzyskiwania dostępu do interfejsu Vertex AI Search API.

SERVICE_ACCOUNT="cloud-run-vertex-ai-search"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT@$PROJECT_ID.iam.gserviceaccount.com

gcloud iam service-accounts create $SERVICE_ACCOUNT \
  --display-name="Cloud Run Vertex AI Search service account"

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/discoveryengine.editor'

Wdrażanie usługi Cloud Run

Teraz możesz użyć wdrożenia opartego na źródle, aby automatycznie kontenerować usługę Cloud Run.

gcloud run deploy $SERVICE_NAME \
--region=$SERVICE_REGION \
--source=. \
--service-account $SERVICE_ACCOUNT \
--update-env-vars SEARCH_ENGINE_ID=$SEARCH_ENGINE_ID,PROJECT_ID=$PROJECT_ID \
--no-allow-unauthenticated

Następnie możesz zapisać adres URL Cloud Run jako zmienną środowiskową, aby użyć jej później.

ENDPOINT_URL="$(gcloud run services describe $SERVICE_NAME --region=$SERVICE_REGION --format='value(status.url)')"

6. Wywoływanie usługi Cloud Run

Możesz teraz wywołać usługę Cloud Run za pomocą ciągu zapytania, aby zadać pytanie What is the final lab due date?.

curl -H "Authorization: bearer $(gcloud auth print-identity-token)" "$ENDPOINT_URL?searchQuery=what+is+the+final+lab+due+date"

Wyniki powinny wyglądać podobnie do tych poniżej:

The final lab is due on Tuesday, March 21 at 4:30 PM [1].

7. Gratulacje!

Gratulujemy ukończenia ćwiczenia!

Zalecamy zapoznanie się z dokumentacją dotyczącą Vertex AI Search i Cloud Run.

Omówione zagadnienia

  • Jak utworzyć aplikację Vertex AI Search do wyszukiwania nieuporządkowanych danych w postaci plików PDF pozyskanych z zasobnika Cloud Storage
  • Jak utworzyć punkt końcowy HTTP za pomocą wdrożenia opartego na źródle w Cloud Run
  • Jak utworzyć konto usługi zgodnie z zasadą najmniejszych uprawnień, aby usługa Cloud Run mogła używać go do wysyłania zapytań do aplikacji Vertex AI Search.
  • Jak wywołać usługę Cloud Run, aby wysłać zapytanie do aplikacji Vertex AI Search

8. Czyszczenie danych

Aby uniknąć przypadkowych opłat (np. jeśli ta funkcja w Cloud Functions zostanie przypadkowo wywołana więcej razy niż miesięczny limit wywołań funkcji w Cloud Functions w warstwie bezpłatnej), możesz usunąć funkcję w Cloud Functions lub projekt utworzony w kroku 2.

Aby usunąć funkcję Cloud Functions, otwórz konsolę Cloud Functions na stronie https://console.cloud.google.com/functions/ i usuń funkcję imagen_vqa (lub $FUNCTION_NAME, jeśli używasz innej nazwy).

Jeśli zdecydujesz się usunąć cały projekt, otwórz stronę https://console.cloud.google.com/cloud-resource-manager, wybierz projekt utworzony w kroku 2 i kliknij Usuń. Jeśli usuniesz projekt, musisz zmienić projekty w Cloud SDK. Listę wszystkich dostępnych projektów możesz wyświetlić, uruchamiając polecenie gcloud projects list.