Skip to content
Learn Agentic AI
Learn Agentic AI14 min read1 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 TD
    START["Building a Financial Planning Agent: Budget Analy…"] --> A
    A["Why Personal Finance Needs Intelligent …"]
    A --> B
    B["System Components"]
    B --> C
    C["Step 1: Transaction Analysis"]
    C --> D
    D["Step 2: Transaction Categorization with…"]
    D --> E
    E["Step 3: Goal Tracking"]
    E --> F
    F["Step 4: Personalized Recommendations"]
    F --> G
    G["Running the Agent"]
    G --> H
    H["FAQ"]
    H --> DONE["Key Takeaways"]
    style START fill:#4f46e5,stroke:#4338ca,color:#fff
    style DONE 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.

flowchart LR
    S0["Step 1: Transaction Analysis"]
    S0 --> S1
    S1["Step 2: Transaction Categorization with…"]
    S1 --> S2
    S2["Step 3: Goal Tracking"]
    S2 --> S3
    S3["Step 4: Personalized Recommendations"]
    style S0 fill:#4f46e5,stroke:#4338ca,color:#fff
    style S3 fill:#059669,stroke:#047857,color:#fff
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.

See AI Voice Agents Handle Real Calls

Book a free demo or calculate how much you can save with AI voice automation.

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.

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
C

Written by

CallSphere Team

Expert insights on AI voice agents and customer communication automation.

Try CallSphere AI Voice Agents

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

Related Articles You May Like

Learn Agentic AI

Creating an AI Email Assistant Agent: Triage, Draft, and Schedule with Gmail API

Build an AI email assistant that reads your inbox, classifies urgency, drafts context-aware responses, and schedules sends using OpenAI Agents SDK and Gmail API.

Learn Agentic AI

Building a Form Filler Agent with GPT Vision: Understanding and Completing Web Forms

Build an AI agent that uses GPT Vision to detect form fields, understand their purpose, map values to the correct inputs, and verify successful submission — all without relying on CSS selectors.

Learn Agentic AI

AI Agent for Legal Research: Case Law Search, Citation Extraction, and Analysis

Build an AI agent that searches legal databases, extracts citations from case law, ranks results by relevance, and generates research memos automatically.

Learn Agentic AI

Building a Real Estate Agent Assistant: Property Search, Valuation, and Document Prep

Build an AI assistant for real estate agents that searches property listings, performs comparative market analysis, generates valuations, and prepares transaction documents.

Learn Agentic AI

Building a Discord Bot Agent: AI-Powered Server Assistant with TypeScript

Build an AI-powered Discord bot that acts as a server assistant using TypeScript. Covers discord.js setup, slash command registration, conversation context management, tool integration, and permission-based access control.

Learn Agentic AI

AI Agent for Insurance Claims: Intake, Assessment, and Processing Automation

Build an AI agent that handles insurance claim intake, analyzes supporting documents, assesses damage, calculates payouts, and routes claims through the processing workflow.