Dev.to AI πŸ€– Ai πŸ‘ 0 πŸ“– 38 min read

How to build an AI Agent with Google ADK

John BullaFollow πŸ’Ό Sr. Cloud Solutions Architect - Cloud, Data & AI | Pre-Sales Architect | Cloud Evangelist πŸ† Google Developer Expert | AWS Community Builder | Alibaba Cloud MVP | Ex-Microsoft MVP

How to build an AI Agent with Google ADK
johnbulla image

John BullaFollow

πŸ’Ό Sr. Cloud Solutions Architect - Cloud, Data & AI | Pre-Sales Architect | Cloud Evangelist πŸ† Google Developer Expert | AWS Community Builder | Alibaba Cloud MVP | Ex-Microsoft MVP

βœ‹ Note: This article was originally published on my blog Wiki Cloud.

Introduction

Artificial intelligence is entering a new stage of evolution. In recent years, generative artificial intelligence models have transformed how we create content, develop software, and access information. However, organizations need more than answers to a prompt: they also need applications capable of accessing enterprise systems, using tools, and executing steps to address specific needs. This evolution is driving agentic artificial intelligence, in which a language model is combined with instructions, tools, and information sources to operate within a workflow.

In this context, Google developed Google Agent Development Kit (Google ADK), an open-source framework for building AI agents through code. It provides components for defining agents and their instructions, integrating models such as Gemini, adding tools and functions, managing sessions, and coordinating workflows that can evolve from a single agent into multi-agent systems. Its value lies not only in generating answers, but also in providing a structure for building extensible, observable, and testable solutions.

In previous articles, I provided an introduction to AI agent development, discussing the evolution from generative AI to agentic AI, what characterizes an agent, and why Google ADK is useful for developing them. I also introduced the architecture and components of Google ADK, a complementary read for exploring the design and elements that make up these solutions.

In this new article, we take the next step: moving from concepts and architecture to the practical implementation of an AI agent with Google ADK.

Solution Objective

In this guide, we will develop an artificial intelligence agent that acts as a Corporate Policies Assistant, capable of answering questions about internal documents from Human Resources, Finance, Technology, Security, Legal, Procurement, Operations, Sustainability, and other departments.

Imagine an employee who needs to know how many vacation days they are entitled to, how to request reimbursement, or what their company's recycling policy states. Instead of manually searching through different documents, they can ask questions in natural language and receive clear, contextualized answers. To achieve this, our agent will consult policies stored as documents in Google Drive, retrieve relevant information, and generate answers supported by the original sources.

To implement this solution, we will use Google ADK as the framework for developing and running the agent; Gemini as the language model; Google Drive as the document repository; and Streamlit to build a chatbot-style web interface in Python. We will also incorporate a lexical-search-based RAG approach, using an in-memory index without requiring a vector database. This will help us understand how the different components interact and how the agent turns a query into a grounded response.

Throughout the exercise, we will prepare our development environment with Python and PowerShell in Visual Studio Code, configure access to Google Drive, implement search tools, and define our agent with Google ADK. Finally, we will build a frontend web application containing a Streamlit chatbot and run tests to validate responses, their sources, and estimated token consumption.

This article is the first part of a hands-on series. In the second part, we will deploy the same agent to Google Cloud Agent Runtime and integrate it with Gemini Enterprise, showing how to evolve from a local application to a solution accessible through an enterprise platform.

Solution Architecture

The following section describes the architecture proposed for this solution and how its workflow operates.

Our Corporate Policies Assistant architecture combines Streamlit, Google ADK, Gemini, and Google Drive, allowing users to query enterprise documents through a conversational interface and receive answers grounded in actual information.

The process starts with corporate policy documents stored in Google Drive. When the application starts, it connects to the repository, identifies the available files, and extracts their content. It then splits the text into smaller chunks and builds an in-memory RAG index to make relevant information easier to find. This index remains available while the application runs and can be refreshed manually when documents are added or updated.

Once the knowledge base is ready, users can ask a question through the web application, which features a chatbot built with Streamlit. The query is sent to the agent developed with Google ADK, which uses the Gemini model to interpret the user's needs and determine whether to use any of its tools.

When a question concerns corporate policies, the agent runs the search_corporate_policies tool, which searches the RAG index for the chunks that best match the query. Unlike traditional searches across entire documents, this approach retrieves only the sections that may contain the answer.

The retrieved chunks are returned to the agent as context. Based on this information, Gemini generates a natural-language answer, aiming to rely only on the information found and to provide references to the original Google Drive documents. If there is insufficient information, the agent should say so rather than make up an answer.

Finally, the response is displayed in Streamlit, where users can continue the conversation, ask follow-up questions, and consult the cited sources. The web application also displays metrics such as estimated token usage and allows users to refresh the index manually when policies are added or modified.

In this way, we obtain a simple architecture that helps explain how an AI agent works: from preparing and indexing documents to interpreting questions, running tools, and generating grounded answers. We achieve all of this without introducing a vector database in this first implementation.

Prerequisites

For this demonstration, we will work on Windows, using PowerShell to run commands and Visual Studio Code as our development environment. We will also need Python 3.12 installed to implement the agent with Google ADK and build the Streamlit web application.

For Google services, we will need access to Google AI Studio to obtain a Gemini API key, with sufficient quota or billing credits to query the model. We will also need a Google Cloud project with the Google Drive API enabled and a folder containing the corporate policies our agent will query.

To access these documents, we will use a Google Cloud service account, granting it read permissions on the relevant Google Drive folder. In enterprise environments, it is important to review your organization's security policies in advance, particularly those concerning the creation and download of JSON keys. For this lab, we will use this authentication method only in an authorized testing environment.

Verifying the Tools

Once the tools are installed, we can verify that they are available by running the following commands in PowerShell:

  • Check the Python version:
py -3.12 --version
#OUTPUT
Python 3.12.10
  • Check the Visual Studio Code installation:
code --version
#OUTPUT
1.145.2
x64
  • Check the Google Cloud CLI installation:
