Add Agent Engine module. (#3429)
This commit is contained in:
248
modules/agent-engine/README.md
Normal file
248
modules/agent-engine/README.md
Normal file
@@ -0,0 +1,248 @@
|
||||
# Agent Engine Module
|
||||
|
||||
The module creates Agent Engine and related dependencies.
|
||||
|
||||
- It can automatically generate and update the Pickle file for you, given a source file.
|
||||
- It optionally creates a GCS storage bucket or can use an existing one and loads on it all your dependencies (`pickle`, `dependencies.tar.gz`, `requirements.txt`)
|
||||
- Manages the service accounts lifecycle
|
||||
|
||||
<!-- BEGIN TOC -->
|
||||
- [Packaging dependencies](#packaging-dependencies)
|
||||
- [Minimal deployment](#minimal-deployment)
|
||||
- [Service accounts](#service-accounts)
|
||||
- [Specify an encryption key](#specify-an-encryption-key)
|
||||
- [Define environment variables and use secrets](#define-environment-variables-and-use-secrets)
|
||||
- [Getting values from context](#getting-values-from-context)
|
||||
- [Variables](#variables)
|
||||
- [Outputs](#outputs)
|
||||
<!-- END TOC -->
|
||||
|
||||
## Packaging dependencies
|
||||
|
||||
To deploy an agent, you first need package your dependencies. This consists of a folder with
|
||||
|
||||
- The source Python file defining your agent to be pickled (or the equivalent pickle file).
|
||||
- The `dependencies.tar.gz`.
|
||||
- The `requirements.txt` file.
|
||||
|
||||
By default, the module expects these files to be in an `src` subfolder.
|
||||
|
||||
You can decide to **let the module create the pickle file for you**, starting from a source agent file.
|
||||
In this case, the module expects you to have in `src` a source file called `agent.py` with a variable referencing your agent function definition called `local_agent`.
|
||||
|
||||
This is an example of `agent.py` file for ADK:
|
||||
|
||||
```python
|
||||
from google.adk.agents import LlmAgent
|
||||
from vertexai.agent_engines import AdkApp
|
||||
|
||||
def get_exchange_rate(
|
||||
currency_from: str = "USD",
|
||||
currency_to: str = "EUR",
|
||||
currency_date: str = "latest",
|
||||
):
|
||||
import requests
|
||||
response = requests.get(
|
||||
f"https://api.frankfurter.app/{currency_date}",
|
||||
params={"from": currency_from, "to": currency_to},
|
||||
)
|
||||
return response.json()
|
||||
|
||||
root_agent = LlmAgent(
|
||||
model="gemini-2.5-flash",
|
||||
instruction="You are a helpful assistant",
|
||||
name='currency_exchange_agent',
|
||||
tools=[get_exchange_rate],
|
||||
)
|
||||
|
||||
local_agent = AdkApp(agent=root_agent)
|
||||
```
|
||||
|
||||
The [tools/serialize_agent.py](tools/serialize_agent.py) is used to generate the `pickle.pkl` file.
|
||||
You module needs [these packages](tools/requirements.txt) to work.
|
||||
|
||||
If you **already have a pickle file**, the module expects you to have in the `src` subfolder a `pickle.pkl` file.
|
||||
|
||||
You can customize these values by using the `source_files` variable.
|
||||
|
||||
## Minimal deployment
|
||||
|
||||
This example assumes you are providing the [source packages](#packaging-dependencies) (`agent.py`, `dependencies.tar.gz` and `requirements.txt`) in the `src` subfolder. Every time you will change the agent definition, the module will generate the new pickle file for you, will update it on the GCS bucket and will update your agent.
|
||||
|
||||
```hcl
|
||||
module "agent_engine" {
|
||||
source = "./fabric/modules/agent-engine"
|
||||
name = "my-agent"
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
|
||||
agent_engine_config = {
|
||||
agent_framework = "google-adk"
|
||||
}
|
||||
|
||||
source_files = {
|
||||
path = "assets/src/"
|
||||
}
|
||||
}
|
||||
# tftest inventory=minimal.yaml
|
||||
```
|
||||
|
||||
Alternatively, you can pass a pre-generated `pickle.pkl` file.
|
||||
|
||||
```hcl
|
||||
module "agent_engine" {
|
||||
source = "./fabric/modules/agent-engine"
|
||||
name = "my-agent"
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
generate_pickle = false
|
||||
|
||||
agent_engine_config = {
|
||||
agent_framework = "google-adk"
|
||||
}
|
||||
|
||||
source_files = {
|
||||
path = "assets/src/"
|
||||
}
|
||||
}
|
||||
# tftest inventory=minimal-pickle.yaml
|
||||
```
|
||||
|
||||
## Service accounts
|
||||
|
||||
By default, the module creates a dedicated service account for your agent and grants it the roles needed to deploy the agent. The default roles are defined in `var.service_account_config.roles`. You can add more roles, as needed.
|
||||
|
||||
You can also use the default Agent Engine (Reasoning Engine) service agent.
|
||||
In this case, it will be your responsibility to grant any other role needed to the service agent service account.
|
||||
At the moment, you'll need at least to grant to it the `roles/viewer` role.
|
||||
|
||||
```hcl
|
||||
module "agent_engine" {
|
||||
source = "./fabric/modules/agent-engine"
|
||||
name = "my-agent"
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
|
||||
agent_engine_config = {
|
||||
agent_framework = "google-adk"
|
||||
}
|
||||
|
||||
service_account_config = {
|
||||
create = false
|
||||
}
|
||||
|
||||
source_files = {
|
||||
path = "assets/src/"
|
||||
}
|
||||
}
|
||||
# tftest inventory=sa-default.yaml
|
||||
```
|
||||
|
||||
Alternatively, you can use an existing service account.
|
||||
|
||||
```hcl
|
||||
module "agent_engine" {
|
||||
source = "./fabric/modules/agent-engine"
|
||||
name = "my-agent"
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
|
||||
agent_engine_config = {
|
||||
agent_framework = "google-adk"
|
||||
}
|
||||
|
||||
service_account_config = {
|
||||
create = false
|
||||
email = "my-sa@${var.project_id}.iam.gserviceaccount.com"
|
||||
}
|
||||
|
||||
source_files = {
|
||||
path = "assets/src/"
|
||||
}
|
||||
}
|
||||
# tftest inventory=sa-custom.yaml
|
||||
```
|
||||
|
||||
## Specify an encryption key
|
||||
|
||||
You can optionally specify an existing encryption key, created in KMS.
|
||||
|
||||
To use KMS keys you'll need to grant the AI Platform Service Agent (`service-YOUR_PROJECT_NUMBER@gcp-sa-aiplatform-re.iam.gserviceaccount.com`) the `roles/cloudkms.cryptoKeyEncrypterDecrypter` role on the key.
|
||||
|
||||
```hcl
|
||||
module "agent_engine" {
|
||||
source = "./fabric/modules/agent-engine"
|
||||
name = "my-agent"
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
encryption_key = "projects/${var.project_id}/locations/${var.region}/keyRings/my-keyring/cryptoKeys/my-key"
|
||||
|
||||
agent_engine_config = {
|
||||
agent_framework = "google-adk"
|
||||
}
|
||||
|
||||
source_files = {
|
||||
path = "assets/src/"
|
||||
}
|
||||
}
|
||||
# tftest inventory=encryption.yaml
|
||||
```
|
||||
|
||||
## Define environment variables and use secrets
|
||||
|
||||
You can define environment variables and load existing secrets as environment variables into your agent.
|
||||
|
||||
```hcl
|
||||
module "agent_engine" {
|
||||
source = "./fabric/modules/agent-engine"
|
||||
name = "my-agent"
|
||||
project_id = var.project_id
|
||||
region = var.region
|
||||
|
||||
agent_engine_config = {
|
||||
agent_framework = "google-adk"
|
||||
|
||||
environment_variables = {
|
||||
FOO = "my-foo-variable"
|
||||
}
|
||||
secret_environment_variables = {
|
||||
BAR = {
|
||||
secret_id = "projects/YOUR_PROJECT_NUMBER/secrets/my-bar-secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source_files = {
|
||||
path = "assets/src/"
|
||||
}
|
||||
}
|
||||
# tftest inventory=environment.yaml
|
||||
```
|
||||
|
||||
## Getting values from context
|
||||
|
||||
The module allows you to dynamically reference context values for resources created outside this module, through the `context` variable. This includes the definition of custom roles, iam_principals, locations, kms_keys and project ids.
|
||||
<!-- BEGIN TFDOC -->
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [agent_engine_config](variables.tf#L17) | The agent configuration. | <code title="object({ agent_framework = string class_methods = optional(list(any), []) environment_variables = optional(map(string), {}) python_version = optional(string, "3.12") secret_environment_variables = optional(map(object({ secret_id = string version = optional(string, "latest") })), {}) })">object({…})</code> | ✓ | |
|
||||
| [name](variables.tf#L77) | The name of the agent. | <code>string</code> | ✓ | |
|
||||
| [project_id](variables.tf#L83) | The id of the project where to deploy the agent. | <code>string</code> | ✓ | |
|
||||
| [region](variables.tf#L89) | The region where to deploy the agent. | <code>string</code> | ✓ | |
|
||||
| [bucket_config](variables.tf#L32) | The GCS bucket configuration. | <code title="object({ create = optional(bool, true) deletion_protection = optional(bool, true) name = optional(string) uniform_bucket_level_access = optional(bool, true) })">object({…})</code> | | <code>{}</code> |
|
||||
| [context](variables.tf#L44) | Context-specific interpolations. | <code title="object({ custom_roles = optional(map(string), {}) iam_principals = optional(map(string), {}) locations = optional(map(string), {}) kms_keys = optional(map(string), {}) project_ids = optional(map(string), {}) })">object({…})</code> | | <code>{}</code> |
|
||||
| [description](variables.tf#L57) | The Agent Engine description. | <code>string</code> | | <code>"Terraform managed."</code> |
|
||||
| [encryption_key](variables.tf#L64) | The full resource name of the Cloud KMS CryptoKey. | <code>string</code> | | <code>null</code> |
|
||||
| [generate_pickle](variables.tf#L70) | Generate the pickle file from a source file. | <code>bool</code> | | <code>true</code> |
|
||||
| [service_account_config](variables.tf#L95) | Service account configurations. | <code title="object({ create = optional(bool, true) email = optional(string) name = optional(string) roles = optional(list(string), [ "roles/aiplatform.user", "roles/storage.objectViewer", "roles/viewer" ]) })">object({…})</code> | | <code>{}</code> |
|
||||
| [source_files](variables.tf#L112) | The to source files path and names. | <code title="object({ dependencies = optional(string, "dependencies.tar.gz") path = optional(string, "./src") pickle_out = optional(string, "pickle.pkl") pickle_src = optional(string, "agent.py") pickle_src_var_name = optional(string, "local_agent") requirements = optional(string, "requirements.txt") })">object({…})</code> | | <code>{}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
| name | description | sensitive |
|
||||
|---|---|:---:|
|
||||
| [id](outputs.tf#L17) | Fully qualified Agent Engine id. | |
|
||||
| [service_account](outputs.tf#L22) | Service account resource. | |
|
||||
<!-- END TFDOC -->
|
||||
Reference in New Issue
Block a user