How to Integrate Anthropic for fintech with pgvector for startups

By Cyprian AaronsUpdated 2026-04-21
anthropic-for-fintechpgvectorstartups

Combining Anthropic for fintech with pgvector gives you a practical pattern for building AI agents that can answer finance questions from your own data, not just model memory. For startups, that means support bots that retrieve policy docs, underwriting notes, transaction context, or compliance guidance before generating a response.

The useful part is the split of responsibilities: Anthropic handles reasoning and generation, while pgvector stores embeddings for fast semantic retrieval over your internal knowledge base. That gives you grounded answers, lower hallucination risk, and a path to auditability.

Prerequisites

  • Python 3.10+
  • A running PostgreSQL instance with the pgvector extension enabled
  • An Anthropic API key
  • A PostgreSQL database/user with permission to create tables and extensions
  • Installed packages:
    • anthropic
    • psycopg[binary]
    • pgvector
    • sqlalchemy
  • A corpus of fintech documents to index:
    • product FAQs
    • KYC/AML policy docs
    • loan application rules
    • support tickets or internal runbooks

Install dependencies:

pip install anthropic psycopg[binary] pgvector sqlalchemy

Integration Steps

1) Enable pgvector and create a table for embeddings

Start by creating the extension and a table that stores text plus vectors. Use the vector dimension that matches your embedding model.

import psycopg

DB_URL = "postgresql://postgres:postgres@localhost:5432/fintech"

with psycopg.connect(DB_URL) as conn:
    with conn.cursor() as cur:
        cur.execute("CREATE EXTENSION IF NOT EXISTS vector;")
        cur.execute("""
            CREATE TABLE IF NOT EXISTS knowledge_base (
                id SERIAL PRIMARY KEY,
                source ტექxt TEXT NOT NULL,
                content TEXT NOT NULL,
                embedding VECTOR(1536)
            );
        """)
    conn.commit()

If you are using OpenAI-style embeddings elsewhere in your stack, VECTOR(1536) is common. If your embedding model uses another size, match it exactly.

2) Generate embeddings and store them in pgvector

Anthropic’s API is used here for generation later, not embeddings. For embeddings, use your existing embedding provider and persist the vectors into pgvector.

import psycopg
from pgvector.psycopg import register_vector

def embed_text(text: str) -> list[float]:
    # Replace with your embedding provider call.
    # Example shape only.
    return [0.01] * 1536

docs = [
    {
        "source": "aml_policy.pdf",
        "content": "Customers with suspicious transaction patterns require enhanced review."
    },
    {
        "source": "loan_playbook.md",
        "content": "Loan approvals above $50k require manual underwriting approval."
    },
]

with psycopg.connect(DB_URL) as conn:
    register_vector(conn)
    with conn.cursor() as cur:
        for doc in docs:
            emb = embed_text(doc["content"])
            cur.execute(
                """
                INSERT INTO knowledge_base (source, content, embedding)
                VALUES (%s, %s, %s)
                """,
                (doc["source"], doc["content"], emb),
            )
    conn.commit()

For production, batch inserts and normalize text before embedding. Keep one row per chunk rather than one row per document.

3) Query pgvector for relevant context

At runtime, convert the user question into an embedding and fetch the nearest chunks from Postgres.

import psycopg
from pgvector.psycopg import register_vector

def embed_query(query: str) -> list[float]:
    return [0.02] * 1536

question = "What happens if a loan request is above $50k?"

with psycopg.connect(DB_URL) as conn:
    register_vector(conn)
    with conn.cursor() as cur:
        q_emb = embed_query(question)
        cur.execute(
            """
            SELECT source, content
            FROM knowledge_base
            ORDER BY embedding <-> %s
            LIMIT 3;
            """,
            (q_emb,),
        )
        results = cur.fetchall()

context = "\n".join([f"[{row[0]}] {row[1]}" for row in results])
print(context)

The <-> operator is the standard pgvector distance operator for nearest-neighbor search. In practice, add an index like HNSW or IVFFLAT once your dataset grows.

4) Call Anthropic with retrieved context

Now pass the retrieved context into Anthropic’s Messages API so the model answers from grounded sources.

import anthropic

client = anthropic.Anthropic(api_key="YOUR_ANTHROPIC_API_KEY")

prompt = f"""
You are a fintech support assistant.
Answer only using the provided context.
If the answer is not in the context, say you don't know.

Context:
{context}

Question:
{question}
"""

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    max_tokens=300,
    temperature=0,
    messages=[
        {"role": "user", "content": prompt}
    ],
)

print(response.content[0].text)

Use low temperature for finance workflows. You want consistent outputs and fewer invented details.

5) Wrap it into an agent-friendly function

This is the piece you wire into your startup’s API layer or agent orchestrator.

def answer_fintech_question(question: str) -> str:
    q_emb = embed_query(question)

    with psycopg.connect(DB_URL) as conn:
        register_vector(conn)
        with conn.cursor() as cur:
            cur.execute(
                """
                SELECT source, content
                FROM knowledge_base
                ORDER BY embedding <-> %s
                LIMIT 3;
                """,
                (q_emb,),
            )
            rows = cur.fetchall()

    context = "\n".join([f"[{src}] {content}" for src, content in rows])

    resp = client.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=250,
        temperature=0,
        messages=[{
            "role": "user",
            "content": f"Context:\n{context}\n\nQuestion:\n{question}"
        }],
    )

    return resp.content[0].text.strip()

This function becomes your retrieval-augmented generation entry point. Put auth checks, logging, and redaction around it before exposing it to users.

Testing the Integration

Run a simple smoke test against a question that should match one of your indexed docs.

answer = answer_fintech_question("Do loans above $50k need manual review?")
print(answer)

Expected output:

Yes. Loans above $50k require manual underwriting approval.

If you get an empty or vague answer, check three things first:

  • Your embeddings are being stored correctly in pgvector
  • The query embedding uses the same dimension as stored vectors
  • The retrieved context actually contains the answer before calling Anthropic

Real-World Use Cases

  • Fintech support agent
    • Answer customer questions about limits, onboarding steps, card disputes, or loan policies using internal docs.
  • Compliance copilot
    • Retrieve AML/KYC procedures from Postgres and have Anthropic draft reviewer guidance or case summaries.
  • Ops assistant
    • Search incident runbooks, payment failure playbooks, and reconciliation notes to help engineers resolve issues faster.

This setup scales well because Postgres stays your system of record for knowledge while Anthropic handles language generation. For startups building regulated AI products, that separation matters more than fancy prompts.


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