Skip to content

Commit 5fba196

Browse files
xuanyang15copybara-github
authored andcommitted
chore: add Gemini API docs as a new datastore for the ADK Answering Agent
PiperOrigin-RevId: 794247007
1 parent 7d2cb65 commit 5fba196

File tree

6 files changed

+129
-11
lines changed

6 files changed

+129
-11
lines changed

.github/workflows/discussion_answering.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
- name: Install dependencies
2828
run: |
2929
python -m pip install --upgrade pip
30-
pip install google-adk
30+
pip install google-adk google-cloud-discoveryengine
3131
3232
- name: Run Answering Script
3333
env:

contributing/samples/adk_answering_agent/agent.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
from adk_answering_agent.gemini_assistant.agent import root_agent as gemini_assistant_agent
1516
from adk_answering_agent.settings import BOT_RESPONSE_LABEL
1617
from adk_answering_agent.settings import IS_INTERACTIVE
1718
from adk_answering_agent.settings import OWNER
@@ -22,6 +23,7 @@
2223
from adk_answering_agent.tools import convert_gcs_links_to_https
2324
from adk_answering_agent.tools import get_discussion_and_comments
2425
from google.adk.agents.llm_agent import Agent
26+
from google.adk.tools.agent_tool import AgentTool
2527
from google.adk.tools.vertex_ai_search_tool import VertexAiSearchTool
2628

