Skip to content
Back to Projects

Meridian Brokerage

Full-stack brokerage portal with a 6-stage LLM pipeline — dual-layer guardrails blocking prompt injection, cross-customer data leakage, and investment advice violations.

Shipping
Full-Stack Finance AI LLM · FastAPI React 19 SQLAlchemy OpenAI SQLite TF-IDF RAG
41 Tests
6-Stage LLM Pipeline
2-Layer Guardrails
4 Demo Accounts

Real recorded session — login, dashboard, a normal account query, and the investment-advice guardrail blocking a buy/sell question

Summary

A full-stack brokerage account dashboard paired with an LLM-guardrailed AI support assistant. The guardrails aren’t a safety afterthought — they’re the core product requirement: what does a finance-compliant LLM support bot actually look like when the failure modes are real?

The Problem

LLM support bots deployed in financial services face three distinct failure modes: prompt injection (users trying to hijack system instructions), cross-customer data leakage (asking about another customer’s account), and unlicensed investment advice (the model drifting into “you should sell X” territory). Most demos skip all three. Meridian doesn’t.

Approach

A 6-stage sequential chat pipeline governs every message turn:

  1. Input guardrail — classifies the incoming message as blocked, escalated, exit, or normal before any tool is called
  2. Router — for normal messages, decides whether to pull account data, policy document chunks, or both
  3. Tool execution — account snapshot (balance, holdings, recent transactions) and/or TF-IDF policy retrieval
  4. Answer synthesis — rewrites raw tool output into a professional customer-facing response
  5. Output guardrail — validates the generated answer for PII leakage, unmasked account numbers, and off-limits recommendations
  6. Persistence — saves both user and assistant messages with their guardrail category tag

TF-IDF RAG (scikit-learn) handles the brokerage policy document without embedding infrastructure — appropriate for a small, static corpus. All 41 tests run fully offline against in-memory SQLite.

Key Results

Live end-to-end testing caught a real guardrail bug: the output guardrail was initially blocking the customer’s own account number as “sensitive data,” even for the authenticated user. The test caught it; the fix tightened the distinction between a customer’s own data (allow) versus another customer’s data (block). This is the kind of issue unit tests alone cannot surface — it required real LLM output flowing through the full pipeline.

  • 41 unit and integration tests across 11 files — guardrail categories, routing, policy RAG, all API endpoints, and edge cases including cross-account access attempts and LLM API failures
  • 4 seeded demo accounts with realistic holdings (AAPL, MSFT, NVDA, VTI, BND) and mixed transaction statuses
  • Session persistence via sessionStorage — conversations and login state survive page reloads