gcloud --version
#OUTPUT
Google Cloud SDK 592.0.0

The last command requires Google Cloud CLI to be installed. We will mainly use it in the second part of this series, when we deploy our agent to Google Cloud Agent Runtime and integrate it with Gemini Enterprise.

For this first local implementation with Google ADK and Streamlit, a Gemini API key and a service account authorized to access Google Drive documents will be sufficient.

With these prerequisites in place, we can create the Python virtual environment and install the dependencies needed to develop our assistant.

Organization and Structure of the Solution's Source Code

In our example, we will organize the code into separate folders for the agent definition, Google Drive integration, corporate policies, tests, and deployment scripts.

Before implementing our agent, let's look at how the project is organized. A clear structure helps us separate the responsibilities of each component, simplify maintenance, and reuse code when we move on to deployment in Google Cloud.

For this demonstration, we organized the source code into a single repository containing two versions of the Corporate Policies Assistant: one in English (sources_en) and one in Spanish (sources_es). Both use the same architecture and features but have their own Python files, agent instructions, corporate policy examples, and environment configuration. This allows us to run and test each version independently.

Project Structure

To simplify the explanation, we will show only the internal structure of sources_en, since sources_es uses the same organization with content adapted to Spanish.

google-adk-gemini-corporate-policies-agent/
β”‚
β”œβ”€β”€ sources_es/ # VersiΓ³n en espaΓ±ol
β”‚ └── ... # Misma estructura que sources_en
β”‚
β”œβ”€β”€ sources_en/ # VersiΓ³n en inglΓ©s
β”‚ β”œβ”€β”€ .streamlit/
β”‚ β”‚ └── config.toml
β”‚ β”‚
β”‚ β”œβ”€β”€ corporate_agent/
β”‚ β”‚ β”œβ”€β”€ __init__.py
β”‚ β”‚ β”œβ”€β”€ agent.py
β”‚ β”‚ └── drive_rag.py
β”‚ β”‚
β”‚ β”œβ”€β”€ corporate_policies/
β”‚ β”‚ └── *.txt
β”‚ β”‚
β”‚ β”œβ”€β”€ credentials/
β”‚ β”‚ └── .gitkeep
β”‚ β”‚
β”‚ β”œβ”€β”€ deployment/
β”‚ β”‚ β”œβ”€β”€ __init__.py
β”‚ β”‚ └── deploy_agent.py
β”‚ β”‚
β”‚ β”œβ”€β”€ prompts/
β”‚ β”‚ └── *.txt
β”‚ β”‚
β”‚ β”œβ”€β”€ test/
β”‚ β”‚ β”œβ”€β”€ __init__.py
β”‚ β”‚ β”œβ”€β”€ test_drive.py
β”‚ β”‚ β”œβ”€β”€ test_gemini.py
β”‚ β”‚ └── test_runtime.py
β”‚ β”‚
β”‚ β”œβ”€β”€ __init__.py
β”‚ β”œβ”€β”€ .env
β”‚ β”œβ”€β”€ app.py
β”‚ └── pyproject.toml
β”‚
β”œβ”€β”€ .gitignore
β”œβ”€β”€ README.md
β”œβ”€β”€ README_ES.md
└── requirements.txt

Component Descriptions

The following table briefly describes the roles of the main folders and files in both versions of our solution.

Folder or File Description
sources_en/ Contains the English version of the agent, including its interface, instructions, and corporate policies.
sources_es/ Contains the Spanish version of the agent, which we will use as a reference throughout this article.
.streamlit/ Contains config.toml, used to customize Streamlit appearance and configuration.
corporate_agent/ Contains the main logic of the AI agent developed with Google ADK.
corporate_agent/agent.py Defines the main agent (root_agent), its instructions, the Gemini model, and the policy search tool.
corporate_agent/drive_rag.py Implements the connection to Google Drive, document reading, chunking, indexing, and RAG retrieval.
corporate_policies/ Contains corporate policy examples in TXT files, written in the language of each version. Once uploaded to Google Drive, these documents will serve as the knowledge base.
credentials/ Folder intended for storing the local credentials needed to access Google Drive.
deployment/ Contains the scripts for deploying the agent to Google Cloud Agent Runtime. It will mainly be used in the second part of the series when the agent is integrated with Gemini Enterprise.
prompts/ Stores the agent instructions or prompts in the corresponding language.
test/ Groups tests that validate Google Drive connectivity, Gemini functionality, and execution of the agent deployed to Agent Runtime.
__init__.py Files used to identify Python packages and organize module imports.
.env Stores application environment variables, such as Gemini, Google Drive, and Agent Runtime settings.
.gitignore Defines files and folders Git should exclude, such as credentials, caches, and virtual environments.
app.py Implements the Streamlit web interface, including the chatbot, sessions, and usage metrics.
pyproject.toml Defines project packaging configuration, needed to generate the installable agent package.
README.md Contains general project documentation, prerequisites, installation instructions, and commands in English.
README_ES.md Contains general project documentation, prerequisites, installation instructions, and commands in Spanish.
requirements.txt Lists the Python dependencies needed to set up the development environment and run the solution.

This separation lets us initially work with Google ADK and Streamlit in our local environment while retaining the components needed to later deploy the same agent to Google Cloud Agent Runtime and integrate it with Gemini Enterprise, without building an entirely new solution.

Source Code Available on GitHub

The source code for both versions is organized in a single GitHub repository, where you can explore the Python files, download sample corporate policies, and follow the installation and execution instructions.

You can download the project using GitHub's Code β†’ Download ZIP option or clone it directly with Git:

git clone https://github.com/johnbulla/google-adk-gemini-corporate-policies-agent.git

After downloading the project, open its folder in Visual Studio Code and select the version you want to run.

The repository includes two documentation files: README.md, available in English by default, and README_ES.md, with instructions in Spanish.

Project repository: Corporate Policies Agent β€” GitHub

Creating a Virtual Environment in VS Code with PowerShell