2729
if IS_INTERACTIVE:
@@ -52,28 +54,31 @@
5254
* The latest comment is not from you or other agents (marked as "Response from XXX Agent").
5355
* The latest comment is asking a question or requesting information.
5456
4. Use the `VertexAiSearchTool` to find relevant information before answering.
57+
* If you need infromation about Gemini API, ask the `gemini_assistant` agent to provide the information and references.
58+
* You can call the `gemini_assistant` agent with multiple queries to find all the relevant information.
5559
5. If you can find relevant information, use the `add_comment_to_discussion` tool to add a comment to the discussion.
56-
6. If you post a commment and the discussion does not have a label named {BOT_RESPONSE_LABEL},
57-
add the label {BOT_RESPONSE_LABEL} to the discussion using the `add_label_to_discussion` tool.
58-
60+
6. If you post a comment, add the label {BOT_RESPONSE_LABEL} to the discussion using the `add_label_to_discussion` tool.
5961
6062
IMPORTANT:
6163
* {APPROVAL_INSTRUCTION}
6264
* Your response should be based on the information you found in the document store. Do not invent
6365
information that is not in the document store. Do not invent citations which are not in the document store.
6466
* **Be Objective**: your answer should be based on the facts you found in the document store, do not be misled by user's assumptions or user's understanding of ADK.
6567
* If you can't find the answer or information in the document store, **do not** respond.
66-
* Inlclude a short summary of your response in the comment as a TLDR, e.g. "**TLDR**: <your summary>".
68+
* Start with a short summary of your response in the comment as a TLDR, e.g. "**TLDR**: <your summary>".
6769
* Have a divider line between the TLDR and your detail response.
6870
* Do not respond to any other discussion except the one specified by the user.
6971
* Please include your justification for your decision in your output
7072
to the user who is telling with you.
7173
* If you uses citation from the document store, please provide a footnote
7274
referencing the source document format it as: "[1] publicly accessible HTTPS URL of the document".
73-
* You can use the `convert_gcs_links_to_https` tool to convert GCS links to HTTPS links.
75+
* You **should always** use the `convert_gcs_links_to_https` tool to convert GCS links (e.g. "gs://...") to HTTPS links.
76+
* **Do not** use the `convert_gcs_links_to_https` tool for non-GCS links.
77+
* Make sure the citation URL is valid. Otherwise do not list this specific citation.
7478
""",
7579
tools=[
7680
VertexAiSearchTool(data_store_id=VERTEXAI_DATASTORE_ID),
81+
AgentTool(gemini_assistant_agent),
7782
get_discussion_and_comments,
7883
add_comment_to_discussion,
7984
add_label_to_discussion,
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
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 json
16+
from typing import Any
17+
from typing import Dict
18+
from typing import List
19+
20+
from adk_answering_agent.settings import ADK_GCP_SA_KEY
21+
from adk_answering_agent.settings import GEMINI_API_DATASTORE_ID
22+
from adk_answering_agent.utils import error_response
23+
from google.adk.agents.llm_agent import Agent
24+
from google.api_core.exceptions import GoogleAPICallError
25+
from google.cloud import discoveryengine_v1beta as discoveryengine
26+
from google.oauth2 import service_account
27+
28+
29+
def search_gemini_api_docs(queries: List[str]) -> Dict[str, Any]:
30+
"""Searches Gemini API docs using Vertex AI Search.
31+
32+
Args:
33+
queries: The list of queries to search.
34+
35+
Returns:
36+
A dictionary containing the status of the request and the list of search
37+
results, which contains the title, url and snippets.
38+
"""
39+
try:
40+
adk_gcp_sa_key_info = json.loads(ADK_GCP_SA_KEY)
41+
client = discoveryengine.SearchServiceClient(
42+
credentials=service_account.Credentials.from_service_account_info(
43+
adk_gcp_sa_key_info
44+
)
45+
)
46+
except (TypeError, ValueError) as e:
47+
return error_response(f"Error creating Vertex AI Search client: {e}")
48+
49+
serving_config = f"{GEMINI_API_DATASTORE_ID}/servingConfigs/default_config"
50+
results = []
51+
try:
52+
for query in queries:
53+
request = discoveryengine.SearchRequest(
54+
serving_config=serving_config,
55+
query=query,
56+
page_size=20,
57+
)
58+
response = client.search(request=request)
59+
for item in response.results:
60+
snippets = []
61+
for snippet in item.document.derived_struct_data.get("snippets", []):
62+
snippets.append(snippet.get("snippet"))
63+
64+
results.append({
65+
"title": item.document.derived_struct_data.get("title"),
66+
"url": item.document.derived_struct_data.get("link"),
67+
"snippets": snippets,
68+
})
69+
except GoogleAPICallError as e:
70+
return error_response(f"Error from Vertex AI Search: {e}")
71+
return {"status": "success", "results": results}
72+
73+
74+
root_agent = Agent(
75+
model="gemini-2.5-pro",
76+
name="gemini_assistant",
77+
description="Answer questions about Gemini API.",
78+
instruction="""
79+
You are a helpful assistant that responds to questions about Gemini API based on information
80+
found in the document store. You can access the document store using the `search_gemini_api_docs` tool.
81+
82+
When user asks a question, here are the steps:
83+
1. Use the `search_gemini_api_docs` tool to find relevant information before answering.
84+
* You can call the tool with multiple queries to find all the relevant information.
85+
2. Provide a response based on the information you found in the document store. Reference the source document in the response.
86+
87+
IMPORTANT:
88+
* Your response should be based on the information you found in the document store. Do not invent
89+
information that is not in the document store. Do not invent citations which are not in the document store.
90+
* If you can't find the answer or information in the document store, just respond with "I can't find the answer or information in the document store".
91+
* If you uses citation from the document store, please always provide a footnote referencing the source document format it as: "[1] URL of the document".
92+
""",
93+
tools=[search_gemini_api_docs],
94+
)

contributing/samples/adk_answering_agent/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131

3232
GOOGLE_CLOUD_PROJECT = os.getenv("GOOGLE_CLOUD_PROJECT")
3333
GCS_BUCKET_NAME = os.getenv("GCS_BUCKET_NAME")
34+
GEMINI_API_DATASTORE_ID = os.getenv("GEMINI_API_DATASTORE_ID")
35+
ADK_GCP_SA_KEY = os.getenv("ADK_GCP_SA_KEY")
36+
3437
ADK_DOCS_ROOT_PATH = os.getenv("ADK_DOCS_ROOT_PATH")
3538
ADK_PYTHON_ROOT_PATH = os.getenv("ADK_PYTHON_ROOT_PATH")
3639

contributing/samples/adk_answering_agent/tools.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,12 @@ def add_comment_to_discussion(
125125
}
126126
}
127127
"""
128-
comment_body = (
129-
"**Response from ADK Answering Agent (experimental, answer may be"
130-
" inaccurate)**\n\n"
131-
+ comment_body
132-
)
128+
if not comment_body.startswith("**Response from ADK Answering Agent"):
129+
comment_body = (
130+
"**Response from ADK Answering Agent (experimental, answer may be"
131+
" inaccurate)**\n\n"
132+
+ comment_body
133+
)
133134

134135
variables = {"discussionId": discussion_id, "body": comment_body}
135136
try:

0 commit comments

Comments
 (0)