Teo McArthur
← Both case studies

Choosing an orchestration architecture for an FP&A-shaped personal finance agent

A working case study in framework selection and roadmap sequencing: why LangGraph was chosen over CrewAI and over a single-agent design, what's actually built today versus the target architecture, and the disciplined process connecting the two.

Most agentic AI builds start with a framework choice made by default — whatever the tutorial used, whatever the AI coding assistant reached for first. This case study documents a different process: a framework decision made against explicit, stated requirements, a target architecture defined up front, and an actual build sequenced deliberately toward it — including a point where an earlier version of the system was found to be built on the wrong foundation and was deliberately torn down and rebuilt before any further feature work continued. The decision originated in, and stayed in, a personal finance agent built for one household's own finances — not a SaaS or multi-tenant product.

The requirement, before the framework

The architecture question was deliberately deferred until the jobs-to-be-done were mapped. FP&A-shaped work breaks into seven distinct cognitive tasks, each with different data dependencies, latency tolerances, and failure modes:

  • Ingestion and normalisation — parsing bank and credit-card CSV exports and mapping every transaction to a standard Chart of Accounts
  • Variance analysis — actual vs. budget, period over period, anomaly flagging
  • Forecasting — rolling forecasts, driver-based projections
  • Cash flow — rolling views, runway alerts
  • Narrative generation — translating the numbers into plain-English explanation
  • Alerts and triggers — budget variance dips, cash thresholds, anomaly spikes
  • Conversational Q&A — ad-hoc questions answered against the user's own data

The deciding factor was not which framework was most capable in the abstract, but which orchestration model matched the shape of a recurring, partly-deterministic process that runs repeatedly against evolving data — not a one-shot generative task.

Three options, evaluated against the requirement

Click through the branching logic below. Each branch leads either to the next question or to a terminal outcome — including the rejected ones, with the reasoning that ruled them out.

What does this workflow actually require from orchestration?

Before picking a framework, the seven job-to-be-done categories were mapped (see narrative below). The deciding axis: does the workflow need emergent multi-agent collaboration, or deterministic repeatable execution?

Workflow is a recurring, partly-deterministic process

Does the system run repeatedly over time, carrying structured state through each step — or is each interaction one-shot and independent?

Recurring — a new file or event triggers the same sequence again

Should the workflow support conditional branching on calculated values (budget variance, projected cash runway), even where that branching isn't built yet?

Yes — the framework should support it without re-architecting later
Selected

LangGraph — selected

A graph-based state machine: a typed state object threading through a fixed sequence of single-purpose nodes, replacing what would otherwise be one long imperative function with auditable, individually-testable steps. Conditional-edge support was chosen for a future phase not yet exercised — threshold-based routing for cash-runway alerts and budget variance flags. Choosing infrastructure for where the system is going, not only for where it is, was the decisive factor.

See the future-state target architecture
No — a single tool-using agent can route ad hoc
Deferred

Single agent, multiple tools — deferred, not dismissed

Acknowledged as a legitimate and underrated option, particularly at MVP stage. One well-prompted agent with a tool registry — data fetch, calculation engine, chart generation, narrative writer, alert dispatcher — can cover roughly 80 percent of the use case with materially less operational complexity and simpler failure debugging. This was not dismissed; it was deferred. It remains the fallback architecture if LangGraph's added complexity does not earn its keep as the system scales.

One-shot — each interaction is independent and self-contained
Deferred

Single agent, multiple tools — deferred, not dismissed

Acknowledged as a legitimate and underrated option, particularly at MVP stage. One well-prompted agent with a tool registry — data fetch, calculation engine, chart generation, narrative writer, alert dispatcher — can cover roughly 80 percent of the use case with materially less operational complexity and simpler failure debugging. This was not dismissed; it was deferred. It remains the fallback architecture if LangGraph's added complexity does not earn its keep as the system scales.

Workflow is one-shot research/writing requiring agent debate and refinement
Rejected

CrewAI — rejected for this use case

CrewAI is well suited to one-shot research or writing workflows where multiple agents debate, critique, and refine a shared output. That model is a poor match for this system, which requires deterministic orchestration rather than emergent multi-agent conversation. A categorisation step and a reporting step should not "discuss" whether a transaction was filed correctly — the system needs a defined, auditable execution path, not a negotiated one. Rejecting CrewAI here was not a verdict on its quality; it was a mismatch between its design intent (collaborative emergence) and the requirement (predictable, repeatable process).

LangGraph — selected

A graph-based state machine maps a typed, structured state object through a fixed sequence of single-purpose nodes, replacing what would otherwise be one long imperative function with auditable, individually-testable steps. Conditional edges are part of why the framework was chosen, not yet why it earns its keep today: the pipeline currently runs the same sequence every time, but threshold-based routing — cash-runway alerts, budget-variance flags — is a deliberate next phase (see Future State, Phase C) the framework already supports without re-architecting. Choosing infrastructure for where the system is going, not only for where it is, was the decisive factor.

