Vertex AI 에이전트를 Google Workspace와 통합하기

1. 시작하기 전에

99afae2505f696fb.png

Vertex AI란 무엇인가요?

Vertex AI는 엔터프라이즈급 AI 에이전트와 애플리케이션을 빌드, 배포, 확장하기 위한 Google Cloud의 통합 개발 플랫폼입니다. 개발자와 데이터 과학자에게 전 세계 규모의 인프라와 긴밀하게 통합된 맞춤형 에이전트 워크플로를 설계하는 데 필요한 정교한 도구를 제공합니다.

  • Model Garden 액세스: 전체 Gemini 제품군, 서드 파티 모델, 전문 오픈소스 모델을 비롯한 150개 이상의 파운데이션 모델 중에서 선택하여 특정 에이전트 작업에 적합한 모델을 찾습니다.
  • 복잡한 조정 설계: Vertex AI는 추론을 사용하여 다단계 작업을 계획하고 실행하며 외부 API를 호출하는 자율 에이전트를 설계하는 프레임워크를 제공합니다.
  • 엔터프라이즈급 그라운딩: 고성능 RAG (검색 증강 생성)를 포함한 실시간 비즈니스 데이터에 에이전트를 연결하여 할루시네이션을 없애고 사실 정확성을 보장합니다.
  • DevOps: 강력한 SDK, API, 평가 도구를 사용하여 에이전트 개발을 기존 CI/CD 파이프라인에 원활하게 통합하여 에이전트 성능과 안전성을 대규모로 측정합니다.
  • 산업 수준의 보안: Vertex AI는 학습 또는 그라운딩에 사용되는 고객 데이터가 비공개로 유지되고 암호화되며 전 세계 거주 요건을 준수하도록 보장합니다.
  • 최적화된 인프라: Google의 세계적 수준의 TPU 및 GPU 클러스터에서 에이전트 워크로드를 손쉽게 확장하여 가장 까다로운 글로벌 애플리케이션에서도 지연 시간이 짧은 성능을 보장합니다.

127f2ed7d484722c.png

Google Workspace란 무엇인가요?

Google Workspace는 개인, 학교, 비즈니스를 위해 설계된 클라우드 기반 생산성 및 공동작업 솔루션 모음입니다.

  • 커뮤니케이션: 전문 이메일 서비스 (Gmail), 화상 회의 (Meet), 팀 메시지 (Chat)
  • 콘텐츠 제작: 문서 작성 (Docs), 스프레드시트 빌드 (Sheets), 프레젠테이션 디자인 (Slides)을 위한 도구입니다.
  • 정리: 공유 캘린더 (Calendar) 및 디지털 메모 (Keep)
  • 스토리지: 파일을 안전하게 저장하고 공유할 수 있는 중앙 집중식 클라우드 공간 (Drive)
  • 관리: 사용자 및 보안 설정을 관리하는 관리 컨트롤 (Workspace 관리 콘솔)

어떤 종류의 맞춤 통합인가요?

Google Workspace와 Vertex AI는 Workspace가 실시간 데이터와 공동작업 컨텍스트를 제공하고 Vertex AI가 지능형 워크플로를 자동화하는 데 필요한 모델, 에이전트 추론, 오케스트레이션을 제공하는 강력한 피드백 루프를 만듭니다.

  • 스마트 연결: Google 관리 데이터 저장소, API, MCP 서버 (Google 관리 및 맞춤)를 통해 에이전트가 Workspace 데이터에 안전하고 원활하게 액세스하고 사용자를 대신하여 조치를 취할 수 있습니다.
  • 맞춤 에이전트: 팀은 노 코드 디자이너 또는 프로 코드 프레임워크를 사용하여 관리자가 관리하는 Workspace 데이터 및 작업을 기반으로 하는 전문 에이전트를 빌드할 수 있습니다.
  • 기본 통합: Workspace 부가기능은 전용 UI 구성요소를 사용하든 백그라운드 프로세스를 사용하든 AI 시스템과 Chat, Gmail과 같은 애플리케이션 간의 격차를 해소합니다. 이를 통해 상담사는 사용자가 있는 곳에서 즉각적이고 맥락에 맞는 지원을 제공할 수 있습니다.

Google Workspace의 강력한 생산성 생태계를 Vertex AI의 고급 에이전트 기능과 결합하면 조직은 팀이 이미 매일 사용하고 있는 도구 내에서 복잡한 워크플로를 직접 자동화하는 맞춤형 데이터 기반 AI 에이전트를 통해 운영을 혁신할 수 있습니다.

기본 요건

자체 환경에서 모든 단계를 따르려면 다음이 필요합니다.

빌드 대상

이 Codelab에서는 Google Workspace와 긴밀하게 통합된 Vertex AI 에이전트를 사용하여 세 가지 솔루션을 빌드합니다. 데이터, 작업, UI와 상호작용하는 데 사용할 수 있는 아키텍처 패턴을 보여줍니다.

Vertex AI Search 앱

이 에이전트를 사용하면 사용자가 자연어로 Workspace 데이터를 검색하고 조치를 취할 수 있습니다. 다음 요소를 사용합니다.

  • 모델: Gemini
  • 데이터 및 작업: Google Workspace (Calendar, Gmail, Drive)용 Vertex AI 데이터 스토어
  • 에이전트 호스트: Vertex AI Search
  • UI: Vertex AI Search 웹 위젯

d276ff8e2b9d0ddf.png

맞춤 에이전트

이 에이전트를 사용하면 사용자가 맞춤 도구와 규칙을 사용하여 자연어로 Workspace의 데이터를 검색하고 작업을 실행할 수 있습니다. 다음 요소를 사용합니다.

  • 모델: Gemini
  • 데이터 및 작업: Google Workspace (Calendar, Gmail, Drive)용 Vertex AI 데이터 스토어, Google 관리형 Vertex AI Search 모델 컨텍스트 프로토콜 (MCP) 서버, Google Chat 메시지를 전송하는 맞춤 도구 기능 (Google Chat API를 통해)
  • 에이전트 빌드 도구: 에이전트 개발 키트 (ADK)
  • 에이전트 호스트: Vertex AI Agent Engine
  • UI: ADK Web

145f47f45332e6be.png

293ec4d3e2bb6a0.png

Google Workspace 부가기능으로 제공되는 에이전트

이 에이전트를 사용하면 사용자가 Workspace 앱 UI의 컨텍스트 내에서 자연어로 Workspace 데이터를 검색할 수 있습니다. 다음 요소를 사용합니다.

  • 모델: Gemini
  • 데이터 및 작업: Google Workspace (Calendar, Gmail, Drive)용 Vertex AI 데이터 스토어, Google 관리형 Vertex AI Search 모델 컨텍스트 프로토콜 (MCP) 서버, Google Chat 메시지를 전송하는 맞춤 도구 기능 (Google Chat API를 통해)
  • 에이전트 빌드 도구: 에이전트 개발 키트 (ADK)
  • 에이전트 호스트: Vertex AI Agent Engine
  • UI: Chat 및 Gmail용 Google Workspace 부가기능 (Calendar, Drive, Docs, Sheets, Slides로 쉽게 확장 가능)
  • Google Workspace 부가기능: Apps Script, Vertex AI Agent Engine API, 컨텍스트 (선택한 Gmail 메시지)