After installing the required tools and reviewing the project structure, the next step is to prepare our development environment in Visual Studio Code (VS Code).

We will use a Python virtual environment to install and manage the libraries our application needs independently, without affecting other Python versions or the dependencies of other projects on our machine.

In this exercise, we will use Python 3.12 and run commands from the integrated VS Code terminal using PowerShell.

Create the Python Virtual Environment

First, open the root folder of our project in Visual Studio Code and access the terminal from Terminal β†’ New Terminal.

From this location, run:

python -m venv .venv

This command creates a virtual environment called .venv inside the project. The libraries needed to develop our agent will be installed there, preventing conflicts with other Python projects.

The name .venv is a common convention that makes it easy for Visual Studio Code to recognize the virtual environment.

Enable and Activate the Virtual Environment

On Windows, PowerShell may restrict script execution for security reasons. If we encounter this restriction when activating the environment, we can temporarily allow script execution with:

Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

This command changes the execution policy only for the current PowerShell session, without permanently modifying the system configuration. Use it only when necessary and permitted by the device's security policies.

Then activate the virtual environment:

.\.venv\Scripts\Activate.ps1

When the environment is active, we will see the prefix (.venv) at the beginning of the command prompt, indicating that Python installations and executions will use our virtual environment.

For example:

(.venv) PS C:\Projects\Corporate Policies Agent\>

Update Python Installation Tools

Before installing dependencies, it is advisable to update the tools Python uses to manage and build packages.

Run:

python -m pip install --upgrade pip setuptools wheel

This command updates three tools:

  • pip: the package manager used to install Python libraries.

  • setuptools: a tool for configuring and building distributable Python packages.

  • wheel: provides support for creating installable .whl packages, which we will later use to deploy the agent to Google Cloud Agent Runtime.

Although pip is sufficient to install many project libraries, setuptools and wheel will be especially useful when we prepare the agent for cloud deployment.

Install Project Dependencies

Our agent will use several Python libraries to interact with Gemini, Google Drive, Google ADK, and Streamlit. Instead of installing them manually one by one, we will list them in a file called requirements.txt, located at the root of the project.

This file provides a centralized dependency list and makes it easier for others to reproduce the same development environment.

To install all libraries, run:

python -m pip install -r requirements.txt

The command reads requirements.txt and installs the declared dependencies along with any additional libraries they require.

Contents of requirements.txt

google-adk
google-genai
google-api-python-client
google-auth
google-auth-oauthlib
google-cloud-storage
python-dotenv
python-docx
pypdf
streamlit
pydantic
cloudpickle
# Dependencies for the environment running deployment scripts
google-cloud-aiplatform[agent_engines,adk]>=1.112.0

Below, we briefly explain what each dependency is used for.

Dependency Description
google-adk The Google framework used to develop our AI agent, define instructions, integrate tools, and manage conversation sessions.
google-genai SDK for interacting with Gemini models, sending queries, and receiving model-generated responses.
google-api-python-client Client for accessing Google APIs. Here, we use it to query and download documents through the Google Drive API.
google-auth Provides the authentication mechanisms required to access Google services with authorized credentials.
google-auth-oauthlib Facilitates OAuth 2.0 flows when an application needs to authenticate with a user account.
google-cloud-storage Enables interaction with Google Cloud Storage. We will mainly use it in the second part to validate the staging bucket used during deployment.
python-dotenv Loads configuration variables defined in .env, such as the Gemini model and Google Drive connection parameters.
python-docx Library for reading and extracting content from Microsoft Word (.docx) documents.
pypdf Extracts text from PDF files that contain selectable text.
streamlit Python framework for building the assistant web interface, including the chatbot and usage indicators.
pydantic Library for defining, validating, and structuring data using Python models. It is also used by components of Google ADK.
cloudpickle Serializes Python objects, which is useful when packaging and deploying agent components to remote environments.
google-cloud-aiplatform[agent_engines,adk]>=1.112.0 Installs the Vertex AI SDK with additional dependencies for Agent Runtime and Google ADK. We will use it in the second part to deploy and test the agent on Google Cloud.

As we can see, some dependencies support local assistant development, while others will be needed later for deployment to Google Cloud.

Although we use a single requirements.txt file to simplify installation, enterprise projects often separate development, testing, and deployment dependencies. It is also recommended to pin specific versions after validating the solution, to avoid unexpected changes when libraries are updated.

Verify That Dependencies Were Installed Correctly

After installation, we can check for dependency conflicts by running:

python -m pip check

If everything is correct, we should see a message similar to:

No broken requirements found.

We can also verify that Google ADK and Streamlit are available:

python -m pip show google-adk streamlit

This command displays information about the installed libraries, such as their versions and locations within the virtual environment.

Finally, it is advisable to select the virtual environment's interpreter in Visual Studio Code. Press Ctrl + Shift + P, search for Python: Select Interpreter, and select the interpreter inside .venv.

At this point, our development environment is ready to implement the Corporate Policies Assistant with Google ADK, Gemini, and Streamlit. In the following sections, we will configure the required credentials and establish the Google Drive connection, which will serve as the agent's knowledge source.

Environment Configuration and Application Variables

With the virtual environment ready and Python dependencies installed, the next step is to configure the variables the application needs to connect to Google services and define some agent operating parameters.

We will use a file called .env, located at the project root. This file centralizes information such as access credentials, the Gemini model to use, the location of documents in Google Drive, and the agent's information retrieval settings.

One of its main advantages is that we can change these settings without modifying the Python code directly. It also lets us keep sensitive information separate from the application logic, simplifying maintenance and configuration across environments.

Our project will use the previously installed python-dotenv library to load these variables from Python.

Security note: In this demonstration, we will configure some credentials locally, including the Gemini API key and a service account JSON file, to simplify development and make the exercise easier to follow. However, placing keys, passwords, or secrets directly in source code (hardcoding) or storing them in public repositories is not good practice.

