Cloud Run 서비스에서 Cloud Storage의 PDF (비정형 데이터)에 Vertex AI Search 사용

1. 소개

개요

Vertex AI Search and Conversation (이전 명칭: 생성형 AI 앱 빌더)을 사용하면 개발자가 Google의 기반 모델, 검색 전문 지식, 대화형 AI 기술을 활용하여 엔터프라이즈급 생성형 AI 애플리케이션을 만들 수 있습니다. 이 Codelab은 Vertex AI Search를 사용하는 데 중점을 둡니다. Vertex AI Search에서는 자체 데이터를 사용해 Google 품질의 검색 앱을 빌드하고 웹페이지 또는 앱에 검색창을 삽입할 수 있습니다.

Cloud Run은 Google의 확장 가능한 인프라에서 직접 컨테이너를 실행할 수 있게 해 주는 관리형 컴퓨팅 플랫폼입니다. 소스 기반 배포 옵션을 사용하여 Cloud Run에서 모든 프로그래밍 언어로 작성된 코드 (컨테이너 내부에 배치할 수 있음)를 배포할 수 있습니다.

이 Codelab에서는 소스 기반 배포를 사용하여 Cloud Storage 버킷의 PDF 파일에서 구조화되지 않은 콘텐츠에 대한 검색 결과를 가져오는 Cloud Run 서비스를 만듭니다. 비정형 콘텐츠 수집에 대해 자세히 알아보세요.

학습할 내용

  • Cloud Storage 버킷에서 수집된 PDF로 구조화되지 않은 데이터를 위한 Vertex AI Search 앱을 만드는 방법
  • Cloud Run에서 소스 기반 배포를 사용하여 HTTP 엔드포인트를 만드는 방법을 알아봅니다.
  • Cloud Run 서비스에서 Vertex AI Search 앱을 쿼리하는 데 사용할 최소 권한의 원칙에 따라 서비스 계정을 만드는 방법
  • Cloud Run 서비스를 호출하여 Vertex AI Search 앱을 쿼리하는 방법

2. 설정 및 요구사항

기본 요건

Cloud Shell 활성화

  1. Cloud Console에서 Cloud Shell 활성화d1264ca30785e435.png를 클릭합니다.

cb81e7c8e34bc8d.png

Cloud Shell을 처음 시작하는 경우에는 무엇이 있는지 설명하는 중간 화면이 표시됩니다. 중간 화면이 표시되면 계속을 클릭합니다.

d95252b003979716.png

Cloud Shell을 프로비저닝하고 연결하는 데 몇 분 정도만 걸립니다.

7833d5e1c5d18f54.png

가상 머신에는 필요한 개발 도구가 모두 들어 있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab에서 대부분의 작업은 브라우저를 사용하여 수행할 수 있습니다.

Cloud Shell에 연결되면 인증이 완료되었고 프로젝트가 자신의 프로젝트 ID로 설정된 것을 확인할 수 있습니다.

  1. Cloud Shell에서 다음 명령어를 실행하여 인증되었는지 확인합니다.
gcloud auth list

명령어 결과

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Cloud Shell에서 다음 명령어를 실행하여 gcloud 명령어가 프로젝트를 알고 있는지 확인합니다.
gcloud config list project

명령어 결과

[core]
project = <PROJECT_ID>

또는 다음 명령어로 설정할 수 있습니다.

gcloud config set project <PROJECT_ID>

명령어 결과

Updated property [core/project].

3. API 사용 설정

Vertex AI Search를 사용하기 전에 먼저 사용 설정해야 하는 API가 몇 가지 있습니다.

먼저 이 Codelab을 사용하려면 Vertex AI Search and Conversation, BigQuery, Cloud Storage API를 사용해야 합니다. 여기에서 이러한 API를 사용 설정할 수 있습니다.

둘째, 다음 단계에 따라 Vertex AI Search and Conversation API를 사용 설정합니다.

  1. Google Cloud 콘솔에서 Vertex AI Search and Conversation 콘솔로 이동합니다.
  2. 서비스 약관을 읽고 동의한 후 '계속'을 클릭하여 API를 활성화하세요.