172da43f310a0579.png

840b494aa5eaa1ef.png

학습할 내용

  • 데이터와 작업을 지원하는 Vertex AI Search와 Google Workspace 간 통합 지점입니다.
  • Vertex AI에서 호스팅되는 맞춤 에이전트를 빌드하는 옵션입니다.
  • 사용자가 Vertex AI Search 웹 위젯, Google Workspace 애플리케이션과 같은 에이전트에 액세스할 수 있는 방법입니다.

2. 설정

솔루션을 빌드하기 전에 프로젝트의 Vertex AI Applications 설정을 초기화하고, 필요한 API를 사용 설정하고, Vertex AI Workspace 데이터 스토어를 만들어야 합니다.

개념 검토

Vertex AI 애플리케이션

Vertex AI 애플리케이션은 머신러닝 모델 (예: 생성형 AI 에이전트 또는 검색 엔진)을 엔터프라이즈 데이터 및 전문 도구와 통합하여 시맨틱 검색, 콘텐츠 생성, 자동화된 고객 상호작용과 같은 복잡한 작업을 실행하는 Google Cloud의 관리형 엔드 투 엔드 솔루션입니다.

Vertex AI 데이터 스토어

Vertex AI 데이터 스토어는 Google Workspace와 같은 퍼스트 파티 데이터 소스 또는 Jira, Shopify와 같은 서드 파티 애플리케이션에서 수집된 데이터를 포함하는 엔티티입니다. 서드 파티 애플리케이션의 데이터가 포함된 데이터 스토어를 데이터 커넥터라고도 합니다.

Vertex AI 애플리케이션 설정 시작

에이전트 생성을 사용 설정하도록 Vertex AI Applications 설정을 초기화합니다.

새 탭에서 Google Cloud 콘솔을 열고 다음 단계를 따르세요.

  1. 프로젝트를 선택합니다.
  2. Google Cloud 검색 필드에서 AI 애플리케이션으로 이동합니다.

  1. 약관을 검토하고 동의한 후 계속 및 API 활성화를 클릭합니다.
  2. 설정으로 이동합니다.
  3. 인증 탭에서 global을 수정합니다.

93b0cc6ed63fba0c.png

  1. Google ID를 선택한 다음 저장을 클릭합니다.

5c01b4cbeebaa93b.png

API 사용 설정

Vertex AI Workspace 데이터 스토어를 사용하려면 다음 API를 사용 설정해야 합니다.

  1. Google Cloud 콘솔에서 Calendar, Gmail, People API를 사용 설정합니다.

3877dcaa56624d0b.png

  1. 메뉴 ☰ > API 및 서비스 > 사용 설정된 API 및 서비스를 클릭한 다음 Google Calendar API, Gmail API, People API가 목록에 있는지 확인합니다.

데이터 스토어 만들기

Google Drive 데이터 스토어를 만듭니다.

  1. Google Cloud 콘솔에서 AI 애플리케이션으로 이동한 다음 데이터 스토어로 이동합니다.

  1. + 데이터 스토어 만들기를 클릭합니다.
  2. 소스Google Drive에서 선택을 클릭합니다.

6939363368bde36d.png

  1. 데이터에서 모두를 선택하고 계속을 클릭합니다.

5044243322acec9e.png

  1. 구성에서 데이터 커넥터 이름drive로 설정하고 적용될 수 있는 요금을 검토하고 동의한 후 계속을 클릭합니다.

1f5deb1aeecee983.png

  1. 가격에서 원하는 가격 모델을 선택하고 만들기를 클릭합니다. 이 Codelab에서는 일반 가격을 사용하는 것이 좋습니다.
  2. 새로 추가된 데이터 스토어를 확인할 수 있는 데이터 스토어로 자동 리디렉션됩니다.

Google Calendar 데이터 스토어를 만듭니다.

  1. + 데이터 스토어 만들기를 클릭합니다.
  2. 소스에서 Google Calendar를 검색하고 선택을 클릭합니다.
  3. 작업 섹션에서 건너뛰기를 클릭합니다.
  4. 구성 섹션에서 데이터 커넥터 이름calendar로 설정합니다.
  5. 만들기를 클릭합니다.
  6. 새로 추가된 데이터 스토어를 확인할 수 있는 데이터 스토어로 자동 리디렉션됩니다.

Google Gmail 데이터 스토어를 만듭니다.

  1. + 새 데이터 스토어를 클릭합니다.
  2. 소스에서 Google Gmail을 검색하고 선택을 클릭합니다.
  3. 작업 섹션에서 건너뛰기를 클릭합니다.
  4. 구성 섹션에서 데이터 커넥터 이름gmail로 설정합니다.
  5. 만들기를 클릭합니다.
  6. 새로 추가된 데이터 스토어를 확인할 수 있는 데이터 스토어로 자동 리디렉션됩니다.

3. Vertex AI Search 앱

이 에이전트를 사용하면 사용자가 자연어로 Workspace 데이터를 검색하고 조치를 취할 수 있습니다. 다음 요소를 사용합니다.

  • 모델: Gemini
  • 데이터 및 작업: Google Workspace (Calendar, Gmail, Drive)용 Vertex AI 데이터 스토어
  • 에이전트 호스트: Vertex AI Search
  • UI: Vertex AI Search 웹 위젯

개념 검토

Vertex AI Search 앱

Vertex AI Search 앱은 최종 사용자에게 검색 결과, 작업, 에이전트를 제공합니다. 앱이라는 용어는 API라는 맥락에서 엔진이라는 용어와 서로 바꿔서 사용할 수 있습니다. 앱이 데이터 스토어에 연결되어 있어야 데이터 스토어의 데이터를 사용하여 검색 결과, 답변 또는 작업을 제공할 수 있습니다.

Vertex AI Search 웹 위젯

Vertex AI Search 웹 위젯은 사전 빌드된 맞춤설정 가능한 UI 구성요소로, 개발자가 코딩을 최소화하여 AI 기반 검색창과 결과 인터페이스를 웹사이트에 직접 삽입할 수 있습니다.

Vertex AI Search 미리보기

Vertex AI Search 미리보기는 Google Cloud 콘솔 내에 내장된 테스트 환경으로, 개발자가 검색 구성과 생성형 답변을 검증한 후 프로덕션 준비가 완료된 Vertex AI Search 웹 위젯에 동일한 설정을 원활하게 배포할 수 있습니다.

솔루션 아키텍처 검토

1f337dc91da74391.png