In enterprise or production environments, we recommend dedicated secrets management solutions, such as Google Cloud Secret Manager or HashiCorp Vault, to store credentials securely, control access, and manage their lifecycle, including generation, rotation, and revocation. Whenever possible, managed identities and temporary credentials are preferable to static keys.

The configuration in this article is intended exclusively for education and demonstration and must be adapted to each organization's security policies and requirements before production use.

As we can see, we have divided the file into four groups to make it easier to understand and manage.

Gemini Configuration

In this first section, we define how our agent will connect to Gemini and which model will process the queries.

Variable Description
GOOGLE_API_KEY Access key for the Gemini API, generated in Google AI Studio. Replace YOUR_GEMINI_API_KEY with your actual API key.
GOOGLE_GENAI_USE_VERTEXAI Indicates whether to use the Gemini API (FALSE) or Vertex AI (TRUE). For this first local implementation, we will keep FALSE.
GEMINI_MODEL Defines the Gemini model used by our agent. In this example, we configure gemini-3.5-flash-lite, provided it is available to our project.
GEMINI_VERTEX_LOCATION Specifies the inference endpoint location when using Vertex AI. We will keep global, which we will use in the second part.

Google Drive Configuration

Here, we configure access to Google Drive, where the documents used as our agent's knowledge base will be stored.

Variable Description
DRIVE_AUTH_MODE Defines the authentication mechanism for accessing Google Drive. For the local application, we will use service_account_file, which authenticates through a service account JSON file.
DRIVE_SERVICE_ACCOUNT_FILE Specifies the location of the JSON file containing service account credentials. Verify that it exists at credentials/service-account.json.
GOOGLE_DRIVE_FOLDER_ID Identifier of the Google Drive folder where corporate policies will be stored. Replace YOUR_DRIVE_FOLDER_ID with the actual folder ID.

For example, if our Google Drive folder has a URL like this:

https://drive.google.com/drive/folders/1ABCdefGhijKlmNopQRstUv

The identifier to configure is the last part of the URL:

GOOGLE_DRIVE_FOLDER_ID=XXXxxxXXXxxxXXXXxxx

We must also ensure that the folder is shared with the application's service account, with the permissions required to access the documents.

Google Cloud Agent Runtime Configuration

Although we will initially run the agent locally with Streamlit, we will prepare some variables for the second part of this series, when we deploy it to Google Cloud Agent Runtime and integrate it with Gemini Enterprise.

Variable Description
GOOGLE_CLOUD_PROJECT Google Cloud project identifier. Replace YOUR_PROJECT_ID with the actual ID of your project.
AGENT_RUNTIME_LOCATION Google Cloud region where we will deploy the agent. In this example, we use europe-west1.
AGENT_RUNTIME_STAGING_BUCKET Google Cloud Storage bucket used during deployment to temporarily store required files. Replace YOUR_STAGING_BUCKET with the name of the bucket you created.
AGENT_RUNTIME_SERVICE_ACCOUNT Service account the agent will use when running on Google Cloud. Replace the sample email address with the account configured for Agent Runtime.

These variables are not required to begin using Streamlit with the Gemini API, but they will let us reuse the same project when we move on to publishing it in Gemini Enterprise.

RAG Configuration and Processing Limits

In this final section, we define parameters that control how document information is retrieved, how much content is processed, and the maximum time allowed to complete queries.

Variable Description Example Value
RAG_TOP_K Maximum number of relevant chunks the agent will retrieve per query. 3
RAG_MAX_FRAGMENT_CHARS Maximum number of characters sent to the model for each retrieved chunk. 900
RAG_REFRESH_INTERVAL_SECONDS Automatic RAG index refresh interval, in seconds. Used when the agent manages its own cache, as in Agent Runtime. 300 (5 minutes)
MAX_DRIVE_FILES Maximum number of Google Drive files processed during indexing. 250
MAX_FILE_BYTES Maximum allowed file size in bytes. 10000000 (10 decimal MB)
MAX_DOCUMENT_CHARS Maximum number of characters extracted and processed from each document. 150000
AGENT_TIMEOUT_SECONDS Maximum time allowed to complete a query from the Streamlit application. 180 seconds

These values are appropriate starting points for our lab and can be adjusted based on document size, the number of policies, and the expected application behavior.

For Streamlit, we will keep a button for manually refreshing the document index. For Agent Runtime, we will use the interval defined in RAG_REFRESH_INTERVAL_SECONDS, which is checked when the agent invokes its search tool again.

Estimated Gemini Cost Configuration

Finally, we will add two optional variables to estimate the financial cost of queries in the Streamlit dashboard.

Variable Description
GEMINI_INPUT_USD_PER_1M Reference price in US dollars per million input tokens.
GEMINI_OUTPUT_USD_PER_1M Reference price in US dollars per million output tokens.

These values allow us to display estimated model interaction costs, but they do not represent actual Google billing. Prices may change depending on the model, service option, and applicable commercial terms, so we should review official pricing before relying on them.

Creating a Gemini API Key

To allow our agent to use Gemini models, we need to generate an API key in Google AI Studio. Go to Google AI Studio and sign in with your Google account.

Once there, open the API Keys section, select the option to create a new key, and choose the Google Cloud project to associate it with. If you do not yet have an available project, you can create or import one, depending on the options enabled for your account.

API Keys in Google AI Studio

Create Gemini API key

After generating the key, copy it and confirm that the project has enough quota or billing capacity to use the selected Gemini model.

With the API key available, open the .env file at the project root and replace the sample value YOUR_GEMINI_API_KEY in the GOOGLE_API_KEY variable with the key generated in Google AI Studio.

Configuring Google Drive and Service Account Authentication

To allow our Corporate Policies Assistant to query documents stored in Google Drive, we need to configure an authentication mechanism that gives the application secure access to the files.

In this exercise, we will use a Google Cloud service account, which represents an identity used by applications and services rather than a conventional user account. This allows the agent to connect to Google Drive and retrieve corporate policies without requiring users to sign in manually every time they ask a question.