CrewAI — rejected

CrewAI is well suited to one-shot research or writing workflows where multiple agents debate, critique, and refine a shared output. That model is a poor match for this system, which requires deterministic orchestration rather than emergent multi-agent conversation. A categorisation step and a reporting step should not "discuss" whether a transaction was filed correctly — the system needs a defined, auditable execution path, not a negotiated one. Rejecting CrewAI here was not a verdict on its quality; it was a mismatch between its design intent (collaborative emergence) and the requirement (predictable, repeatable process).

Single agent, multiple tools — rejected for now

Acknowledged as a legitimate and underrated option, particularly at MVP stage. One well-prompted agent with a tool registry — data fetch, calculation engine, chart generation, narrative writer, alert dispatcher — can cover roughly 80 percent of the use case with materially less operational complexity and simpler failure debugging. This was not dismissed; it was deferred. It remains the fallback architecture if LangGraph's added complexity does not earn its keep as the system scales.

Future state: the target architecture

The framework decision was made for this destination, not for what exists today. Four phases, each gated on the one before it being trustworthy:

A. Budget & variance

A budgets table (Chart-of-Accounts code mapped to a monthly target) plus a variance step comparing actual spend to budget per category. Depends on classification accuracy — a miscategorised transaction breaks its bucket's variance, not just its total.

B. Cash flow forecasting

The existing backward-looking cash flow report extended into a forward rolling projection, driven by trailing average spend and income per category. Depends on Phase A's categorised, budget-aware actuals as forecast drivers.

C. Threshold-based alerting

The first real use of LangGraph's conditional-edge routing in this system — alerting when a projected cash runway drops below a set number of weeks, or a category's variance crosses a threshold. The framework was chosen with this in mind; it is not exercised until this phase exists.

D. Conversational Q&A

A router classifying intent, retrieving relevant report and transaction context, and a single agent answering ad-hoc questions. Deliberately last — answers should be backed by data already verified in the earlier phases — and deliberately a single agent, not a graph, kept separate from the deterministic pipeline above it.

Current state: what's actually running

Two LangGraph graphs, no shared state between them. An ingestion pipeline — ingest, normalise, categorise, persist, review, learn, notify — triggered by a folder-watcher daemon every time a new bank or credit-card export lands. A separate reporting pipeline — report, then narrate — that pulls profit-and-loss, net-worth, and (backward-looking) cash-flow data and turns it into a plain-English summary via Claude Haiku.

Categorisation runs as a cost-ordered cascade: a rule lookup first (instant, free, for merchants already seen), a local model (Qwen 2.5) if no rule matches, and Claude Haiku only if the local model is uncertain. Whatever is left after that cascade — and whatever the system itself flags as low-confidence — goes to a human review queue rather than guessing. Reviewed corrections feed back into the rule set, so the rule tier covers more of each subsequent import over time.

Not yet built: budget data, forecasting, conditional graph routing, alerting, and the conversational interface — all four are the Future State phases above, not the current pipeline.

The path: classification-first, by necessity, not by plan

An earlier version of this system existed before the one described above — a different database schema, organised around flat category and bank tables, with its own ingestion agent. It was deleted. Not refactored: deleted, along with the agent built on top of it, and rebuilt from a proper Chart of Accounts up, because the schema underneath the original version turned out to be the wrong foundation to build analysis on. Every later feature — the classification cascade, the review queue, the learning loop, the reports — was sequenced after that rebuild, not before it.

The same logic carries forward into the future-state roadmap above: Phase A waits on classification accuracy for the same reason the schema was rebuilt first — building analysis on numbers that are not trustworthy yet just means redoing the analysis once the numbers are fixed. The phases are gated in that order on purpose, not because they happened to come up in that sequence.

Where the systems thinking is still incomplete

This case study does not claim mastery of LangGraph internals. The implementation work for both the personal finance agent and an email-handling agent built on the same framework was done with AI-assisted development (Claude Code), which produces legible, working systems without necessarily building the fluency to write or debug the framework from first principles. That gap has been identified, not hidden, and is being closed deliberately through formal study (LangChain Academy) rather than continued reliance on AI-assisted implementation alone.

A second gap: the four-phase roadmap in Future State did not exist as a written document before this case study was put together. The sequencing existed in how the work was actually done — the schema rebuild, the order specs shipped in — but not as something stated in advance. Writing it down is itself part of closing that gap, not a retrofit to make the story look more deliberate than it was. A systems-thinking process that cannot name its own gaps is not a credible one.

The same framework decision was reused, not re-derived, for a second system.

Read the email-agent case study →