앱 만들기

데이터 스토어를 고정할 새 검색 앱을 만듭니다.

Cloud 콘솔에서 AI 애플리케이션 > 앱을 열고 다음 단계를 따르세요.

  1. + 앱 만들기를 클릭합니다.
  2. 유형맞춤 검색 (일반)에서 만들기를 클릭합니다.

9714a5fff49b5e1b.png

  1. 구성에서 가격을 검토하고 동의한 후 Enterprise 버전 기능생성형 대답을 선택합니다.
  2. 앱 이름codelab로 설정합니다.
  3. 이름을 기반으로 ID가 생성되어 필드 아래에 표시되므로 복사합니다.
  4. 회사 이름Codelab로 설정합니다.
  5. 멀티 리전global (Global)로 설정합니다.
  6. 계속을 클릭합니다.

327702cd837cbb18.png

  1. 데이터에서 데이터 스토어 drive, gmail, calendar를 선택한 다음 계속을 클릭합니다.

5745607f3c43d5c0.png

  1. 가격에서 원하는 가격 모델을 선택하고 만들기를 클릭합니다. 이 Codelab에서는 일반 가격을 사용하는 것이 좋습니다.
  2. 앱이 생성되고 AI Applications > Apps > codelab > App overview로 자동 리디렉션됩니다.
  3. 연결된 데이터 스토어로 이동합니다.
  4. 몇 분 후에 연결된 모든 데이터 스토어 상태가 활성으로 표시됩니다.

d53ed9d9d1ced955.png

웹 위젯 구성

검색 위젯의 시각적 디자인과 동작을 구성합니다.

  1. 구성으로 이동합니다.
  2. UI 탭에서 검색 유형후속 조치와 함께 검색으로 설정한 다음 저장 및 게시를 클릭합니다.

af1ca3bd78e1cb4f.png

앱 사용해 보기

Google Cloud 콘솔에서 직접 검색 앱을 테스트합니다.

  1. 미리보기로 이동하면 웹 위젯이 표시됩니다.
  2. 채팅에서 Do I have any meetings today?를 입력하고 enter를 누릅니다.
  3. 채팅에서 Did I receive an email on March 1st 2026?를 입력하고 enter를 누릅니다.
  4. 채팅에서 Give me the title of the latest Drive file I created를 입력하고 enter를 누릅니다.

d276ff8e2b9d0ddf.png

4. 커스텀 에이전트

이 에이전트를 사용하면 사용자가 맞춤 도구와 규칙을 사용하여 자연어로 Workspace의 데이터를 검색하고 작업을 실행할 수 있습니다. 다음 요소를 사용합니다.

  • 모델: Gemini
  • 데이터 및 작업: Google Workspace (Calendar, Gmail, Drive)용 Vertex AI 데이터 스토어, Google 관리형 Vertex AI Search 모델 컨텍스트 프로토콜 (MCP) 서버, Google Chat 메시지를 전송하는 맞춤 도구 기능 (Google Chat API를 통해)
  • 에이전트 빌드 도구: 에이전트 개발 키트 (ADK)
  • 에이전트 호스트: Vertex AI Agent Engine
  • UI: ADK Web

개념 검토

에이전트 개발 키트(ADK)

에이전트 개발 키트 (ADK)는 추론, 메모리 관리, 도구 통합을 위한 사전 빌드된 모듈을 제공하여 자율 AI 에이전트의 생성을 간소화하도록 설계된 특수 도구 및 프레임워크 모음입니다.

Model Context Protocol(MCP)

모델 컨텍스트 프로토콜 (MCP)은 범용 '플러그 앤 플레이' 인터페이스를 통해 AI 애플리케이션과 다양한 데이터 소스 또는 도구 간의 원활하고 안전한 통합을 지원하도록 설계된 개방형 표준입니다.

함수 도구

함수 도구는 AI 모델이 트리거하여 특정 작업을 실행하거나 외부 시스템에서 실시간 데이터를 검색할 수 있는 사전 정의된 실행 가능한 루틴으로, 간단한 텍스트 생성 이상의 기능을 확장합니다.

ADK 웹

ADK 웹은 더 쉬운 개발과 디버깅을 위해 ADK SDK와 함께 제공되는 내장 개발 UI입니다.

솔루션 아키텍처 검토

f14251cca6a19b1f.png

소스 코드 검토

agent.py

다음 코드는 Vertex AI로 인증하고, Vertex AI Search MCP 및 Chat API 도구를 초기화하고, 에이전트의 동작을 정의합니다.

  1. 인증: 환경 변수에서 ACCESS_TOKEN를 검색하여 MCP 및 API 호출을 인증합니다.
  2. 도구 설정: Vertex AI Search 모델 컨텍스트 프로토콜 (MCP) 서버 및 send_direct_message 도구에 연결되는 도구 세트인 vertexai_mcp를 초기화합니다. 이렇게 하면 에이전트가 연결된 데이터 스토어를 검색하고 Google Chat 메시지를 보낼 수 있습니다.
  3. 에이전트 정의: gemini-2.5-flash 모델을 사용하여 root_agent를 정의합니다. 이 안내는 에이전트에게 정보 검색에는 검색 도구를 사용하고 작업에는 send_direct_message 도구를 사용하도록 우선순위를 지정하여 에이전트를 기업 데이터에 효과적으로 그라운딩하도록 지시합니다.
...
MODEL = "gemini-2.5-flash"

# Access token for authentication
ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN")
if not ACCESS_TOKEN:
    raise ValueError("ACCESS_TOKEN environment variable must be set")

VERTEXAI_SEARCH_TIMEOUT = 15.0

def get_project_id():
    """Fetches the consumer project ID from the environment natively."""
    _, project = google.auth.default()
    if project:
        return project
    raise Exception(f"Failed to resolve GCP Project ID from environment.")

def find_serving_config_path():
    """Dynamically finds the default serving config in the engine."""
    project_id = get_project_id()
    engines = discoveryengine_v1.EngineServiceClient().list_engines(
        parent=f"projects/{project_id}/locations/global/collections/default_collection"
    )
    for engine in engines:
        # engine.name natively contains the numeric Project Number
        return f"{engine.name}/servingConfigs/default_serving_config"
    raise Exception(f"No Discovery Engines found in project {project_id}")

def send_direct_message(email: str, message: str) -> dict:
    """Sends a Google Chat Direct Message (DM) to a specific user by email address."""
    chat_client = chat_v1.ChatServiceClient(
        credentials=Credentials(token=ACCESS_TOKEN)
    )

    # 1. Setup the DM space or find existing one
    person = chat_v1.User(
        name=f"users/{email}",
        type_=chat_v1.User.Type.HUMAN
    )
    membership = chat_v1.Membership(member=person)
    space_req = chat_v1.Space(space_type=chat_v1.Space.SpaceType.DIRECT_MESSAGE)
    setup_request = chat_v1.SetUpSpaceRequest(
        space=space_req,
        memberships=[membership]
    )
    space_response = chat_client.set_up_space(request=setup_request)
    space_name = space_response.name
    
    # 2. Send the message
    msg = chat_v1.Message(text=message)
    message_request = chat_v1.CreateMessageRequest(
        parent=space_name,
        message=msg
    )
    message_response = chat_client.create_message(request=message_request)
    
    return {"status": "success", "message_id": message_response.name, "space": space_name}