For the demonstration, we will create a dedicated service account, grant it read access to the folder containing the documents, and download its credentials as a JSON file for use by our Python application.

Enable the Google Drive API

First, we need to enable the API that allows our application to access the documents stored in Google Drive.

  1. Open Google Cloud Console and sign in.
  2. Select the Google Cloud project you will use for the exercise.
  3. From the navigation menu, go to APIs & Services β†’ Library.
  4. Search for Google Drive API.
  5. Select the API and click Enable.

We can also enable it from PowerShell using Google Cloud CLI:

gcloud services enable drive.googleapis.com --project=YOUR_PROJECT_ID

Replace YOUR_PROJECT_ID with your actual Google Cloud project ID.

Create the Service Account

Once the API is enabled, we will create the identity our agent will use to access the documents.

Follow these steps in Google Cloud Console:

  1. Go to IAM & Admin β†’ Service Accounts.
  2. Click Create Service Account.
  3. Enter the following sample values:
Field Suggested Value
Name Corporate Policies Drive Reader
Service account ID drive-agent-reader
Description Service account for reading corporate policy documents stored in Google Drive

The service account email address will follow a format similar to:

drive-agent-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com
  1. Select Create and Continue.
  2. In the project role assignment step, you can continue without granting general IAM permissions.
  3. Finish by clicking Done.

In this case, we do not need to assign roles such as Editor or Owner because our agent only needs to access documents in a specific Google Drive folder. Access to those files will be managed directly through Drive sharing permissions.

Google Cloud allows service accounts to be created without initially granting them IAM roles on the project.

We can also create the account using PowerShell:

