#Vertex AI Agent Builder #Generative AI #Google Cloud
Google 드라이브를 데이터 소스로 사용하는 Vertex AI Search 앱에 대해 Python에서 검색 할 때 검색 결과가 0 건이되는 경우의 대처법에 대해 소개합니다.
소개
이 기사에서는 Google Cloud(이전 GCP)에서 제공하는 검색 엔진 서비스인 Vertex AI Search 에서 Google 드라이브를 데이터 소스로 사용하는 Vertex AI Search 앱을 Python에서 검색하는 방법을 소개합니다.
Vertex AI Search 앱을 Python에서 검색하는 방법에는 두 가지가 있습니다.
- 파이썬 클라이언트 를 사용하는 방법
- Requests 라이브러리를 사용하여 직접 Google Cloud APIs 에 액세스하는 방법
그러나 구현 방법에 따라서는 검색 결과가 0건이 되어 버리는 경우가 있습니다.
검색에 실패하는 경우
Google Cloud APIs 채널이 v1alpha가 아닌 경우
이 문서를 작성한 2024년 12월 현재 Google 드라이브를 데이터 소스로 사용하는 Vertex AI Search 앱에 대한 검색은 ‘Python Client를 사용하는 방법’과 ‘직접 Google Cloud APIs에 액세스하는 방법’ 모두 v1alpha 에서 만 예상대로 작동합니다. 반면 v1 또는 v1beta를 사용하면 검색 결과가 0입니다.
Google Cloud APIs에서 v1alpha는 API 버전을 나타내는 채널 중 하나입니다. 성이 있기 때문에 프로덕션 환경에서의 사용은 사용되지 않습니다.
- 참고 : 버전 관리
서비스 계정을 사용하는 경우
Google Cloud APIs는 일반적으로 Google 계정 또는 서비스 계정 자격 증명을 사용하여 액세스합니다.
그러나 2024년 12월 현재 서비스 계정을 사용하여 Google 드라이브를 데이터 소스로 사용하는 Vertex AI Search 앱으로 검색하면 서버 측 오류(500 Internal Server Error)가 발생합니다.
대처법
본 사건에 대한 2024년 12월 현재의 대처법은 다음과 같습니다.
- v1alpha 채널의 클라이언트 라이브러리 사용
- 서비스 계정이 아닌 Google 계정 자격 증명 사용
파이썬 클라이언트
샘플 코드
Python Client를 사용하는 경우 샘플 코드는 다음과 같습니다.
from google.cloud.discoveryengine_v1alpha import SearchServiceClient, SearchRequestfrom google.protobuf.json_format import MessageToDictPROJECT_ID = "xxx" # Google Cloud 프로젝트 IDVERTEX_AI_APP_ID = "xxx" # Vertex AI Search 앱 IDclient = SearchServiceClient(credentials=credentials)serving_config = f "projects/{PROJECT_ID}/locations/global/collections/default_collection/engines/{VERTEX_AI_APP_ID}/servingConfigs/default_serving_config"content_search_spec = SearchRequest.ContentSearchSpec (# 스 니펫을 출력하지 않음snippet_spec=SearchRequest.ContentSearchSpec().SnippetSpec(return_snippet= False),# 요약문을 출력한다summary_spec=SearchRequest.ContentSearchSpec().SummarySpec(summary_result_count= 3 ,include_citations = False ,# Gemini Pro를 사용하도록 지정model_spec=SearchRequest.ContentSearchSpec().SummarySpec().ModelSpec(version= "gemini-1.5-flash-001/answer_gen/v1")))# Vertex AI Search에 검색어 던지기response = client.search(SearchRequest (serving_config=serving_config,query= "G-gen이란?" ,page_size= 3 ,content_search_spec=content_search_spec))# 요약 문을 표준 출력print (response.summary.summary_text)# 검색 결과를 표준 출력for r in response.results:r_dct = MessageToDict(r._pb)print (r_dct)
포인트
o 라이브러리 채널 지정
from google.cloud.discoveryengine_v1alpha import SearchServiceClient, SearchRequest
_v1alpha google -cloud-discoveryengine을 가져올 때 채널 지정은 명시 적으로 지정해야합니다 . , 검색결과가 0개입니다.
# 지정되지 않음from google.cloud.discoveryengine import SearchServiceClient, SearchRequest# v1 지정from google.cloud.discoveryengine_v1 import SearchServiceClient, SearchRequest# v1beta 지정from google.cloud.discoveryengine_v1beta import SearchServiceClient, SearchRequest
Credentials
client = SearchServiceClient(credentials=credentials)에서 매개변수로 제공하는 자격 증명은 서비스 계정이 아니며 Google 계정이어야 합니다.
Google 계정 자격 증명의 경우 변수 유형이, google.oauth2.credentials.Credentials서비스 계정 자격 증명의 경우 변수 유형 google.oauth2.service_account.Credentials입니다.
Requests 라이브러리를 사용한 직접 액세스
샘플 코드
Requests 라이브러리를 사용하여 Google Cloud APIs에 직접 액세스하는 예제 코드는 다음과 같습니다.
import requestsPROJECT_NUMBER = "xxx" # Google Cloud 프로젝트 번호VERTEX_AI_APP_ID = "xxx" # Vertex AI Search 앱 ID# API URLurl = f "https://discoveryengine.googleapis.com/v1alpha/projects/{PROJECT_NUMBER}/locations/global/collections/default_collection/engines/{VERTEX_AI_APP_ID}/servingConfigs/default_search"# 요청 헤더headers={"Authorization" : "Bearer " + credentials.token,"Content-Type" : "application/json" ,}# 요청 본문session = f "projects/{PROJECT_NUMBER}/locations/global/collections/default_collection/engines/{VERTEX_AI_APP_ID}/sessions/-"data={"query" : "G-gen이란?" ,"pageSize" : 3 ,"contentSearchSpec" : {"snippetSpec" : {"returnSnippet" : False},"extractiveContentSpec" : {"maxExtractiveAnswerCount" : 1}},"session" : session}# 검색 요청 제출response = requests.post(f "{url}:search" , headers=headers, json=data)# 검색 결과를 표준 출력for r in response.json().get( "results" ):print (r)data={"query" : {"text" : "G-gen이란?" ,"queryId" : response.json().get( "sessionInfo" ).get( "queryId" )},"session" : response.json().get( "sessionInfo" ).get( "name" ),"answerGenerationSpec" : {"modelSpec" : {"modelVersion" : "gemini-1.5-flash-001/answer_gen/v1"}}}# 요약 요청 제출response = requests.post(f "{url}:answer" , headers=headers, json=data)# 요약 문을 표준 출력print (response.json().get( "answer" ).get( "answerText" ))