vertexai_mcp = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://discoveryengine.googleapis.com/mcp",
        timeout=VERTEXAI_SEARCH_TIMEOUT,
        sse_read_timeout=VERTEXAI_SEARCH_TIMEOUT,
        headers={"Authorization": f"Bearer {ACCESS_TOKEN}"}
    ),
    tool_filter=['search']
)

# Answer nicely the following user queries:
#  - Please find my meetings for today, I need their titles and links
#  - What is the latest Drive file I created?
#  - What is the latest Gmail message I received?
#  - Please send the following message to someone@example.com: Hello, this is a test message.

root_agent = LlmAgent(
    model=MODEL,
    name='enterprise_ai',
    instruction=f"""
        You are a helpful assistant that always uses the Vertex AI MCP search tool to answer the user's message, unless the user asks you to send a message to someone.
        If the user asks you to send a message to someone, use the send_direct_message tool to send the message.
        You MUST unconditionally use the Vertex AI MCP search tool to find answer, even if you believe you already know the answer or believe the Vertex AI MCP search tool does not contain the data.
        The Vertex AI MCP search tool accesses the user's data through datastores including Google Drive, Google Calendar, and Gmail.
        Only use the Vertex AI MCP search tool with servingConfig and query parameters, do not use any other parameters.
        Always use the servingConfig {find_serving_config_path()} while using the Vertex AI MCP search tool.
    """,
    tools=[vertexai_mcp, FunctionTool(send_direct_message)]
)

소스 코드 다운로드

시작하려면 로컬 환경에 샘플 코드를 다운로드하세요.

  1. 이 GitHub 저장소를 다운로드합니다.

  1. 터미널에서 solutions/enterprise-ai-agent-local 디렉터리를 엽니다.

API 사용 설정

솔루션에는 추가 API를 사용 설정해야 합니다.

  1. Google Cloud 콘솔에서 Vertex AI, Cloud Resource Manager, Google Chat API를 사용 설정합니다.

60bae4065338c5bf.png

  1. 메뉴 ☰ > API 및 서비스 > 사용 설정된 API 및 서비스를 클릭한 다음 Vertex AI API, Cloud Resource Manager API, Google Chat API가 목록에 있는지 확인합니다.

이 솔루션에는 동의 화면 구성이 필요합니다.

  1. Google Cloud 콘솔에서 메뉴 ☰ > Google 인증 플랫폼 > 브랜딩을 클릭합니다.

  1. 시작하기를 클릭합니다.
  2. 앱 정보에서 앱 이름Codelab로 설정합니다 .
  3. 사용자 지원 이메일에서 사용자가 동의에 대해 문의할 수 있는 지원 이메일 주소를 선택합니다.
  4. 다음을 클릭합니다.
  5. 대상에서 내부를 선택합니다.
  6. 다음을 클릭합니다.
  7. 연락처 정보에서 프로젝트 변경사항에 대한 알림을 받을 수 있는 이메일 주소를 입력합니다.
  8. 다음을 클릭합니다.
  9. 완료에서 Google API 서비스 사용자 데이터 정책을 검토하고 동의하는 경우 Google API 서비스: 사용자 데이터 정책에 동의합니다를 선택합니다.
  10. 계속을 클릭한 다음 만들기를 클릭합니다.

bb53eeb45c51d301.png

  1. 구성이 저장되고 Google 인증 플랫폼 > 개요로 자동 리디렉션됩니다.

자세한 내용은 OAuth 동의 구성 가이드를 참고하세요.

OAuth 클라이언트 사용자 인증 정보 만들기

로컬 환경에서 사용자를 인증하기 위해 새 데스크톱 앱 OAuth 클라이언트를 만듭니다.

  1. Google Cloud 콘솔에서 메뉴 ☰ > Google 인증 플랫폼 > 클라이언트를 클릭합니다.

  1. + 클라이언트 만들기를 클릭합니다.
  2. 애플리케이션 유형으로 데스크톱 앱을 선택합니다.
  3. 이름codelab로 설정합니다.
  4. 만들기를 클릭합니다. 새로 생성된 사용자 인증 정보가 표시됩니다.
  5. JSON 다운로드를 클릭하고 파일을 solutions/enterprise-ai-agent-local 디렉터리에 client_secret.json으로 저장합니다.

c1c9bc2f8c14dd6c.png

Vertex AI Search MCP 사용 설정

  1. 터미널에서 다음을 실행합니다.
gcloud beta services mcp enable discoveryengine.googleapis.com \
     --project=$(gcloud config get-value project)

Chat 앱 구성

기본 정보 세부정보를 사용하여 Google Chat 앱을 구성합니다.

  1. Google Cloud 콘솔의 Google Cloud 검색 필드에서 Google Chat API를 검색하고 Google Chat API를 클릭한 다음 관리를 클릭하고 구성을 클릭합니다.

  1. 앱 이름설명Vertex AI로 설정합니다.
  2. 아바타 URLhttps://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png로 설정합니다.
  3. 대화형 기능 사용 설정을 선택 해제한 다음 표시되는 모달 대화상자에서 사용 중지를 클릭합니다.
  4. Logging에 오류 로깅을 선택합니다.
  5. 저장을 클릭합니다.

952e7ebcb945f1b2.png

ADK 웹에서 에이전트 실행

ADK 웹 인터페이스를 사용하여 에이전트를 로컬로 실행합니다.

  1. 터미널에서 solutions/enterprise-ai-agent-local 디렉터리를 열고 다음을 실행합니다.
# 1. Authenticate with all the required scopes
gcloud auth application-default login \
  --client-id-file=client_secret.json \
   --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/chat.spaces,https://www.googleapis.com/auth/chat.messages

# 2. Configure environment
export ACCESS_TOKEN=$(gcloud auth application-default print-access-token)
export GOOGLE_GENAI_USE_VERTEXAI=1
export GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project)
export GOOGLE_CLOUD_LOCATION=us-central1

# 3. Create and activate a new virtual environment
python3 -m venv .venv
source .venv/bin/activate

# 4. Install poetry and project dependencies
pip install poetry
poetry install

# 5. Start ADK Web
adk web

95fc30883ce3d56f.png

에이전트 사용해 보기

