How to Integrate FastAPI for retail banking with LangChain for multi-agent systems

By Cyprian AaronsUpdated 2026-04-21
fastapi-for-retail-bankinglangchainmulti-agent-systems

Combining FastAPI for retail banking with LangChain gives you a clean way to expose banking workflows as APIs while letting agents coordinate across tools, policies, and data sources. The practical win is simple: your banking backend stays deterministic and auditable, while LangChain handles orchestration for tasks like balance lookup, transaction summaries, dispute triage, and customer support handoffs.

Prerequisites

  • Python 3.10+
  • FastAPI installed and running in a retail banking service
  • A LangChain-compatible LLM provider configured
  • uvicorn for local API execution
  • httpx for calling FastAPI endpoints from LangChain tools
  • Access to a sandbox banking API or mocked banking service
  • Basic familiarity with:
    • FastAPI()
    • @app.get() / @app.post()
    • LangChain Tool, ChatPromptTemplate, create_react_agent, and AgentExecutor

Install the core packages:

pip install fastapi uvicorn httpx langchain langchain-openai pydantic

Integration Steps

1) Expose retail banking operations with FastAPI

Start by defining the banking operations you want agents to call. Keep the API small and explicit: balance lookup, recent transactions, and payment initiation are enough for most agent flows.

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List

app = FastAPI(title="Retail Banking API")

class TransferRequest(BaseModel):
    from_account: str
    to_account: str
    amount: float
    currency: str = "USD"

@app.get("/accounts/{account_id}/balance")
def get_balance(account_id: str):
    # Replace with real core-banking integration
    return {"account_id": account_id, "balance": 1250.75, "currency": "USD"}

@app.get("/accounts/{account_id}/transactions")
def get_transactions(account_id: str):
    return {
        "account_id": account_id,
        "transactions": [
            {"id": "tx_001", "amount": -42.19, "merchant": "Grocery Store"},
            {"id": "tx_002", "amount": -15.00, "merchant": "Streaming Service"},
        ],
    }

@app.post("/transfers")
def create_transfer(req: TransferRequest):
    if req.amount <= 0:
        raise HTTPException(status_code=400, detail="Transfer amount must be positive")
    return {
        "status": "pending_review",
        "transfer_id": "trf_12345",
        "from_account": req.from_account,
        "to_account": req.to_account,
        "amount": req.amount,
        "currency": req.currency,
    }

Run it with:

uvicorn banking_api:app --reload --port 8000

2) Wrap FastAPI endpoints as LangChain tools

LangChain agents need tools they can call. Use httpx inside tool functions so the agent can query your FastAPI service without knowing anything about your backend internals.

import httpx
from langchain_core.tools import tool

BASE_URL = "http://localhost:8000"

@tool
def get_account_balance(account_id: str) -> dict:
    """Fetch account balance from the retail banking API."""
    response = httpx.get(f"{BASE_URL}/accounts/{account_id}/balance", timeout=10)
    response.raise_for_status()
    return response.json()

@tool
def get_recent_transactions(account_id: str) -> dict:
    """Fetch recent transactions from the retail banking API."""
    response = httpx.get(f"{BASE_URL}/accounts/{account_id}/transactions", timeout=10)
    response.raise_for_status()
    return response.json()

@tool
def initiate_transfer(from_account: str, to_account: str, amount: float) -> dict:
    """Create a transfer request in the retail banking API."""
    payload = {
        "from_account": from_account,
        "to_account": to_account,
        "amount": amount,
        "currency": "USD",
    }
    response = httpx.post(f"{BASE_URL}/transfers", json=payload, timeout=10)
    response.raise_for_status()
    return response.json()

This is the boundary you want in production:

  • FastAPI owns policy enforcement and transaction state.
  • LangChain owns reasoning and routing.
  • The tool layer is just an adapter.

3) Build a multi-agent workflow with LangChain

For multi-agent systems, split responsibilities. One agent can answer customer questions, another can handle risk checks or payment actions. A simple pattern is a supervisor agent that decides which specialist tool path to use.

import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain.agents import create_react_agent, AgentExecutor

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

tools = [get_account_balance, get_recent_transactions, initiate_transfer]

prompt = ChatPromptTemplate.from_messages([
    ("system", """You are a retail banking assistant.
Use tools only when needed.
Never invent balances or transaction data.
For transfers, confirm intent before action."""),
    ("human", "{input}"),
])

agent = create_react_agent(llm=llm, tools=tools, prompt=prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

Now you have an agent that can inspect balances or fetch transactions through your FastAPI service. In a multi-agent setup, you can add another agent for fraud review or compliance checks and route between them based on intent.

4) Add a supervisor router for agent coordination

A practical multi-agent system uses a router to decide whether the request is informational or transactional. Keep the router deterministic where possible.

def route_banking_request(user_input: str) -> str:
    text = user_input.lower()
    if any(k in text for k in ["transfer", "send money", "pay"]):
        return "payments_agent"
    if any(k in text for k in ["balance", "transactions", "spent"]):
        return "servicing_agent"
    return "general_agent"

# Example usage:
route = route_banking_request("Show me my last 5 transactions")
print(route)

You can wire this router into separate executors:

servicing_executor = executor  # balance/transactions specialist

payments_prompt = ChatPromptTemplate.from_messages([
    ("system", """You handle transfers.
Always verify source account, destination account, and amount before calling tools."""),
    ("human", "{input}"),
])

payments_agent = create_react_agent(llm=llm, tools=[initiate_transfer], prompt=payments_prompt)
payments_executor = AgentExecutor(agent=payments_agent, tools=[initiate_transfer], verbose=True)

5) Enforce guardrails before tool execution

Banking systems need hard controls outside the model. Validate amounts, block suspicious requests, and require explicit confirmation before money movement.

def validate_transfer(amount: float) -> None:
    if amount > 5000:
        raise ValueError("Manual review required for transfers above $5,000")
    if amount <= 0:
        raise ValueError("Transfer amount must be positive")

def safe_initiate_transfer(from_account: str, to_account: str, amount: float) -> dict:
    validate_transfer(amount)
    return initiate_transfer.invoke({
        "from_account": from_account,
        "to_account": to_account,
        "amount": amount,
    })

That pattern matters more than prompt wording. The model proposes; your code disposes.

Testing the Integration

Use one end-to-end query against the servicing agent and verify it calls your FastAPI backend correctly.

result = servicing_executor.invoke({
    "input": "What is the balance on account ACC123?"
})
print(result["output"])

Expected output:

The balance on account ACC123 is $1250.75 USD.

For a transfer flow:

try:
    transfer_result = safe_initiate_transfer("ACC123", "ACC456", 250.00)
    print(transfer_result)
except Exception as e:
    print(str(e))

Expected output:

{'status': 'pending_review', 'transfer_id': 'trf_12345', 'from_account': 'ACC123', 'to_account': 'ACC456', 'amount': 250.0, 'currency': 'USD'}

Real-World Use Cases

  • Customer servicing assistant

    • Answer balance questions, show recent transactions, and explain card charges through controlled API calls.
  • Payments triage agent

    • Collect transfer details from chat or voice channels and pass them through validation before creating payment requests.
  • Fraud and dispute workflow

    • Let one agent summarize transaction history while another flags anomalies and opens case-management tickets.

Keep learning

By Cyprian Aarons, AI Consultant at Topiax.

Want the complete 8-step roadmap?

Grab the free AI Agent Starter Kit — architecture templates, compliance checklists, and a 7-email deep-dive course.

Get the Starter Kit

Related Guides