Autonomous finance review powered by Claude Code agentics with specialized self-validating agents.
Watch the full walkthrough: Specialized Self-Validating Agents in Claude Code
If you want your agents to accomplish valuable work autonomously, they must be able to validate their work. Validation increases trust, and trust saves your most valuable engineering resource: time.
This project demonstrates how to build specialized self-validating agents using Claude Code's hooks system. Each agent is hyper-focused on one task and validates its own work using deterministic scripts.
Focused Agent + Specialized Validation = Trusted Automation
The key insight: specialized hooks embed in prompts, subagents, and skills.
Before this feature, hooks were global (in settings.json). Now you can define hooks that run only for specific agents, enabling:
- CSV agents that validate CSV structure after every file operation
- Build agents that run linters and type checkers on completion
- UI agents that validate HTML output
This application processes raw bank CSV exports through a multi-agent pipeline, producing:
Input: Raw bank CSVs (checking, savings, credit card statements)
Output:
apps/agentic-finance-review/data/mock_dataset_2026/
├── agentic_cumulative_dataset_2026.csv # Year-to-date merged data
├── index.html # Yearly dashboard
├── assets/ # Yearly graphs
│ └── *.png
└── mock_dataset_mar_1st_2026/ # Monthly output
├── raw_checkings.csv # Original input (copied)
├── normalized_checkings.csv # Standardized format + categories
├── agentic_merged_transactions.csv # All accounts merged
├── index.html # Monthly dashboard
└── assets/ # Generated visualizations
├── plot_01_spending_by_category_pie.png
├── plot_02_daily_spending_trend.png
├── plot_03_income_vs_expenses.png
├── plot_04_top_merchants.png
├── plot_05_category_over_time.png
├── plot_06_running_balance.png
├── plot_07_spending_distribution.png
└── plot_08_spending_by_weekday.png
Pipeline stages:
- Normalize - Convert bank-specific formats to standard columns
- Categorize - Auto-categorize transactions (groceries, utilities, etc.)
- Merge - Combine all accounts into single dataset
- Accumulate - Add to year-to-date cumulative file
- Graph - Generate 8 financial insight visualizations
- Dashboard - Create interactive HTML report
Each stage has its own specialized agent with targeted validation hooks.
.claude/
├── commands/ # Custom slash commands (prompts)
│ ├── csv-edit.md # CSV editing with PostToolUse validation
│ ├── build.md # Build command with Stop validation
│ └── review-finances.md # Orchestrator command
├── agents/ # Subagents for parallel work
│ ├── csv-edit-agent.md
│ ├── normalize-csv-agent.md
│ └── generative-ui-agent.md
└── hooks/
└── validators/ # Validation scripts
├── csv-single-validator.py
├── csv-validator.py
├── html-validator.py
└── ...
mock-input-data/ # Sample bank exports (fictional data)
├── raw_checkings_*.csv
└── raw_savings_*.csv
apps/agentic-finance-review/data/ # Generated output
└── mock_dataset_2026/ # Processed results
Custom slash commands live in .claude/commands/. Here's csv-edit.md:
---
model: opus
description: Make modifications or report on csv files
argument-hint: [csv_file] [user_request]
allowed-tools: Glob, Grep, Read, Edit, Write
hooks:
PostToolUse:
- matcher: "Read|Edit|Write"
hooks:
- type: command
command: "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/validators/csv-single-validator.py"
---
# Purpose
Make modifications or report on csv files.
## Workflow
1. Read the CSV File: $1
2. Make the modification or report: $2
3. Report the resultsKey frontmatter fields:
| Field | Purpose |
|---|---|
model |
Which model to use (opus, sonnet, haiku) |
description |
When Claude should invoke this command |
argument-hint |
Shows users expected arguments |
allowed-tools |
Restricts tool access for security/focus |
hooks |
Specialized validation hooks |
Subagents enable parallelization and context isolation. Here's csv-edit-agent.md:
---
name: csv-edit-agent
description: Make modifications or report on csv files. Use only when directly requested.
tools: Glob, Grep, Read, Edit, Write
model: opus
hooks:
PostToolUse:
- matcher: "Read|Edit|Write"
hooks:
- type: command
command: "uv run $CLAUDE_PROJECT_DIR/.claude/hooks/validators/csv-single-validator.py"
color: cyan
---
# Purpose
Make modifications or report on csv files.
## Workflow
1. Read the CSV File: DETERMINE FROM PROMPT
2. Make the modification or report: DETERMINE FROM PROMPT
3. Report the resultsPrompts vs Subagents:
| Feature | Prompt (Slash Command) | Subagent |
|---|---|---|
| Context | Runs in current context | Isolated context window |
| Parallelism | Sequential | Can run multiple in parallel |
| Arguments | Uses $1, $2, $ARGUMENTS |
Infers from prompt |
| Invocation | /csv-edit file.csv "add row" |
"Use csv-edit-agent to..." |
Validators receive hook input via stdin as JSON and output a decision. See csv-single-validator.py for a complete example.
Exit codes matter:
| Exit Code | Behavior |
|---|---|
| 0 | Success - proceed normally |
| 2 | Blocking error - stderr fed back to Claude |
| Other | Non-blocking error |
| Hook Event | When It Fires | Use Case |
|---|---|---|
PreToolUse |
Before a tool runs | Block dangerous operations |
PostToolUse |
After a tool completes | Validate output |
Stop |
When agent finishes | Final validation/cleanup |
Examples in this repo:
- PostToolUse: csv-edit.md - validates after every Read/Edit/Write
- Stop: build.md - runs linter + type checker on completion
- Multiple Stop hooks: normalize-csv-agent.md - runs CSV + balance validation
User: /csv-edit savings.csv "add a row for a $100 deposit"
Agent: [Reads file]
Hook: [Validates CSV structure] ✓
Agent: [Edits file to add row]
Hook: [Validates CSV structure]
✗ Balance mismatch! Expected $1100, got $1000
Agent: [Fixes balance calculation]
Hook: [Validates CSV structure] ✓
Agent: "Added deposit row with correct balance."
The /review-finances orchestrator chains specialized agents:
/review-finances mar checkings.csv savings.csv
│
├─> normalize-csv-agent (validates CSV + balance)
├─> categorize-csv-agent (validates CSV)
├─> merge-accounts-agent (validates merged output)
├─> graph-agent (validates PNG generation)
└─> generative-ui-agent (validates HTML)
User: "Use one CSV edit agent per file in mock-input-data/"
Claude: [Spawns 4 agents in parallel]
├─> csv-edit-agent (checkings.csv)
├─> csv-edit-agent (savings.csv)
├─> csv-edit-agent (credit.csv)
└─> csv-edit-agent (expenses.csv)
[All 4 agents validate their work independently]
A focused agent with one purpose outperforms an unfocused agent with many purposes.
| Approach | Result |
|---|---|
| General agent doing everything | Works sometimes, fails unpredictably |
| Specialized agent + validation | Consistent, reliable, trustworthy |
Specialization + Deterministic Validation = Trust
This is a sample repository for learning agentic patterns. If you want to use it with real financial data:
- Create a private fork - Never commit real bank statements to a public repo
- Add your data directories to
.gitignore- The repo ignoresapps/agentic-finance-review/data/*/by default, but double-check - Never commit
.mcp.json- Contains API keys (already in.gitignore) - Review before pushing - Always
git diffbefore committing to ensure no sensitive data
The mock data in this repo (mock-input-data/) is entirely fictional.
This repo includes mock CSV data for January, February, and March 2026 in mock-input-data/.
March (fresh run):
claude
> /review-finances mar mock-input-data/raw_checkings_mar.csv mock-input-data/raw_savings_mar.csvJanuary or February (already processed):
These months have existing output directories. Delete them first to re-run:
rm -rf apps/agentic-finance-review/data/mock_dataset_2026/mock_dataset_jan_1st_2026
rm -rf apps/agentic-finance-review/data/mock_dataset_2026/mock_dataset_feb_1st_2026Then run:
claude
> /review-finances feb mock-input-data/raw_checkings_feb.csv mock-input-data/raw_savings_feb.csvclaude
> /csv-edit mock-input-data/raw_checkings_mar.csv "report on data structure"claude
> Use one csv-edit-agent per file in mock-input-data/ to report on the data structure- Read the docs. Actually read the documentation. Don't just paste it into your agent.
- Build focused agents. One agent, one purpose, extraordinary results.
- Add specialized validation. Every good engineer validates their work. Your agents should too.
- Use hooks strategically:
PostToolUsefor each operation,Stopfor final validation,PreToolUseto block dangerous operations. - Log everything. Observability is critical.
Prepare for the future of software engineering
Learn tactical agentic coding patterns with Tactical Agentic Coding
Follow the IndyDevDan YouTube channel to improve your agentic coding advantage.
