How to Integrate FastAPI for retail banking with LangChain for multi-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
- •
uvicornfor local API execution - •
httpxfor 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, andAgentExecutor
- •
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
- •The complete AI Agents Roadmap — my full 8-step breakdown
- •Free: The AI Agent Starter Kit — PDF checklist + starter code
- •Work with me — I build AI for banks and insurance companies
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