Upload 16 files
Browse filesadding agentic rag
- .gitattributes +1 -0
- Agentic_RAG/.env.example +23 -0
- Agentic_RAG/RAG_architecture.png +3 -0
- Agentic_RAG/RAG_workflow.png +0 -0
- Agentic_RAG/README.md +328 -0
- Agentic_RAG/deployment/deploy.py +75 -0
- Agentic_RAG/deployment/grant_permissions.sh +91 -0
- Agentic_RAG/deployment/run.py +74 -0
- Agentic_RAG/eval/data/conversation.test.json +252 -0
- Agentic_RAG/eval/data/test_config.json +6 -0
- Agentic_RAG/eval/test_eval.py +38 -0
- Agentic_RAG/pyproject.toml +36 -0
- Agentic_RAG/rag/__init__.py +15 -0
- Agentic_RAG/rag/agent.py +50 -0
- Agentic_RAG/rag/prompts.py +106 -0
- Agentic_RAG/rag/shared_libraries/prepare_corpus_and_data.py +154 -0
- Agentic_RAG/tests/__init__.py +14 -0
.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
|
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 |
+

|
| 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 |
+

|
| 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 |
+
|