How to Integrate LangChain for wealth management with PostgreSQL for multi-agent systems
LangChain for wealth management gives you the orchestration layer for agentic financial workflows: portfolio Q&A, client summarization, suitability checks, and task routing across specialist agents. PostgreSQL gives you the durable state layer you need to store client profiles, holdings, interaction history, and agent memory without losing traceability.
Together, they let you build multi-agent systems that can answer wealth questions with context, persist decisions, and coordinate work across planning, compliance, and advisory agents.
Prerequisites
- •Python 3.10+
- •A PostgreSQL 14+ instance running locally or in your cloud environment
- •
OPENAI_API_KEYor another supported LLM provider key for LangChain - •A LangChain setup with:
- •
langchain - •
langchain-openai - •
langchain-community - •
langgraphif you want multi-agent orchestration
- •
- •PostgreSQL driver:
- •
psycopg2-binaryorpsycopgv3
- •
- •A database user with permissions to create tables and read/write rows
- •A schema ready for:
- •client records
- •portfolio snapshots
- •agent messages / memory
Install the core packages:
pip install langchain langchain-openai langchain-community langgraph psycopg2-binary sqlalchemy
Integration Steps
- •
Set up PostgreSQL tables for agent state and client data
You want a simple schema first. Keep one table for client context and another for agent memory so your agents can retrieve state deterministically.
import psycopg2
conn = psycopg2.connect(
host="localhost",
dbname="wealth_db",
user="wealth_user",
password="secret",
port=5432,
)
with conn.cursor() as cur:
cur.execute("""
CREATE TABLE IF NOT EXISTS clients (
client_id TEXT PRIMARY KEY,
full_name TEXT NOT NULL,
risk_profile TEXT NOT NULL,
portfolio_value NUMERIC(18,2) NOT NULL,
notes TEXT
)
""")
cur.execute("""
CREATE TABLE IF NOT EXISTS agent_memory (
id SERIAL PRIMARY KEY,
session_id TEXT NOT NULL,
agent_name TEXT NOT NULL,
message ტექXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
)
""")
conn.commit()
conn.close()
- •
Connect LangChain to your LLM and define a wealth-focused prompt
For wealth management workflows, keep prompts specific. You want the model to reason over portfolio constraints, risk profile, and client intent.
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
prompt = ChatPromptTemplate.from_messages([
("system", "You are a wealth management assistant. Be concise, compliant, and factual."),
("human", "Client: {client_name}\nRisk: {risk_profile}\nPortfolio: {portfolio_value}\nQuestion: {question}")
])
chain = prompt | llm
- •
Pull client context from PostgreSQL and feed it into LangChain
This is the core integration point. Read the authoritative client record from Postgres, then pass it into the chain as structured context.
import psycopg2
def get_client_context(client_id: str):
conn = psycopg2.connect(
host="localhost",
dbname="wealth_db",
user="wealth_user",
password="secret",
port=5432,
)
try:
with conn.cursor() as cur:
cur.execute(
"SELECT full_name, risk_profile, portfolio_value FROM clients WHERE client_id = %s",
(client_id,),
)
row = cur.fetchone()
if not row:
raise ValueError(f"Client {client_id} not found")
return {
"client_name": row[0],
"risk_profile": row[1],
"portfolio_value": str(row[2]),
}
finally:
conn.close()
context = get_client_context("client_001")
response = chain.invoke({
**context,
"question": "Should this client rebalance after a 12% equity rally?"
})
print(response.content)
- •
Add persistence for multi-agent coordination
Multi-agent systems need shared memory. Store each agent’s outputs in PostgreSQL so downstream agents can inspect prior reasoning instead of starting from scratch.
def save_agent_message(session_id: str, agent_name: str, message: str):
conn = psycopg2.connect(
host="localhost",
dbname="wealth_db",
user="wealth_user",
password="secret",
port=5432,
)
try:
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO agent_memory (session_id, agent_name, message)
VALUES (%s, %s, %s)
""",
(session_id, agent_name, message),
)
conn.commit()
finally:
conn.close()
save_agent_message(
session_id="sess_1001",
agent_name="planner_agent",
message="Recommend review of equity allocation due to recent rally."
)
- •
Orchestrate multiple agents with LangGraph
For production multi-agent flows, use LangGraph to route between planner and compliance agents while keeping state in PostgreSQL.
from typing import TypedDict
from langgraph.graph import StateGraph, END
class AgentState(TypedDict):
session_id: str
client_id: str
question: str
draft_answer: str
final_answer: str
def planner_node(state: AgentState):
ctx = get_client_context(state["client_id"])
result = chain.invoke({
**ctx,
"question": state["question"]
})
draft = result.content
save_agent_message(state["session_id"], "planner_agent", draft)
return {"draft_answer": draft}
def compliance_node(state: AgentState):
review_prompt = ChatPromptTemplate.from_messages([
("system", "You are a compliance reviewer for wealth management."),
("human", "Review this draft for suitability issues:\n{draft_answer}")
])
review_chain = review_prompt | llm
result = review_chain.invoke({"draft_answer": state["draft_answer"]})
final_text = result.content
save_agent_message(state["session_id"], "compliance_agent", final_text)
return {"final_answer": final_text}
graph = StateGraph(AgentState)
graph.add_node("planner", planner_node)
graph.add_node("compliance", compliance_node)
graph.set_entry_point("planner")
graph.add_edge("planner", "compliance")
graph.add_edge("compliance", END)
app = graph.compile()
Testing the Integration
Run a quick end-to-end check by inserting a test client and invoking the graph.
def seed_client():
conn = psycopg2.connect(
host="localhost",
dbname="wealth_db",
user="wealth_user",
password="secret",
port=5432,
)
try:
with conn.cursor() as cur:
cur.execute("""
INSERT INTO clients (client_id, full_name, risk_profile, portfolio_value, notes)
VALUES (%s, %s, %s, %s, %s)
ON CONFLICT (client_id) DO UPDATE SET
full_name = EXCLUDED.full_name,
risk_profile = EXCLUDED.risk_profile,
portfolio_value = EXCLUDED.portfolio_value,
notes = EXCLUDED.notes
""", ("client_001", "Amina Patel", "moderate", 1250000.00, "Prefers tax-efficient strategies"))
conn.commit()
finally:
conn.close()
seed_client()
result = app.invoke({
"session_id": "sess_1001",
"client_id": "client_001",
"question": "What is the best next step after equities outperformed fixed income this quarter?",
})
print(result["final_answer"])
Expected output:
A compliance-reviewed response suggesting a portfolio review may be appropriate given the client's moderate risk profile...
You should also verify that both agents wrote rows into agent_memory.
conn = psycopg2.connect(
host="localhost",
dbname="wealth_db",
user="wealth_user",
password="secret",
)
with conn.cursor() as cur:
cur.execute("SELECT agent_name, message FROM agent_memory WHERE session_id = %s ORDER BY created_at ASC", ("sess_1001",))
rows = cur.fetchall()
print(rows)
conn.close()
Real-World Use Cases
- •Portfolio review assistants that read live client data from PostgreSQL and generate advisor-ready summaries through LangChain.
- •Compliance-aware advisory workflows where one agent drafts recommendations and another validates them against policy before response.
- •Client service copilots that persist conversation history in PostgreSQL so multiple agents can pick up context across sessions without losing auditability.
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