From f2005a20267e1ee8581cb79c37aa55dc8e18c0ea Mon Sep 17 00:00:00 2001 From: "Xiang (Sean) Zhou" Date: Fri, 8 Aug 2025 11:15:58 -0700 Subject: [PATCH] chore: Add sample agent to test support of output_schema and tools at the same time for gemini model PiperOrigin-RevId: 792694074 --- .../output_schema_with_tools/README.md | 36 +++++++ .../output_schema_with_tools/__init__.py | 15 +++ .../samples/output_schema_with_tools/agent.py | 101 ++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 contributing/samples/output_schema_with_tools/README.md create mode 100644 contributing/samples/output_schema_with_tools/__init__.py create mode 100644 contributing/samples/output_schema_with_tools/agent.py diff --git a/contributing/samples/output_schema_with_tools/README.md b/contributing/samples/output_schema_with_tools/README.md new file mode 100644 index 00000000..a275d891 --- /dev/null +++ b/contributing/samples/output_schema_with_tools/README.md @@ -0,0 +1,36 @@ +# Output Schema with Tools Sample Agent + +This sample demonstrates how to use structured output (`output_schema`) alongside other tools in an ADK agent. Previously, this combination was not allowed, but now it's supported through a special processor that handles the interaction. + +## How it Works + +The agent combines: +- **Tools**: `search_wikipedia` and `get_current_year` for gathering information +- **Structured Output**: `PersonInfo` schema to ensure consistent response format + +When both `output_schema` and `tools` are specified: +1. ADK automatically adds a special `set_model_response` tool +2. The model can use the regular tools for information gathering +3. For the final response, the model uses `set_model_response` with structured data +4. ADK extracts and validates the structured response + +## Expected Response Format + +The agent will return information in this structured format for user query "Tell me about Albert Einstein": + +```json +{ + "name": "Albert Einstein", + "age": 76, + "occupation": "Theoretical Physicist", + "location": "Princeton, New Jersey, USA", + "biography": "German-born theoretical physicist who developed the theory of relativity..." +} +``` + +## Key Features Demonstrated + +1. **Tool Usage**: Agent can search Wikipedia and get current year +2. **Structured Output**: Response follows strict PersonInfo schema +3. **Validation**: ADK validates the response matches the schema +4. **Flexibility**: Works with any combination of tools and output schemas diff --git a/contributing/samples/output_schema_with_tools/__init__.py b/contributing/samples/output_schema_with_tools/__init__.py new file mode 100644 index 00000000..c48963cd --- /dev/null +++ b/contributing/samples/output_schema_with_tools/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from . import agent diff --git a/contributing/samples/output_schema_with_tools/agent.py b/contributing/samples/output_schema_with_tools/agent.py new file mode 100644 index 00000000..bd89f18d --- /dev/null +++ b/contributing/samples/output_schema_with_tools/agent.py @@ -0,0 +1,101 @@ +# Copyright 2025 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Sample agent demonstrating output_schema with tools feature. + +This agent shows how to use structured output (output_schema) alongside +other tools. Previously, this combination was not allowed, but now it's +supported through a workaround that uses a special set_model_response tool. +""" + +from google.adk.agents import LlmAgent +from pydantic import BaseModel +from pydantic import Field +import requests + + +class PersonInfo(BaseModel): + """Structured information about a person.""" + + name: str = Field(description="The person's full name") + age: int = Field(description="The person's age in years") + occupation: str = Field(description="The person's job or profession") + location: str = Field(description="The city and country where they live") + biography: str = Field(description="A brief biography of the person") + + +def search_wikipedia(query: str) -> str: + """Search Wikipedia for information about a topic. + + Args: + query: The search query to look up on Wikipedia + + Returns: + Summary of the Wikipedia article if found, or error message if not found + """ + try: + # Use Wikipedia API to search for the article + search_url = ( + "https://en.wikipedia.org/api/rest_v1/page/summary/" + + query.replace(" ", "_") + ) + response = requests.get(search_url, timeout=10) + + if response.status_code == 200: + data = response.json() + return ( + f"Title: {data.get('title', 'N/A')}\n\nSummary:" + f" {data.get('extract', 'No summary available')}" + ) + else: + return ( + f"Wikipedia article not found for '{query}'. Status code:" + f" {response.status_code}" + ) + + except Exception as e: + return f"Error searching Wikipedia: {str(e)}" + + +def get_current_year() -> str: + """Get the current year. + + Returns: + The current year as a string + """ + from datetime import datetime + + return str(datetime.now().year) + + +# Create the agent with both output_schema and tools +root_agent = LlmAgent( + name="person_info_agent", + model="gemini-1.5-pro", + instruction=""" +You are a helpful assistant that gathers information about famous people. + +When asked about a person, you should: +1. Use the search_wikipedia tool to find information about them +2. Use the get_current_year tool if you need to calculate ages +3. Compile the information into a structured response using the PersonInfo format + +Always use the set_model_response tool to provide your final answer in the required structured format. + """.strip(), + output_schema=PersonInfo, + tools=[ + search_wikipedia, + get_current_year, + ], +)