How to Integrate LangChain for wealth management with PostgreSQL for multi-agent systems

By Cyprian AaronsUpdated 2026-04-21
langchain-for-wealth-managementpostgresqlmulti-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_KEY or another supported LLM provider key for LangChain
  • A LangChain setup with:
    • langchain
    • langchain-openai
    • langchain-community
    • langgraph if you want multi-agent orchestration
  • PostgreSQL driver:
    • psycopg2-binary or psycopg v3
  • 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

  1. 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()
  1. 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
  1. 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)
  1. 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."
)
  1. 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

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