How to Build a loan approval Agent Using LlamaIndex in Python for wealth management
A loan approval agent for wealth management evaluates client applications against policy, portfolio context, and compliance rules, then produces a recommendation with a traceable rationale. It matters because private banking and advisory teams need faster decisions without losing control over suitability checks, auditability, and jurisdiction-specific constraints.
Architecture
- •
Client data ingestion
- •Pull structured data from CRM, core banking, and portfolio systems.
- •Normalize income, liabilities, AUM, collateral, and KYC fields.
- •
Policy and compliance knowledge base
- •Index internal lending policy, suitability rules, AML/KYC procedures, and product constraints.
- •Keep this separate from client data so updates do not require code changes.
- •
Decision engine
- •Use LlamaIndex to retrieve relevant policy snippets and client facts.
- •Generate a recommendation: approve, reject, or escalate for manual review.
- •
Audit trail
- •Store retrieved sources, model output, timestamps, and decision inputs.
- •This is mandatory for regulated workflows in wealth management.
- •
Guardrail layer
- •Block unsupported actions like changing credit policy or fabricating missing documents.
- •Force escalation when confidence is low or required fields are missing.
Implementation
1) Install dependencies and prepare your documents
Use LlamaIndex for retrieval plus a local embedding model if you want to keep data residency under control.
pip install llama-index llama-index-embeddings-huggingface llama-index-llms-openai pydantic
Create separate document sets for policy and client files. In production, client records should come from your internal systems; below is a minimal example using Document objects.
from llama_index.core import Document
policy_docs = [
Document(text="""
Wealth management lending policy:
- Minimum net worth: $500k
- Debt service ratio must be below 40%
- Loans above $250k require manual review
- Any PEP or sanctions match requires escalation
""", metadata={"source": "lending_policy_v1"})
]
client_docs = [
Document(text="""
Client profile:
- Net worth: $1.2M
- Annual income: $180k
- Existing debt service ratio: 28%
- Jurisdiction: Singapore
- PEP status: false
""", metadata={"source": "crm_export_2026_04"})
]
2) Build indexed knowledge bases
Use VectorStoreIndex.from_documents() to create retrieval indexes. For wealth management, I recommend keeping policy and client data in separate indexes so you can control access boundaries more cleanly.
from llama_index.core import VectorStoreIndex
policy_index = VectorStoreIndex.from_documents(policy_docs)
client_index = VectorStoreIndex.from_documents(client_docs)
policy_retriever = policy_index.as_retriever(similarity_top_k=3)
client_retriever = client_index.as_retriever(similarity_top_k=3)
3) Define a structured decision output
Do not let the agent free-form its response. Use a schema so downstream systems can consume the result safely.
from pydantic import BaseModel, Field
from typing import Literal
class LoanDecision(BaseModel):
decision: Literal["approve", "reject", "manual_review"]
reason: str = Field(..., description="Short explanation grounded in retrieved evidence")
risk_flags: list[str] = Field(default_factory=list)
Now wire the retrievers into an LLM-backed query engine. The key pattern is to retrieve evidence first, then ask the model to make a constrained decision using that evidence only.
from llama_index.core import Settings
from llama_index.llms.openai import OpenAI
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
def build_context(query: str) -> str:
policy_nodes = policy_retriever.retrieve(query)
client_nodes = client_retriever.retrieve(query)
sections = ["POLICY EVIDENCE:"]
for node in policy_nodes:
sections.append(f"- {node.node.text}")
sections.append("\nCLIENT EVIDENCE:")
for node in client_nodes:
sections.append(f"- {node.node.text}")
return "\n".join(sections)
def decide_loan(query: str) -> LoanDecision:
context = build_context(query)
prompt = f"""
You are a loan approval assistant for wealth management.
Use only the evidence below. If required information is missing, choose manual_review.
Return JSON matching this schema:
decision: approve|reject|manual_review
reason: string
risk_flags: list of strings
Evidence:
{context}
Application:
{query}
"""
response = Settings.llm.complete(prompt)
# Minimal parsing pattern; in production use robust JSON validation.
import json
data = json.loads(response.text)
return LoanDecision(**data)
result = decide_loan("Evaluate this client for a $200k secured loan.")
print(result.model_dump())
4) Add an audit log before returning the decision
Wealth management workflows need traceability. Capture the retrieved evidence and final answer so compliance teams can reconstruct why the agent made a recommendation.
import json
from datetime import datetime
def audit_record(application_id: str, query: str, decision: LoanDecision):
record = {
"application_id": application_id,
"timestamp_utc": datetime.utcnow().isoformat(),
"query": query,
"decision": decision.model_dump(),
"model": "gpt-4o-mini",
"policy_version": "lending_policy_v1",
"data_residency": "sg-region",
}
with open("loan_audit_log.jsonl", "a") as f:
f.write(json.dumps(record) + "\n")
audit_record("LN-10492", "Evaluate this client for a $200k secured loan.", result)
Production Considerations
- •
Deployment
- •Keep policy indexes in-region if your firm has data residency requirements.
- •Separate PII-bearing client retrieval from public or shared knowledge stores.
- •Use environment-based secrets management for model keys and database credentials.
- •
Monitoring
- •Track approval rates, manual review rates, retrieval hit quality, and JSON parse failures.
- •Log every source document ID used in each decision.
- •Alert on sudden shifts in reject/approve ratios by jurisdiction or advisor desk.
- •
Guardrails
- •Force
manual_reviewwhen KYC status is stale or sanctions screening is incomplete. - •Reject any request that asks the model to override policy thresholds.
- •Add deterministic checks outside the LLM for hard rules like minimum net worth or maximum debt ratio.
- •Force
- •
Compliance
- •Version every policy document and preserve historical versions used at decision time.
- •Make sure explanations are short but specific enough for audit and customer communication review.
- •Treat model output as recommendation only unless your legal/compliance team explicitly approves automation level.
Common Pitfalls
- •
Mixing policy text with client records in one index
- •This creates noisy retrieval and weak access control.
- •Keep them separate and merge only at decision time.
- •
Letting the model decide without hard validation
- •If net worth or debt ratio is missing, the agent may guess.
- •Run explicit rule checks before calling the LLM and force escalation on missing fields.
- •
Skipping audit metadata
- •A plain “approved” response is useless during an internal review.
- •Store source IDs, timestamps, model version, and policy version for every decision.
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