Pankaj001 commited on
Commit
8e8a896
·
verified ·
1 Parent(s): d8931af

Upload 16 files

Browse files

adding agentic rag

.gitattributes CHANGED
@@ -34,3 +34,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  sample_model_files/pb[[:space:]]files/pb/variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
 
 
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
  sample_model_files/pb[[:space:]]files/pb/variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
37
+ Agentic_RAG/RAG_architecture.png filter=lfs diff=lfs merge=lfs -text
Agentic_RAG/.env.example ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copy as .env file and fill your values below
2
+ # Run ./update_dotenv_example.sh to update .env-example from your .env file.
3
+
4
+ # Choose Model Backend: 0 -> ML Dev, 1 -> Vertex
5
+ GOOGLE_GENAI_USE_VERTEXAI=1
6
+
7
+ # ML Dev backend config
8
+ GOOGLE_API_KEY=YOUR_VALUE_HERE
9
+
10
+ # Vertex backend config
11
+ # Rag Engine only works with Vertex. So we should configure it to use Vertex:
12
+ GOOGLE_CLOUD_PROJECT=YOUR_VALUE_HERE
13
+ GOOGLE_CLOUD_LOCATION=YOUR_VALUE_HERE
14
+
15
+ # Existing corpus in Vertex RAG Engine to be used by RAG agent
16
+ # e.g. projects/123/locations/us-central1/ragCorpora/456
17
+ RAG_CORPUS=YOUR_VALUE_HERE
18
+
19
+ # Staging bucket name for ADK agent deployment to Vertex AI Agent Engine (Shall respect this format gs://your-bucket-name)
20
+ STAGING_BUCKET=YOUR_VALUE_HERE
21
+
22
+ # Agent Engine ID in the following format: projects/<PROJECT_NUMBER>/locations/us-central1/reasoningEngines/<AGENT_ENGINE_ID>
23
+ AGENT_ENGINE_ID=YOUR_VALUE_HERE
Agentic_RAG/RAG_architecture.png ADDED

Git LFS Details

  • SHA256: fbd178abc265fd90f5e9a2fdcd3b37e64671fb37e6ebfaf325549558f2140b69
  • Pointer size: 131 Bytes
  • Size of remote file: 255 kB
