Skip to content
Learn Agentic AI
Learn Agentic AI14 min read5 views

Building a Financial Planning Agent: Budget Analysis, Goal Tracking, and Recommendations

Build an AI financial planning agent that integrates bank data, analyzes spending patterns, tracks savings goals, and generates personalized financial recommendations.

Why Personal Finance Needs Intelligent Agents

Budgeting apps show you what happened. A financial planning agent tells you what to do next. By combining transaction data analysis, goal tracking, and LLM-powered reasoning, an agent can provide the kind of personalized advice that previously required a human financial advisor. In this tutorial, you will build an agent that analyzes spending patterns, monitors progress toward financial goals, and generates actionable recommendations.

System Components

  1. Transaction Analyzer — categorize and analyze spending data
  2. Goal Tracker — monitor progress toward financial targets
  3. Projection Engine — forecast future financial state
  4. Recommendation Generator — produce personalized advice

Step 1: Transaction Analysis

We start by modeling transactions and building a spending analyzer.

flowchart LR
    INPUT(["User intent"])
    PARSE["Parse plus<br/>classify"]
    PLAN["Plan and tool<br/>selection"]
    AGENT["Agent loop<br/>LLM plus tools"]
    GUARD{"Guardrails<br/>and policy"}
    EXEC["Execute and<br/>verify result"]
    OBS[("Trace and metrics")]
    OUT(["Outcome plus<br/>next action"])
    INPUT --> PARSE --> PLAN --> AGENT --> GUARD
    GUARD -->|Pass| EXEC --> OUT
    GUARD -->|Fail| AGENT
    AGENT --> OBS
    style AGENT fill:#4f46e5,stroke:#4338ca,color:#fff
    style GUARD fill:#f59e0b,stroke:#d97706,color:#1f2937
    style OBS fill:#ede9fe,stroke:#7c3aed,color:#1e1b4b
    style OUT fill:#059669,stroke:#047857,color:#fff
from pydantic import BaseModel
from datetime import date, datetime
from collections import defaultdict

class Transaction(BaseModel):
    date: date
    description: str
    amount: float  # negative = expense, positive = income
    category: str | None = None
    account: str

class SpendingSummary(BaseModel):
    period: str
    total_income: float
    total_expenses: float
    net_savings: float
    savings_rate: float
    category_breakdown: dict[str, float]
    top_merchants: list[dict]

def analyze_spending(
    transactions: list[Transaction], period_start: date, period_end: date
) -> SpendingSummary:
    """Analyze spending patterns for a given period."""
    filtered = [
        t for t in transactions
        if period_start <= t.date <= period_end
    ]

    income = sum(t.amount for t in filtered if t.amount > 0)
    expenses = sum(abs(t.amount) for t in filtered if t.amount < 0)
    net = income - expenses
    savings_rate = (net / income * 100) if income > 0 else 0

    # Category breakdown
    by_category = defaultdict(float)
    by_merchant = defaultdict(float)

    for t in filtered:
        if t.amount < 0:
            cat = t.category or "Uncategorized"
            by_category[cat] += abs(t.amount)
            by_merchant[t.description] += abs(t.amount)

    top_merchants = sorted(
        [{"name": k, "total": v} for k, v in by_merchant.items()],
        key=lambda x: x["total"],
        reverse=True,
    )[:10]

    return SpendingSummary(
        period=f"{period_start} to {period_end}",
        total_income=income,
        total_expenses=expenses,
        net_savings=net,
        savings_rate=round(savings_rate, 1),
        category_breakdown=dict(by_category),
        top_merchants=top_merchants,
    )

Step 2: Transaction Categorization with LLM

Bank transactions often have cryptic descriptions. The agent uses an LLM to categorize them.

Hear it before you finish reading

Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.

Try Live Demo →
from openai import OpenAI

client = OpenAI()

class CategorizedTransaction(BaseModel):
    description: str
    category: str
    subcategory: str
    is_recurring: bool
    is_essential: bool

class BatchCategorization(BaseModel):
    transactions: list[CategorizedTransaction]

CATEGORIES = [
    "Housing", "Transportation", "Food & Dining",
    "Utilities", "Healthcare", "Insurance",
    "Entertainment", "Shopping", "Personal Care",
    "Education", "Savings & Investments",
    "Debt Payments", "Gifts & Donations", "Other",
]

def categorize_transactions(
    descriptions: list[str],
) -> list[CategorizedTransaction]:
    """Categorize transactions using an LLM."""
    desc_list = "\n".join(
        f"{i+1}. {d}" for i, d in enumerate(descriptions)
    )

    response = client.beta.chat.completions.parse(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": (
                    "Categorize each transaction into one of these "
                    f"categories: {', '.join(CATEGORIES)}. "
                    "Also identify if it is recurring and essential."
                ),
            },
            {"role": "user", "content": desc_list},
        ],
        response_format=BatchCategorization,
    )
    return response.choices[0].message.parsed.transactions