맞춤 에이전트와 채팅하여 흐름을 확인합니다.

  1. 인터넷 브라우저에서 ADK 웹사이트를 엽니다.
  2. 채팅에서 Please find my meetings for today, I need their titles and links를 입력하고 enter를 누릅니다.
  3. 에이전트가 사용자의 계정에 따라 캘린더 일정 목록으로 대답합니다.
  4. 채팅에서 Please send a Chat message to someone@example.com with the following text: Hello!를 입력하고 enter를 누릅니다.
  5. 에이전트가 확인 메시지로 대답합니다.

145f47f45332e6be.png

293ec4d3e2bb6a0.png

5. Google Workspace 부가기능으로 에이전트

이 에이전트를 사용하면 사용자가 Workspace 앱 UI의 컨텍스트 내에서 자연어로 Workspace 데이터를 검색할 수 있습니다. 다음 요소를 사용합니다.

  • 모델: Gemini
  • 데이터 및 작업: Google Workspace (Calendar, Gmail, Drive)용 Vertex AI 데이터 스토어, Google 관리형 Vertex AI Search 모델 컨텍스트 프로토콜 (MCP) 서버, Google Chat 메시지를 전송하는 맞춤 도구 기능 (Google Chat API를 통해)
  • 에이전트 빌드 도구: 에이전트 개발 키트 (ADK)
  • 에이전트 호스트: Vertex AI Agent Engine
  • UI: Chat 및 Gmail용 Google Workspace 부가기능 (Calendar, Drive, Docs, Sheets, Slides로 쉽게 확장 가능)
  • Google Workspace 부가기능: Apps Script, Vertex AI Agent Engine API, 컨텍스트 (선택한 Gmail 메시지)

개념 검토

Google Workspace 부가기능

Google Workspace 부가기능은 하나 이상의 Google Workspace 애플리케이션 (Gmail, Chat, Calendar, Docs, Drive, Meet, Sheets, Slides)을 확장하는 맞춤 애플리케이션입니다.

Apps Script

Apps Script는 Google Drive에서 제공하는 클라우드 기반 JavaScript 플랫폼으로, Google 제품 전반에서 작업을 통합하고 자동화할 수 있습니다.

Google Workspace 카드 프레임워크

Google Workspace의 카드 프레임워크를 사용하면 개발자가 풍부한 대화형 사용자 인터페이스를 만들 수 있습니다. 텍스트, 이미지, 버튼, 기타 위젯을 포함할 수 있는 체계적이고 시각적으로 매력적인 카드를 구성할 수 있습니다. 이러한 카드는 구조화된 정보를 제공하고 Workspace 애플리케이션 내에서 직접 빠른 작업을 실행할 수 있도록 지원하여 사용자 환경을 개선합니다.

솔루션 아키텍처 검토

f2fd048ba298f431.png

소스 코드 검토

Agent

agent.py

다음 코드는 Vertex AI로 인증하고, Vertex AI Search MCP 및 Chat API 도구를 초기화하고, 에이전트의 동작을 정의합니다.

  1. 인증: 도우미 함수 _get_access_token_from_context를 사용하여 클라이언트가 삽입하는 인증 토큰 (CLIENT_AUTH_NAME)을 가져옵니다. 이 토큰은 Vertex AI Search MCP 및 Google Chat 도구와 같은 다운스트림 서비스를 안전하게 호출하는 데 중요합니다.
  2. 도구 설정: Vertex AI Search 모델 컨텍스트 프로토콜 (MCP) 서버 및 send_direct_message 도구에 연결되는 도구 세트인 vertexai_mcp를 초기화합니다. 이렇게 하면 에이전트가 연결된 데이터 스토어를 검색하고 Google Chat 메시지를 보낼 수 있습니다.
  3. 에이전트 정의: gemini-2.5-flash 모델을 사용하여 root_agent를 정의합니다. 이 안내는 에이전트에게 정보 검색에는 검색 도구를 사용하고 작업에는 send_direct_message 도구를 사용하도록 우선순위를 지정하여 에이전트를 기업 데이터에 효과적으로 그라운딩하도록 지시합니다.
...
MODEL = "gemini-2.5-flash"

# Client injects a bearer token into the ToolContext state.
# The key pattern is "CLIENT_AUTH_NAME_<random_digits>".
# We dynamically parse this token to authenticate our MCP and API calls.
CLIENT_AUTH_NAME = "enterprise-ai"

VERTEXAI_SEARCH_TIMEOUT = 15.0

def get_project_id():
    """Fetches the consumer project ID from the environment natively."""
    _, project = google.auth.default()
    if project:
        return project
    raise Exception(f"Failed to resolve GCP Project ID from environment.")

def find_serving_config_path():
    """Dynamically finds the default serving config in the engine."""
    project_id = get_project_id()
    engines = discoveryengine_v1.EngineServiceClient().list_engines(
        parent=f"projects/{project_id}/locations/global/collections/default_collection"
    )
    for engine in engines:
        # engine.name natively contains the numeric Project Number
        return f"{engine.name}/servingConfigs/default_serving_config"
    raise Exception(f"No Discovery Engines found in project {project_id}")

def _get_access_token_from_context(tool_context: ToolContext) -> str:
    """Helper method to dynamically parse the intercepted bearer token from the context state."""
    escaped_name = re.escape(CLIENT_AUTH_NAME)
    pattern = re.compile(fr"^{escaped_name}_\d+$")
    # Handle ADK varying state object types (Raw Dict vs ADK State)
    state_dict = tool_context.state.to_dict() if hasattr(tool_context.state, 'to_dict') else tool_context.state
    matching_keys = [k for k in state_dict.keys() if pattern.match(k)]
    if matching_keys:
        return state_dict.get(matching_keys[0])
    raise Exception(f"No bearer token found in ToolContext state matching pattern {pattern.pattern}")

def auth_header_provider(tool_context: ToolContext) -> dict[str, str]:
    token = _get_access_token_from_context(tool_context)
    return {"Authorization": f"Bearer {token}"}

def send_direct_message(email: str, message: str, tool_context: ToolContext) -> dict:
    """Sends a Google Chat Direct Message (DM) to a specific user by email address."""
    chat_client = chat_v1.ChatServiceClient(
        credentials=Credentials(token=_get_access_token_from_context(tool_context))
    )

    # 1. Setup the DM space or find existing one
    person = chat_v1.User(
        name=f"users/{email}",
        type_=chat_v1.User.Type.HUMAN
    )
    membership = chat_v1.Membership(member=person)
    space_req = chat_v1.Space(space_type=chat_v1.Space.SpaceType.DIRECT_MESSAGE)
    setup_request = chat_v1.SetUpSpaceRequest(
        space=space_req,
        memberships=[membership]
    )
    space_response = chat_client.set_up_space(request=setup_request)
    space_name = space_response.name
    
    # 2. Send the message
    msg = chat_v1.Message(text=message)
    message_request = chat_v1.CreateMessageRequest(
        parent=space_name,
        message=msg
    )
    message_response = chat_client.create_message(request=message_request)
    
    return {"status": "success", "message_id": message_response.name, "space": space_name}

