How to Integrate FastAPI for lending with LangChain for RAG

By Cyprian AaronsUpdated 2026-04-21
fastapi-for-lendinglangchainrag

Combining FastAPI for lending with LangChain gives you a clean way to expose lending workflows as APIs while adding retrieval-augmented generation on top. The practical win is simple: your agent can answer policy, underwriting, and loan-status questions using live system data instead of stale prompts or hardcoded rules.

Prerequisites

  • Python 3.10+
  • A running FastAPI for lending service with API access
  • LangChain installed
  • An LLM provider configured through LangChain
  • A vector store or document source for RAG
  • Environment variables set for API base URLs and credentials

Install the core packages:

pip install fastapi uvicorn requests langchain langchain-openai langchain-community faiss-cpu python-dotenv

Integration Steps

  1. Expose lending data through FastAPI

    Your lending service should expose endpoints for loan applications, customer records, and policy docs. If you already have a FastAPI app, keep the response payloads stable so LangChain tools can consume them without brittle parsing.

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

app = FastAPI(title="Lending API")

class LoanApplication(BaseModel):
    customer_id: str
    amount: float
    term_months: int
    purpose: str

@app.get("/loans/{customer_id}")
def get_customer_loans(customer_id: str):
    return {
        "customer_id": customer_id,
        "active_loans": [
            {"loan_id": "LN001", "balance": 12000, "status": "current"},
            {"loan_id": "LN002", "balance": 4500, "status": "delinquent"},
        ],
    }

@app.post("/loans/apply")
def apply_for_loan(application: LoanApplication):
    if application.amount <= 0:
        raise HTTPException(status_code=400, detail="Invalid loan amount")
    return {"status": "received", "application_id": "APP123"}
  1. Wrap FastAPI endpoints as LangChain tools

    Use LangChain tools to let the agent call your lending API during retrieval or decision support. The @tool decorator is enough for straightforward REST calls.

import os
import requests
from langchain_core.tools import tool

LENDING_API_BASE = os.getenv("LENDING_API_BASE", "http://localhost:8000")

@tool
def fetch_customer_loans(customer_id: str) -> dict:
    """Fetch active loans for a customer from the lending API."""
    resp = requests.get(f"{LENDING_API_BASE}/loans/{customer_id}", timeout=10)
    resp.raise_for_status()
    return resp.json()

@tool
def submit_loan_application(customer_id: str, amount: float, term_months: int, purpose: str) -> dict:
    """Submit a loan application to the lending API."""
    payload = {
        "customer_id": customer_id,
        "amount": amount,
        "term_months": term_months,
        "purpose": purpose,
    }
    resp = requests.post(f"{LENDING_API_BASE}/loans/apply", json=payload, timeout=10)
    resp.raise_for_status()
    return resp.json()
  1. Build the RAG layer with LangChain

    Put lending policies, product docs, and compliance notes into a retriever. Here I’m using FAISS with OpenAI embeddings, but any LangChain-compatible vector store works.

from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.documents import Document

docs = [
    Document(page_content="Personal loans require income verification and no active delinquency over 30 days."),
    Document(page_content="Loan terms are available from 6 to 60 months depending on risk tier."),
    Document(page_content="Applications above $25,000 require manual review by underwriting."),
]

splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
chunks = splitter.split_documents(docs)

embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
  1. Combine retrieval with tool calling in an agent

    This is where the integration becomes useful. The agent retrieves policy context first, then calls FastAPI when it needs live customer data or needs to submit an application.

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

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

tools = [fetch_customer_loans, submit_loan_application]

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a lending assistant. Use retrieved policy context and tools when needed."),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),
])

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

def answer_lending_question(question: str):
    context_docs = retriever.invoke(question)
    context_text = "\n".join([d.page_content for d in context_docs])
    enriched_question = f"Policy context:\n{context_text}\n\nQuestion:\n{question}"
    return executor.invoke({"input": enriched_question})
  1. Expose the combined workflow through your own API

    In production you usually want a single orchestration layer that your UI or internal systems call. Wrap the RAG + tool flow in a second FastAPI endpoint.

from fastapi import FastAPI
from pydantic import BaseModel

orchestrator = FastAPI(title="Lending AI Orchestrator")

class QueryRequest(BaseModel):
    question: str

@orchestrator.post("/assistant/query")
def assistant_query(req: QueryRequest):
    result = answer_lending_question(req.question)
    return {"answer": result["output"]}

Testing the Integration

Run both services locally:

uvicorn app:app --reload --port 8000
uvicorn orchestrator:orchestrator --reload --port 8001

Then test the orchestrator endpoint:

import requests

resp = requests.post(
    "http://localhost:8001/assistant/query",
    json={"question": "Can customer CUST100 apply for a $30k personal loan? Also check their current loans."},
    timeout=20,
)

print(resp.status_code)
print(resp.json())

Expected output:

{
  "answer": "...mentions policy context from RAG and includes fetched loan data..."
}

If everything is wired correctly, you should see:

  • Retrieved policy text influencing the response
  • A live call to GET /loans/{customer_id}
  • A grounded answer that reflects both static knowledge and current system state

Real-World Use Cases

  • Loan eligibility assistant
    Answer eligibility questions by combining underwriting rules from documents with live borrower data from FastAPI.

  • Underwriting copilot
    Pull customer history from your lending API and use LangChain retrieval to surface relevant policy clauses before a decision.

  • Customer support automation
    Let support agents ask natural-language questions like “Why was this application flagged?” and get answers grounded in both case data and compliance docs.


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