How to Integrate Anthropic for wealth management with pgvector for AI agents
Combining Anthropic for wealth management with pgvector gives you a practical pattern for agentic financial workflows: retrieve the right client context, policy, or market note from vector search, then let the model draft a compliant response, summary, or recommendation. For wealth management teams, this is the difference between a generic chatbot and an agent that can answer with grounded portfolio context, suitability constraints, and historical interactions.
Prerequisites
- •Python 3.10+
- •PostgreSQL 15+ with the
pgvectorextension installed - •An Anthropic API key
- •A working embedding model for your document chunks
- •A database user with permission to create tables and extensions
- •
pippackages:- •
anthropic - •
psycopg[binary] - •
pgvector - •
python-dotenv
- •
pip install anthropic psycopg[binary] pgvector python-dotenv
Integration Steps
- •Set up PostgreSQL with pgvector and create your schema.
import os
import psycopg
from pgvector.psycopg import register_vector
DB_URL = os.getenv("DATABASE_URL")
with psycopg.connect(DB_URL) as conn:
register_vector(conn)
with conn.cursor() as cur:
cur.execute("CREATE EXTENSION IF NOT EXISTS vector;")
cur.execute("""
CREATE TABLE IF NOT EXISTS wealth_docs (
id SERIAL PRIMARY KEY,
client_id TEXT NOT NULL,
doc_type TEXT NOT NULL,
content TEXT NOT NULL,
embedding vector(1536) NOT NULL
);
""")
cur.execute("""
CREATE INDEX IF NOT EXISTS wealth_docs_embedding_idx
ON wealth_docs USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
""")
conn.commit()
- •Generate embeddings for wealth-management documents and store them in pgvector.
Use Anthropic’s embeddings-compatible workflow through your own embedding model if you already have one in production. If you’re standardizing on Anthropic for generation and another embedding source for vectors, keep the interface separate so retrieval stays stable.
import os
import psycopg
from pgvector.psycopg import register_vector
# Example assumes you already have a 1536-dim embedding from your embedding service.
def get_embedding(text: str) -> list[float]:
# Replace with your embedding provider call.
raise NotImplementedError
docs = [
{
"client_id": "client_123",
"doc_type": "risk_profile",
"content": "Client has moderate risk tolerance and prefers dividend-focused equities."
},
{
"client_id": "client_123",
"doc_type": "investment_policy",
"content": "Portfolio must maintain at least 20% fixed income allocation."
}
]
with psycopg.connect(os.getenv("DATABASE_URL")) as conn:
register_vector(conn)
with conn.cursor() as cur:
for doc in docs:
emb = get_embedding(doc["content"])
cur.execute(
"""
INSERT INTO wealth_docs (client_id, doc_type, content, embedding)
VALUES (%s, %s, %s, %s)
""",
(doc["client_id"], doc["doc_type"], doc["content"], emb),
)
conn.commit()
- •Retrieve relevant context from pgvector using cosine distance.
For an AI agent, retrieval should be filtered by client first, then ranked by semantic similarity. That keeps one client’s data from leaking into another client’s answer.
import os
import psycopg
from pgvector.psycopg import register_vector
def get_embedding(text: str) -> list[float]:
# Replace with your embedding provider call.
raise NotImplementedError
query = "What constraints apply to this client's portfolio?"
with psycopg.connect(os.getenv("DATABASE_URL")) as conn:
register_vector(conn)
q_emb = get_embedding(query)
with conn.cursor() as cur:
cur.execute(
"""
SELECT client_id, doc_type, content
FROM wealth_docs
WHERE client_id = %s
ORDER BY embedding <=> %s
LIMIT 3;
""",
("client_123", q_emb),
)
rows = cur.fetchall()
context = "\n".join([f"[{r[1]}] {r[2]}" for r in rows])
print(context)
- •Call Anthropic to generate the agent response using retrieved context.
Use the Anthropic Messages API. Keep the prompt grounded in retrieved records and force the model to stay within policy boundaries.
import os
from anthropic import Anthropic
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
context = """
[risk_profile] Client has moderate risk tolerance and prefers dividend-focused equities.
[investment_policy] Portfolio must maintain at least 20% fixed income allocation.
"""
user_question = "Can I increase equity exposure this quarter?"
response = client.messages.create(
model="claude-3-5-sonnet-latest",
max_tokens=400,
temperature=0.2,
system=(
"You are a wealth management assistant. "
"Answer only using the provided context. "
"If the context is insufficient, say so clearly."
),
messages=[
{
"role": "user",
"content": f"Context:\n{context}\n\nQuestion:\n{user_question}"
}
],
)
print(response.content[0].text)
- •Wrap retrieval + generation into one agent function.
This is the production shape: fetch memory from pgvector, then hand it to Anthropic for final response generation.
import os
import psycopg
from anthropic import Anthropic
from pgvector.psycopg import register_vector
anthropic_client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
def get_embedding(text: str) -> list[float]:
# Replace with your embedding provider call.
raise NotImplementedError
def answer_client_question(client_id: str, question: str) -> str:
q_emb = get_embedding(question)
with psycopg.connect(os.getenv("DATABASE_URL")) as conn:
register_vector(conn)
with conn.cursor() as cur:
cur.execute(
"""
SELECT doc_type, content
FROM wealth_docs
WHERE client_id = %s
ORDER BY embedding <=> %s
LIMIT 5;
""",
(client_id, q_emb),
)
docs = cur.fetchall()
context = "\n".join([f"[{doc_type}] {content}" for doc_type, content in docs])
resp = anthropic_client.messages.create(
model="claude-3-5-sonnet-latest",
max_tokens=300,
temperature=0.2,
system="You are a compliant wealth management assistant.",
messages=[
{
"role": "user",
"content": f"Use this context only:\n{context}\n\nQuestion: {question}"
}
],
)
return resp.content[0].text
print(answer_client_question("client_123", "What allocation constraints should I respect?"))
Testing the Integration
Run a simple end-to-end test that inserts one known policy document, retrieves it through pgvector, and checks that Anthropic answers using that policy.
def test_pipeline():
answer = answer_client_question(
client_id="client_123",
question="What fixed income minimum applies?"
)
print(answer)
test_pipeline()
Expected output:
The portfolio must maintain at least 20% fixed income allocation.
If retrieval is working but generation drifts, tighten the system prompt and lower temperature to 0 or 0.1.
Real-World Use Cases
- •Client policy Q&A agent: Answer questions about IPS constraints, risk profile changes, concentration limits, and rebalancing rules using retrieved client documents.
- •Advisor copilot: Summarize meeting notes plus portfolio history into a short brief before an advisor call.
- •Compliance-aware drafting: Generate outbound client emails that stay aligned with stored suitability rules and approved product language.
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