How to Integrate FastAPI for investment banking with LangChain for AI agents

By Cyprian AaronsUpdated 2026-04-21
fastapi-for-investment-bankinglangchainai-agents

Why this integration matters

FastAPI gives you the API layer for banking workflows: trade intake, portfolio lookups, risk checks, and approval flows. LangChain adds the agent layer on top, so your system can reason over those endpoints, call the right tools, and return structured answers instead of brittle chat responses.

The useful pattern here is simple: FastAPI exposes deterministic finance operations, and LangChain orchestrates them through an AI agent. That lets you build internal copilots for bankers, ops teams, and analysts without letting the model freestyle around core business logic.

Prerequisites

  • Python 3.10+
  • FastAPI installed
  • Uvicorn installed
  • LangChain installed
  • An OpenAI-compatible LLM key or another LangChain-supported model provider
  • Pydantic v2
  • A running FastAPI service that exposes investment banking endpoints
  • Basic familiarity with async Python

Install the core packages:

pip install fastapi uvicorn langchain langchain-openai pydantic requests

Integration Steps

  1. Build a FastAPI service for your banking operations.

Your API should expose narrow, auditable endpoints. Keep business rules in the API layer, not inside the agent.

# banking_api.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

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

class TradeRequest(BaseModel):
    ticker: str
    quantity: int
    side: str  # buy or sell

class RiskRequest(BaseModel):
    portfolio_id: str

@app.post("/trades")
async def create_trade(trade: TradeRequest):
    if trade.side not in {"buy", "sell"}:
        raise HTTPException(status_code=400, detail="side must be buy or sell")

    return {
        "trade_id": "TRD-10021",
        "ticker": trade.ticker.upper(),
        "quantity": trade.quantity,
        "side": trade.side,
        "status": "accepted"
    }

@app.get("/portfolio/{portfolio_id}/risk")
async def get_risk(portfolio_id: str):
    return {
        "portfolio_id": portfolio_id,
        "var_95": 1250000,
        "exposure_usd": 84000000,
        "status": "ok"
    }

Run it with:

uvicorn banking_api:app --reload --port 8000
  1. Wrap FastAPI endpoints as LangChain tools.

LangChain agents do best when each tool has one job. Use @tool from langchain_core.tools to make your HTTP calls callable by the agent.

# tools.py
import requests
from langchain_core.tools import tool

BASE_URL = "http://localhost:8000"

@tool
def create_trade_tool(ticker: str, quantity: int, side: str) -> dict:
    """Create an investment banking trade."""
    resp = requests.post(
        f"{BASE_URL}/trades",
        json={"ticker": ticker, "quantity": quantity, "side": side},
        timeout=10,
    )
    resp.raise_for_status()
    return resp.json()

@tool
def get_portfolio_risk_tool(portfolio_id: str) -> dict:
    """Fetch portfolio risk metrics."""
    resp = requests.get(f"{BASE_URL}/portfolio/{portfolio_id}/risk", timeout=10)
    resp.raise_for_status()
    return resp.json()
  1. Create a LangChain agent that can call those tools.

Use a chat model plus create_tool_calling_agent and AgentExecutor. This is the cleanest pattern for function-calling style workflows.

# agent.py
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

from tools import create_trade_tool, get_portfolio_risk_tool

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are an assistant for investment banking operations. Use tools for all factual actions."),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

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

tools = [create_trade_tool, get_portfolio_risk_tool]

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

if __name__ == "__main__":
    result = executor.invoke({
        "input": "Create a buy trade for 500 shares of AAPL and then check risk for portfolio PF-7781."
    })
    print(result["output"])
  1. Add structured output when you need downstream automation.

For bank systems, free-form text is not enough. If another service consumes the result, force a schema using Pydantic and parse the model output before persisting it.

# structured_agent.py
from pydantic import BaseModel
from langchain_openai import ChatOpenAI

class TradeSummary(BaseModel):
    trade_id: str
    ticker: str
    quantity: int
    side: str
    status: str

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
structured_llm = llm.with_structured_output(TradeSummary)

summary = structured_llm.invoke(
    "Return a trade summary for TRD-10021: AAPL buy 500 accepted."
)

print(summary.model_dump())
  1. Keep auth and audit logging outside the agent loop.

Do not let the model manage credentials or write directly to production systems. Put authentication in FastAPI middleware or dependency injection, then log every tool invocation with request IDs and user context.

# audit_example.py
import uuid
import logging

logger = logging.getLogger("banking_audit")

def log_tool_call(user_id: str, tool_name: str, payload: dict):
    logger.info({
        "request_id": str(uuid.uuid4()),
        "user_id": user_id,
        "tool": tool_name,
        "payload": payload,
    })

Testing the Integration

Use a direct agent invocation to verify the full path from prompt to tool to API response.

# test_integration.py
from agent import executor

response = executor.invoke({
    "input": "Check risk for portfolio PF-7781."
})

print(response["output"])

Expected output:

Portfolio PF-7781 has VaR 95 of 1,250,000 USD and exposure of 84,000,000 USD.

If you want to verify the raw API independently:

curl http://localhost:8000/portfolio/PF-7781/risk

Expected JSON:

{
  "portfolio_id": "PF-7781",
  "var_95": 1250000,
  "exposure_usd": 84000000,
  "status": "ok"
}

Real-World Use Cases

  • Trade assistant: bankers ask for order creation in natural language; the agent validates intent and calls /trades.
  • Risk copilot: analysts query VaR, exposure, or concentration metrics across portfolios without opening five internal systems.
  • Ops workflow automation: route settlement exceptions or booking issues through FastAPI endpoints while LangChain handles triage and next-step suggestions.

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