vertexai_mcp = McpToolset(
    connection_params=StreamableHTTPConnectionParams(
        url="https://discoveryengine.googleapis.com/mcp",
        timeout=VERTEXAI_SEARCH_TIMEOUT,
        sse_read_timeout=VERTEXAI_SEARCH_TIMEOUT
    ),
    tool_filter=['search'],
    # The auth_header_provider dynamically injects the bearer token from the ToolContext
    # into the MCP call for authentication.
    header_provider=auth_header_provider
)

# Answer nicely the following user queries:
#  - Please find my meetings for today, I need their titles and links
#  - What is the latest Drive file I created?
#  - What is the latest Gmail message I received?
#  - Please send the following message to someone@example.com: Hello, this is a test message.

root_agent = LlmAgent(
    model=MODEL,
    name='enterprise_ai',
    instruction=f"""
        You are a helpful assistant that always uses the Vertex AI MCP search tool to answer the user's message, unless the user asks you to send a message to someone.
        If the user asks you to send a message to someone, use the send_direct_message tool to send the message.
        You MUST unconditionally use the Vertex AI MCP search tool to find answer, even if you believe you already know the answer or believe the Vertex AI MCP search tool does not contain the data.
        The Vertex AI MCP search tool accesses the user's data through datastores including Google Drive, Google Calendar, and Gmail.
        Only use the Vertex AI MCP search tool with servingConfig and query parameters, do not use any other parameters.
        Always use the servingConfig {find_serving_config_path()} while using the Vertex AI MCP search tool.
    """,
    tools=[vertexai_mcp, FunctionTool(send_direct_message)]
)

클라이언트

appsscript.json

다음 구성은 부가기능의 트리거와 권한을 정의합니다.

  1. 부가기능 정의: 이 프로젝트가 ChatGmail 모두를 위한 부가기능임을 Workspace에 알립니다.
  2. 문맥 트리거: Gmail의 경우 사용자가 이메일 메시지를 열 때마다 onAddonEvent을 실행하는 contextualTrigger을 설정합니다. 이렇게 하면 부가기능이 이메일 콘텐츠를 '볼' 수 있습니다.
  3. 권한: 현재 이메일을 읽고, 스크립트를 실행하고, 외부 서비스 (예: Vertex AI API)에 연결하는 권한과 같이 부가기능을 실행하는 데 필요한 oauthScopes이 나열됩니다.
...
"addOns": {
    "common": {
      "name": "Vertex AI",
      "logoUrl": "https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png"
    },
    "chat": {},
    "gmail": {
      "contextualTriggers": [
        {
          "unconditional": {},
          "onTriggerFunction": "onAddonEvent"
        }
      ]
    }
  },
  "oauthScopes": [
   "https://www.googleapis.com/auth/script.external_request",
   "https://www.googleapis.com/auth/cloud-platform",
   "https://www.googleapis.com/auth/gmail.addons.execute",
   "https://www.googleapis.com/auth/gmail.addons.current.message.readonly"
 ]
...

Chat.gs

다음 코드는 수신 Google Chat 메시지를 처리합니다.

  1. 메시지 수신: onMessage 함수는 메시지 상호작용의 진입점입니다.
  2. 컨텍스트 관리: space.name (채팅 스페이스의 ID)를 사용자의 속성에 저장합니다. 이렇게 하면 상담사가 답장할 준비가 되었을 때 메시지를 게시할 대화를 정확하게 알 수 있습니다.
  3. Delegates to Agent: API 통신을 처리하는 핵심 로직에 사용자의 메시지를 전달하여 requestAgent를 호출합니다.
...
// Service that handles Google Chat operations.

// Handle incoming Google Chat message events, actions will be taken via Google Chat API calls
function onMessage(event) {
  if (isInDebugMode()) {
    console.log(`MESSAGE event received (Chat): ${JSON.stringify(event)}`);
  }
  // Extract data from the event.
  const chatEvent = event.chat;
  setChatConfig(chatEvent.messagePayload.space.name);

  // Request AI agent to answer the message
  requestAgent(chatEvent.messagePayload.message);
  // Respond with an empty response to the Google Chat platform to acknowledge execution
  return null; 
}

// --- Utility functions ---

// The Chat direct message (DM) space associated with the user
const SPACE_NAME_PROPERTY = "DM_SPACE_NAME"

// Sets the Chat DM space name for subsequent operations.
function setChatConfig(spaceName) {
  const userProperties = PropertiesService.getUserProperties();
  userProperties.setProperty(SPACE_NAME_PROPERTY, spaceName);
  console.log(`Space is set to ${spaceName}`);
}

// Retrieved the Chat DM space name to sent messages to.
function getConfiguredChat() {
  const userProperties = PropertiesService.getUserProperties();
  return userProperties.getProperty(SPACE_NAME_PROPERTY);
}

