Documentation Index
Fetch the complete documentation index at: https://docs.agentops.ai/llms.txt
Use this file to discover all available pages before exploring further.
View Notebook on Github
Google ADK Human Approval Workflow with AgentOps
This example shows you how to build a complete human approval workflow using Google’s Agent Development Kit (ADK) with comprehensive tracking via AgentOps.
What We’re Building
A 3-agent sequential workflow for processing approval requests:
- 🔍 Prepare Agent: Extracts and validates approval request details
- 👤 Approval Agent: Handles human approval via external tool
- ✅ Decision Agent: Processes approval decisions and provides final response
With AgentOps, you’ll get complete visibility into agent conversations, tool usage, costs, and performance.
Step-by-Step Implementation
Step 1: Install Dependencies
Install Google ADK with required packages and AgentOps for tracking:
pip install google-adk agentops nest_asyncio python-dotenv
What AgentOps adds:
- 🔍 Automatic tracking of all LLM calls and agent interactions
- 💰 Cost monitoring with token usage breakdown
- 🛠️ Tool usage analytics for approval workflow steps
- 📊 Performance metrics and execution timelines
- 🐛 Session replay for debugging and optimization
Step 2: Create Google ADK Project
Create the proper project structure for your approval workflow:
# Create project directory
mkdir human_approval_workflow
cd human_approval_workflow
# Create agent module
mkdir approval_agent
touch approval_agent/__init__.py
touch approval_agent/agent.py
touch approval_agent/.env
This creates the standard Google ADK structure:
human_approval_workflow/
└── approval_agent/
├── __init__.py # Module initialization
├── agent.py # Agent definitions
└── .env # API keys
Step 3: Set Up Environment Variables
Create the .env file in approval_agent/ directory:
# approval_agent/.env
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY=your_google_api_key_here
AGENTOPS_API_KEY=your_agentops_api_key_here
Get your API keys:
Note: For Vertex AI, set GOOGLE_GENAI_USE_VERTEXAI=TRUE and run gcloud auth application-default login
Step 4: Create Module Initialization
Edit approval_agent/__init__.py:
# approval_agent/__init__.py
from . import agent
Step 5: Define the Agent Workflow
Edit approval_agent/agent.py to create your approval workflow:
# approval_agent/agent.py
import json
import os
import asyncio
from google.adk.agents import LlmAgent, SequentialAgent
from google.adk.tools import FunctionTool
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from pydantic import BaseModel, Field
import nest_asyncio
import agentops
from dotenv import load_dotenv
# Load environment and initialize AgentOps
load_dotenv()
nest_asyncio.apply()
agentops.init(auto_start_session=False)
# Constants
APP_NAME = "human_approval_workflow"
USER_ID = "approval_user"
MODEL_NAME = "gemini-2.0-flash"
# Data models
class ApprovalRequest(BaseModel):
amount: float = Field(description="The amount requiring approval")
reason: str = Field(description="The reason for the request")
class ApprovalDecision(BaseModel):
decision: str = Field(description="The approval decision: 'approved' or 'rejected'")
comments: str = Field(description="Additional comments from the approver")
Add the approval tool function:
# External approval tool with human interaction
async def external_approval_tool(amount: float, reason: str) -> str:
"""
Prompts for human approval and returns the decision as a JSON string.
"""
print("🔔 HUMAN APPROVAL REQUIRED:")
print(f" Amount: ${amount:,.2f}")
print(f" Reason: {reason}")
decision = ""
while decision.lower() not in ["approved", "rejected"]:
decision = input(" Enter decision (approved/rejected): ").strip().lower()
if decision.lower() not in ["approved", "rejected"]:
print(" Invalid input. Please enter 'approved' or 'rejected'.")
comments = input(" Enter comments (optional): ").strip()
print(f" Decision: {decision.upper()}")
print(f" Comments: {comments if comments else 'N/A'}")
return json.dumps({"decision": decision, "comments": comments, "amount": amount, "reason": reason})
# Create the approval tool instance
approval_tool = FunctionTool(func=external_approval_tool)
Step 6: Define the Three-Agent Workflow
Add the agent definitions to create your sequential workflow:
# Agent 1: Prepare the approval request
prepare_request = LlmAgent(
model=MODEL_NAME,
name="PrepareApprovalAgent",
description="Extracts and prepares approval request details from user input",
instruction="""You are an approval request preparation agent.
Your task:
1. Extract the amount and reason from the user's request
2. Store these values in the session state with keys 'approval_amount' and 'approval_reason'
3. Validate that both amount and reason are provided
4. Respond with a summary of what will be submitted for approval
If the user input is missing amount or reason, ask for clarification.
""",
output_key="request_prepared",
)
# Agent 2: Request human approval using the tool
request_approval = LlmAgent(
model=MODEL_NAME,
name="RequestHumanApprovalAgent",
description="Calls the external approval system with prepared request details",
instruction="""You are a human approval request agent.
Your task:
1. Get the 'approval_amount' and 'approval_reason' from the session state
2. Use the external_approval_tool with these values
3. Store the approval decision in session state with key 'human_decision'
4. Respond with the approval status
Always use the exact values from the session state for the tool call.
""",
tools=[approval_tool],
output_key="approval_requested",
)
# Agent 3: Process the approval decision
process_decision = LlmAgent(
model=MODEL_NAME,
name="ProcessDecisionAgent",
description="Processes the human approval decision and provides final response",
instruction="""You are a decision processing agent.
Your task:
1. Check the 'human_decision' from session state
2. Parse the approval decision JSON
3. If approved: congratulate and provide next steps
4. If rejected: explain the rejection and suggest alternatives
5. Provide a clear, helpful final response to the user
Be professional and helpful in your response.
""",
output_key="final_decision",
)
Step 7: Create the Sequential Workflow and Runner
Combine agents into a workflow with session management:
# Create sequential workflow
approval_workflow = SequentialAgent(
name="HumanApprovalWorkflow",
description="Complete workflow for processing approval requests with human oversight",
sub_agents=[prepare_request, request_approval, process_decision],
)
# Set up session service and runner
session_service = InMemorySessionService()
workflow_runner = Runner(agent=approval_workflow, app_name=APP_NAME, session_service=session_service)
Step 8: Add the Main Execution Function
Create the function to run the approval workflow with AgentOps tracking:
async def run_approval_workflow(user_request: str, session_id: str):
"""Run the complete approval workflow with AgentOps tracking"""
# Start AgentOps session
session = agentops.start_session(tags=["google-adk", "approval-workflow"])
try:
print(f"{'=' * 60}")
print(f" Starting Approval Workflow for Session: {session_id}")
print(f"{'=' * 60}")
print(f"User Request: {user_request}")
# Create user message
user_content = types.Content(role="user", parts=[types.Part(text=user_request)])
step_count = 0
final_response = "No response received"
# Run the workflow
async for event in workflow_runner.run_async(
user_id=USER_ID,
session_id=session_id,
new_message=user_content,
):
if event.author and event.content:
step_count += 1
print(f"📋 Step {step_count} - {event.author}:")
if event.content.parts:
response_text = event.content.parts[0].text
print(f" {response_text}")
if event.is_final_response():
final_response = response_text
# Display session state
session_data = await session_service.get_session(
app_name=APP_NAME,
user_id=USER_ID,
session_id=session_id,
)
print(f"{'=' * 60}")
print(f"📊 Workflow Complete - Session State ({session_id}):")
print(f"{'=' * 60}")
for key, value in session_data.state.items():
print(f" {key}: {value}")
print(f"🎯 Final Response: {final_response}")
# End AgentOps session successfully
agentops.end_session("Success")
return final_response
except Exception as e:
print(f"Error occurred: {e}")
agentops.end_session("Failed", end_state_reason=str(e))
raise
Finally, add the main execution logic:
# Main execution function
async def main():
test_requests = [
"I need approval for $750 for team lunch and celebrations",
"Please approve $3,000 for a conference ticket and travel expenses",
"I need $12,000 approved for critical software licenses renewal",
]
for i, request in enumerate(test_requests, 1):
current_session_id = f"approval_session_{456 + i - 1}"
# Create the session before running the workflow
await session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=current_session_id)
print(f"Created session: {current_session_id}")
await run_approval_workflow(request, current_session_id)
# Export the workflow for ADK
root_agent = approval_workflow
Step 9: Run Your Approval Workflow
Navigate to your project directory and run the workflow:
Option 1: Interactive Development UI
cd human_approval_workflow
adk web
Then open http://localhost:8000, select “approval_agent” from the dropdown, and interact with your workflow.
Option 2: Terminal Interface
cd human_approval_workflow
adk run approval_agent
Option 3: Run Programmatically
# Run this in a separate script or notebook
import asyncio
from approval_agent.agent import main
if __name__ == "__main__":
try:
asyncio.run(main())
except Exception as e:
print(f"Error: {e}")
What happens:
- AgentOps session starts automatically
- Prepare agent extracts amount and reason from requests
- Approval agent prompts for human input via terminal
- Decision agent processes the approval and provides final response
- AgentOps captures all interactions, tool usage, and costs
- Session ends with success/failure status
View Results in AgentOps Dashboard
After running your approval workflow, visit your AgentOps Dashboard to see:
- Session Overview: Complete timeline of the 3-agent workflow
- Agent Conversations: Every LLM call with prompts and responses
- Tool Execution: Human approval interactions and decisions
- Cost Breakdown: Token usage and costs per agent and step
- Performance Analytics: Execution times and success rates
- Session Replay: Step-by-step playback for debugging
Key Files Created
Project structure you built:
approval_agent/__init__.py - Module initialization with agent import
approval_agent/agent.py - Complete workflow with 3 agents and AgentOps integration
approval_agent/.env - API keys for Google AI and AgentOps
AgentOps Integration Points:
agentops.init() - Enables automatic instrumentation
agentops.start_session() - Begins tracking each workflow run
agentops.end_session() - Completes the session with status
Next Steps
- Customize approval thresholds and business logic
- Add more sophisticated approval routing
- Integrate with external approval systems (Slack, email, etc.)
- Use Google ADK’s web UI for better user experience
- Use AgentOps analytics to optimize approval times