Build a Smart AI Financial Advisor Using Google ADK
Build an intelligent agent that analyzes U.S. tax scenarios (2025 IRS brackets), optimizes 401(k)/IRA contributions, and calculates mortgage acceleration strategies.
A comprehensive guide to building a specialized US financial planning agent using Google ADK, Python, and Gemini.
What You'll Build
You will create a Python-based AI agent that acts as a personal financial planner. Unlike generic chatbots, this agent uses deterministic tools for precise calculations while leveraging LLMs for reasoning and natural language explanation.
Tax Optimization
- Precise 2025 IRS tax bracket calculations
- Standard deduction logic ($15,750 Single)
- 401(k) and IRA tax-savings analysis
Mortgage Mastery
- Monthly payment calculation
- Lump-sum payoff modeling
- Interest savings projections
Debt Management
- High-interest debt detection
- "Avalanche method" prioritization
- Cash flow allocation strategy
Intelligent Advice
- Context-aware recommendations
- Synthesized financial plans
- Clear, explainable logic
Prerequisites
- Python 3.8+ is installed on your local machine.
- Google Cloud Platform Account with Vertex AI API enabled.
- Google ADK (Agent Development Kit) familiarity.
- Basic Financial Knowledge: Understanding of US progressive tax brackets, standard deductions, and retirement accounts (401k/IRA).
Architecture Overview
The system follows a standard Tool-Use Agent architecture:
- User Input: The user provides financial data (income, debts, mortgage details).
- Agent Core (Gemini 2.0): The LLM analyzes the request and decides which tools to call.
- Deterministic Tools:Python functions handle the math:
tax_tools.py: Handles IRS brackets and tax logic.mortgage_tools.py: Handles amortization and interest math.
- Synthesis: The Agent combines tool outputs into a coherent, personalized advice narrative.
STEP 1: Project Setup
Create a clean directory for your project and install the necessary dependencies.
# 1. Create project directory
mkdir ai_financial_advisor
cd ai_financial_advisor
# 2. Create virtual environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# 3. Install dependencies
pip install google-adk numpy-financial google-cloud-aiplatform
Important:
Ensure you have authenticated with Google Cloud using gcloud auth application-default login before running the agent.
STEP 2: Tax Calculation Tools (tax_tools.py)
This module handles US-specific tax logic using 2025 IRS data. It calculates progressive tax liability and estimates savings from 401(k) contributions.
File: backend/tools/tax_tools.py
import logging
from typing import List, Dict
logger = logging.getLogger(__name__)
# --- 2025 US Federal Tax Brackets (Single Filer) ---
# Source: IRS Inflation Adjustments for Tax Year 2025
TAX_BRACKETS = [
{"limit": 11925, "rate": 0.10},
{"limit": 48475, "rate": 0.12},
{"limit": 103350, "rate": 0.22},
{"limit": 197300, "rate": 0.24},
{"limit": 250525, "rate": 0.32},
{"limit": 626350, "rate": 0.35},
{"limit": float('inf'), "rate": 0.37},
]
# 2025 Standard Deduction for Single Filers
STANDARD_DEDUCTION = 15750
def _calculate_federal_tax(gross_income):
"""Calculates US federal tax using progressive brackets."""
# Apply Standard Deduction
taxable_income = max(0, gross_income - STANDARD_DEDUCTION)
tax_owing = 0
previous_limit = 0
for bracket in TAX_BRACKETS:
limit = bracket["limit"]
rate = bracket["rate"]
# Determine income falling into this bracket
if taxable_income > previous_limit:
income_in_bracket = min(taxable_income, limit) - previous_limit
tax_owing += income_in_bracket * rate
previous_limit = limit
if taxable_income <= limit:
break
return tax_owing
def calculate_tax_scenario(
income: float,
contribution_401k: float = 0.0
) -> dict:
"""
Calculates estimated federal taxes before and after a Traditional 401(k) contribution.
"""
try:
if income < 0 or contribution_401k < 0:
return {"status": "error", "error_message": "Income and contribution cannot be negative."}
# Traditional 401(k) reduces current year taxable gross income
income_after_contrib = max(0, income - contribution_401k)
tax_before = _calculate_federal_tax(income)
tax_after = _calculate_federal_tax(income_after_contrib)
tax_savings = max(0, tax_before - tax_after)
logger.info(f"Tax Scenario: Income=${income:,.2f}, 401k=${contribution_401k:,.2f}, Savings=${tax_savings:,.2f}")
return {
"status": "success",
"gross_income": income,
"contribution_401k": contribution_401k,
"standard_deduction": STANDARD_DEDUCTION,
"estimated_tax_before_401k": round(tax_before, 2),
"estimated_tax_after_401k": round(tax_after, 2),
"estimated_tax_savings": round(tax_savings, 2)
}
except Exception as e:
logger.error(f"Error in calculate_tax_scenario: {e}", exc_info=True)
return {"status": "error", "error_message": str(e)}
def recommend_contribution_strategy(
income: float,
debts: List[dict],
available_funds: float = 0.0,
age: int = 30
) -> dict:
"""
Recommends a 401(k)/IRA strategy based on debt and 2025 contribution limits.
"""
try:
recommendations = []
remaining_funds = available_funds
# 2025 Contribution Limits
LIMIT_401K = 23500
LIMIT_IRA = 7000
# Catch-up contributions for age 50+
if age >= 50:
LIMIT_401K += 7500
LIMIT_IRA += 1000
# 1. High-Interest Debt Check (Avalanche Method)
high_interest_threshold = 7.0
high_interest_debts = [d for d in debts if d.get('interest_rate', 0) > high_interest_threshold]
if high_interest_debts:
high_interest_debts.sort(key=lambda x: x.get('interest_rate', 0), reverse=True)
top_debt = high_interest_debts[0]
recommendations.append(
f"CRITICAL: You have high-interest debt ({top_debt['type']} at {top_debt['interest_rate']}%). "
f"Prioritize paying this off before maximizing retirement contributions beyond an employer match."
)
# Allocate funds to debt first
debt_payment = min(remaining_funds, top_debt.get('balance', 0))
remaining_funds -= debt_payment
# 2. Retirement Contributions
if remaining_funds > 0:
rec_401k = min(remaining_funds, LIMIT_401K)
if rec_401k > 0:
recommendations.append(
f"Contribute ${rec_401k:,.2f} to your 401(k). This lowers your taxable income immediately. "
f"2025 Limit is ${LIMIT_401K:,.0f}."
)
remaining_funds -= rec_401k
if remaining_funds > 0:
rec_ira = min(remaining_funds, LIMIT_IRA)
recommendations.append(
f"With remaining funds, consider funding an IRA (Traditional or Roth) up to ${rec_ira:,.2f}. "
f"2025 Limit is ${LIMIT_IRA:,.0f}."
)
return {
"status": "success",
"recommendations": recommendations,
"limits_used": {"401k_limit": LIMIT_401K, "ira_limit": LIMIT_IRA}
}
except Exception as e:
logger.error(f"Error in strategy: {e}")
return {"status": "error", "error_message": str(e)}
STEP 3: Mortgage Tools (mortgage_tools.py)
This module calculates standard fixed-rate mortgage payments. It is essential for determining if a user should use their tax refund to pay down principal.
File: backend/tools/mortgage_tools.py
import logging
import numpy_financial as npf
logger = logging.getLogger(__name__)
def _calculate_monthly_payment(principal, annual_interest_rate, years):
"""Calculates the fixed monthly mortgage payment (P&I)."""
if principal <= 0 or annual_interest_rate < 0 or years <= 0:
return 0
monthly_rate = (annual_interest_rate / 100) / 12
num_payments = years * 12
# Returns negative value, so we negate it
return -npf.pmt(monthly_rate, num_payments, principal)
def analyze_mortgage_profile(
principal: float,
annual_interest_rate: float,
remaining_years: float
) -> dict:
"""
Analyzes current mortgage status.
"""
try:
monthly_payment = _calculate_monthly_payment(principal, annual_interest_rate, remaining_years)
total_paid = monthly_payment * remaining_years * 12
total_interest = total_paid - principal
return {
"status": "success",
"current_principal": principal,
"interest_rate": annual_interest_rate,
"monthly_payment": round(monthly_payment, 2),
"total_interest_remaining": round(total_interest, 2)
}
except Exception as e:
return {"status": "error", "error_message": str(e)}
def generate_acceleration_scenario(
principal: float,
annual_interest_rate: float,
remaining_years: float,
lump_sum_payment: float = 0.0
) -> dict:
"""
Calculates impact of applying a lump sum (e.g., tax refund) to principal.
"""
try:
# Baseline
orig_payment = _calculate_monthly_payment(principal, annual_interest_rate, remaining_years)
orig_interest = (orig_payment * remaining_years * 12) - principal
# New Scenario: Reduce principal immediately
new_principal = principal - lump_sum_payment
if new_principal <= 0:
return {"status": "success", "message": "Mortgage fully paid off!"}
monthly_rate = (annual_interest_rate / 100) / 12
# Calculate new number of periods (nper) keeping payment same
new_num_payments = npf.nper(monthly_rate, -orig_payment, new_principal)
new_years = new_num_payments / 12
new_total_cost = (orig_payment * new_num_payments)
new_interest = new_total_cost - new_principal
interest_saved = orig_interest - new_interest
return {
"status": "success",
"lump_sum_applied": lump_sum_payment,
"original_payoff_years": remaining_years,
"new_payoff_years": round(new_years, 2),
"years_saved": round(remaining_years - new_years, 2),
"interest_saved": round(interest_saved, 2)
}
except Exception as e:
return {"status": "error", "error_message": str(e)}
STEP 4: Financial Advisor Agent Configuration
Now we assemble the agent using Google ADK. The key here is the instruction prompt, which must strictly enforce the persona of a US financial planner.
File: backend/agents/financial_advisor_agent.py
from google.adk.agents import Agent
from tools.tax_tools import calculate_tax_scenario, recommend_contribution_strategy
from tools.mortgage_tools import analyze_mortgage_profile, generate_acceleration_scenario
# Define the tools list
financial_tools = [
calculate_tax_scenario,
recommend_contribution_strategy,
analyze_mortgage_profile,
generate_acceleration_scenario
]
# Configure the Agent
advisor_agent = Agent(
name="us_financial_advisor",
model="gemini-2.5-flash", # Fast, efficient model
description="A US-focused financial advisor for tax and debt planning.",
instruction=(
"You are an expert US Financial Advisor. Your goal is to optimize the user's financial health "
"by minimizing federal tax liability and efficiently managing debt.\n\n"
"RULES & BEHAVIORS:\n"
"1. ALWAYS prioritize high-interest debt (Credit Cards, Personal Loans > 7%) over investing.\n"
"2. Use 'calculate_tax_scenario' to show the specific dollar benefit of 401(k) contributions.\n"
"3. If the user gets a tax refund (savings), suggest applying it to their mortgage using 'generate_acceleration_scenario' IF they plan to stay in the home long-term.\n"
"4. All tax references must use 2025 IRS rules. The standard deduction is $15,750 for singles.\n"
"5. Explain concepts simply. Do not just output numbers; explain WHY a strategy works."
),
tools=financial_tools
)
STEP 5: Project Structure
Ensure your final directory looks like this. Don't forget empty `__init__.py` files to make directories treatable as packages.
ai_financial_advisor/
├── venv/
├── backend/
│ ├── __init__.py
│ ├── agents/
│ │ ├── __init__.py
│ │ └── financial_advisor_agent.py
│ └── tools/
│ ├── __init__.py
│ ├── tax_tools.py
│ └── mortgage_tools.py
└── main.py # Entry point script
STEP 6: Testing Your Agent
Create a simple `main.py` to interact with your agent.
# main.py
from backend.agents.financial_advisor_agent import advisor_agent
# Scenario: Single earner, high income, some credit card debt
user_query = (
"I make $110,000/year. I have $5,000 on a credit card at 18% APR. "
"I also have a $300,000 mortgage at 6.5% with 25 years left. "
"I have $10,000 in cash available. Should I put it in my 401k or pay off debt?"
)
response = advisor_agent.run(user_query)
print(response)
How It Works
When you run the query above, the following sequence occurs:
- Parsing: Gemini analyzes the prompt and extracts: Income ($110k), Debts (CC: $5k @ 18%), Cash ($10k).
- Tool Call 1 (Strategy): It calls
recommend_contribution_strategy. The tool sees the 18% debt and returns a "CRITICAL" warning to pay that $5k first. - Tool Call 2 (Tax): For the remaining $5k, it calls
calculate_tax_scenarioto see how much tax is saved by putting $5k into a 401(k). - Synthesis: The agent combines these. It will tell you: "Pay off the $5,000 credit card immediately because 18% interest is guaranteed loss. Then, put the remaining $5,000 into your 401(k), which will save you approximately $1,100 in taxes."
Example Use Cases
1. The "Young Professional"
Input: $85,000 income, no debt, wants to lower taxes.
Agent Action: Calculates that their marginal rate is 22%. Suggests maximizing 401(k) to reduce taxable income below the $48,475 bracket threshold if possible (though unlikely with just contributions), or simply taking the guaranteed 22% tax savings.
2. The "Mortgage Accelerator"
Input: $150,000 income, received a $4,000 tax refund.
Agent Action: Calls generate_acceleration_scenario with a $4,000 lump sum. It might show that this one-time payment saves $12,000 in interest over the life of a 30-year loan, providing a powerful incentive to invest the refund.
3. The "Debt Trap"
Input: $60,000 income, $15,000 credit card debt.
Agent Action: The agent will aggressively advise against investing. Even though 401(k) saves taxes, the 20%+ APR on credit cards destroys wealth faster. It prioritizes the "Avalanche Method."
Best Practices & Customization
- State Taxes: The current code handles Federal only. You could add a
stateparameter tocalculate_tax_scenarioand import a dictionary of state tax rates. - Catch-up Contributions: Ensure you pass the user's
ageto the strategy tool to unlock higher limits ($31,000 total for 401k) for those over 50. - Security: Never store PII (Personally Identifiable Information) in logs. Notice our loggers only record "Analysis performed" or anonymized figures.
- Database: For a production app, persist user profiles in a database (SQL/NoSQL) so they don't have to re-enter details every session.
Conclusion
By combining Python's computational accuracy with Gemini's reasoning capabilities, you've built a financial advisor that is both smart and safe. It doesn't hallucinate tax math—it calculates it—while still providing the conversational experience users expect.
Opinions expressed by DZone contributors are their own.