Agentic_RAG/RAG_workflow.png ADDED
Agentic_RAG/README.md ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Documentation Retrieval Agent
2
+
3
+ ## Overview
4
+
5
+ This agent is designed to answer questions related to documents you uploaded to Vertex AI RAG Engine. It utilizes Retrieval-Augmented Generation (RAG) with the Vertex AI RAG Engine to fetch relevant documentation snippets and code references, which are then synthesized by an LLM (Gemini) to provide informative answers with citations.
6
+
7
+
8
+ ![RAG Architecture](RAG_architecture.png)
9
+
10
+ This diagram outlines the agent's workflow, designed to provide informed and context-aware responses. User queries are processed by agent development kit. The LLM determines if external knowledge (RAG corpus) is required. If so, the `VertexAiRagRetrieval` tool fetches relevant information from the configured Vertex RAG Engine corpus. The LLM then synthesizes this retrieved information with its internal knowledge to generate an accurate answer, including citations pointing back to the source documentation URLs.
11
+
12
+ ## Agent Details
13
+ | Attribute | Details |
14
+ | :---------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15
+ | **Interaction Type** | Conversational |
16
+ | **Complexity** | Intermediate
17
+ | **Agent Type** | Single Agent |
18
+ | **Components** | Tools, RAG, Evaluation |
19
+ | **Vertical** | Horizontal |
20
+ ### Agent Architecture
21
+
22
+ ![RAG](RAG_workflow.png)
23
+
24
+
25
+ ### Key Features
26
+
27
+ * **Retrieval-Augmented Generation (RAG):** Leverages [Vertex AI RAG
28
+ Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/rag-overview)
29
+ to fetch relevant documentation.
30
+ * **Citation Support:** Provides accurate citations for the retrieved content,
31
+ formatted as URLs.
32
+ * **Clear Instructions:** Adheres to strict guidelines for providing factual
33
+ answers and proper citations.
34
+
35
+ ## Setup and Installation Instructions
36
+ ### Prerequisites
37
+
38
+ * **Google Cloud Account:** You need a Google Cloud account.
39
+ * **Python 3.9+:** Ensure you have Python 3.9 or a later version installed.
40
+ * **Poetry:** Install Poetry by following the instructions on the official Poetry website: [https://python-poetry.org/docs/](https://python-poetry.org/docs/)
41
+ * **Git:** Ensure you have git installed.
42
+
43
+ ### Project Setup with Poetry
44
+
45
+ 1. **Clone the Repository:**
46
+
47
+ ```bash
48
+ git clone https://github.com/google/adk-samples.git
49
+ cd adk-samples/python/agents/RAG
50
+ ```
51
+
52
+ 2. **Install Dependencies with Poetry:**
53
+
54
+ **Note for Linux users:** If you get an error related to `keyring` during the installation, you can disable it by running the following command:
55
+ ```bash
56
+ poetry config keyring.enabled false
57
+ ```
58
+ This is a one-time setup.
59
+
60
+ ```bash
61
+ poetry install
62
+ ```
63
+
64
+ This command reads the `pyproject.toml` file and installs all the necessary dependencies into a virtual environment managed by Poetry.
65
+
66
+ 3. **Activate the Poetry Shell:**
67
+
68
+ ```bash
69
+ poetry env activate
70
+ ```
71
+
72
+ This activates the virtual environment, allowing you to run commands within the project's environment.
73
+ Make sure the environment is active. If not, you can also activate it through
74
+
75
+ ```bash
76
+ source .venv/bin/activate
77
+ ```
78
+ 4. **Set up Environment Variables:**
79
+ Rename the file ".env.example" to ".env"
80
+ Follow the steps in the file to set up the environment variables.
81
+
82
+ 5. **Setup Corpus:**
83
+ If you have an existing corpus in Vertex AI RAG Engine, please set corpus information in your .env file. For example: RAG_CORPUS='projects/123/locations/us-central1/ragCorpora/456'.
84
+
85
+ If you don't have a corpus setup yet, please follow "How to upload my file to my RAG corpus" section. The `prepare_corpus_and_data.py` script will automatically create a corpus (if needed) and update the `RAG_CORPUS` variable in your `.env` file with the resource name of the created or retrieved corpus.
86
+
87
+ #### How to upload my file to my RAG corpus
88
+
89
+ The `rag/shared_libraries/prepare_corpus_and_data.py` script helps you set up a RAG corpus and upload an initial document. By default, it downloads Alphabet's 2024 10-K PDF and uploads it to a new corpus.
90
+
91
+ 1. **Authenticate with your Google Cloud account:**
92
+ ```bash
93
+ gcloud auth application-default login
94
+ ```
95
+
96
+ 2. **Set up environment variables in your `.env` file:**
97
+ Ensure your `.env` file (copied from `.env.example`) has the following variables set:
98
+ ```
99
+ GOOGLE_CLOUD_PROJECT=your-project-id
100
+ GOOGLE_CLOUD_LOCATION=your-location # e.g., us-central1
101
+ ```
102
+
103
+ 3. **Configure and run the preparation script:**
104
+ * **To use the default behavior (upload Alphabet's 10K PDF):**
105
+ Simply run the script:
106
+ ```bash
107
+ python rag/shared_libraries/prepare_corpus_and_data.py
108
+ ```
109
+ This will create a corpus named `Alphabet_10K_2024_corpus` (if it doesn't exist) and upload the PDF `goog-10-k-2024.pdf` downloaded from the URL specified in the script.
110
+
111
+ * **To upload a different PDF from a URL:**
112
+ a. Open the `rag/shared_libraries/prepare_corpus_and_data.py` file.
113
+ b. Modify the following variables at the top of the script:
114
+ ```python
115
+ # --- Please fill in your configurations ---
116
+ # ... project and location are read from .env ...
117
+ CORPUS_DISPLAY_NAME = "Your_Corpus_Name" # Change as needed
118
+ CORPUS_DESCRIPTION = "Description of your corpus" # Change as needed
119
+ PDF_URL = "https://path/to/your/document.pdf" # URL to YOUR PDF document
120
+ PDF_FILENAME = "your_document.pdf" # Name for the file in the corpus
121
+ # --- Start of the script ---
122
+ ```
123
+ c. Run the script:
124
+ ```bash
125
+ python rag/shared_libraries/prepare_corpus_and_data.py
126
+ ```
127
+
128
+ * **To upload a local PDF file:**
129
+ a. Open the `rag/shared_libraries/prepare_corpus_and_data.py` file.
130
+ b. Modify the `CORPUS_DISPLAY_NAME` and `CORPUS_DESCRIPTION` variables as needed (see above).
131
+ c. Modify the `main()` function at the bottom of the script to directly call `upload_pdf_to_corpus` with your local file details:
132
+ ```python
133
+ def main():
134
+ initialize_vertex_ai()
135
+ corpus = create_or_get_corpus() # Uses CORPUS_DISPLAY_NAME & CORPUS_DESCRIPTION
136
+
137
+ # Upload your local PDF to the corpus
138
+ local_file_path = "/path/to/your/local/file.pdf" # Set the correct path
139
+ display_name = "Your_File_Name.pdf" # Set the desired display name
140
+ description = "Description of your file" # Set the description
141
+
142
+ # Ensure the file exists before uploading
143
+ if os.path.exists(local_file_path):
144
+ upload_pdf_to_corpus(
145
+ corpus_name=corpus.name,
146
+ pdf_path=local_file_path,
147
+ display_name=display_name,
148
+ description=description
149
+ )
150
+ else:
151
+ print(f"Error: Local file not found at {local_file_path}")
152
+
153
+ # List all files in the corpus
154
+ list_corpus_files(corpus_name=corpus.name)
155
+ ```
156
+ d. Run the script:
157
+ ```bash
158
+ python rag/shared_libraries/prepare_corpus_and_data.py
159
+ ```
160
+
161
+ More details about managing data in Vertex RAG Engine can be found in the
162
+ [official documentation page](https://cloud.google.com/vertex-ai/generative-ai/docs/rag-quickstart).
163
+
164
+ ## Running the Agent
165
+ You can run the agent using the ADK command in your terminal.
166
+ from the root project directory:
167
+
168
+ 1. Run agent in CLI:
169
+
170
+ ```bash
171
+ adk run rag
172
+ ```
173
+
174
+ 2. Run agent with ADK Web UI:
175
+ ```bash
176
+ adk web
177
+ ```
178
+ Select the RAG from the dropdown
179
+
180
+
181
+ ### Example Interaction
182
+ Here's a quick example of how a user might interact with the agent:
183
+
184
+ **Example 1: Document Information Retrieval**
185
+
186
+ User: What are the key business segments mentioned in Alphabet's 2024 10-K report?
187
+
188
+ Agent: According to Alphabet's 2024 10-K report, the key business segments are:
189
+ 1. Google Services (including Google Search, YouTube, Google Maps, Play Store)
190
+ 2. Google Cloud (offering cloud computing services, data analytics, and AI solutions)
191
+ 3. Other Bets (including Waymo for autonomous driving technology)
192
+ [Source: goog-10-k-2024.pdf]
193
+
194
+ ## Evaluating the Agent
195
+
196
+ The evaluation can be run from the `RAG` directory using
197
+ the `pytest` module:
198
+
199
+ ```
200
+ poetry run pytest eval
201
+ ```
202
+
203
+ ### Evaluation Process
204
+
205
+ The evaluation framework consists of three key components:
206
+
207
+ 1. **test_eval.py**: The main test script that orchestrates the evaluation process. It uses the `AgentEvaluator` from Google ADK to run the agent against a test dataset and assess its performance based on predefined criteria.
208
+
209
+ 2. **conversation.test.json**: Contains a sequence of test cases structured as a conversation. Each test case includes:
210
+ - A user query (e.g., questions about Alphabet's 10-K report)
211
+ - Expected tool usage (which tools the agent should call and with what parameters)
212
+ - Reference answers (ideal responses the agent should provide)
213
+
214
+ 3. **test_config.json**: Defines evaluation criteria and thresholds:
215
+ - `tool_trajectory_avg_score`: Measures how well the agent uses the appropriate tools
216
+ - `response_match_score`: Measures how closely the agent's responses match the reference answers
217
+
218
+ When you run the evaluation, the system:
219
+ 1. Loads the test cases from conversation.test.json
220
+ 2. Sends each query to the agent
221
+ 3. Compares the agent's tool usage against expected tool usage
222
+ 4. Compares the agent's responses against reference answers
223
+ 5. Calculates scores based on the criteria in test_config.json
224
+
225
+ This evaluation helps ensure the agent correctly leverages the RAG capabilities to retrieve relevant information and generates accurate responses with proper citations.
226
+
227
+ ## Deploying the Agent
228
+
229
+ The Agent can be deployed to Vertex AI Agent Engine using the following
230
+ commands:
231
+
232
+ ```
233
+ python deployment/deploy.py
234
+ ```
235
+
236
+ After deploying the agent, you'll be able to read the following INFO log message:
237
+
238
+ ```
239
+ Deployed agent to Vertex AI Agent Engine successfully, resource name: projects/<PROJECT_NUMBER>/locations/us-central1/reasoningEngines/<AGENT_ENGINE_ID>
240
+ ```
241
+
242
+ Please note your Agent Engine resource name and update `.env` file accordingly as this is crucial for testing the remote agent.
243
+
244
+ You may also modify the deployment script for your use cases.
245
+
246
+ ## Testing the deployed agent
247
+
248
+ After deploying the agent, follow these steps to test it:
249
+
250
+ 1. **Update Environment Variables:**
251
+ - Open your `.env` file.
252
+ - The `AGENT_ENGINE_ID` should have been automatically updated by the `deployment/deploy.py` script when you deployed the agent. Verify that it is set correctly:
253
+ ```
254
+ AGENT_ENGINE_ID=projects/<PROJECT_NUMBER>/locations/us-central1/reasoningEngines/<AGENT_ENGINE_ID>
255
+ ```
256
+
257
+ 2. **Grant RAG Corpus Access Permissions:**
258
+ - Ensure your `.env` file has the following variables set correctly:
259
+ ```
260
+ GOOGLE_CLOUD_PROJECT=your-project-id
261
+ RAG_CORPUS=projects/<project-number>/locations/us-central1/ragCorpora/<corpus-id>
262
+ ```
263
+ - Run the permissions script:
264
+ ```bash
265
+ chmod +x deployment/grant_permissions.sh
266
+ ./deployment/grant_permissions.sh
267
+ ```
268
+ This script will:
269
+ - Read the environment variables from your `.env` file
270
+ - Create a custom role with RAG Corpus query permissions
271
+ - Grant the necessary permissions to the AI Platform Reasoning Engine Service Agent
272
+
273
+ 3. **Test the Remote Agent:**
274
+ - Run the test script:
275
+ ```bash
276
+ python deployment/run.py
277
+ ```
278
+ This script will:
279
+ - Connect to your deployed agent
280
+ - Send a series of test queries
281
+ - Display the agent's responses with proper formatting
282
+
283
+ The test script includes example queries about Alphabet's 10-K report. You can modify the queries in `deployment/run.py` to test different aspects of your deployed agent.
284
+
285
+ ## Customization
286
+
287
+ ### Customize Agent
288
+ You can customize system instruction for the agent and add more tools to suit your need, for example, google search.
289
+
290
+ ### Customize Vertex RAG Engine
291
+ You can read more about [official Vertex RAG Engine documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/rag-quickstart) for more details on customizing corpora and data.
292
+
293
+
294
+ ### Plug-in other retrieval sources
295
+ You can also integrate your preferred retrieval sources to enhance the agent's
296
+ capabilities. For instance, you can seamlessly replace or augment the existing
297
+ `VertexAiRagRetrieval` tool with a tool that utilizes Vertex AI Search or any
298
+ other retrieval mechanism. This flexibility allows you to tailor the agent to
299
+ your specific data sources and retrieval requirements.
300
+
301
+
302
+ ## Troubleshooting
303
+
304
+ ### Quota Exceeded Errors
305
+
306
+ When running the `prepare_corpus_and_data.py` script, you may encounter an error related to API quotas, such as:
307
+
308
+ ```
309
+ Error uploading file ...: 429 Quota exceeded for aiplatform.googleapis.com/online_prediction_requests_per_base_model with base model: textembedding-gecko.
310
+ ```
311
+
312
+ This is especially common for new Google Cloud projects that have lower default quotas.
313
+
314
+ **Solution:**
315
+
316
+ You will need to request a quota increase for the model you are using.
317
+
318
+ 1. Navigate to the **Quotas** page in the Google Cloud Console: [https://console.cloud.google.com/iam-admin/quotas](https://console.cloud.google.com/iam-admin/quotas)
319
+ 2. Follow the instructions in the official documentation to request a quota increase: [https://cloud.google.com/vertex-ai/docs/quotas#request_a_quota_increase](https://cloud.google.com/vertex-ai/docs/quotas#request_a_quota_increase)
320
+
321
+
322
+ ## Disclaimer
323
+
324
+ This agent sample is provided for illustrative purposes only and is not intended for production use. It serves as a basic example of an agent and a foundational starting point for individuals or teams to develop their own agents.
325
+
326
+ This sample has not been rigorously tested, may contain bugs or limitations, and does not include features or optimizations typically required for a production environment (e.g., robust error handling, security measures, scalability, performance considerations, comprehensive logging, or advanced configuration options).
327
+
328
+ Users are solely responsible for any further development, testing, security hardening, and deployment of agents based on this sample. We recommend thorough review, testing, and the implementation of appropriate safeguards before using any derived agent in a live or critical system.
Agentic_RAG/deployment/deploy.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import vertexai
16
+ from vertexai import agent_engines
17
+ from vertexai.preview.reasoning_engines import AdkApp
18
+ from rag.agent import root_agent
19
+ import logging
20
+ import os
21
+ from dotenv import set_key
22
+
23
+ logging.basicConfig(level=logging.DEBUG)
24
+ logger = logging.getLogger(__name__)
25
+
26
+ GOOGLE_CLOUD_PROJECT = os.getenv("GOOGLE_CLOUD_PROJECT")
27
+ GOOGLE_CLOUD_LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION")
28
+ STAGING_BUCKET = os.getenv("STAGING_BUCKET")
29
+ # Define the path to the .env file relative to this script
30
+ ENV_FILE_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".env"))
31
+
32
+ vertexai.init(
33
+ project=GOOGLE_CLOUD_PROJECT,
34
+ location=GOOGLE_CLOUD_LOCATION,
35
+ staging_bucket=STAGING_BUCKET,
36
+ )
37
+
38
+ # Function to update the .env file
39
+ def update_env_file(agent_engine_id, env_file_path):
40
+ """Updates the .env file with the agent engine ID."""
41
+ try:
42
+ set_key(env_file_path, "AGENT_ENGINE_ID", agent_engine_id)
43
+ print(f"Updated AGENT_ENGINE_ID in {env_file_path} to {agent_engine_id}")
44
+ except Exception as e:
45
+ print(f"Error updating .env file: {e}")
46
+
47
+ logger.info("deploying app...")
48
+ app = AdkApp(
49
+ agent=root_agent,
50
+ enable_tracing=True,
51
+ )
52
+
53
+ logging.debug("deploying agent to agent engine:")
54
+
55
+ remote_app = agent_engines.create(
56
+ app,
57
+ requirements=[
58
+ "google-cloud-aiplatform[adk,agent-engines]==1.108.0",
59
+ "google-adk==1.10.0",
60
+ "python-dotenv",
61
+ "google-auth",
62
+ "tqdm",
63
+ "requests",
64
+ "llama-index",
65
+ ],
66
+ extra_packages=[
67
+ "./rag",
68
+ ],
69
+ )
70
+
71
+ # log remote_app
72
+ logging.info(f"Deployed agent to Vertex AI Agent Engine successfully, resource name: {remote_app.resource_name}")
73
+
74
+ # Update the .env file with the new Agent Engine ID
75
+ update_env_file(remote_app.resource_name, ENV_FILE_PATH)
Agentic_RAG/deployment/grant_permissions.sh ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Copyright 2025 Google LLC
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+
17
+ # Script to grant RAG Corpus access permissions to AI Platform Reasoning Engine Service Agent
18
+
19
+ set -e
20
+
21
+ # Load environment variables from .env file
22
+ SCRIPT_DIR="$(dirname "$0")"
23
+ ENV_FILE="${SCRIPT_DIR}/../.env"
24
+ if [ -f "$ENV_FILE" ]; then
25
+ source "$ENV_FILE"
26
+ else
27
+ echo "Error: .env file not found at $ENV_FILE"
28
+ exit 1
29
+ fi
30
+
31
+ # Get the project ID from environment variable
32
+ PROJECT_ID="$GOOGLE_CLOUD_PROJECT"
33
+ if [ -z "$PROJECT_ID" ]; then
34
+ echo "No project ID found. Please set your project ID with 'gcloud config set project YOUR_PROJECT_ID'"
35
+ exit 1
36
+ fi
37
+
38
+ # Get the project number
39
+ PROJECT_NUMBER=$(gcloud projects describe "$PROJECT_ID" --format="value(projectNumber)")
40
+ if [ -z "$PROJECT_NUMBER" ]; then
41
+ echo "Failed to retrieve project number for project $PROJECT_ID"
42
+ exit 1
43
+ fi
44
+
45
+ # Define the service account
46
+ SERVICE_ACCOUNT="service-${PROJECT_NUMBER}@gcp-sa-aiplatform-re.iam.gserviceaccount.com"
47
+
48
+ # Get RAG Corpus ID from the RAG_CORPUS environment variable
49
+ if [ -z "$RAG_CORPUS" ]; then
50
+ echo "RAG_CORPUS environment variable is not set in the .env file"
51
+ exit 1
52
+ fi
53
+
54
+ # Extract RAG_CORPUS_ID from the full RAG_CORPUS path
55
+ RAG_CORPUS_ID=$(echo $RAG_CORPUS | awk -F'/' '{print $NF}')
56
+
57
+ # Define the RAG Corpus resource
58
+ RAG_CORPUS="projects/${PROJECT_NUMBER}/locations/us-central1/ragCorpora/${RAG_CORPUS_ID}"
59
+
60
+ echo "Granting permissions to $SERVICE_ACCOUNT..."
61
+
62
+ # Ensure the AI Platform service identity exists
63
+ gcloud alpha services identity create --service=aiplatform.googleapis.com --project="$PROJECT_ID"
64
+
65
+ # Create a custom role with only the RAG Corpus query permission
66
+ ROLE_ID="ragCorpusQueryRole"
67
+ ROLE_TITLE="RAG Corpus Query Role"
68
+ ROLE_DESCRIPTION="Custom role with permission to query RAG Corpus"
69
+
70
+ # Check if the custom role already exists
71
+ echo "Checking if custom role $ROLE_ID exists..."
72
+ if gcloud iam roles describe "$ROLE_ID" --project="$PROJECT_ID" &>/dev/null; then
73
+ echo "Custom role $ROLE_ID already exists."
74
+ else
75
+ echo "Custom role $ROLE_ID does not exist. Creating it..."
76
+ gcloud iam roles create "$ROLE_ID" \
77
+ --project="$PROJECT_ID" \
78
+ --title="$ROLE_TITLE" \
79
+ --description="$ROLE_DESCRIPTION" \
80
+ --permissions="aiplatform.ragCorpora.query"
81
+ echo "Custom role $ROLE_ID created successfully."
82
+ fi
83
+
84
+ # Grant the custom role to the service account
85
+ echo "Granting custom role for RAG Corpus query permissions for $RAG_CORPUS..."
86
+ gcloud projects add-iam-policy-binding "$PROJECT_ID" \
87
+ --member="serviceAccount:$SERVICE_ACCOUNT" \
88
+ --role="projects/$PROJECT_ID/roles/$ROLE_ID" \
89
+
90
+ echo "Permissions granted successfully."
91
+ echo "Service account $SERVICE_ACCOUNT can now query the specific RAG Corpus: $RAG_CORPUS"
Agentic_RAG/deployment/run.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import vertexai
3
+ from vertexai import agent_engines
4
+ from google.adk.sessions import VertexAiSessionService
5
+ from dotenv import load_dotenv
6
+ import json
7
+
8
+ import asyncio
9
+
10
+ def pretty_print_event(event):
11
+ """Pretty prints an event with truncation for long content."""
12
+ if "content" not in event:
13
+ print(f"[{event.get('author', 'unknown')}]: {event}")
14
+ return
15
+
16
+ author = event.get("author", "unknown")
17
+ parts = event["content"].get("parts", [])
18
+
19
+ for part in parts:
20
+ if "text" in part:
21
+ text = part["text"]
22
+ # Truncate long text to 200 characters
23
+ if len(text) > 200:
24
+ text = text[:197] + "..."
25
+ print(f"[{author}]: {text}")
26
+ elif "functionCall" in part:
27
+ func_call = part["functionCall"]
28
+ print(f"[{author}]: Function call: {func_call.get('name', 'unknown')}")
29
+ # Truncate args if too long
30
+ args = json.dumps(func_call.get("args", {}))
31
+ if len(args) > 100:
32
+ args = args[:97] + "..."
33
+ print(f" Args: {args}")
34
+ elif "functionResponse" in part:
35
+ func_response = part["functionResponse"]
36
+ print(f"[{author}]: Function response: {func_response.get('name', 'unknown')}")
37
+ # Truncate response if too long
38
+ response = json.dumps(func_response.get("response", {}))
39
+ if len(response) > 100:
40
+ response = response[:97] + "..."
41
+ print(f" Response: {response}")
42
+
43
+ load_dotenv()
44
+
45
+ vertexai.init(
46
+ project=os.getenv("GOOGLE_CLOUD_PROJECT"),
47
+ location=os.getenv("GOOGLE_CLOUD_LOCATION"),
48
+ )
49
+
50
+ session_service = VertexAiSessionService(project=os.getenv("GOOGLE_CLOUD_PROJECT"),location=os.getenv("GOOGLE_CLOUD_LOCATION"))
51
+ AGENT_ENGINE_ID = os.getenv("AGENT_ENGINE_ID")
52
+
53
+ session = asyncio.run(session_service.create_session(
54
+ app_name=AGENT_ENGINE_ID,
55
+ user_id="123",
56
+ ))
57
+
58
+ agent_engine = agent_engines.get(AGENT_ENGINE_ID)
59
+
60
+ queries = [
61
+ "Hi, how are you?",
62
+ "According to the MD&A, how might the increasing proportion of revenues derived from non-advertising sources like Google Cloud and devices potentially impact Alphabet's overall operating margin, and why?",
63
+ "The report mentions significant investments in AI. What specific connection is drawn between these AI investments and the company's expectations regarding future capital expenditures?",
64
+ "Thanks, I got all the information I need. Goodbye!",
65
+ ]
66
+
67
+ for query in queries:
68
+ print(f"\n[user]: {query}")
69
+ for event in agent_engine.stream_query(
70
+ user_id="123",
71
+ session_id=session.id,
72
+ message=query,
73
+ ):
74
+ pretty_print_event(event)
Agentic_RAG/eval/data/conversation.test.json ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "query": "Hi there, I have some questions about the Alphabet 10-K report.",
4
+ "expected_tool_use": [],
5
+ "reference": "Hello! I can help with that. What would you like to know based on the Alphabet 10-K for the fiscal year ended December 31, 2024?"
6
+ },
7
+ {
8
+ "query": "According to the MD&A, how might the increasing proportion of revenues derived from non-advertising sources like Google Cloud and devices potentially impact Alphabet's overall operating margin, and why?",
9
+ "expected_tool_use": [
10
+ {
11
+ "tool_name": "retrieve_rag_documentation",
12
+ "tool_input": {
13
+ "query": "How does the growth of non-advertising revenue affect Alphabet's margins?"
14
+ }
15
+ }
16
+ ],
17
+ "reference": "The report states that revenues from cloud, consumer subscriptions, platforms, and devices are increasing. It notes that the margins on these revenues vary significantly and are generally lower than advertising margins. Specifically, device sales adversely affect consolidated margins due to pricing pressure and higher cost of sales. Therefore, this trend may exert downward pressure on the overall operating margin. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7]"
18
+ },
19
+ {
20
+ "query": "The report mentions significant investments in AI. What specific connection is drawn between these AI investments and the company's expectations regarding future capital expenditures?",
21
+ "expected_tool_use": [
22
+ {
23
+ "tool_name": "retrieve_rag_documentation",
24
+ "tool_input": {
25
+ "query": "Relationship between Alphabet's AI strategy and capital expenditure forecasts"
26
+ }
27
+ }
28
+ ],
29
+ "reference": "The report explicitly states an expectation that capital expenditures will increase, including expected spend and increased technical infrastructure investment, *in particular* to support AI products and services. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7 & Note About Forward-Looking Statements]"
30
+ },
31
+ {
32
+ "query": "Beyond basic functionality issues, what specific legal, ethical, or societal challenges does Alphabet identify in its Risk Factors as potentially arising from the development and use of AI?",
33
+ "expected_tool_use": [
34
+ {
35
+ "tool_name": "retrieve_rag_documentation",
36
+ "tool_input": {
37
+ "query": "What ethical and legal risks does Alphabet associate with artificial intelligence?"
38
+ }
39
+ }
40
+ ],
41
+ "reference": "The risks mentioned include harmful content, inaccuracies, discrimination, intellectual property infringement/misappropriation, violation of rights of publicity, defamation, data privacy, cybersecurity issues, and unintended consequences or uses potentially affecting human rights, privacy, employment, or other social concerns. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 1A]"
42
+ },
43
+ {
44
+ "query": "The report details several ongoing antitrust investigations and lawsuits. Synthesizing the information provided, what common themes or business areas appear to be the primary focus of regulatory scrutiny?",
45
+ "expected_tool_use": [
46
+ {
47
+ "tool_name": "retrieve_rag_documentation",
48
+ "tool_input": {
49
+ "query": "What areas of Alphabet's business face the most antitrust scrutiny?"
50
+ }
51
+ }
52
+ ],
53
+ "reference": "Common themes of regulatory scrutiny focus on Search and Search advertising distribution/practices, Advertising Technology (ad tech stack), the Android operating system distribution agreements, and Google Play store operations (billing, fees, business model). [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 1A & Note 10]"
54
+ },
55
+ {
56
+ "query": "How does Alphabet account for its investments in non-marketable equity securities, and what specific events trigger adjustments to their carrying value according to Note 1?",
57
+ "expected_tool_use": [
58
+ {
59
+ "tool_name": "retrieve_rag_documentation",
60
+ "tool_input": {
61
+ "query": "Alphabet accounting policy for non-marketable equity securities"
62
+ }
63
+ }
64
+ ],
65
+ "reference": "They are primarily accounted for under the measurement alternative (cost, less impairment, +/- adjustments). Adjustments to carrying value are triggered by observable price changes in orderly transactions for identical or similar investments of the same issuer, or upon impairment identification. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Note 1 & Note 3]"
66
+ },
67
+ {
68
+ "query": "While Google Cloud's operating income turned positive and grew significantly in 2024, what factors mentioned in the MD&A partially offset the revenue growth and moderated the profitability increase?",
69
+ "expected_tool_use": [
70
+ {
71
+ "tool_name": "retrieve_rag_documentation",
72
+ "tool_input": {
73
+ "query": "Factors limiting Google Cloud profitability growth in 2024"
74
+ }
75
+ }
76
+ ],
77
+ "reference": "The increase in operating income was partially offset by increases in usage costs for technical infrastructure as well as increases in employee compensation expenses, largely driven by headcount growth. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7, Segment Profitability]"
78
+ },
79
+ {
80
+ "query": "Explain the primary reasons for the significant increase in Alphabet's 'Other income (expense), net' from $1.4 billion in 2023 to $7.4 billion in 2024.",
81
+ "expected_tool_use": [
82
+ {
83
+ "tool_name": "retrieve_rag_documentation",
84
+ "tool_input": {
85
+ "query": "Drivers of the change in Alphabet's Other Income (Expense), net in 2024"
86
+ }
87
+ }
88
+ ],
89
+ "reference": "The increase was primarily due to an increase in net gains on equity securities (mainly unrealized gains on non-marketable equity securities driven by fair value adjustments) and a decrease in net losses on foreign currency exchange compared to the prior year. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7, Other Income (Expense), Net & Note 7]"
90
+ },
91
+ {
92
+ "query": "What key factors contributed to the increase in Alphabet's effective tax rate from 13.9% in 2023 to 16.4% in 2024?",
93
+ "expected_tool_use": [
94
+ {
95
+ "tool_name": "retrieve_rag_documentation",
96
+ "tool_input": {
97
+ "query": "Why did Alphabet's effective tax rate increase in 2024?"
98
+ }
99
+ }
100
+ ],
101
+ "reference": "The increase was primarily due to a 2023 one-time adjustment for IRS tax rule changes related to foreign tax credits and R&D capitalization (which lowered the 2023 rate), plus a decrease in the 2024 U.S. federal Foreign Derived Intangible Income deduction. This was partially offset by higher stock-based compensation tax benefits in 2024. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7, Provision for Income Taxes & Note 14]"
102
+ },
103
+ {
104
+ "query": "Regarding the DOJ antitrust lawsuit focused on Search, what was the court's ruling in August 2024, and what are the subsequent steps outlined in the report?",
105
+ "expected_tool_use": [
106
+ {
107
+ "tool_name": "retrieve_rag_documentation",
108
+ "tool_input": {
109
+ "query": "Status and ruling in the DOJ Search antitrust case against Google"
110
+ }
111
+ }
112
+ ],
113
+ "reference": "The U.S. District Court for the District of Columbia ruled that Google violated antitrust laws related to Search and Search advertising. A separate proceeding is being held to determine remedies. Alphabet intends to appeal after the remedy decision. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 1A & Note 10]"
114
+ },
115
+ {
116
+ "query": "What potential challenges does Alphabet acknowledge regarding achieving its ambitious 2030 sustainability goals (net-zero and 24/7 CFE)?",
117
+ "expected_tool_use": [
118
+ {
119
+ "tool_name": "retrieve_rag_documentation",
120
+ "tool_input": {
121
+ "query": "What uncertainties or difficulties does Alphabet foresee in meeting its climate goals?"
122
+ }
123
+ }
124
+ ],
125
+ "reference": "Challenges include the path not being easy or linear, long lead times for large-scale infrastructure, significant uncertainty (e.g., future environmental impact of AI), dependency on new technology development (by Alphabet and the energy sector), and the expectation that total GHG emissions might rise before dropping toward the target. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 1]"
126
+ },
127
+ {
128
+ "query": "How might Alphabet's share repurchase program, as mentioned in the risk factors, potentially influence the relative voting control held by its founders, Larry Page and Sergey Brin?",
129
+ "expected_tool_use": [
130
+ {
131
+ "tool_name": "retrieve_rag_documentation",
132
+ "tool_input": {
133
+ "query": "Impact of Alphabet share buybacks on founder voting power"
134
+ }
135
+ }
136
+ ],
137
+ "reference": "The risk factor on concentration of ownership explicitly states that share repurchases 'may also affect Larry and Sergey’s relative voting power.' By repurchasing lower-vote Class A or non-voting Class C shares, the proportional voting power of their high-vote Class B shares increases relative to other classes. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 1A]"
138
+ },
139
+ {
140
+ "query": "What accounting estimates does Alphabet identify as 'critical' due to the significant level of uncertainty and potential material impact on financial results?",
141
+ "expected_tool_use": [
142
+ {
143
+ "tool_name": "retrieve_rag_documentation",
144
+ "tool_input": {
145
+ "query": "What are identified as Alphabet's critical accounting estimates?"
146
+ }
147
+ }
148
+ ],
149
+ "reference": "The critical accounting estimates identified are: Fair Value Measurements of Non-Marketable Equity Securities; Property and Equipment (useful lives assessment); Income Taxes (evaluation of uncertain tax positions); and Loss Contingencies (likelihood and estimation of loss). [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7]"
150
+ },
151
+ {
152
+ "query": "Describe Alphabet's strategy for using derivative financial instruments, including the types of risks hedged and the accounting designations applied.",
153
+ "expected_tool_use": [
154
+ {
155
+ "tool_name": "retrieve_rag_documentation",
156
+ "tool_input": {
157
+ "query": "Describe Alphabet's derivative hedging strategy and accounting"
158
+ }
159
+ }
160
+ ],
161
+ "reference": "Alphabet uses derivatives, primarily foreign currency contracts, to manage foreign exchange risk. They designate contracts as Cash Flow Hedges for forecasted revenue, Fair Value Hedges for certain foreign currency marketable securities, and Net Investment Hedges for investments in foreign subsidiaries. Non-designated derivatives are used for other exposures like intercompany transactions and for investment purposes. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Note 3 & Item 7A]"
162
+ },
163
+ {
164
+ "query": "What constitutes the majority of Alphabet's $93.2 billion revenue backlog as of year-end 2024, and what is the anticipated timeframe for recognizing roughly half of this amount?",
165
+ "expected_tool_use": [
166
+ {
167
+ "tool_name": "retrieve_rag_documentation",
168
+ "tool_input": {
169
+ "query": "Details on Alphabet's revenue backlog composition and recognition period"
170
+ }
171
+ }
172
+ ],
173
+ "reference": "The revenue backlog primarily relates to Google Cloud commitments for future services not yet recognized as revenue. Approximately half of this backlog is expected to be recognized as revenue over the next 24 months. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Note 2]"
174
+ },
175
+ {
176
+ "query": "Analyze the change in Google Services operating income from 2023 to 2024. What were the primary positive drivers, and what costs partially offset the increase?",
177
+ "expected_tool_use": [
178
+ {
179
+ "tool_name": "retrieve_rag_documentation",
180
+ "tool_input": {
181
+ "query": "Analysis of Google Services operating income change in 2024"
182
+ }
183
+ }
184
+ ],
185
+ "reference": "Google Services operating income increased by $25.4 billion. This was primarily driven by an increase in revenues. Factors partially offsetting this included increases in content acquisition costs and Traffic Acquisition Costs (TAC). A reduction in employee compensation expenses also contributed positively to the income increase. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7, Segment Profitability]"
186
+ },
187
+ {
188
+ "query": "The report mentions 'Alphabet-level activities' in its segment reporting. What types of costs are typically included in this category and not allocated to the main segments?",
189
+ "expected_tool_use": [
190
+ {
191
+ "tool_name": "retrieve_rag_documentation",
192
+ "tool_input": {
193
+ "query": "What costs are included in Alphabet-level activities?"
194
+ }
195
+ }
196
+ ],
197
+ "reference": "Costs included in Alphabet-level activities primarily consist of certain AI-focused shared R&D (like general AI model development), corporate initiatives (e.g., philanthropy), corporate shared costs (some finance, HR, legal functions, certain fines/settlements), charges related to employee severance and office space optimization (during 2023/2024), and hedging gains/losses related to revenue. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Note 15 & Item 7]"
198
+ },
199
+ {
200
+ "query": "Contrast the year-over-year percentage change in 'Paid clicks' versus 'Cost-per-click' for Google Search & other in 2024. What does this suggest about monetization trends in that area?",
201
+ "expected_tool_use": [
202
+ {
203
+ "tool_name": "retrieve_rag_documentation",
204
+ "tool_input": {
205
+ "query": "Comparison of paid click and cost-per-click growth for Google Search in 2024"
206
+ }
207
+ }
208
+ ],
209
+ "reference": "For Google Search & other in 2024 vs 2023, Paid clicks increased by 5%, while Cost-per-click increased by 7%. This suggests that the average revenue generated per click grew slightly faster than the volume of clicks for these properties during the year. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 7, Monetization Metrics]"
210
+ },
211
+ {
212
+ "query": "What is the purpose of the 'measurement alternative' accounting method used for certain non-marketable equity securities, and how does it differ from marking-to-market based purely on estimated fair value each period?",
213
+ "expected_tool_use": [
214
+ {
215
+ "tool_name": "retrieve_rag_documentation",
216
+ "tool_input": {
217
+ "query": "Explain the 'measurement alternative' accounting for equity securities"
218
+ }
219
+ }
220
+ ],
221
+ "reference": "The measurement alternative measures these securities at cost less impairment, plus or minus adjustments resulting *only* from observable price changes in orderly transactions for identical or similar investments of the same issuer. This differs from marking-to-market based on estimated fair value each period (like public stocks), as adjustments under the measurement alternative only occur upon specific observable events or impairment, reducing period-to-period volatility unless such events occur. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Note 1 & Note 3]"
222
+ },
223
+ {
224
+ "query": "According to the discussion on competition, what types of companies or services represent competitive threats to Google's general-purpose search engine beyond just other search engines?",
225
+ "expected_tool_use": [
226
+ {
227
+ "tool_name": "retrieve_rag_documentation",
228
+ "tool_input": {
229
+ "query": "What types of competitors does Google Search face besides other search engines?"
230
+ }
231
+ }
232
+ ],
233
+ "reference": "Competitive threats mentioned include vertical search engines and e-commerce providers (where users navigate directly), online advertising platforms and networks (including online shopping and streaming services), social networks (used for product/service referrals), and digital assistant providers. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Item 1]"
234
+ },
235
+ {
236
+ "query": "How does Alphabet assess the recoverability of its long-lived assets like property & equipment and operating lease assets, and what happens if an asset is deemed impaired?",
237
+ "expected_tool_use": [
238
+ {
239
+ "tool_name": "retrieve_rag_documentation",
240
+ "tool_input": {
241
+ "query": "Alphabet's process for testing long-lived assets for impairment"
242
+ }
243
+ }
244
+ ],
245
+ "reference": "Alphabet reviews long-lived assets for impairment when events indicate the carrying amount may not be recoverable. Recoverability is assessed by comparing the carrying amount to the *future undiscounted cash flows* the asset or asset group is expected to generate. If the carrying value is not recoverable, an impairment loss is recognized, measured as the amount by which the carrying value exceeds the asset's *fair value*. [Citation: Based on Alphabet 10-K for FYE Dec 31, 2024, Note 1]"
246
+ },
247
+ {
248
+ "query": "That covers my questions for now. Thanks!",
249
+ "expected_tool_use": [],
250
+ "reference": "You're welcome! Glad I could help. Feel free to ask if anything else comes up."
251
+ }
252
+ ]
Agentic_RAG/eval/data/test_config.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ {
2
+ "criteria": {
3
+ "tool_trajectory_avg_score": 0.09,
4
+ "response_match_score": 0.4
5
+ }
6
+ }
Agentic_RAG/eval/test_eval.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import pathlib
16
+
17
+ import dotenv
18
+ import pytest
19
+ from google.adk.evaluation.agent_evaluator import AgentEvaluator
20
+
21
+ pytest_plugins = ("pytest_asyncio",)
22
+
23
+
24
+ @pytest.fixture(scope="session", autouse=True)
25
+ def load_env():
26
+ dotenv.load_dotenv()
27
+
28
+
29
+ @pytest.mark.asyncio
30
+ async def test_eval_full_conversation():
31
+ """Test the agent's basic ability on a few examples."""
32
+ await AgentEvaluator.evaluate(
33
+ agent_module="rag",
34
+ eval_dataset_file_path_or_dir=str(
35
+ pathlib.Path(__file__).parent / "data/conversation.test.json"
36
+ ),
37
+ num_runs=1,
38
+ )
Agentic_RAG/pyproject.toml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ name = "rag"
3
+ version = "0.1.0"
4
+ description = "Answer questions related to Vertex AI documentation using Vertex AI RAG Engine"
5
+ authors = [
6
+ { name = "Hangfei Lin", email = "hangfei@google.com" },
7
+ { name = "Chouaieb Nemri", email = "nemri@google.com" },
8
+ ]
9
+
10
+ license = "Apache License 2.0"
11
+ readme = "README.md"
12
+
13
+ [tool.poetry.dependencies]
14
+ python = "^3.11"
15
+ pydantic-settings = "^2.8.1"
16
+ tabulate = "^0.9.0"
17
+ google-auth = "^2.36.0"
18
+ requests = "^2.32.3"
19
+ google-adk = "^1.10.0"
20
+ google-cloud-aiplatform = { extras = [
21
+ "adk",
22
+ "agent-engines",
23
+ ], version = "^1.108.0" }
24
+ llama-index = "^0.12"
25
+
26
+ [tool.poetry.group.dev.dependencies]
27
+ pytest = "^8.3.5"
28
+ pytest-mock = "^3.14.0"
29
+ scikit-learn = "^1.6.1"
30
+ pytest-cov = "^6.0.0"
31
+ pytest-asyncio = "^0.26.0"
32
+ black = "^25.1.0"
33
+
34
+ [build-system]
35
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
36
+ build-backend = "poetry.core.masonry.api"
Agentic_RAG/rag/__init__.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from . import agent
Agentic_RAG/rag/agent.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ import os
16
+
17
+ from google.adk.agents import Agent
18
+ from google.adk.tools.retrieval.vertex_ai_rag_retrieval import VertexAiRagRetrieval
19
+ from vertexai.preview import rag
20
+
21
+ from dotenv import load_dotenv
22
+ from .prompts import return_instructions_root
23
+
24
+ load_dotenv()
25
+
26
+ ask_vertex_retrieval = VertexAiRagRetrieval(
27
+ name='retrieve_rag_documentation',
28
+ description=(
29
+ 'Use this tool to retrieve documentation and reference materials for the question from the RAG corpus,'
30
+ ),
31
+ rag_resources=[
32
+ rag.RagResource(
33
+ # please fill in your own rag corpus
34
+ # here is a sample rag corpus for testing purpose
35
+ # e.g. projects/123/locations/us-central1/ragCorpora/456
36
+ rag_corpus=os.environ.get("RAG_CORPUS")
37
+ )
38
+ ],
39
+ similarity_top_k=10,
40
+ vector_distance_threshold=0.6,
41
+ )
42
+
43
+ root_agent = Agent(
44
+ model='gemini-2.5-flash',
45
+ name='ask_rag_agent',
46
+ instruction=return_instructions_root(),
47
+ tools=[
48
+ ask_vertex_retrieval,
49
+ ]
50
+ )
Agentic_RAG/rag/prompts.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """Module for storing and retrieving agent instructions.
16
+
17
+ This module defines functions that return instruction prompts for the root agent.
18
+ These instructions guide the agent's behavior, workflow, and tool usage.
19
+ """
20
+
21
+
22
+ def return_instructions_root() -> str:
23
+
24
+ instruction_prompt_v1 = """
25
+ You are an AI assistant with access to specialized corpus of documents.
26
+ Your role is to provide accurate and concise answers to questions based
27
+ on documents that are retrievable using ask_vertex_retrieval. If you believe
28
+ the user is just chatting and having casual conversation, don't use the retrieval tool.
29
+
30
+ But if the user is asking a specific question about a knowledge they expect you to have,
31
+ you can use the retrieval tool to fetch the most relevant information.
32
+
33
+ If you are not certain about the user intent, make sure to ask clarifying questions
34
+ before answering. Once you have the information you need, you can use the retrieval tool
35
+ If you cannot provide an answer, clearly explain why.
36
+
37
+ Do not answer questions that are not related to the corpus.
38
+ When crafting your answer, you may use the retrieval tool to fetch details
39
+ from the corpus. Make sure to cite the source of the information.
40
+
41
+ Citation Format Instructions:
42
+
43
+ When you provide an answer, you must also add one or more citations **at the end** of
44
+ your answer. If your answer is derived from only one retrieved chunk,
45
+ include exactly one citation. If your answer uses multiple chunks
46
+ from different files, provide multiple citations. If two or more
47
+ chunks came from the same file, cite that file only once.
48
+
49
+ **How to cite:**
50
+ - Use the retrieved chunk's `title` to reconstruct the reference.
51
+ - Include the document title and section if available.
52
+ - For web resources, include the full URL when available.
53
+
54
+ Format the citations at the end of your answer under a heading like
55
+ "Citations" or "References." For example:
56
+ "Citations:
57
+ 1) RAG Guide: Implementation Best Practices
58
+ 2) Advanced Retrieval Techniques: Vector Search Methods"
59
+
60
+ Do not reveal your internal chain-of-thought or how you used the chunks.
61
+ Simply provide concise and factual answers, and then list the
62
+ relevant citation(s) at the end. If you are not certain or the
63
+ information is not available, clearly state that you do not have
64
+ enough information.
65
+ """
66
+
67
+ instruction_prompt_v0 = """
68
+ You are a Documentation Assistant. Your role is to provide accurate and concise
69
+ answers to questions based on documents that are retrievable using ask_vertex_retrieval. If you believe
70
+ the user is just discussing, don't use the retrieval tool. But if the user is asking a question and you are
71
+ uncertain about a query, ask clarifying questions; if you cannot
72
+ provide an answer, clearly explain why.
73
+
74
+ When crafting your answer,
75
+ you may use the retrieval tool to fetch code references or additional
76
+ details. Citation Format Instructions:
77
+
78
+ When you provide an
79
+ answer, you must also add one or more citations **at the end** of
80
+ your answer. If your answer is derived from only one retrieved chunk,
81
+ include exactly one citation. If your answer uses multiple chunks
82
+ from different files, provide multiple citations. If two or more
83
+ chunks came from the same file, cite that file only once.
84
+
85
+ **How to
86
+ cite:**
87
+ - Use the retrieved chunk's `title` to reconstruct the
88
+ reference.
89
+ - Include the document title and section if available.
90
+ - For web resources, include the full URL when available.
91
+
92
+ Format the citations at the end of your answer under a heading like
93
+ "Citations" or "References." For example:
94
+ "Citations:
95
+ 1) RAG Guide: Implementation Best Practices
96
+ 2) Advanced Retrieval Techniques: Vector Search Methods"
97
+
98
+ Do not
99
+ reveal your internal chain-of-thought or how you used the chunks.
100
+ Simply provide concise and factual answers, and then list the
101
+ relevant citation(s) at the end. If you are not certain or the
102
+ information is not available, clearly state that you do not have
103
+ enough information.
104
+ """
105
+
106
+ return instruction_prompt_v1
Agentic_RAG/rag/shared_libraries/prepare_corpus_and_data.py ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from google.auth import default
16
+ from google.api_core.exceptions import ResourceExhausted
17
+ import vertexai
18
+ from vertexai.preview import rag
19
+ import os
20
+ from dotenv import load_dotenv, set_key
21
+ import requests
22
+ import tempfile
23
+
24
+ # Load environment variables from .env file
25
+ load_dotenv()
26
+
27
+ # --- Please fill in your configurations ---
28
+ # Retrieve the PROJECT_ID from the environmental variables.
29
+ PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")
30
+ if not PROJECT_ID:
31
+ raise ValueError(
32
+ "GOOGLE_CLOUD_PROJECT environment variable not set. Please set it in your .env file."
33
+ )
34
+ LOCATION = os.getenv("GOOGLE_CLOUD_LOCATION")
35
+ if not LOCATION:
36
+ raise ValueError(
37
+ "GOOGLE_CLOUD_LOCATION environment variable not set. Please set it in your .env file."
38
+ )
39
+ CORPUS_DISPLAY_NAME = "Alphabet_10K_2024_corpus"
40
+ CORPUS_DESCRIPTION = "Corpus containing Alphabet's 10-K 2024 document"
41
+ PDF_URL = "https://abc.xyz/assets/77/51/9841ad5c4fbe85b4440c47a4df8d/goog-10-k-2024.pdf"
42
+ PDF_FILENAME = "goog-10-k-2024.pdf"
43
+ ENV_FILE_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", ".env"))
44
+
45
+
46
+ # --- Start of the script ---
47
+ def initialize_vertex_ai():
48
+ credentials, _ = default()
49
+ vertexai.init(
50
+ project=PROJECT_ID, location=LOCATION, credentials=credentials
51
+ )
52
+
53
+
54
+ def create_or_get_corpus():
55
+ """Creates a new corpus or retrieves an existing one."""
56
+ embedding_model_config = rag.EmbeddingModelConfig(
57
+ publisher_model="publishers/google/models/text-embedding-004"
58
+ )
59
+ existing_corpora = rag.list_corpora()
60
+ corpus = None
61
+ for existing_corpus in existing_corpora:
62
+ if existing_corpus.display_name == CORPUS_DISPLAY_NAME:
63
+ corpus = existing_corpus
64
+ print(f"Found existing corpus with display name '{CORPUS_DISPLAY_NAME}'")
65
+ break
66
+ if corpus is None:
67
+ corpus = rag.create_corpus(
68
+ display_name=CORPUS_DISPLAY_NAME,
69
+ description=CORPUS_DESCRIPTION,
70
+ embedding_model_config=embedding_model_config,
71
+ )
72
+ print(f"Created new corpus with display name '{CORPUS_DISPLAY_NAME}'")
73
+ return corpus
74
+
75
+
76
+ def download_pdf_from_url(url, output_path):
77
+ """Downloads a PDF file from the specified URL."""
78
+ print(f"Downloading PDF from {url}...")
79
+ response = requests.get(url, stream=True)
80
+ response.raise_for_status() # Raise an exception for HTTP errors
81
+
82
+ with open(output_path, 'wb') as f:
83
+ for chunk in response.iter_content(chunk_size=8192):
84
+ f.write(chunk)
85
+
86
+ print(f"PDF downloaded successfully to {output_path}")
87
+ return output_path
88
+
89
+
90
+ def upload_pdf_to_corpus(corpus_name, pdf_path, display_name, description):
91
+ """Uploads a PDF file to the specified corpus."""
92
+ print(f"Uploading {display_name} to corpus...")
93
+ try:
94
+ rag_file = rag.upload_file(
95
+ corpus_name=corpus_name,
96
+ path=pdf_path,
97
+ display_name=display_name,
98
+ description=description,
99
+ )
100
+ print(f"Successfully uploaded {display_name} to corpus")
101
+ return rag_file
102
+ except ResourceExhausted as e:
103
+ print(f"Error uploading file {display_name}: {e}")
104
+ print("\nThis error suggests that you have exceeded the API quota for the embedding model.")
105
+ print("This is common for new Google Cloud projects.")
106
+ print("Please see the 'Troubleshooting' section in the README.md for instructions on how to request a quota increase.")
107
+ return None
108
+ except Exception as e:
109
+ print(f"Error uploading file {display_name}: {e}")
110
+ return None
111
+
112
+ def update_env_file(corpus_name, env_file_path):
113
+ """Updates the .env file with the corpus name."""
114
+ try:
115
+ set_key(env_file_path, "RAG_CORPUS", corpus_name)
116
+ print(f"Updated RAG_CORPUS in {env_file_path} to {corpus_name}")
117
+ except Exception as e:
118
+ print(f"Error updating .env file: {e}")
119
+
120
+ def list_corpus_files(corpus_name):
121
+ """Lists files in the specified corpus."""
122
+ files = list(rag.list_files(corpus_name=corpus_name))
123
+ print(f"Total files in corpus: {len(files)}")
124
+ for file in files:
125
+ print(f"File: {file.display_name} - {file.name}")
126
+
127
+
128
+ def main():
129
+ initialize_vertex_ai()
130
+ corpus = create_or_get_corpus()
131
+
132
+ # Update the .env file with the corpus name
133
+ update_env_file(corpus.name, ENV_FILE_PATH)
134
+
135
+ # Create a temporary directory to store the downloaded PDF
136
+ with tempfile.TemporaryDirectory() as temp_dir:
137
+ pdf_path = os.path.join(temp_dir, PDF_FILENAME)
138
+
139
+ # Download the PDF from the URL
140
+ download_pdf_from_url(PDF_URL, pdf_path)
141
+
142
+ # Upload the PDF to the corpus
143
+ upload_pdf_to_corpus(
144
+ corpus_name=corpus.name,
145
+ pdf_path=pdf_path,
146
+ display_name=PDF_FILENAME,
147
+ description="Alphabet's 10-K 2024 document"
148
+ )
149
+
150
+ # List all files in the corpus
151
+ list_corpus_files(corpus_name=corpus.name)
152
+
153
+ if __name__ == "__main__":
154
+ main()
Agentic_RAG/tests/__init__.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2025 Google LLC
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+