agent-starter-pack 0.18.2__py3-none-any.whl → 0.21.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. agent_starter_pack/agents/{langgraph_base_react → adk_a2a_base}/.template/templateconfig.yaml +5 -12
  2. agent_starter_pack/agents/adk_a2a_base/README.md +37 -0
  3. agent_starter_pack/{frontends/streamlit/frontend/style/app_markdown.py → agents/adk_a2a_base/app/__init__.py} +3 -23
  4. agent_starter_pack/agents/adk_a2a_base/app/agent.py +70 -0
  5. agent_starter_pack/agents/adk_a2a_base/notebooks/adk_a2a_app_testing.ipynb +583 -0
  6. agent_starter_pack/agents/{crewai_coding_crew/notebooks/evaluating_crewai_agent.ipynb → adk_a2a_base/notebooks/evaluating_adk_agent.ipynb} +163 -199
  7. agent_starter_pack/agents/adk_a2a_base/tests/integration/test_agent.py +58 -0
  8. agent_starter_pack/agents/adk_base/app/__init__.py +2 -2
  9. agent_starter_pack/agents/adk_base/app/agent.py +3 -0
  10. agent_starter_pack/agents/adk_base/notebooks/adk_app_testing.ipynb +13 -28
  11. agent_starter_pack/agents/adk_live/app/__init__.py +17 -0
  12. agent_starter_pack/agents/adk_live/app/agent.py +3 -0
  13. agent_starter_pack/agents/agentic_rag/app/__init__.py +2 -2
  14. agent_starter_pack/agents/agentic_rag/app/agent.py +3 -0
  15. agent_starter_pack/agents/agentic_rag/notebooks/adk_app_testing.ipynb +13 -28
  16. agent_starter_pack/agents/{crewai_coding_crew → langgraph_base}/.template/templateconfig.yaml +12 -9
  17. agent_starter_pack/agents/langgraph_base/README.md +30 -0
  18. agent_starter_pack/agents/langgraph_base/app/__init__.py +17 -0
  19. agent_starter_pack/agents/{langgraph_base_react → langgraph_base}/app/agent.py +4 -4
  20. agent_starter_pack/agents/{langgraph_base_react → langgraph_base}/tests/integration/test_agent.py +1 -1
  21. agent_starter_pack/base_template/.gitignore +4 -2
  22. agent_starter_pack/base_template/Makefile +110 -16
  23. agent_starter_pack/base_template/README.md +97 -12
  24. agent_starter_pack/base_template/deployment/terraform/dev/apis.tf +4 -6
  25. agent_starter_pack/base_template/deployment/terraform/dev/providers.tf +5 -1
  26. agent_starter_pack/base_template/deployment/terraform/dev/variables.tf +5 -3
  27. agent_starter_pack/base_template/deployment/terraform/dev/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +193 -0
  28. agent_starter_pack/base_template/deployment/terraform/github.tf +16 -9
  29. agent_starter_pack/base_template/deployment/terraform/locals.tf +7 -7
  30. agent_starter_pack/base_template/deployment/terraform/providers.tf +5 -1
  31. agent_starter_pack/base_template/deployment/terraform/sql/completions.sql +138 -0
  32. agent_starter_pack/base_template/deployment/terraform/storage.tf +0 -9
  33. agent_starter_pack/base_template/deployment/terraform/variables.tf +15 -19
  34. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}build_triggers.tf{% else %}unused_build_triggers.tf{% endif %} +20 -22
  35. agent_starter_pack/base_template/deployment/terraform/{% if cookiecutter.is_adk %}telemetry.tf{% else %}unused_telemetry.tf{% endif %} +206 -0
  36. agent_starter_pack/base_template/pyproject.toml +5 -17
  37. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/deploy-to-prod.yaml +19 -4
  38. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'github_actions' %}.github{% else %}unused_github{% endif %}/workflows/staging.yaml +36 -11
  39. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/deploy-to-prod.yaml +24 -5
  40. agent_starter_pack/base_template/{% if cookiecutter.cicd_runner == 'google_cloud_build' %}.cloudbuild{% else %}unused_.cloudbuild{% endif %}/staging.yaml +44 -9
  41. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/telemetry.py +96 -0
  42. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/{utils → app_utils}/typing.py +4 -6
  43. agent_starter_pack/{agents/crewai_coding_crew/app/crew/config/agents.yaml → base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/__init__.py } +9 -23
  44. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}converters{% else %}unused_converters{% endif %}/part_converter.py +138 -0
  45. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/__init__.py +13 -0
  46. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/a2a_agent_executor.py +265 -0
  47. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/app_utils/{% if cookiecutter.is_a2a and cookiecutter.agent_name == 'langgraph_base' %}executor{% else %}unused_executor{% endif %}/task_result_aggregator.py +152 -0
  48. agent_starter_pack/cli/commands/create.py +40 -4
  49. agent_starter_pack/cli/commands/enhance.py +1 -1
  50. agent_starter_pack/cli/commands/register_gemini_enterprise.py +1070 -0
  51. agent_starter_pack/cli/main.py +2 -0
  52. agent_starter_pack/cli/utils/cicd.py +20 -4
  53. agent_starter_pack/cli/utils/template.py +257 -25
  54. agent_starter_pack/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +113 -16
  55. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/README.md +2 -2
  56. agent_starter_pack/deployment_targets/agent_engine/tests/load_test/load_test.py +178 -9
  57. agent_starter_pack/deployment_targets/agent_engine/tests/{% if cookiecutter.is_a2a %}helpers.py{% else %}unused_helpers.py{% endif %} +138 -0
  58. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/agent_engine_app.py +193 -307
  59. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/app_utils/deploy.py +414 -0
  60. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/{utils → app_utils}/{% if cookiecutter.is_adk_live %}expose_app.py{% else %}unused_expose_app.py{% endif %} +13 -14
  61. agent_starter_pack/deployment_targets/cloud_run/Dockerfile +4 -1
  62. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/dev/service.tf +85 -86
  63. agent_starter_pack/deployment_targets/cloud_run/deployment/terraform/service.tf +139 -107
  64. agent_starter_pack/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +228 -12
  65. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/README.md +4 -4
  66. agent_starter_pack/deployment_targets/cloud_run/tests/load_test/load_test.py +92 -12
  67. agent_starter_pack/deployment_targets/cloud_run/{{cookiecutter.agent_directory}}/{server.py → fast_api_app.py} +194 -121
  68. agent_starter_pack/frontends/adk_live_react/frontend/package-lock.json +18 -18
  69. agent_starter_pack/frontends/adk_live_react/frontend/src/multimodal-live-types.ts +5 -3
  70. agent_starter_pack/resources/docs/adk-cheatsheet.md +198 -41
  71. agent_starter_pack/resources/locks/uv-adk_a2a_base-agent_engine.lock +4966 -0
  72. agent_starter_pack/resources/locks/uv-adk_a2a_base-cloud_run.lock +5011 -0
  73. agent_starter_pack/resources/locks/uv-adk_base-agent_engine.lock +1443 -709
  74. agent_starter_pack/resources/locks/uv-adk_base-cloud_run.lock +1058 -874
  75. agent_starter_pack/resources/locks/uv-adk_live-agent_engine.lock +1443 -709
  76. agent_starter_pack/resources/locks/uv-adk_live-cloud_run.lock +1058 -874
  77. agent_starter_pack/resources/locks/uv-agentic_rag-agent_engine.lock +1568 -749
  78. agent_starter_pack/resources/locks/uv-agentic_rag-cloud_run.lock +1123 -929
  79. agent_starter_pack/resources/locks/{uv-langgraph_base_react-agent_engine.lock → uv-langgraph_base-agent_engine.lock} +1714 -1689
  80. agent_starter_pack/resources/locks/{uv-langgraph_base_react-cloud_run.lock → uv-langgraph_base-cloud_run.lock} +1285 -2374
  81. agent_starter_pack/utils/watch_and_rebuild.py +1 -1
  82. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/METADATA +3 -6
  83. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/RECORD +89 -93
  84. agent_starter_pack-0.21.0.dist-info/entry_points.txt +2 -0
  85. llm.txt +4 -5
  86. agent_starter_pack/agents/crewai_coding_crew/README.md +0 -34
  87. agent_starter_pack/agents/crewai_coding_crew/app/agent.py +0 -47
  88. agent_starter_pack/agents/crewai_coding_crew/app/crew/config/tasks.yaml +0 -37
  89. agent_starter_pack/agents/crewai_coding_crew/app/crew/crew.py +0 -71
  90. agent_starter_pack/agents/crewai_coding_crew/tests/integration/test_agent.py +0 -47
  91. agent_starter_pack/agents/langgraph_base_react/README.md +0 -9
  92. agent_starter_pack/agents/langgraph_base_react/notebooks/evaluating_langgraph_agent.ipynb +0 -1574
  93. agent_starter_pack/base_template/deployment/terraform/dev/log_sinks.tf +0 -69
  94. agent_starter_pack/base_template/deployment/terraform/log_sinks.tf +0 -79
  95. agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/utils/tracing.py +0 -155
  96. agent_starter_pack/cli/utils/register_gemini_enterprise.py +0 -406
  97. agent_starter_pack/deployment_targets/agent_engine/deployment/terraform/{% if not cookiecutter.is_adk_live %}service.tf{% else %}unused_service.tf{% endif %} +0 -82
  98. agent_starter_pack/deployment_targets/agent_engine/notebooks/intro_agent_engine.ipynb +0 -1025
  99. agent_starter_pack/deployment_targets/agent_engine/{{cookiecutter.agent_directory}}/utils/deployment.py +0 -99
  100. agent_starter_pack/frontends/streamlit/frontend/side_bar.py +0 -214
  101. agent_starter_pack/frontends/streamlit/frontend/streamlit_app.py +0 -265
  102. agent_starter_pack/frontends/streamlit/frontend/utils/chat_utils.py +0 -67
  103. agent_starter_pack/frontends/streamlit/frontend/utils/local_chat_history.py +0 -127
  104. agent_starter_pack/frontends/streamlit/frontend/utils/message_editing.py +0 -59
  105. agent_starter_pack/frontends/streamlit/frontend/utils/multimodal_utils.py +0 -217
  106. agent_starter_pack/frontends/streamlit/frontend/utils/stream_handler.py +0 -310
  107. agent_starter_pack/frontends/streamlit/frontend/utils/title_summary.py +0 -94
  108. agent_starter_pack/resources/locks/uv-crewai_coding_crew-agent_engine.lock +0 -6650
  109. agent_starter_pack/resources/locks/uv-crewai_coding_crew-cloud_run.lock +0 -7825
  110. agent_starter_pack-0.18.2.dist-info/entry_points.txt +0 -3
  111. /agent_starter_pack/agents/{crewai_coding_crew → langgraph_base}/notebooks/evaluating_langgraph_agent.ipynb +0 -0
  112. /agent_starter_pack/base_template/{{cookiecutter.agent_directory}}/{utils → app_utils}/gcs.py +0 -0
  113. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/WHEEL +0 -0
  114. {agent_starter_pack-0.18.2.dist-info → agent_starter_pack-0.21.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,1025 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": null,
6
- "metadata": {
7
- "id": "ijGzTHJJUCPY"
8
- },
9
- "outputs": [],
10
- "source": [
11
- "# Copyright 2024 Google LLC\n",
12
- "#\n",
13
- "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
14
- "# you may not use this file except in compliance with the License.\n",
15
- "# You may obtain a copy of the License at\n",
16
- "#\n",
17
- "# https://www.apache.org/licenses/LICENSE-2.0\n",
18
- "#\n",
19
- "# Unless required by applicable law or agreed to in writing, software\n",
20
- "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
21
- "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
22
- "# See the License for the specific language governing permissions and\n",
23
- "# limitations under the License."
24
- ]
25
- },
26
- {
27
- "cell_type": "markdown",
28
- "metadata": {
29
- "id": "VEqbX8OhE8y9"
30
- },
31
- "source": [
32
- "# Intro to Building and Deploying an Agent with Agent Engine in Vertex AI\n",
33
- "\n",
34
- "<table align=\"left\">\n",
35
- " <td style=\"text-align: center\">\n",
36
- " <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\">\n",
37
- " <img src=\"https://cloud.google.com/ml-engine/images/colab-logo-32px.png\" alt=\"Google Colaboratory logo\"><br> Run in Colab\n",
38
- " </a>\n",
39
- " </td>\n",
40
- " <td style=\"text-align: center\">\n",
41
- " <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Fintro_agent_engine.ipynb\">\n",
42
- " <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Run in Colab Enterprise\n",
43
- " </a>\n",
44
- " </td> \n",
45
- " <td style=\"text-align: center\">\n",
46
- " <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\">\n",
47
- " <img src=\"https://cloud.google.com/ml-engine/images/github-logo-32px.png\" alt=\"GitHub logo\"><br> View on GitHub\n",
48
- " </a>\n",
49
- " </td>\n",
50
- " <td style=\"text-align: center\">\n",
51
- " <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/intro_agent_engine.ipynb\">\n",
52
- " <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Vertex AI Workbench\n",
53
- " </a>\n",
54
- " </td>\n",
55
- " <td style=\"text-align: center\">\n",
56
- " <a href=\"https://goo.gle/4jeQzJW\">\n",
57
- " <img width=\"32px\" src=\"https://cdn.qwiklabs.com/assets/gcp_cloud-e3a77215f0b8bfa9b3f611c0d2208c7e8708ed31.svg\" alt=\"Google Cloud logo\"><br> Open in Cloud Skills Boost\n",
58
- " </a>\n",
59
- " </td>\n",
60
- "</table>\n",
61
- "\n",
62
- "<div style=\"clear: both;\"></div>\n",
63
- "\n",
64
- "<b>Share to:</b>\n",
65
- "\n",
66
- "<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
67
- " <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
68
- "</a>\n",
69
- "\n",
70
- "<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
71
- " <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
72
- "</a>\n",
73
- "\n",
74
- "<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
75
- " <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
76
- "</a>\n",
77
- "\n",
78
- "<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
79
- " <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
80
- "</a>\n",
81
- "\n",
82
- "<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/intro_agent_engine.ipynb\" target=\"_blank\">\n",
83
- " <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
84
- "</a> \n"
85
- ]
86
- },
87
- {
88
- "cell_type": "markdown",
89
- "metadata": {
90
- "id": "84e7e432e6ff"
91
- },
92
- "source": [
93
- "| | |\n",
94
- "|-|-|\n",
95
- "|Author(s) | [Kristopher Overholt](https://github.com/koverholt) |"
96
- ]
97
- },
98
- {
99
- "attachments": {},
100
- "cell_type": "markdown",
101
- "metadata": {
102
- "id": "CkHPv2myT2cx"
103
- },
104
- "source": [
105
- "## Overview\n",
106
- "\n",
107
- "### Gemini\n",
108
- "\n",
109
- "Gemini is a family of generative AI models developed by Google DeepMind that is designed for multimodal use cases.\n",
110
- "\n",
111
- "### Function Calling in Gemini\n",
112
- "\n",
113
- "[Function calling](https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/function-calling) lets developers create a description of a function in their code, then pass that description to a language model in a request. The response from the model includes the name of a function that matches the description and the arguments to call it with.\n",
114
- "\n",
115
- "### Agent Engine in Vertex AI\n",
116
- "\n",
117
- "[Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) is a managed service that helps you to build and deploy an agent framework. It gives you the flexibility to choose how much reasoning you want to delegate to the LLM and how much you want to handle with customized code. You can define Python functions that get used as tools via [Gemini Function Calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling). Agent Engine integrates closely with the Python SDK for the Gemini model in Vertex AI, and it can manage prompts, agents, and examples in a modular way. Agent Engine is compatible with LangChain, LlamaIndex, or other Python frameworks.\n",
118
- "\n",
119
- "<img width=\"60%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-engine-overview.png\" alt=\"Agent Engine on Vertex AI\" />"
120
- ]
121
- },
122
- {
123
- "cell_type": "markdown",
124
- "metadata": {
125
- "id": "DrkcqHrrwMAo"
126
- },
127
- "source": [
128
- "### Objectives\n",
129
- "\n",
130
- "In this tutorial, you will learn how to build and deploy an agent (model, tools, and reasoning) using the Vertex AI SDK for Python.\n",
131
- "\n",
132
- "You'll build and deploy an agent that uses the Gemini Pro model, Python functions as tools, and LangChain for orchestration.\n",
133
- "\n",
134
- "You will complete the following tasks:\n",
135
- "\n",
136
- "- Install the Vertex AI SDK for Python\n",
137
- "- Use the Vertex AI SDK to build components of a simple agent\n",
138
- "- Test your agent locally before deploying\n",
139
- "- Deploy and test your agent on Vertex AI\n",
140
- "- Customize each layer of your agent (model, tools, orchestration)"
141
- ]
142
- },
143
- {
144
- "cell_type": "markdown",
145
- "metadata": {
146
- "id": "C9nEPojogw-g"
147
- },
148
- "source": [
149
- "### Costs\n",
150
- "\n",
151
- "This tutorial uses billable components of Google Cloud:\n",
152
- "\n",
153
- "- Vertex AI\n",
154
- "\n",
155
- "Learn about [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) and use the [Pricing Calculator](https://cloud.google.com/products/calculator/) to generate a cost estimate based on your projected usage.\n"
156
- ]
157
- },
158
- {
159
- "cell_type": "markdown",
160
- "metadata": {
161
- "id": "r11Gu7qNgx1p"
162
- },
163
- "source": [
164
- "## Getting Started\n"
165
- ]
166
- },
167
- {
168
- "cell_type": "markdown",
169
- "metadata": {
170
- "id": "No17Cw5hgx12"
171
- },
172
- "source": [
173
- "### Install Vertex AI SDK for Python\n",
174
- "\n",
175
- "Install the latest version of the Vertex AI SDK for Python as well as extra dependencies related to Agent Engine and LangChain:"
176
- ]
177
- },
178
- {
179
- "cell_type": "code",
180
- "execution_count": 1,
181
- "metadata": {
182
- "id": "tFy3H3aPgx12"
183
- },
184
- "outputs": [],
185
- "source": [
186
- "%pip install --upgrade --quiet \\\n",
187
- " \"google-cloud-aiplatform[agent_engines,langchain]\" \\\n",
188
- " cloudpickle==3.0.0 \\\n",
189
- " \"pydantic>=2.10\" \\\n",
190
- " requests"
191
- ]
192
- },
193
- {
194
- "cell_type": "markdown",
195
- "metadata": {
196
- "id": "R5Xep4W9lq-Z"
197
- },
198
- "source": [
199
- "### Restart current runtime\n",
200
- "\n",
201
- "To use the newly installed packages in this Jupyter runtime, you must restart the runtime. You can do this by running the cell below, which will restart the current kernel."
202
- ]
203
- },
204
- {
205
- "cell_type": "code",
206
- "execution_count": 2,
207
- "metadata": {
208
- "id": "XRvKdaPDTznN"
209
- },
210
- "outputs": [],
211
- "source": [
212
- "# Restart kernel after installs so that your environment can access the new packages\n",
213
- "import IPython\n",
214
- "\n",
215
- "app = IPython.Application.instance()\n",
216
- "app.kernel.do_shutdown(True)"
217
- ]
218
- },
219
- {
220
- "cell_type": "markdown",
221
- "metadata": {
222
- "id": "SbmM4z7FOBpM"
223
- },
224
- "source": [
225
- "<div class=\"alert alert-block alert-warning\">\n",
226
- "<b>⚠️ The kernel is going to restart. Please wait until it is finished before continuing to the next step. ⚠️</b>\n",
227
- "</div>\n"
228
- ]
229
- },
230
- {
231
- "cell_type": "markdown",
232
- "metadata": {
233
- "id": "dmWOrTJ3gx13"
234
- },
235
- "source": [
236
- "### Authenticate your notebook environment (Colab only)\n",
237
- "\n",
238
- "If you are running this notebook on Google Colab, run the following cell to authenticate your environment. This step is not required if you are using [Vertex AI Workbench](https://cloud.google.com/vertex-ai-workbench)."
239
- ]
240
- },
241
- {
242
- "cell_type": "code",
243
- "execution_count": 3,
244
- "metadata": {
245
- "id": "NyKGtVQjgx13"
246
- },
247
- "outputs": [],
248
- "source": [
249
- "import sys\n",
250
- "\n",
251
- "if \"google.colab\" in sys.modules:\n",
252
- " from google.colab import auth\n",
253
- "\n",
254
- " auth.authenticate_user()"
255
- ]
256
- },
257
- {
258
- "cell_type": "markdown",
259
- "metadata": {
260
- "id": "DF4l8DTdWgPY"
261
- },
262
- "source": [
263
- "### Set Google Cloud project information and initialize Vertex AI SDK\n",
264
- "\n",
265
- "To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
266
- "\n",
267
- "Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
268
- ]
269
- },
270
- {
271
- "cell_type": "code",
272
- "execution_count": 4,
273
- "metadata": {
274
- "id": "Nqwi-5ufWp_B"
275
- },
276
- "outputs": [],
277
- "source": [
278
- "PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
279
- "LOCATION = \"us-central1\" # @param {type:\"string\"}\n",
280
- "STAGING_BUCKET = \"gs://[your-staging-bucket]\" # @param {type:\"string\"}\n",
281
- "\n",
282
- "import vertexai\n",
283
- "\n",
284
- "vertexai.init(project=PROJECT_ID, location=LOCATION, staging_bucket=STAGING_BUCKET)"
285
- ]
286
- },
287
- {
288
- "cell_type": "markdown",
289
- "metadata": {
290
- "id": "1e5c96372296"
291
- },
292
- "source": [
293
- "## Example: Build and deploy an agent"
294
- ]
295
- },
296
- {
297
- "cell_type": "markdown",
298
- "metadata": {
299
- "id": "jXHfaVS66_01"
300
- },
301
- "source": [
302
- "### Import libraries"
303
- ]
304
- },
305
- {
306
- "cell_type": "code",
307
- "execution_count": 5,
308
- "metadata": {
309
- "id": "lslYAvw37JGQ"
310
- },
311
- "outputs": [],
312
- "source": [
313
- "from vertexai import agent_engines"
314
- ]
315
- },
316
- {
317
- "cell_type": "markdown",
318
- "metadata": {
319
- "id": "43c61bf4c3f5"
320
- },
321
- "source": [
322
- "### Define model"
323
- ]
324
- },
325
- {
326
- "cell_type": "markdown",
327
- "metadata": {
328
- "id": "f685ca44c1e9"
329
- },
330
- "source": [
331
- "As you construct your agent from the bottom up, the first component deals with which generative model you want to use in your agent.\n",
332
- "\n",
333
- "<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-1.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
334
- "\n",
335
- "Here you'll use the Gemini 1.5 Pro model:"
336
- ]
337
- },
338
- {
339
- "cell_type": "code",
340
- "execution_count": 6,
341
- "metadata": {
342
- "id": "921890fcb875"
343
- },
344
- "outputs": [],
345
- "source": [
346
- "model = \"gemini-1.5-pro\""
347
- ]
348
- },
349
- {
350
- "cell_type": "markdown",
351
- "metadata": {
352
- "id": "60eba5468448"
353
- },
354
- "source": [
355
- "### Define Python functions (tools)\n",
356
- "\n",
357
- "The second component of your agent includes tools and functions, which enable the generative model to interact with external systems, databases, document stores, and other APIs so that the model can get the most up-to-date information or take action with those systems.\n",
358
- "\n",
359
- "<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-2.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
360
- "\n",
361
- "In this example, you'll define a function called `get_exchange_rate` that uses the `requests` library to retrieve real-time currency exchange information from an API:"
362
- ]
363
- },
364
- {
365
- "cell_type": "code",
366
- "execution_count": 7,
367
- "metadata": {
368
- "id": "ff7991bf37bf"
369
- },
370
- "outputs": [],
371
- "source": [
372
- "def get_exchange_rate(\n",
373
- " currency_from: str = \"USD\",\n",
374
- " currency_to: str = \"EUR\",\n",
375
- " currency_date: str = \"latest\",\n",
376
- "):\n",
377
- " \"\"\"Retrieves the exchange rate between two currencies on a specified date.\"\"\"\n",
378
- " import requests\n",
379
- "\n",
380
- " response = requests.get(\n",
381
- " f\"https://api.frankfurter.app/{currency_date}\",\n",
382
- " params={\"from\": currency_from, \"to\": currency_to},\n",
383
- " )\n",
384
- " return response.json()"
385
- ]
386
- },
387
- {
388
- "cell_type": "markdown",
389
- "metadata": {
390
- "id": "971f56c167e7"
391
- },
392
- "source": [
393
- "Test the function with sample inputs to ensure that it's working as expected:"
394
- ]
395
- },
396
- {
397
- "cell_type": "code",
398
- "execution_count": 8,
399
- "metadata": {
400
- "id": "4ae49a2ccd2e"
401
- },
402
- "outputs": [
403
- {
404
- "data": {
405
- "text/plain": [
406
- "{'amount': 1.0, 'base': 'USD', 'date': '2025-01-22', 'rates': {'SEK': 10.9806}}"
407
- ]
408
- },
409
- "execution_count": 8,
410
- "metadata": {},
411
- "output_type": "execute_result"
412
- }
413
- ],
414
- "source": [
415
- "get_exchange_rate(currency_from=\"USD\", currency_to=\"SEK\")"
416
- ]
417
- },
418
- {
419
- "cell_type": "markdown",
420
- "metadata": {
421
- "id": "35ca52a9021c"
422
- },
423
- "source": [
424
- "### Define agent\n",
425
- "\n",
426
- "The third component of your agent involves adding a reasoning layer, which helps your agent use the tools that you provided to help the end user achieve a higher-level goal.\n",
427
- "\n",
428
- "<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-3.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
429
- "\n",
430
- "If you were to use Gemini and Function Calling on their own without a reasoning layer, you would need to handle the process of calling functions and APIs in your application code, and you would need to implement retries and additional logic to ensure that your function calling code is resilient to failures and malformed requests.\n",
431
- "\n",
432
- "Here, you'll use the LangChain agent template provided in the Vertex AI SDK for Agent Engine, which brings together the model, tools, and reasoning that you've built up so far:"
433
- ]
434
- },
435
- {
436
- "cell_type": "code",
437
- "execution_count": 9,
438
- "metadata": {
439
- "id": "68bc1b395f9d"
440
- },
441
- "outputs": [],
442
- "source": [
443
- "agent = agent_engines.LangchainAgent(\n",
444
- " model=model,\n",
445
- " tools=[get_exchange_rate],\n",
446
- " agent_executor_kwargs={\"return_intermediate_steps\": True},\n",
447
- ")"
448
- ]
449
- },
450
- {
451
- "cell_type": "markdown",
452
- "metadata": {
453
- "id": "fa3c33f6ec72"
454
- },
455
- "source": [
456
- "Now we can test the model and agent behavior to ensure that it's working as expected before we deploy it:"
457
- ]
458
- },
459
- {
460
- "cell_type": "markdown",
461
- "metadata": {
462
- "id": "68a527f87e42"
463
- },
464
- "source": [
465
- "### Test your agent locally\n",
466
- "\n",
467
- "With all of the core components of your agent in place, you can send a prompt to your agent using `.query` to test that it's working as expected, including the intermediate steps that the agent performed between the input prompt and the generated summary output. In the default mode, the agent processes your input and returns the **entire agent output in a single response when complete**:"
468
- ]
469
- },
470
- {
471
- "cell_type": "code",
472
- "execution_count": 10,
473
- "metadata": {
474
- "id": "e0c5c699de12"
475
- },
476
- "outputs": [
477
- {
478
- "data": {
479
- "text/plain": [
480
- "{'input': \"What's the exchange rate from US dollars to Swedish currency today?\",\n",
481
- " 'output': 'The exchange rate from US dollars to Swedish krona is 1 USD to 10.9806 SEK. \\n',\n",
482
- " 'intermediate_steps': [[{'lc': 1,\n",
483
- " 'type': 'constructor',\n",
484
- " 'id': ['langchain', 'schema', 'agent', 'ToolAgentAction'],\n",
485
- " 'kwargs': {'tool': 'get_exchange_rate',\n",
486
- " 'tool_input': {'currency_from': 'USD', 'currency_to': 'SEK'},\n",
487
- " 'log': \"\\nInvoking: `get_exchange_rate` with `{'currency_from': 'USD', 'currency_to': 'SEK'}`\\n\\n\\n\",\n",
488
- " 'type': 'AgentActionMessageLog',\n",
489
- " 'message_log': [{'lc': 1,\n",
490
- " 'type': 'constructor',\n",
491
- " 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'],\n",
492
- " 'kwargs': {'content': '',\n",
493
- " 'additional_kwargs': {'function_call': {'name': 'get_exchange_rate',\n",
494
- " 'arguments': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}'}},\n",
495
- " 'response_metadata': {'safety_ratings': [{'category': 'HARM_CATEGORY_HATE_SPEECH',\n",
496
- " 'probability_label': 'NEGLIGIBLE',\n",
497
- " 'probability_score': 0.1416015625,\n",
498
- " 'blocked': False,\n",
499
- " 'severity': 'HARM_SEVERITY_NEGLIGIBLE',\n",
500
- " 'severity_score': 0.1240234375},\n",
501
- " {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT',\n",
502
- " 'probability_label': 'NEGLIGIBLE',\n",
503
- " 'probability_score': 0.2490234375,\n",
504
- " 'blocked': False,\n",
505
- " 'severity': 'HARM_SEVERITY_LOW',\n",
506
- " 'severity_score': 0.265625},\n",
507
- " {'category': 'HARM_CATEGORY_HARASSMENT',\n",
508
- " 'probability_label': 'NEGLIGIBLE',\n",
509
- " 'probability_score': 0.1669921875,\n",
510
- " 'blocked': False,\n",
511
- " 'severity': 'HARM_SEVERITY_NEGLIGIBLE',\n",
512
- " 'severity_score': 0.10693359375},\n",
513
- " {'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT',\n",
514
- " 'probability_label': 'NEGLIGIBLE',\n",
515
- " 'probability_score': 0.08740234375,\n",
516
- " 'blocked': False,\n",
517
- " 'severity': 'HARM_SEVERITY_NEGLIGIBLE',\n",
518
- " 'severity_score': 0.1025390625}],\n",
519
- " 'finish_reason': 'STOP'},\n",
520
- " 'type': 'AIMessageChunk',\n",
521
- " 'id': 'run-5772c381-37c4-4ad9-8abe-004881ea5d38',\n",
522
- " 'tool_calls': [{'name': 'get_exchange_rate',\n",
523
- " 'args': {'currency_from': 'USD', 'currency_to': 'SEK'},\n",
524
- " 'id': '7ccbe707-ffea-4081-a1bf-ac0b16bf4ca8',\n",
525
- " 'type': 'tool_call'}],\n",
526
- " 'usage_metadata': {'input_tokens': 41,\n",
527
- " 'output_tokens': 13,\n",
528
- " 'total_tokens': 54},\n",
529
- " 'tool_call_chunks': [{'name': 'get_exchange_rate',\n",
530
- " 'args': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}',\n",
531
- " 'id': '7ccbe707-ffea-4081-a1bf-ac0b16bf4ca8',\n",
532
- " 'index': None,\n",
533
- " 'type': 'tool_call_chunk'}],\n",
534
- " 'invalid_tool_calls': []}}],\n",
535
- " 'tool_call_id': '7ccbe707-ffea-4081-a1bf-ac0b16bf4ca8'}},\n",
536
- " {'amount': 1.0,\n",
537
- " 'base': 'USD',\n",
538
- " 'date': '2025-01-22',\n",
539
- " 'rates': {'SEK': 10.9806}}]]}"
540
- ]
541
- },
542
- "execution_count": 10,
543
- "metadata": {},
544
- "output_type": "execute_result"
545
- }
546
- ],
547
- "source": [
548
- "agent.query(input=\"What's the exchange rate from US dollars to Swedish currency today?\")"
549
- ]
550
- },
551
- {
552
- "cell_type": "markdown",
553
- "metadata": {
554
- "id": "b1cf06f5fa46"
555
- },
556
- "source": [
557
- "In addition to the default query mode, the `.stream_query` method allows you to **see the agent's intermediate steps and final output from the chain**.\n",
558
- "\n",
559
- "Instead of waiting for the agent to complete all sub-tasks, the agent sends back the response in **chunks as it's being generated**:"
560
- ]
561
- },
562
- {
563
- "cell_type": "code",
564
- "execution_count": 11,
565
- "metadata": {
566
- "id": "7a931f086fc9"
567
- },
568
- "outputs": [
569
- {
570
- "name": "stdout",
571
- "output_type": "stream",
572
- "text": [
573
- "\n",
574
- "------\n",
575
- "\n",
576
- "Action:\n",
577
- "\n",
578
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'agent', 'ToolAgentAction'], 'kwargs': {'tool': 'get_exchange_rate', 'tool_input': {'currency_from': 'USD', 'currency_to': 'SEK'}, 'log': \"\\nInvoking: `get_exchange_rate` with `{'currency_from': 'USD', 'currency_to': 'SEK'}`\\n\\n\\n\", 'type': 'AgentActionMessageLog', 'message_log': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'content': '', 'additional_kwargs': {'function_call': {'name': 'get_exchange_rate', 'arguments': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}'}}, 'response_metadata': {'safety_ratings': [{'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.1416015625, 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.1240234375}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.2490234375, 'blocked': False, 'severity': 'HARM_SEVERITY_LOW', 'severity_score': 0.265625}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.1669921875, 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.10693359375}, {'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.08740234375, 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.1025390625}], 'finish_reason': 'STOP'}, 'type': 'AIMessageChunk', 'id': 'run-3162126c-cdb1-453d-a00b-da810a1fa6f9', 'tool_calls': [{'name': 'get_exchange_rate', 'args': {'currency_from': 'USD', 'currency_to': 'SEK'}, 'id': '0cb6cd0c-3de8-4ce6-a825-10d1eb5406e4', 'type': 'tool_call'}], 'usage_metadata': {'input_tokens': 41, 'output_tokens': 13, 'total_tokens': 54}, 'tool_call_chunks': [{'name': 'get_exchange_rate', 'args': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}', 'id': '0cb6cd0c-3de8-4ce6-a825-10d1eb5406e4', 'index': None, 'type': 'tool_call_chunk'}], 'invalid_tool_calls': []}}], 'tool_call_id': '0cb6cd0c-3de8-4ce6-a825-10d1eb5406e4'}}]\n",
579
- "\n",
580
- "------\n",
581
- "\n",
582
- "Message:\n",
583
- "\n",
584
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'content': '', 'additional_kwargs': {'function_call': {'name': 'get_exchange_rate', 'arguments': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}'}}, 'response_metadata': {'safety_ratings': [{'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.1416015625, 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.1240234375}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.2490234375, 'blocked': False, 'severity': 'HARM_SEVERITY_LOW', 'severity_score': 0.265625}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.1669921875, 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.10693359375}, {'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability_label': 'NEGLIGIBLE', 'probability_score': 0.08740234375, 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE', 'severity_score': 0.1025390625}], 'finish_reason': 'STOP'}, 'type': 'AIMessageChunk', 'id': 'run-3162126c-cdb1-453d-a00b-da810a1fa6f9', 'tool_calls': [{'name': 'get_exchange_rate', 'args': {'currency_from': 'USD', 'currency_to': 'SEK'}, 'id': '0cb6cd0c-3de8-4ce6-a825-10d1eb5406e4', 'type': 'tool_call'}], 'usage_metadata': {'input_tokens': 41, 'output_tokens': 13, 'total_tokens': 54}, 'tool_call_chunks': [{'name': 'get_exchange_rate', 'args': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}', 'id': '0cb6cd0c-3de8-4ce6-a825-10d1eb5406e4', 'index': None, 'type': 'tool_call_chunk'}], 'invalid_tool_calls': []}}]\n",
585
- "\n",
586
- "------\n",
587
- "\n",
588
- "Message:\n",
589
- "\n",
590
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'FunctionMessage'], 'kwargs': {'content': '{\"amount\": 1.0, \"base\": \"USD\", \"date\": \"2025-01-22\", \"rates\": {\"SEK\": 10.9806}}', 'type': 'function', 'name': 'get_exchange_rate'}}]\n",
591
- "\n",
592
- "------\n",
593
- "\n",
594
- "Message:\n",
595
- "\n",
596
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessage'], 'kwargs': {'content': 'The exchange rate from US dollars to Swedish krona is 1 USD to 10.9806 SEK. ', 'type': 'ai', 'tool_calls': [], 'invalid_tool_calls': []}}]\n",
597
- "\n",
598
- "------\n",
599
- "\n",
600
- "Output:\n",
601
- "\n",
602
- "The exchange rate from US dollars to Swedish krona is 1 USD to 10.9806 SEK. \n"
603
- ]
604
- }
605
- ],
606
- "source": [
607
- "message_types = {\"actions\": \"Action\", \"messages\": \"Message\", \"output\": \"Output\"}\n",
608
- "for chunk in agent.stream_query(\n",
609
- " input=\"What's the exchange rate from US dollars to Swedish currency today?\"\n",
610
- "):\n",
611
- " for key, label in message_types.items():\n",
612
- " if key in chunk:\n",
613
- " print(\"\\n------\\n\")\n",
614
- " print(f\"{label}:\")\n",
615
- " print()\n",
616
- " print(chunk[key])"
617
- ]
618
- },
619
- {
620
- "cell_type": "markdown",
621
- "metadata": {
622
- "id": "bbe3d34ec106"
623
- },
624
- "source": [
625
- "This allows you to observe the agent's actions in real-time (such as function calls, and intermediate steps), which is helpful for debugging purposes or for providing real-time updates to the end user."
626
- ]
627
- },
628
- {
629
- "cell_type": "markdown",
630
- "metadata": {
631
- "id": "77b0a9f0d75b"
632
- },
633
- "source": [
634
- "### Deploy your agent on Vertex AI\n",
635
- "\n",
636
- "Now that you've specified a model, tools, and reasoning for your agent and tested it out, you're ready to deploy your agent as a remote service in Vertex AI!\n",
637
- "\n",
638
- "<img width=\"40%\" src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/agent-stack-4.png\" alt=\"Components of an agent in Agent Engine on Vertex AI\" />\n",
639
- "\n",
640
- "You can re-define the agent to avoid any stateful information in the agent due to our testing in the previous cell:"
641
- ]
642
- },
643
- {
644
- "cell_type": "code",
645
- "execution_count": 12,
646
- "metadata": {
647
- "id": "b2f8365735d2"
648
- },
649
- "outputs": [],
650
- "source": [
651
- "agent = agent_engines.LangchainAgent(\n",
652
- " model=model,\n",
653
- " tools=[get_exchange_rate],\n",
654
- ")"
655
- ]
656
- },
657
- {
658
- "cell_type": "markdown",
659
- "metadata": {
660
- "id": "ebe2c3be1ca6"
661
- },
662
- "source": [
663
- "Now you're ready to deploy your agent to Agent Engine in Vertex AI by calling `agent_engines.create()` along with:\n",
664
- "\n",
665
- "1. The instance of your agent class\n",
666
- "2. The Python packages and versions that your agent requires at runtime, similar to how you would define packages and versions in a `requirements.txt` file."
667
- ]
668
- },
669
- {
670
- "cell_type": "code",
671
- "execution_count": 13,
672
- "metadata": {
673
- "id": "fd3b88c73411"
674
- },
675
- "outputs": [
676
- {
677
- "name": "stdout",
678
- "output_type": "stream",
679
- "text": [
680
- "Using bucket your-bucket-name\n",
681
- "Writing to gs://your-bucket-name/agent_engine/agent_engine.pkl\n",
682
- "Writing to gs://your-bucket-name/agent_engine/requirements.txt\n",
683
- "Creating in-memory tarfile of extra_packages\n",
684
- "Writing to gs://your-bucket-name/agent_engine/dependencies.tar.gz\n",
685
- "Creating AgentEngine\n",
686
- "Create AgentEngine backing LRO: projects/your-project-number/locations/us-central1/reasoningEngines/3381833884248309760/operations/2331218534991921152\n",
687
- "AgentEngine created. Resource name: projects/your-project-number/locations/us-central1/reasoningEngines/3381833884248309760\n",
688
- "To use this AgentEngine in another session:\n",
689
- "agent_engine = vertexai.agent_engines.get('projects/your-project-number/locations/us-central1/reasoningEngines/3381833884248309760')\n"
690
- ]
691
- }
692
- ],
693
- "source": [
694
- "remote_agent = agent_engines.create(\n",
695
- " agent,\n",
696
- " requirements=[\n",
697
- " \"google-cloud-aiplatform[agent_engines,langchain]\",\n",
698
- " \"cloudpickle==3.0.0\",\n",
699
- " \"pydantic>=2.10\",\n",
700
- " \"requests\",\n",
701
- " ],\n",
702
- ")"
703
- ]
704
- },
705
- {
706
- "cell_type": "markdown",
707
- "metadata": {
708
- "id": "e698a4c3d786"
709
- },
710
- "source": [
711
- "Now you can send a prompt to your remote agent using `.query` to test that it's working as expected:"
712
- ]
713
- },
714
- {
715
- "cell_type": "code",
716
- "execution_count": 14,
717
- "metadata": {
718
- "id": "d01b37cb77dc"
719
- },
720
- "outputs": [
721
- {
722
- "data": {
723
- "text/plain": [
724
- "{'input': \"What's the exchange rate from US dollars to Swedish currency today?\",\n",
725
- " 'output': 'The exchange rate from US dollars to Swedish krona is 1 USD to 10.9806 SEK. \\n'}"
726
- ]
727
- },
728
- "execution_count": 14,
729
- "metadata": {},
730
- "output_type": "execute_result"
731
- }
732
- ],
733
- "source": [
734
- "remote_agent.query(\n",
735
- " input=\"What's the exchange rate from US dollars to Swedish currency today?\"\n",
736
- ")"
737
- ]
738
- },
739
- {
740
- "cell_type": "markdown",
741
- "metadata": {
742
- "id": "ff3620f5fa01"
743
- },
744
- "source": [
745
- "Or you can stream the results back from the remote agent interactively using `.stream_query`:"
746
- ]
747
- },
748
- {
749
- "cell_type": "code",
750
- "execution_count": 15,
751
- "metadata": {
752
- "id": "a4250671731e"
753
- },
754
- "outputs": [
755
- {
756
- "name": "stdout",
757
- "output_type": "stream",
758
- "text": [
759
- "\n",
760
- "------\n",
761
- "\n",
762
- "Action:\n",
763
- "\n",
764
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'agent', 'ToolAgentAction'], 'kwargs': {'tool': 'get_exchange_rate', 'tool_input': {'currency_from': 'USD', 'currency_to': 'SEK'}, 'log': \"\\nInvoking: `get_exchange_rate` with `{'currency_from': 'USD', 'currency_to': 'SEK'}`\\n\\n\\n\", 'type': 'AgentActionMessageLog', 'message_log': [{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'content': '', 'additional_kwargs': {'function_call': {'name': 'get_exchange_rate', 'arguments': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}'}}, 'response_metadata': {'safety_ratings': [{'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE'}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_LOW'}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE'}, {'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE'}], 'finish_reason': 'STOP', 'logprobs_result': {'top_candidates': [], 'chosen_candidates': []}}, 'type': 'AIMessageChunk', 'id': 'run-bb1eaa31-ae2e-4e48-a155-8ee787b666b9', 'tool_calls': [{'name': 'get_exchange_rate', 'args': {'currency_from': 'USD', 'currency_to': 'SEK'}, 'id': '61ffcbd8-30b8-41ba-a5b4-094c0d8619e7', 'type': 'tool_call'}], 'usage_metadata': {'input_tokens': 41, 'output_tokens': 13, 'total_tokens': 54}, 'tool_call_chunks': [{'name': 'get_exchange_rate', 'args': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}', 'id': '61ffcbd8-30b8-41ba-a5b4-094c0d8619e7', 'index': None, 'type': 'tool_call_chunk'}], 'invalid_tool_calls': []}}], 'tool_call_id': '61ffcbd8-30b8-41ba-a5b4-094c0d8619e7'}}]\n",
765
- "\n",
766
- "------\n",
767
- "\n",
768
- "Message:\n",
769
- "\n",
770
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessageChunk'], 'kwargs': {'content': '', 'additional_kwargs': {'function_call': {'name': 'get_exchange_rate', 'arguments': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}'}}, 'response_metadata': {'safety_ratings': [{'category': 'HARM_CATEGORY_HATE_SPEECH', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE'}, {'category': 'HARM_CATEGORY_DANGEROUS_CONTENT', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_LOW'}, {'category': 'HARM_CATEGORY_HARASSMENT', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE'}, {'category': 'HARM_CATEGORY_SEXUALLY_EXPLICIT', 'probability_label': 'NEGLIGIBLE', 'blocked': False, 'severity': 'HARM_SEVERITY_NEGLIGIBLE'}], 'finish_reason': 'STOP', 'logprobs_result': {'top_candidates': [], 'chosen_candidates': []}}, 'type': 'AIMessageChunk', 'id': 'run-bb1eaa31-ae2e-4e48-a155-8ee787b666b9', 'tool_calls': [{'name': 'get_exchange_rate', 'args': {'currency_from': 'USD', 'currency_to': 'SEK'}, 'id': '61ffcbd8-30b8-41ba-a5b4-094c0d8619e7', 'type': 'tool_call'}], 'usage_metadata': {'input_tokens': 41, 'output_tokens': 13, 'total_tokens': 54}, 'tool_call_chunks': [{'name': 'get_exchange_rate', 'args': '{\"currency_from\": \"USD\", \"currency_to\": \"SEK\"}', 'id': '61ffcbd8-30b8-41ba-a5b4-094c0d8619e7', 'index': None, 'type': 'tool_call_chunk'}], 'invalid_tool_calls': []}}]\n",
771
- "\n",
772
- "------\n",
773
- "\n",
774
- "Message:\n",
775
- "\n",
776
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'FunctionMessage'], 'kwargs': {'content': '{\"amount\": 1.0, \"base\": \"USD\", \"date\": \"2025-01-22\", \"rates\": {\"SEK\": 10.9806}}', 'type': 'function', 'name': 'get_exchange_rate'}}]\n",
777
- "\n",
778
- "------\n",
779
- "\n",
780
- "Message:\n",
781
- "\n",
782
- "[{'lc': 1, 'type': 'constructor', 'id': ['langchain', 'schema', 'messages', 'AIMessage'], 'kwargs': {'content': 'The exchange rate from US dollars to Swedish krona is 1 USD to 10.9806 SEK. ', 'type': 'ai', 'tool_calls': [], 'invalid_tool_calls': []}}]\n",
783
- "\n",
784
- "------\n",
785
- "\n",
786
- "Output:\n",
787
- "\n",
788
- "The exchange rate from US dollars to Swedish krona is 1 USD to 10.9806 SEK. \n"
789
- ]
790
- }
791
- ],
792
- "source": [
793
- "message_types = {\"actions\": \"Action\", \"messages\": \"Message\", \"output\": \"Output\"}\n",
794
- "for chunk in remote_agent.stream_query(\n",
795
- " input=\"What's the exchange rate from US dollars to Swedish currency today?\"\n",
796
- "):\n",
797
- " for key, label in message_types.items():\n",
798
- " if key in chunk:\n",
799
- " print(\"\\n------\\n\")\n",
800
- " print(f\"{label}:\")\n",
801
- " print()\n",
802
- " print(chunk[key])"
803
- ]
804
- },
805
- {
806
- "cell_type": "markdown",
807
- "metadata": {
808
- "id": "9f2f7d3ed7bd"
809
- },
810
- "source": [
811
- "### Querying your deployed agent\n",
812
- "\n",
813
- "You've now deployed your agent and can [interact with it in multiple ways](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/overview), both within this notebook and from other applications or environments. The primary methods for accessing your deployed agent are via the Python client library or through REST API calls. Here's an overview of both methods:\n",
814
- "\n",
815
- "**Method 1: Reusing within this notebook or another Python environment**\n",
816
- "\n",
817
- "You can directly reuse and query the `remote_agent` instance you created in this notebook.\n",
818
- "\n",
819
- "Or, you can instantiate a new instance in another notebook or Python script. To do this, you'll need to retrieve your deployed agent's resource name that uniquely identifies your agent, which is a string that includes the project, location, and Agent Engine ID. You can retrieve it by running the following code in the notebook or environment where you created your agent:"
820
- ]
821
- },
822
- {
823
- "cell_type": "code",
824
- "execution_count": 16,
825
- "metadata": {
826
- "id": "fdaf8b91413f"
827
- },
828
- "outputs": [
829
- {
830
- "data": {
831
- "text/plain": [
832
- "'projects/your-project-number/locations/us-central1/reasoningEngines/3381833884248309760'"
833
- ]
834
- },
835
- "execution_count": 16,
836
- "metadata": {},
837
- "output_type": "execute_result"
838
- }
839
- ],
840
- "source": [
841
- "remote_agent.resource_name"
842
- ]
843
- },
844
- {
845
- "cell_type": "markdown",
846
- "metadata": {
847
- "id": "060f8369d113"
848
- },
849
- "source": [
850
- "Use the resource name to load the agent in your other notebook or Python script, then query the remote agent as usual:"
851
- ]
852
- },
853
- {
854
- "cell_type": "code",
855
- "execution_count": 17,
856
- "metadata": {
857
- "id": "78af4442827e"
858
- },
859
- "outputs": [],
860
- "source": [
861
- "# from vertexai import agent_engines\n",
862
- "\n",
863
- "# AGENT_ENGINE_RESOURCE_NAME = \"YOUR_AGENT_ENGINE_RESOURCE_NAME\" # Replace with the resource name of your deployed Agent Engine\n",
864
- "\n",
865
- "# remote_agent = agent_engines.get(AGENT_ENGINE_RESOURCE_NAME)\n",
866
- "# response = remote_agent.query(input=query)"
867
- ]
868
- },
869
- {
870
- "cell_type": "markdown",
871
- "metadata": {
872
- "id": "63ab06554fc0"
873
- },
874
- "source": [
875
- "**Method 2: Accessing from other environments via REST API**\n",
876
- "\n",
877
- "Beyond the Python client library, your deployed Vertex AI agent can be [queried using REST API calls](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/use/overview), including:\n",
878
- "\n",
879
- "- Python: You can use Python's `requests` library or similar tools to make HTTP calls to the Vertex AI REST API.\n",
880
- "- cURL: A command-line tool, cURL allows you to send HTTP requests directly. This is useful for testing and debugging.\n",
881
- "- Other Programming Languages: If you prefer a different language for your application, you can use its native HTTP client library to make REST API calls.\n",
882
- "\n",
883
- "In summary, you have access to your deployed agent through the Python client library within Python environments, and more universally through its REST API via tools and programming languages of your choosing."
884
- ]
885
- },
886
- {
887
- "cell_type": "markdown",
888
- "metadata": {
889
- "id": "82d321fd62e0"
890
- },
891
- "source": [
892
- "## Customizing your agent"
893
- ]
894
- },
895
- {
896
- "cell_type": "markdown",
897
- "metadata": {
898
- "id": "353d586b9b1b"
899
- },
900
- "source": [
901
- "The example above includes the minimal amount of configuration required for each component within the agent to help you get started.\n",
902
- "\n",
903
- "But what if you want to swap to a different Gemini model version, change the generative model parameters or safety filters, or perform additional customizations to the agent? The following example shows some of the most common parameters that you'll want to customize in your agent. Agent Engine in Vertex AI works with [Gemini model versions that support Function Calling](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling) and LangChain agents."
904
- ]
905
- },
906
- {
907
- "cell_type": "markdown",
908
- "metadata": {
909
- "id": "fdda38e6dc6b"
910
- },
911
- "source": [
912
- "### Model configuration\n",
913
- "\n",
914
- "You'll start with customizations for the model component within your agent. Refer to the Vertex AI documentation for more information about configuration parameters related to [generative AI model versions](https://cloud.google.com/vertex-ai/generative-ai/docs/learn/model-versioning), [safety attributes](https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/configure-safety-attributes), and [model parameters](https://ai.google.dev/gemini-api/docs/models/gemini#model-attributes):"
915
- ]
916
- },
917
- {
918
- "cell_type": "code",
919
- "execution_count": 18,
920
- "metadata": {
921
- "id": "5408d3da2726"
922
- },
923
- "outputs": [],
924
- "source": [
925
- "## Model variant and version\n",
926
- "model = \"gemini-1.5-pro\"\n",
927
- "\n",
928
- "## Model safety settings\n",
929
- "from langchain_google_vertexai import HarmBlockThreshold, HarmCategory\n",
930
- "\n",
931
- "safety_settings = {\n",
932
- " HarmCategory.HARM_CATEGORY_UNSPECIFIED: HarmBlockThreshold.BLOCK_NONE,\n",
933
- " HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,\n",
934
- " HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,\n",
935
- " HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_MEDIUM_AND_ABOVE,\n",
936
- " HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_ONLY_HIGH,\n",
937
- "}\n",
938
- "\n",
939
- "## Model parameters\n",
940
- "model_kwargs = {\n",
941
- " \"temperature\": 0.3,\n",
942
- " \"max_output_tokens\": 1000,\n",
943
- " \"top_p\": 0.95,\n",
944
- " \"top_k\": 40,\n",
945
- " \"safety_settings\": safety_settings,\n",
946
- "}"
947
- ]
948
- },
949
- {
950
- "cell_type": "markdown",
951
- "metadata": {
952
- "id": "5e48ed43107e"
953
- },
954
- "source": [
955
- "### Agent configuration\n",
956
- "\n",
957
- "You can also customize aspects of the agent component, including whether it should return all of the intermediate steps for a given input prompt and output response, maximum number of iterations, how to handle parsing errors, and the size of the sliding context window that the agent has visibility into:"
958
- ]
959
- },
960
- {
961
- "cell_type": "code",
962
- "execution_count": 19,
963
- "metadata": {
964
- "id": "08623f46a9e4"
965
- },
966
- "outputs": [],
967
- "source": [
968
- "# Agent parameters\n",
969
- "agent_executor_kwargs = {\n",
970
- " \"return_intermediate_steps\": True,\n",
971
- " \"max_iterations\": 3,\n",
972
- " \"handle_parsing_errors\": False,\n",
973
- " \"trim_intermediate_steps\": -1,\n",
974
- "}"
975
- ]
976
- },
977
- {
978
- "cell_type": "markdown",
979
- "metadata": {
980
- "id": "164b7a580493"
981
- },
982
- "source": [
983
- "Each component within your agent has additional parameters that can be customized or overridden, including the system instructions, preamble prompts, ability to manage chat sessions and history so that your agent maintains context between multi-turn queries.\n",
984
- "\n",
985
- "Each component within your agent (model, tools, reasoning) is modular and composable so that you can customize your agent as little or as much as you want.\n",
986
- "\n",
987
- "Refer to the [Agent Engine documentation in Vertex AI](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) for more details on each agent component and the available options for customization."
988
- ]
989
- },
990
- {
991
- "cell_type": "markdown",
992
- "metadata": {
993
- "id": "6415b2a47a0e"
994
- },
995
- "source": [
996
- "## Cleaning up\n",
997
- "\n",
998
- "After you've finished, it's a good practice to clean up your cloud resources. You can delete the deployed Agent Engine instance to avoid any unexpected charges on your Google Cloud account."
999
- ]
1000
- },
1001
- {
1002
- "cell_type": "code",
1003
- "execution_count": 20,
1004
- "metadata": {
1005
- "id": "7cec827288b7"
1006
- },
1007
- "outputs": [],
1008
- "source": [
1009
- "remote_agent.delete()"
1010
- ]
1011
- }
1012
- ],
1013
- "metadata": {
1014
- "colab": {
1015
- "name": "intro_agent_engine.ipynb",
1016
- "toc_visible": true
1017
- },
1018
- "kernelspec": {
1019
- "display_name": "Python 3",
1020
- "name": "python3"
1021
- }
1022
- },
1023
- "nbformat": 4,
1024
- "nbformat_minor": 0
1025
- }