Step 3: Goal Tracking

Financial goals need monitoring with progress calculations and projections.

from dataclasses import dataclass

@dataclass
class FinancialGoal:
    name: str
    target_amount: float
    current_amount: float
    target_date: date
    monthly_contribution: float
    priority: int  # 1 = highest

    @property
    def progress_pct(self) -> float:
        if self.target_amount == 0:
            return 100.0
        return (self.current_amount / self.target_amount) * 100

    @property
    def remaining(self) -> float:
        return max(0, self.target_amount - self.current_amount)

    @property
    def months_to_goal(self) -> float | None:
        if self.monthly_contribution <= 0:
            return None
        return self.remaining / self.monthly_contribution

    @property
    def on_track(self) -> bool:
        if self.months_to_goal is None:
            return False
        today = date.today()
        months_left = (
            (self.target_date.year - today.year) * 12
            + self.target_date.month - today.month
        )
        return self.months_to_goal <= months_left

def track_goals(goals: list[FinancialGoal]) -> list[dict]:
    """Generate status report for all financial goals."""
    report = []
    for goal in sorted(goals, key=lambda g: g.priority):
        status = {
            "name": goal.name,
            "progress": f"{goal.progress_pct:.1f}%",
            "remaining": goal.remaining,
            "monthly_contribution": goal.monthly_contribution,
            "on_track": goal.on_track,
        }
        if goal.months_to_goal is not None:
            status["months_to_goal"] = round(goal.months_to_goal, 1)
        report.append(status)
    return report

Step 4: Personalized Recommendations

The agent combines spending analysis and goal tracking to generate advice.

def generate_recommendations(
    spending: SpendingSummary,
    goals: list[dict],
    monthly_income: float,
) -> str:
    """Generate personalized financial recommendations."""
    context = (
        f"Monthly Income: ${monthly_income:,.2f}\n"
        f"Monthly Expenses: ${spending.total_expenses:,.2f}\n"
        f"Savings Rate: {spending.savings_rate}%\n\n"
        f"Spending Breakdown:\n"
    )
    for cat, amount in sorted(
        spending.category_breakdown.items(),
        key=lambda x: x[1],
        reverse=True,
    ):
        pct = (amount / spending.total_expenses) * 100
        context += f"  {cat}: ${amount:,.2f} ({pct:.1f}%)\n"

    context += "\nFinancial Goals:\n"
    for goal in goals:
        track = "ON TRACK" if goal["on_track"] else "BEHIND"
        context += (
            f"  {goal['name']}: {goal['progress']} "
            f"[{track}]\n"
        )

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {
                "role": "system",
                "content": (
                    "You are a certified financial planner. Analyze the "
                    "spending data and goals, then provide 5 specific, "
                    "actionable recommendations. Be concrete with dollar "
                    "amounts. Prioritize high-impact changes."
                ),
            },
            {"role": "user", "content": context},
        ],
    )
    return response.choices[0].message.content

Running the Agent

# Load and analyze transactions
spending = analyze_spending(transactions, date(2026, 2, 1), date(2026, 2, 28))

# Track goals
goals = track_goals([
    FinancialGoal("Emergency Fund", 15000, 8500, date(2026, 12, 31), 800, 1),
    FinancialGoal("Vacation", 3000, 1200, date(2026, 8, 1), 400, 2),
])

# Get recommendations
advice = generate_recommendations(spending, goals, 6500.0)
print(advice)

FAQ

How do you connect to real bank data?

Use a service like Plaid, Yodlee, or MX to access transaction data via API. Plaid provides a Python SDK that handles bank authentication and returns standardized transaction objects. Always store tokens securely and never cache raw bank credentials.

Still reading? Stop comparing — try CallSphere live.

CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.

How do you handle privacy when sending financial data to an LLM?

Anonymize transactions before sending them to the LLM — replace merchant names with categories where possible and never include account numbers or personal identifiers. For maximum privacy, use a local model for transaction categorization and only send aggregated summaries to cloud APIs.

Can the agent adapt its advice based on life events?

Yes. Add context about life events (new job, marriage, home purchase) to the recommendation prompt. The LLM can adjust advice accordingly — for example, recommending higher emergency fund targets after a job change or suggesting tax-advantaged accounts after marriage.


#FinancialPlanning #BudgetAnalysis #GoalTracking #PersonalFinance #AIAgent #AgenticAI #LearnAI #AIEngineering

Share

Try CallSphere AI Voice Agents

See how AI voice agents work for your industry. Live demo available -- no signup required.