Manual Deploy — Agent Engine 수동 배포
Agent Studio 의 “Deploy” 버튼은 편리하지만, 내부적으로 사용하는 google-adk SDK 버전이 빠르게 업데이트되지 않아 GE 호환 메서드 (streaming_agent_run_with_events) 가 누락된 reasoning engine 이 만들어지는 경우가 있습니다. 이때는 로컬에서 Python 스크립트로 직접 deploy 하여 SDK 버전을 명시적으로 pin 해야 합니다.
본 챕터의 절차는 Troubleshooting 6 — InvocationMethodNotFoundError 와 짝을 이룹니다.
목차
1. 언제 manual deploy 가 필요한가
| 상황 | Manual deploy 필요? |
|---|---|
| Agent Studio 에서 deploy 후 GE 가 정상 응답 | ❌ 불필요 |
streaming_agent_run_with_events not found 로그 |
✅ 필요 |
| Tool / instruction 을 자주 변경하며 빠르게 iterate | ✅ 권장 (자동화 용이) |
| Studio UI 에 없는 ADK feature (custom callback, memory, planner 등) 사용 | ✅ 필요 |
| Compliance / 코드 리뷰 대상 (배포 코드를 git 관리 필요) | ✅ 필요 |
2. 사전 준비
2.1 SDK 설치
pip install -U \
"google-adk>=1.19" \
"google-cloud-aiplatform[adk,agent_engines]" \
"vertexai"
2.2 GCP 인증
gcloud auth application-default login
gcloud config set project <YOUR_PROJECT>
2.3 Staging 버킷
Deploy 시 ADK 코드 + dependency 가 gs://<bucket>/agent_engine/... 로 업로드됩니다.
| 옵션 | 권장도 |
|---|---|
Deploy 프로젝트 안에 전용 버킷 (gs://<project>-agent-engine-staging) |
⭐ 가장 간단 |
| 기존 공용 버킷 재사용 | 가능하지만 cross-project 권한 부여 필요 — Troubleshooting 7 참조 |
2.4 권한 (deploy 실행 주체)
roles/aiplatform.userroles/storage.objectAdmin(staging 버킷)roles/discoveryengine.editor(Vertex AI Search 도구 사용 시)
3. Deploy 스크립트 전체
scripts/deploy_agent.py:
"""
Agent Engine manual deploy.
요구: google-adk>=1.19, google-cloud-aiplatform[adk,agent_engines]
"""
import vertexai
from vertexai import agent_engines
from vertexai.preview.reasoning_engines import AdkApp
from google.adk.agents import LlmAgent
from google.adk.tools import agent_tool, url_context, VertexAiSearchTool
from google.adk.tools.google_search_tool import GoogleSearchTool
# ── 설정 ──
PROJECT = "<YOUR_PROJECT>"
LOCATION = "us-west1" # us-central1 / asia-northeast3 도 가능
STAGING_BUCKET = "gs://<staging-bucket>"
DATA_STORE = (
"projects/<YOUR_PROJECT>/locations/global/collections/"
"default_collection/dataStores/<YOUR_DATA_STORE_ID>"
)
vertexai.init(project=PROJECT, location=LOCATION, staging_bucket=STAGING_BUCKET)
# ── Sub-agents ──
google_search_agent = LlmAgent(
name="google_search_agent",
model="gemini-2.5-pro",
description="Agent specialized in performing Google searches.",
instruction="Use the GoogleSearchTool to find information on the web.",
tools=[GoogleSearchTool()],
)
url_context_agent = LlmAgent(
name="url_context_agent",
model="gemini-2.5-pro",
description="Agent specialized in fetching content from URLs.",
instruction="Use the UrlContextTool to retrieve content from provided URLs.",
tools=[url_context],
)
vertex_ai_search_agent = LlmAgent(
name="vertex_ai_search_agent",
model="gemini-2.5-pro",
description="Agent specialized in performing Vertex AI Search.",
instruction="Use the VertexAISearchTool to find information using Vertex AI Search.",
tools=[VertexAiSearchTool(data_store_id=DATA_STORE)],
)
# ── Root agent ──
root_agent = LlmAgent(
name="my_root_agent",
model="gemini-2.5-pro",
description="자동차 세일즈 에이전트 데모",
instruction=(
"사용자의 질문에 답변할 때 반드시 참조한 문서의 파일명과 관련 내용을 함께 명시하세요.\n"
"1. vertex_ai_search 도구의 모든 검색 결과에는 `uri` (또는 `link`) 필드에 "
"GCS 경로가 포함됩니다. 반드시 GCS 경로 자체를 참고로 나열하세요."
),
tools=[
agent_tool.AgentTool(agent=google_search_agent),
agent_tool.AgentTool(agent=url_context_agent),
agent_tool.AgentTool(agent=vertex_ai_search_agent),
],
)
# ── 핵심: AdkApp wrap + 최신 SDK pin ──
app = AdkApp(agent=root_agent, enable_tracing=True)
print("=== 배포 시작 (10~15분 소요) ===")
remote = agent_engines.create(
app,
display_name="My Agent (manual)",
requirements=[
"google-adk>=1.19",
"google-cloud-aiplatform[adk,agent_engines]",
],
)
print()
print("=== 배포 완료 ===")
print(f"resource_name: {remote.resource_name}")
4. 실행
python scripts/deploy_agent.py
진행 단계 (로그 예시):
=== 배포 시작 (10~15분 소요) ===
Identified the following requirements: {'cloudpickle': '...', 'pydantic': '...', ...}
Using bucket <staging-bucket>
Wrote to gs://<staging-bucket>/agent_engine/agent_engine.pkl
Writing to gs://<staging-bucket>/agent_engine/requirements.txt
Creating in-memory tarfile of extra_packages
Writing to gs://<staging-bucket>/agent_engine/dependencies.tar.gz
Bidi stream API mode is not supported yet in Vertex SDK ... Skipping method bidi_stream_query.
Creating AgentEngine
Create AgentEngine backing LRO: projects/<NUM>/locations/.../reasoningEngines/<ID>/operations/<OP>
...
AgentEngine created. Resource name: projects/<NUM>/locations/.../reasoningEngines/<ID>
⚠️ “Bidi stream API mode is not supported yet” 메시지는 정상입니다 — Vertex SDK 가 아직 양방향 스트리밍을 미지원해서 자동 skip 합니다.
5. 노출 메서드 검증
ENGINE_ID="<NEW_ID>"
PROJECT="<YOUR_PROJECT>"
LOCATION="us-west1"
curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${LOCATION}-aiplatform.googleapis.com/v1/projects/${PROJECT}/locations/${LOCATION}/reasoningEngines/${ENGINE_ID}" \
| python -c "import sys, json; d=json.load(sys.stdin); methods=d.get('spec',{}).get('classMethods', d.get('classMethods', [])); print(f'총 {len(methods)}개:'); [print(' -', m.get('name','?')) for m in methods]"
정상 출력 (총 13개):
총 13개:
- get_session
- list_sessions
- create_session
- delete_session
- async_get_session
- async_list_sessions
- async_create_session
- async_delete_session
- async_add_session_to_memory
- async_search_memory
- stream_query
- streaming_agent_run_with_events ← ★ 이게 있으면 GE 호환 OK ★
- async_stream_query
streaming_agent_run_with_events 가 없다면 SDK 버전 / AdkApp wrap 누락 의심.
6. GE 에 등록
- Gemini Enterprise → 해당 App / Agent 페이지
- (기존 등록이 있으면) Unregister / Delete agent
- Add agent → “ADK” / “Agent Engine” 모드 선택
resource_name입력:projects/<PROJECT_NUMBER>/locations/<LOCATION>/reasoningEngines/<NEW_ID>- 저장 후 대화 테스트
A2A 모드와 ADK 모드는 다른 API 스펙입니다. 본 manual deploy 산출물은 ADK 모드 전용 — A2A 로 노출하려면 A2A 모드 비교 챕터 참조.
7. 업데이트와 정리
7.1 같은 에이전트를 업데이트 (코드 / 도구 / instruction 수정)
remote = agent_engines.update(
resource_name="projects/<PROJECT_NUMBER>/locations/<LOCATION>/reasoningEngines/<ID>",
agent_engine=app,
requirements=[...],
)
장점: GE 재등록 불필요 — 같은 ID 유지.
7.2 좀비 / 구버전 reasoning engine 삭제
Studio v1, v2 등 더 이상 안 쓰는 reasoning engine 은 비용 발생을 피하기 위해 삭제:
# GE 등록 먼저 제거한 후
gcloud beta ai reasoning-engines delete <ZOMBIE_ID> \
--location=<LOCATION> --project=<YOUR_PROJECT>
7.3 비용 관리
Reasoning Engine 은 호출이 없어도 컨테이너 idle 비용이 발생합니다. PoC 가 끝나면 반드시 삭제하거나 Cloud Scheduler 로 영업시간 외 강제 종료 / 자동 cleanup 스크립트 운용을 권장합니다.