gcloud iam service-accounts create drive-agent-reader `
--display-name="Corporate Policies Drive Reader" `
--description="Read corporate policy documents from Google Drive" `
--project=YOUR_PROJECT_ID

Configure Google Drive Access Permissions

After creating the service account, we must authorize it to access the folder containing the corporate policies.

In our example, we will have a main Google Drive folder with documents from Human Resources, Finance, Technology, Security, Legal, Procurement, Operations, and Sustainability.

To grant access:

  1. Open Google Drive.
  2. Find the main folder containing the corporate policies.
  3. Right-click it and select Share.
  4. Enter the email address of the service account created earlier.
  5. Select the Viewer permission.
  6. Confirm the sharing settings.

For example:

Cuenta:
drive-agent-reader@YOUR_PROJECT_ID.iam.gserviceaccount.com
Permiso:
Lector (Viewer)

Google Drive permissions for the service account

With this permission, the service account can read available documents within the folder and its subfolders, provided permissions are inherited correctly and no additional restrictions apply. Edit access is not required, because our agent only reads information to answer questions.

Google Workspace supports sharing files and folders directly with a service account using its email address, without granting administrative privileges.

Generate the service-account.json Credentials File

Once the service account has been created and authorized, we need to obtain the credentials our Python application will use to authenticate locally.

Return to Google Cloud Console and follow these steps:

  1. Go to IAM & Admin β†’ Service Accounts.
  2. Select the drive-agent-reader service account.
  3. Open the Keys tab.
  4. Click Add Key β†’ Create New Key.
  5. Select JSON format.
  6. Click Create.

Google Cloud will automatically download a JSON file containing the service account credentials. Rename the downloaded file to service-account.json.

This file contains information such as the project ID, the service account email address, and a private key used for authentication. Therefore, it must be treated as a sensitive credential.

Save it inside our project's credentials folder:

Corporate Policies Agent/
β”œβ”€β”€ corporate_agent/
β”œβ”€β”€ corporate_policies/
β”œβ”€β”€ credentials/
β”‚ └── service-account.json
β”œβ”€β”€ app.py
β”œβ”€β”€ .env
└── requirements.txt

Configure Credentials in the .env File

With the JSON file stored in the credentials folder, we will configure the environment variables our application uses to connect to Google Drive.

Open .env and complete the relevant section:

# ============================================================
# 2. LOCAL GOOGLE DRIVE AUTHENTICATION
# ============================================================
DRIVE_AUTH_MODE=service_account_file
DRIVE_SERVICE_ACCOUNT_FILE=credentials/service-account.json
GOOGLE_DRIVE_FOLDER_ID=YOUR_DRIVE_FOLDER_ID

Verify the Google Drive Connection

Before implementing the agent, it is advisable to check that the credentials work and we can access the documents.

Our project includes a test file called test_drive.py, located in the test folder, which validates this connection.

From the Visual Studio Code PowerShell terminal, with the virtual environment activated, run:

python -m sources_en.test.test_drive

This test will allow us to check whether the application can authenticate and access Google Drive. The exact result depends on the checks implemented in the script.

OUTPUT
Google Drive connection successful
πŸ“ Root folder: Corporate Policies
πŸ†” ID: YOUR_DRIVE_FOLDER_ID
πŸ“š Files found:
-----------------------------------------------------------------
-----------------------------------------------------------------
βœ… Total files found: 0
(.venv) PS C:\Projects\Corporate Policies Agent> python -m test.test_drive
βœ… Google Drive connection successful
πŸ“ Root folder: Corporate Policies
πŸ†” ID: YOUR_DRIVE_FOLDER_ID
πŸ“š Files found:
-----------------------------------------------------------------
πŸ“„ en_legal_policies.txt
πŸ“„ en_it_policies.txt
πŸ“„ en_human_resources_policies.txt
πŸ“„ en_finance_policies.txt
-----------------------------------------------------------------
βœ… Total files found: 4

If you encounter a 403 Forbidden error, review the service account's permissions on the folder, the API configuration, and project permissions. If you encounter a 404 Not Found error, confirm that the folder ID is correct and the account has access to it.

Security Considerations

For this demonstration, we are using a service account JSON file because it simplifies the local environment setup and helps illustrate how authentication between Python and Google Drive works. However, JSON keys are long-lived credentials and are not recommended as the standard authentication mechanism for enterprise applications or production environments.

In production, managed identities, temporary credentials, and authentication mechanisms that avoid storing private keys in local files are preferable. Google Cloud recommends limiting the use of exportable service account keys and applying appropriate controls throughout their lifecycle.

With this setup, we will have established the connection between our application and Google Drive, which will act as the knowledge repository for the Corporate Policies Assistant.

In the following sections, we will use these credentials to implement document reading, chunking, indexing, and the search tool that our agent will invoke through Google ADK.

Implementing the RAG System for Document Queries

Now that access to Google Drive is configured, we will implement the component responsible for retrieving the information our agent will use to answer user questions.

We will use RAG (Retrieval-Augmented Generation), which supplements Gemini's responses with information retrieved from our corporate documents.

In this first implementation, we will build an in-memory lexical RAG system without a vector database. The process involves querying Google Drive documents, extracting their content, splitting it into chunks, and building an index to locate the most relevant information for each question.

All this logic will be implemented in corporate_agent/drive_rag.py, organized into six main sections.

Google Drive Configuration and MIME Types

# ============================================================
# 1. CONFIGURACIΓ“N DE GOOGLE DRIVE Y TIPOS MIME
# ============================================================

In the first section, we define the general settings for working with Google Drive, including read-only access (drive.readonly) and the file formats our application can process.

Supported formats include Google Docs, TXT, Markdown, PDF, and Word (DOCX) files. We also define a list of common words (stopwords) that will be excluded from searches to improve result relevance.

Text Tokenization and Chunking

# ============================================================
# 2. TOKENIZACIΓ“N Y SEGMENTACIΓ“N DE TEXTO
# ============================================================

This section prepares document content for subsequent indexing and searching. It contains two functions:

  • words(): converts text into words, normalizes them, and removes common terms that add little value to search.

  • split_chunks(): splits documents into smaller chunks, retaining some overlap to avoid losing relevant information when dividing the content.

Chunking allows us to retrieve only the sections related to a question rather than sending entire documents to the Gemini model.

Downloading Files and Connecting to Google Drive

# ============================================================
# 3. DESCARGA Y CONEXIΓ“N CON DRIVE
# ============================================================

In this section, we implement the Google Drive connection and document downloads:

  • get_drive_service(): establishes a connection using the credentials configured in .env. It supports both the service account JSON file for the local environment and ADC authentication, which we will use later in Agent Runtime.

  • download_bytes(): downloads files in chunks and checks that they do not exceed the maximum allowed size.

This centralizes access to Google Drive and lets us control how much information our application can download.

Folder Traversal and Pagination

# ============================================================
# 4. RECORRIDO DE CARPETAS Y PAGINACIΓ“N
# ============================================================

The list_files() function locates the documents available in the Google Drive folder configured for our project.

It also traverses subfolders, uses pagination to retrieve results, and selects only supported formats while respecting the file limit set in MAX_DRIVE_FILES.

Extracting Text by File Format

# ============================================================
# 5. EXTRACCIΓ“N DE TEXTO POR FORMATO
# ============================================================

Once the documents have been identified, we need to extract their content in a format we can process.

The extract_text() function handles this task based on the file type: it exports Google Docs as text, uses pypdf for PDFs, python-docx for Word documents, and directly decodes TXT and Markdown files.

It is important to note that, in this version, scanned PDFs containing only images cannot be processed correctly, because we would need to add an OCR mechanism.

Chunk Model and RAG Index

# ============================================================
# 6. MODELO DE FRAGMENTOS E ÍNDICE RAG
# ============================================================

This final section contains the main indexing and retrieval logic.

The Chunk class represents each text fragment and stores information such as the document name, its Google Drive link, and the words it contains.

The DriveKnowledgeBase class manages our knowledge base through three main methods:

  • __init__(): initializes the structures used to store chunks, statistics, and warnings.

  • refresh(): queries Google Drive documents, extracts their content, and rebuilds the in-memory RAG index.

  • search(): receives the user's question, identifies the most relevant chunks using a TF-IDF-based lexical score, and returns results along with their sources.

The retrieved chunks will later be used by the agent developed with Google ADK, which will supply them to Gemini as context for generating a grounded response.

Important Considerations

Although this implementation is sufficient to understand RAG and integrate it with our agent, we should be aware of a few characteristics:

  • In-memory indexing: processed documents are not stored in a persistent database. Therefore, the index must be rebuilt when needed.

  • Lexical search: retrieval is based on matching words rather than semantic similarity. This means that questions expressed using synonyms may fail to retrieve the expected chunks.

  • Processing limits: we can control the number of documents, their size, and the number of retrieved chunks using the variables configured in .env.

  • Document security: the application can query any documents accessible to its service account. It is important to use an authorized folder and avoid including information that should not be available to agent users.

For our example, this approach lets us understand the entire information retrieval process without adding the complexity of a vector database or additional services.

With drive_rag.py ready, we now have the component responsible for querying our knowledge base. Next, we will create the agent with Google ADK and integrate this functionality as a tool Gemini can use during conversations.

Developing and Configuring the AI Agent with Google ADK

Once our RAG system is implemented, the next step is to develop the agent responsible for interpreting user questions, querying corporate policies, and generating responses using Gemini.

We will use Google Agent Development Kit (ADK) to define the agent's behavior, integrate tools, and manage interactions with the language model.

All this logic will be implemented in corporate_agent/agent.py, organized into five main sections.

Project Configuration

# ============================================================
# 1. CONFIGURACIΓ“N DEL PROYECTO
# ============================================================

In the first section, we load the environment variables from .env and configure the Gemini model and parameters used by our agent.

The create_agent_model() function selects how to connect to Gemini depending on the runtime: through an API key for the local application or through Vertex AI when the agent is deployed to Google Cloud.

We also configure parameters such as RAG_TOP_K, which sets the maximum number of retrieved chunks, and RAG_REFRESH_INTERVAL_SECONDS, which determines the refresh interval of the index managed by Agent Runtime.

Knowledge Base

# ============================================================
# 2. BASE DE CONOCIMIENTO
# ============================================================

This section manages the RAG index implemented earlier in drive_rag.py, allowing retrieved information to be reused without continuously querying Google Drive.

It contains three main functions:

  • set_knowledge_base(): allows our Streamlit application to provide the agent with a previously loaded RAG index managed by the application itself.

  • _cache_is_current(): checks whether the index stored in memory remains valid or needs refreshing.

  • get_knowledge_base(): retrieves the available index and, when appropriate, queries Google Drive again to rebuild it.

This prevents unnecessary downloads and improves response times. In Streamlit, refreshing is controlled manually, whereas in Agent Runtime it can happen automatically when a query arrives after the configured interval has expired.

RAG Tool for Google ADK

# ============================================================
# 3. HERRAMIENTA RAG PARA GOOGLE ADK
# ============================================================

Here, we implement search_corporate_policies(), the tool our agent will use to query corporate information.

When users ask a question, this function accesses the RAG index, retrieves the most relevant chunks, and returns their content along with the names and links of the original documents.

It also includes error handling to identify connection, permission, or Google Drive access issues without exposing sensitive information during execution.

Per-Turn Document Search Control

# ============================================================
# 4. CONTROL DE CONSULTA DOCUMENTAL POR TURNO
# ============================================================

This section introduces enforce_search_per_turn(), which we use as a Google ADK callback to control when the search tool must run. Its goal is to ensure that the agent performs a new document search whenever a user submits a question, rather than answering solely from information retrieved earlier in the conversation.

Once search_corporate_policies has been executed and returned its results, the agent can continue generating a response through Gemini.

This behavior is particularly useful when corporate policies change and we need to consult up-to-date information.

Defining the Agent with Google ADK

# ============================================================
# 5. DEFINICIΓ“N DEL AGENTE CON GOOGLE ADK
# ============================================================

Finally, we define our main agent using root_agent = Agent(), the central component of the solution.

In this configuration, we set its key properties:

  • name: identifies the agent as corporate_policies_assistant.

  • model: specifies which Gemini model the agent will use to interpret queries and generate answers.

  • description: briefly explains its purpose within the organization.

  • instruction: contains the instructions or prompt that determine how the agent should behave, including consulting documents, generating grounded answers, and including references.

  • tools: registers the search_corporate_policies function as an available tool for the agent.

  • before_model_callback: adds the mechanism requiring a new document search whenever a user query is received.

The agent's instructions are especially important because they specify that answers must be based on retrieved documents and that the assistant should acknowledge insufficient information rather than make up an answer. They also limit its behavior to corporate policy topics.

Important Considerations

With this implementation, our agent integrates Google ADK, Gemini, and the RAG system developed earlier, allowing it to answer questions about policies stored in Google Drive.

It is important to remember that response quality depends on the information available in the documents and the chunks retrieved during the search. For this reason, we have included instructions to rely on document sources and avoid unsupported answers.

The design also allows the same agent to run in our local Streamlit application and later in Google Cloud Agent Runtime, mainly by changing the authentication mechanism and model configuration.

With our agent defined, the next step is to build the Streamlit web interface, where users can ask questions, view answers, and see information about documents and token usage.

Developing the Agent's Web Interface with Streamlit

Once our Google ADK agent and its RAG system integration have been implemented, the next step is to build a web interface that allows users to interact with it easily.

We will use Streamlit, a Python framework for creating web applications without working directly with HTML, JavaScript, or additional frontend frameworks.

The entire interface logic will be implemented in app.py, located at the project root and organized into eight main sections.

Environment Variables and Project Configuration

# ============================================================
# 1. VARIABLES DE ENTORNO Y CONFIGURACIΓ“N DEL PROYECTO
# ============================================================

In the first section, we load the environment variables from .env, import our Google ADK agent, and configure general Streamlit parameters.

We also define the maximum agent response time and the reference prices used to calculate estimated token costs.

Dashboard Visual Styles

# ============================================================
# 2. ESTILOS VISUALES DEL DASHBOARD (TEMA OSCURO)
# ============================================================

This section defines the application's appearance, including colors, typography, cards, and dashboard components.

The render_dashboard_style() function applies custom styles using CSS, while get_kb() loads and keeps the RAG index of Google Drive documents in memory.

Creating Sessions and the Google ADK Runner

# ============================================================
# 3. CREACIΓ“N DE SESIONES Y RUNNER DE GOOGLE ADK
# ============================================================

The init_runner() function initializes the components that execute our agent and maintain conversation context.

We use Google ADK's Runner and InMemorySessionService to process queries and manage conversation sessions.

Measuring Tokens, Costs, and Agent Execution

# ============================================================
# 4. MEDICIΓ“N DE TOKENS, COSTES Y EJECUCIΓ“N DEL AGENTE
# ============================================================

This section sends questions to the agent, receives answers, and collects information about Gemini model consumption.

Its main functions are:

  • new_usage_metrics(): initializes usage metrics.

  • collect_usage(): gathers token usage information available in Google ADK events.

  • calculate_estimated_cost(): calculates the approximate cost of queries.

  • render_usage_metrics() and render_session_usage(): display metrics for an individual query and the session.

  • ask_agent(): sends a question to the agent and retrieves the generated answer.

We also have select_chat_page(), which simplifies navigation to the chatbot.

Footer and Version Information

# ============================================================
# 5. PIE DE PÁGINA COMÚN Y DATOS DE VERSIΓ“N
# ============================================================

The render_footer() function adds a shared footer displaying application details, copyright information, and version.

Introduction Page

# ============================================================
# 6. PÁGINA DE INTRODUCCIΓ“N (DISEΓ‘O DASHBOARD)
# ============================================================

The render_intro_page() function builds the application's welcome screen.

It presents the assistant's goal, the technologies used, and a brief explanation of how Google ADK, Gemini, and Google Drive work together.

Chat Page, Index, and Query Tools

# ============================================================
# 7. PÁGINA DE CHAT, ÍNDICE Y HERRAMIENTAS DE CONSULTA
# ============================================================

This section contains the render_chat_page() function, which builds the chatbot's main interface.

On this screen, users can ask questions about corporate policies, view answers and their sources, inspect usage metrics, and manually refresh the documents indexed from Google Drive.

Main Navigation and Entry Point

# ============================================================
# 8. NAVEGACIΓ“N PRINCIPAL Y PUNTO DE ENTRADA
# ============================================================

Finally, the main() function controls navigation between screens and coordinates our Streamlit application's execution. This section also contains the main entry point from which the application starts.

Streamlit Visual Configuration with config.toml

In addition to the custom styles defined in app.py, we will use .streamlit/config.toml to set the general configuration of our Streamlit application. This file lets us customize visual elements such as the theme, primary colors, background, and typography while keeping these preferences separate from the Python code. Our project will use a dark appearance (Dark Mode), supplemented with the CSS styles defined in render_dashboard_style(). In this way, we can maintain a consistent interface and easily change its appearance without affecting the agent logic or its Google ADK and Gemini integrations.

Final Considerations

By implementing app.py, we complete the integration of the solution's main components: Streamlit as the web interface, Google ADK to run the agent, Gemini to generate answers, and Google Drive as the document repository.

We have also added features such as session management, manual RAG index refresh, and usage metrics, allowing us to evaluate the assistant's behavior during testing.

We now have everything needed to run the Corporate Policies Assistant locally and start submitting our first queries.

Running and Testing the Agent Locally

With the solution's components developed, we can now launch the Corporate Policies Assistant and verify its behavior.

We will test it in three ways: through our custom Streamlit interface, the ADK Web development interface, and directly from the Google ADK command-line interface (CLI).

Run the Application with Streamlit

Streamlit will be our main interface because it provides a chatbot for interacting with the agent and displays additional information, such as indexed documents and usage metrics.

Although both versions are in the same repository, we can run them independently using the same Python virtual environment.

To start the English version, run the following from the project root:

python -m streamlit run .\sources_en\app.py

To start the Spanish version:

python -m streamlit run .\sources_es\app.py

We can also run both applications simultaneously on ports 8501 and 8502, respectively. Each version will use its own .env configuration, instructions, and configured Google Drive documents.

This setup allows us to work with two language versions of the same solution while keeping their components separate and making it easier to evolve toward Google Cloud Agent Runtime and Gemini Enterprise.

Once the server has started, open the following address in your browser: http://localhost:8501

From the application, we can ask questions about corporate policies, view the cited sources, and manually refresh the index of documents stored in Google Drive.

Streamlit assistant interface

Run the Agent from ADK Web

Google ADK includes a development web interface that allows us to interact directly with agents, review their responses, and observe tool execution. From the project root, run:

To start the English version, run the following from the project root:

adk web --port 8000 .\sources_en

To start the Spanish version:

adk web --port 8001 .\sources_es

Then open: http://localhost:8000 or http://localhost:8001

In the interface, select our corporate_agent and start asking questions.

This mode is especially useful during development because it lets us inspect interactions with Gemini and see when the agent runs the search_corporate_policies tool.

Running the agent in ADK Web

View Animated GIF

Run the Agent from the Command Line

We can also interact with our agent directly from PowerShell, without a graphical interface. To do so, run:

To start the English version, run the following from the project root:

adk run .\sources_en\corporate_agent

To start the Spanish version:

adk run .\sources_es\corporate_agent

This command starts an interactive session where we can type questions and receive answers directly in the terminal.

It is a simple alternative for quick testing, checking agent behavior, and identifying errors during development.

Agent in the command line

Validate the Agent's Behavior

Regardless of how we run it, we can ask questions about the documents stored in Google Drive:

  • How many vacation days do employees receive each year?
  • What is the company's remote work policy?
  • How can I request reimbursement for an expense?
  • What does the recycling and sustainability policy say?

During these tests, we should verify that the agent queries documents using search_corporate_policies, generates coherent responses, and provides references to the original sources.

It is also advisable to ask a question that the documents cannot answer to verify that the agent acknowledges when it lacks sufficient information.

Note: Streamlit, ADK Web, and ADK CLI all allow interaction with the same agent but offer different experiences. Streamlit is our custom interface, while ADK Web and ADK CLI are primarily intended for development and testing. The latter two do not replace a production-ready enterprise interface.

To stop any of the servers or sessions, press Ctrl + C in the corresponding terminal.

With these tests, we will have completed the local implementation of our Corporate Policies Assistant. In the second part of this series, we will reuse the agent to deploy it to Google Cloud Agent Runtime and make it available to users through Gemini Enterprise.

Conclusions

Throughout this exercise, we developed a Corporate Policies Assistant using Google ADK, Gemini, Google Drive, and Streamlit. With a simple RAG-based architecture, we connected an artificial intelligence agent to enterprise documents, enabling it to query information, retrieve relevant content, and generate natural-language answers accompanied by their sources. We also explored key aspects of agent development, including tool integration, session management, model instructions, and building a web interface.

Developing AI agents offers organizations an opportunity to transform how employees access information and perform everyday tasks. Solutions like the one we built can reduce the time spent searching for documents, improve access to corporate knowledge, and serve as a starting point for automating more complex processes. However, adoption also requires attention to security, access permissions, information quality, and oversight of generated responses. This exercise helps us understand the foundations of agentic AI and how to begin applying these capabilities to real enterprise scenarios.

In the second part of this series, we will take the next step: deploying our agent to Google Cloud Agent Runtime and integrating it with Gemini Enterprise, moving from a local application to a solution accessible through an enterprise platform.

Resources

To learn more about the technologies used in this exercise, see the following official documentation:

I hope you find this useful!!!

Follow us:

πŸ‘‰Wiki Cloud | πŸ‘‰X | πŸ‘‰LinkedIn | πŸ‘‰Github | πŸ‘‰Youtube

πŸ“° Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.