4. Cloud Storage에서 비정형 데이터를 위한 검색 앱 만들기

  1. Google Cloud 콘솔에서 검색 및 대화 페이지로 이동합니다. 새 앱을 클릭합니다.
  2. 앱 유형 선택 창에서 검색을 선택합니다.
  3. 문서에서 추출된 답변을 그대로 받으려면 Enterprise 기능사용 설정해야 합니다.
  4. 검색 요약을 받으려면 고급 LLM 기능 옵션이 사용 설정되어야 합니다.
  5. 앱 이름 필드에 앱의 이름을 입력합니다. 앱 ID가 앱 이름 아래에 표시됩니다.
  6. 앱 위치로 global(Global)(전역)을 선택하고 계속을 클릭합니다.
  7. 데이터 스토어 창에서 새 데이터 스토어 만들기를 클릭합니다.
  8. 데이터 소스 선택 창에서 Cloud Storage를 선택합니다.
  9. GCS에서 데이터 가져오기 창에서 폴더가 선택되어 있는지 확인합니다.
  10. gs:// 필드에 cloud-samples-data/gen-app-builder/search/stanford-cs-224 값을 입력합니다. 이 Cloud Storage 버킷에는 테스트 목적으로 공개적으로 사용 가능한 Cloud Storage 폴더의 PDF 파일이 포함됩니다.
  11. 구조화되지 않은 문서를 선택하고 계속을 클릭합니다.
  12. 데이터 스토어 구성 창에서 데이터 스토어의 위치로 전역 (Global)을 선택합니다.
  13. 데이터 스토어의 이름을 입력합니다. 나중에 이 Codelab에서 Cloud Run 서비스를 배포할 때 이 이름을 사용합니다. 만들기를 클릭합니다.
  14. 데이터 스토어 창에서 새 데이터 스토어를 선택하고 만들기를 클릭합니다.
  15. 데이터 스토어의 데이터 페이지에서 활동 탭을 클릭하여 데이터 수집 상태를 확인합니다. 가져오기 프로세스가 완료되면 상태 열에 가져오기 완료가 표시됩니다.
  16. 가져온 문서 수를 확인하려면 문서 탭을 클릭합니다.
  17. 탐색 메뉴에서 미리보기를 클릭하여 검색 앱을 테스트합니다.
  18. 검색창에 final lab due date을 입력한 후 Enter를 눌러 결과를 확인합니다.

5. Cloud Run 서비스 만들기

이 섹션에서는 검색어에 쿼리 문자열을 허용하는 Cloud Run 서비스를 만듭니다. 이 서비스는 Discovery Engine API용 Python 클라이언트 라이브러리를 사용합니다. 지원되는 다른 런타임의 경우 여기에서 목록을 확인할 수 있습니다.

함수의 소스 코드 만들기

먼저 디렉터리를 생성하고 cd 명령어로 해당 디렉터리로 이동합니다.

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

그런 다음, 다음 콘텐츠로 requirements.txt 파일을 만듭니다.

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

다음으로, 다음 콘텐츠로 main.py 소스 파일을 만듭니다.

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)))

환경 변수 설정

이 코드에서는 몇 가지 환경 변수를 만들어 이 Codelab에 사용되는 gcloud 명령어의 가독성을 개선합니다.

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>

서비스 계정 만들기

이 Codelab에서는 Vertex AI Search API에 액세스하는 데 사용할 Cloud Run 서비스의 서비스 계정을 만드는 방법을 보여줍니다.

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'

Cloud Run 서비스 배포

이제 소스 기반 배포를 사용하여 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

그러면 Cloud Run URL을 환경 변수로 저장했다가 나중에 사용할 수 있습니다.

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

6. Cloud Run 서비스 호출

이제 쿼리 문자열로 Cloud Run 서비스를 호출하여 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"

결과는 아래 출력 예와 유사합니다.

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

7. 축하합니다.

축하합니다. Codelab을 완료했습니다.

Vertex AI SearchCloud Run에 관한 문서를 검토하시기 바랍니다.

학습한 내용

  • Cloud Storage 버킷에서 수집된 PDF로 구조화되지 않은 데이터를 위한 Vertex AI Search 앱을 만드는 방법
  • Cloud Run에서 소스 기반 배포를 사용하여 HTTP 엔드포인트를 만드는 방법을 알아봅니다.
  • Cloud Run 서비스에서 Vertex AI Search 앱을 쿼리하는 데 사용할 최소 권한의 원칙에 따라 서비스 계정을 만드는 방법을 알아봅니다.
  • Cloud Run 서비스를 호출하여 Vertex AI Search 앱을 쿼리하는 방법

8. 삭제

실수로 인한 청구를 피하려면(예: 이 Cloud 함수가 무료 등급의 월별 Cloud 함수 호출 할당보다 실수로 더 많이 호출된 경우) Cloud 함수를 삭제하거나 2단계에서 만든 프로젝트를 삭제하면 됩니다.

Cloud 함수를 삭제하려면 Cloud 함수 콘솔(https://console.cloud.google.com/functions/)으로 이동하여 imagen_vqa 함수(또는 다른 이름을 사용한 경우 $FUNCTION_NAME)를 삭제합니다.

전체 프로젝트를 삭제하려면 https://console.cloud.google.com/cloud-resource-manager로 이동하여 2단계에서 만든 프로젝트를 선택한 후 삭제를 선택하면 됩니다. 프로젝트를 삭제하면 Cloud SDK에서 프로젝트를 변경해야 합니다. gcloud projects list를 실행하면 사용 가능한 모든 프로젝트의 목록을 볼 수 있습니다.