// Finds the Chat DM space name between the Chat app and the given user.
function findChatAppDm(userName) {
  return Chat.Spaces.findDirectMessage(
    { 'name': userName },
    {'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}`}
  ).name;
}

// Creates a Chat message in the configured space.
function createMessage(message) {
  const spaceName = getConfiguredChat();
  console.log(`Creating message in space ${spaceName}...`);
  return Chat.Spaces.Messages.create(
    message,
    spaceName,
    {},
    {'Authorization': `Bearer ${getAddonCredentials().getAccessToken()}`}
  ).name;
}

Sidebar.gs

다음 코드는 Gmail 사이드바를 빌드하고 이메일 컨텍스트를 캡처합니다.

  1. UI 빌드: createSidebarCard는 Workspace Card Service를 사용하여 시각적 인터페이스를 구성합니다. 텍스트 입력 영역과 '메시지 보내기' 버튼이 있는 간단한 레이아웃을 만듭니다.
  2. 이메일 컨텍스트 캡처: handleSendMessage에서 코드는 사용자가 현재 이메일 (event.gmail.messageId)을 보고 있는지 확인합니다. 보고 있다면 이메일의 제목과 본문을 안전하게 가져와 사용자의 프롬프트에 추가합니다.
  3. 결과 표시: 에이전트가 응답하면 코드가 사이드바 카드를 업데이트하여 답장을 표시합니다.
...
// Service that handles Gmail operations.

// Triggered when the user opens the Gmail Add-on or selects an email.
function onAddonEvent(event) {
  // If this was triggered by a button click, handle it
  if (event.parameters && event.parameters.action === 'send') {
    return handleSendMessage(event);
  }

  // Otherwise, just render the default initial sidebar
  return createSidebarCard();
}

// Creates the standard Gmail sidebar card consisting of a text input and send button.
// Optionally includes an answer section if a response was generated.
function createSidebarCard(optionalAnswerSection) {
  const card = CardService.newCardBuilder();
  const actionSection = CardService.newCardSection();

  // Create text input for the user's message
  const messageInput = CardService.newTextInput()
    .setFieldName("message")
    .setTitle("Message")
    .setMultiline(true);

  // Create action for sending the message
  const sendAction = CardService.newAction()
    .setFunctionName('onAddonEvent')
    .setParameters({ 'action': 'send' });

  const sendButton = CardService.newTextButton()
    .setText("Send message")
    .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
    .setOnClickAction(sendAction);

  actionSection.addWidget(messageInput);
  actionSection.addWidget(CardService.newButtonSet().addButton(sendButton));

  card.addSection(actionSection);

  // Attach the response at the bottom if we have one
  if (optionalAnswerSection) {
    card.addSection(optionalAnswerSection);
  }

  return card.build();
}

// Handles clicks from the Send message button.
function handleSendMessage(event) {
  const commonEventObject = event.commonEventObject || {};
  const formInputs = commonEventObject.formInputs || {};
  const messageInput = formInputs.message;

  let userMessage = "";
  if (messageInput && messageInput.stringInputs && messageInput.stringInputs.value.length > 0) {
    userMessage = messageInput.stringInputs.value[0];
  }

  if (!userMessage || userMessage.trim().length === 0) {
    return CardService.newActionResponseBuilder()
      .setNotification(CardService.newNotification().setText("Please enter a message."))
      .build();
  }

  let finalQueryText = `USER MESSAGE TO ANSWER: ${userMessage}`;

  // If we have an email selected in Gmail, append its content as context
  if (event.gmail && event.gmail.messageId) {
    try {
      GmailApp.setCurrentMessageAccessToken(event.gmail.accessToken);
      const message = GmailApp.getMessageById(event.gmail.messageId);

      const subject = message.getSubject();
      const bodyText = message.getPlainBody() || message.getBody();

      finalQueryText += `\n\nEMAIL THE USER HAS OPENED ON SCREEN:\nSubject: ${subject}\nBody:\n---\n${bodyText}\n---`;
    } catch (e) {
      console.error("Could not fetch Gmail context: " + e);
      // Invalidate the token explicitly so the next prompt requests the missing scopes
      ScriptApp.invalidateAuth();

      CardService.newAuthorizationException()
        .setResourceDisplayName("Enterprise AI")
        .setAuthorizationUrl(ScriptApp.getAuthorizationUrl())
        .throwException();
    }
  }

  try {
    const response = queryAgent({ text: finalQueryText });

    // We leverage the 'showdown' library to parse the LLM's Markdown output into HTML
    // We also substitute markdown listings with arrows and adjust newlines for clearer rendering in the sidebar
    let displayedText = substituteListingsFromMarkdown(response.text);
    displayedText = new showdown.Converter().makeHtml(displayedText).replace(/\n/g, '\n\n');

    const textParagraph = CardService.newTextParagraph();
    textParagraph.setText(displayedText);

    const answerSection = CardService.newCardSection()
      .addWidget(textParagraph);

    const updatedCard = createSidebarCard(answerSection);

    return CardService.newActionResponseBuilder()
      .setNavigation(CardService.newNavigation().updateCard(updatedCard))
      .build();

  } catch (err) {
    return CardService.newActionResponseBuilder()
      .setNotification(CardService.newNotification().setText("Error fetching response: " + err.message))
      .build();
  }
}
...

AgentHandler.gs

다음 코드는 Vertex AI에 대한 API 호출을 오케스트레이션합니다.

  1. API 호출 조정: queryAgent는 부가기능과 Vertex AI Agent Engine 간의 브리지입니다. 사용자의 질문과 인증 토큰이 상태에 포함된 요청을 구성합니다.
  2. 대답 스트리밍: 에이전트 대답은 시간이 걸릴 수 있으므로 서버 전송 이벤트 (SSE)와 함께 streamQuery API를 사용합니다. 코드는 응답을 청크로 수집하고 전체 답변을 재구성합니다.
...
// Service that handles Vertex AI Agent operations.

// Submits a query to the AI agent and returns the response string synchronously
function queryAgent(input) {
 let systemPrompt = "SYSTEM PROMPT START Do not respond with tables but use bullet points instead." +
   " Do not ask the user follow-up questions or converse with them as history is not kept in this interface." +
   " SYSTEM PROMPT END\n\n";

 const requestPayload = {
   "class_method": "async_stream_query",
   "input": {
     "user_id": "vertex_ai_add_on",
     "message": { "role": "user", "parts": [{ "text": systemPrompt + input.text }] },
     "state_delta": {
       "enterprise-ai_999": `${ScriptApp.getOAuthToken()}`
     }
   }
 };

 const responseContentText = UrlFetchApp.fetch(
   `https://${getLocation()}-aiplatform.googleapis.com/v1/${getReasoningEngine()}:streamQuery?alt=sse`,
   {
     method: 'post',
     headers: { 'Authorization': `Bearer ${ScriptApp.getOAuthToken()}` },
     contentType: 'application/json',
     payload: JSON.stringify(requestPayload),
     muteHttpExceptions: true
   }
 ).getContentText();
  if (isInDebugMode()) {
   console.log(`Response: ${responseContentText}`);
 }

 const events = responseContentText.split('\n').map(s => s.replace(/^data:\s*/, '')).filter(s => s.trim().length > 0);
 console.log(`Received ${events.length} agent events.`);

 let author = "default";
 let answerText = "";
 for (const eventJson of events) {
   if (isInDebugMode()) {
     console.log("Event: " + eventJson);
   }
   const event = JSON.parse(eventJson);

   // Retrieve the agent responsible for generating the content
   author = event.author;
  
   // Ignore events that are not useful for the end-user
   if (!event.content) {
     console.log(`${author}: internal event`);
     continue;
   }

   // Handle text answers
   const parts = event.content.parts || [];
   const textPart = parts.find(p => p.text);
   if (textPart) {
     answerText += textPart.text;
   }
 }
 return { author: author, text: answerText };
}
...

Vertex AI Agent Engine에 에이전트 배포

  1. 터미널에서 이전 단계에서 다운로드한 소스의 solutions/enterprise-ai-agent 디렉터리를 연 다음 다음을 실행합니다.
# 1. Create and activate a new virtual environment
deactivate
python3 -m venv .venv
source .venv/bin/activate

# 2. Install poetry and project dependencies
pip install poetry
poetry install

# 3. Deploy the agent
adk deploy agent_engine \
  --project=$(gcloud config get-value project) \
  --region=us-central1 \
  --display_name="Enterprise AI" \
  enterprise_ai

eafd2f9c4fbf305.png

  1. 로그에 Deploying to agent engine...이라는 줄이 표시되면 새 터미널을 열고 다음 명령어를 실행하여 Vertex AI Reasoning Engine 서비스 에이전트에 필요한 권한을 추가합니다.
# 1. Get the current Project ID
PROJECT_ID=$(gcloud config get-value project)

# 2. Extract the Project Number for that ID
PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

# 3. Construct the Service Account name
SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"

# 4. Apply the IAM policy binding
gcloud projects add-iam-policy-binding $PROJECT_ID \
     --member="serviceAccount:$SERVICE_ACCOUNT" \
     --role="roles/discoveryengine.viewer"
  1. adk deploy 명령어가 완료될 때까지 기다린 후 새로 배포된 에이전트의 리소스 이름을 명령 출력에서 녹색으로 복사합니다.

d098fe1347d6581b.png

서비스 계정 시작

애드온의 서버 측 작업을 승인할 전용 서비스 계정을 만듭니다.

Google Cloud 콘솔에서 다음 단계를 따르세요.

  1. 메뉴 ☰ > IAM 및 관리자 > 서비스 계정 > + 서비스 계정 만들기를 클릭합니다.

  1. 서비스 계정 이름vertexai-add-on으로 설정합니다.

46be0eb53f416c59.png

  1. 완료를 클릭합니다. 서비스 계정 페이지로 리디렉션되고 만든 서비스 계정을 볼 수 있습니다.

f002fef61c71ed8.png

  1. 새로 만든 서비스 계정을 선택한 다음 탭을 선택합니다.
  2. 키 추가를 클릭한 후 새 키 만들기를 클릭합니다.
  3. JSON을 선택한 후 만들기를 클릭합니다.

7b140535d9e1af44.png

  1. 대화상자가 닫히고 새로 생성된 공개 키/비공개 키 쌍이 자동으로 로컬 환경에 JSON 파일로 다운로드됩니다.

Apps Script 프로젝트 만들기 및 구성

부가기능 코드를 호스팅할 새 Apps Script 프로젝트를 만들고 연결 속성을 구성합니다.

  1. 다음 버튼을 클릭하여 Enterprise AI 부가기능 Apps Script 프로젝트를 엽니다.

  1. 개요 > 사본 만들기를 클릭합니다.
  2. Apps Script 프로젝트에서 프로젝트 설정 > 스크립트 속성 수정 > 스크립트 속성 추가를 클릭하여 스크립트 속성을 추가합니다.
  3. REASONING_ENGINE_RESOURCE_NAME을 이전 단계에서 복사한 Vertex AI 에이전트 리소스 이름으로 설정합니다. 형식은 다음과 같습니다.
projects/<PROJECT_NUMBER>/locations/us-central1/reasoningEngines/<AGENT_ID>
  1. APP_SERVICE_ACCOUNT_KEY를 이전 단계에서 다운로드한 서비스 계정 파일의 JSON 키로 설정합니다.
  2. 스크립트 속성 저장을 클릭합니다.

Gmail 및 Chat에 배포

Gmail 및 Google Chat 내에서 직접 테스트할 수 있도록 부가기능을 배포합니다.

Apps Script 프로젝트에서 다음 단계를 따르세요.

  1. 배포 > 테스트 배포를 클릭한 다음 설치를 클릭합니다. 이제 Gmail에서 사용할 수 있습니다.
  2. 배포 책임자 ID 아래의 복사를 클릭합니다.

b0cba69eef271850.png

Google Cloud 콘솔에서 다음 단계를 따르세요.

  1. Google Cloud 검색 필드에서 Google Chat API를 검색하고 Google Chat API를 클릭한 다음 관리를 클릭하고 구성을 클릭합니다.

  1. 대화형 기능 사용 설정을 선택합니다.
  2. 스페이스 및 그룹 대화 참여를 선택 해제합니다.
  3. 연결 설정에서 Apps Script를 선택합니다.
  4. 배포 ID를 이전 단계에서 복사한 헤드 배포 ID로 설정합니다.
  5. 공개 상태에서 내 Workspace 도메인의 특정 사용자 및 그룹에서 이 Chat 앱을 사용할 수 있도록 설정을 선택하고 이메일 주소를 입력합니다.
  6. 저장을 클릭합니다.

6ea187ccb90a0e49.png

부가기능 사용해 보기

실시간 애드온과 상호작용하여 데이터를 가져오고 맥락에 맞는 질문에 답변할 수 있는지 확인합니다.

새 탭에서 Google Chat을 열고 다음 단계를 따르세요.

  1. Chat 앱 Vertex AI와의 채팅 메시지 스페이스를 엽니다.

495632314dec5a5d.png

  1. 구성을 클릭하고 인증 흐름을 진행합니다.
  2. What are my meetings for today?라고 입력하고 enter 키를 누릅니다. Vertex AI 채팅 앱이 결과로 대답해야 합니다.

172da43f310a0579.png

새 탭에서 Gmail을 열고 다음 단계를 따르세요.

  1. 제목We need to talk로 설정되고 본문Are you available today between 8 and 9 AM?로 설정된 이메일을 자신에게 보냅니다.
  2. 새로 수신된 이메일을 엽니다.
  3. Vertex AI 부가기능 사이드바를 엽니다.
  4. 메시지Do I have any meeting conflicts?로 설정합니다.
  5. 메시지 보내기를 클릭합니다.
  6. 답변은 버튼 뒤에 표시됩니다.

840b494aa5eaa1ef.png

6. 삭제

Google Cloud 프로젝트 삭제

이 Codelab에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 Google Cloud 프로젝트를 삭제하는 것이 좋습니다.

Google Cloud 콘솔에서 다음 단계를 따르세요.

  1. 메뉴 ☰ > IAM 및 관리자 > 설정을 클릭합니다.

  1. 종료를 클릭합니다.
  2. 프로젝트 ID를 입력합니다.
  3. 무시하고 종료를 클릭합니다.

3b9492d97f771b2c.png

7. 축하합니다

축하합니다. Vertex AI와 Google Workspace를 더 가깝게 연결하여 작업자를 위한 솔루션을 빌드했습니다.

다음 단계

이 Codelab에서는 가장 일반적인 사용 사례만 보여드렸지만, 솔루션에서 고려해 볼 만한 다양한 확대 영역이 있습니다. 예를 들면 다음과 같습니다.

  • Gemini CLI, Antigravity와 같은 AI 기반 개발자 도구를 사용하세요.
  • 맞춤 MCP, 맞춤 함수 호출, 생성형 UI와 같은 다른 에이전트 프레임워크 및 도구와 통합
  • Vertex AI와 같은 전용 플랫폼에서 호스팅되는 커스텀 모델을 비롯한 다른 AI 모델과 통합
  • Dialogflow와 같은 전용 플랫폼에서 호스팅되거나 Cloud Marketplace를 통해 서드 파티에서 호스팅되는 다른 에이전트와 통합
  • Cloud Marketplace에 에이전트를 게시하여 팀, 조직 또는 공개 사용자를 지원합니다.

자세히 알아보기

YouTube 동영상, 문서 웹사이트, 코드 샘플, 가이드 등 개발자를 위한 다양한 리소스가 마련되어 있습니다.