How to Integrate Anthropic for payments with pgvector for production AI
Combining Anthropic with pgvector gives you a clean pattern for production AI agents that need both reasoning and retrieval. In practice, this means your agent can answer from company knowledge stored in vectors, then route payment-related actions through Anthropic-backed workflows with traceable context.
For banks and insurance systems, that matters because you want the model to see only the right retrieved facts before it makes a payment decision. pgvector handles semantic search over policies, invoices, claims, or transaction notes; Anthropic handles the language layer that decides what to do next.
Prerequisites
- •Python 3.10+
- •PostgreSQL 14+ with the
pgvectorextension installed - •An Anthropic API key
- •A PostgreSQL user with permission to create tables and extensions
- •
psycopgorpsycopg2-binary - •
anthropicPython SDK - •A working payments backend or sandbox endpoint if you are triggering payment actions from the agent
- •Basic environment variables set:
- •
ANTHROPIC_API_KEY - •
DATABASE_URL
- •
Integration Steps
- •
Install dependencies and enable pgvector
Start by installing the Python packages and enabling the vector extension in Postgres.
pip install anthropic psycopg[binary] pgvector python-dotenvimport os import psycopg from dotenv import load_dotenv load_dotenv() conn = psycopg.connect(os.environ["DATABASE_URL"]) conn.execute("CREATE EXTENSION IF NOT EXISTS vector;") conn.commit() conn.close() - •
Create a vector table for payment-related context
Store invoice notes, customer messages, policy clauses, or payment instructions as embeddings. Use a fixed embedding dimension that matches your embedding model.
import os import psycopg conn = psycopg.connect(os.environ["DATABASE_URL"]) with conn.cursor() as cur: cur.execute(""" CREATE TABLE IF NOT EXISTS payment_docs ( id BIGSERIAL PRIMARY KEY, source ტექst TEXT NOT NULL, content TEXT NOT NULL, embedding vector(1536) ); """) cur.execute(""" CREATE INDEX IF NOT EXISTS payment_docs_embedding_idx ON payment_docs USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100); """) conn.commit() conn.close() - •
Generate embeddings with Anthropic-compatible retrieval flow
Anthropic’s core API is for text generation, so in production you usually pair it with an embedding model service for vectors. If your architecture keeps embeddings outside Anthropic, store them in pgvector and use Anthropic for reasoning over retrieved chunks.
The pattern below uses an embedding function placeholder and then stores vectors in Postgres.
import os import psycopg from anthropic import Anthropic client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]) def embed_text(text: str) -> list[float]: # Replace with your embedding provider. # Keep the return shape aligned with vector(1536). return [0.0] * 1536 docs = [ ("invoice_1042", "Customer requested a refund after duplicate charge."), ("policy_22", "Refunds above $500 require manager approval."), ("payment_runbook", "Use ACH for domestic vendor payouts under $10k.") ] conn = psycopg.connect(os.environ["DATABASE_URL"]) with conn.cursor() as cur: for source, content in docs: emb = embed_text(content) cur.execute( "INSERT INTO payment_docs (source, content, embedding) VALUES (%s, %s, %s)", (source, content, emb) ) conn.commit() conn.close() - •
Retrieve relevant context from pgvector before calling Anthropic
This is the production pattern: search Postgres first, then send only the top matches to Anthropic. That keeps prompts smaller and decisions grounded in your internal data.
import os import psycopg from anthropic import Anthropic client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]) def embed_text(text: str) -> list[float]: return [0.0] * 1536 def retrieve_context(query: str, k: int = 3) -> list[str]: query_vec = embed_text(query) conn = psycopg.connect(os.environ["DATABASE_URL"]) with conn.cursor() as cur: cur.execute( """ SELECT source, content FROM payment_docs ORDER BY embedding <=> %s::vector LIMIT %s; """, (query_vec, k), ) rows = cur.fetchall() conn.close() return [f"{source}: {content}" for source, content in rows] query = "Can we approve a $700 refund for duplicate billing?" context = retrieve_context(query) message = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=300, messages=[ { "role": "user", "content": f"""
You are a payments assistant. Use this internal context:
{chr(10).join(context)}
Question: {query} Return a decision and short rationale. """.strip(), } ], )
print(message.content[0].text)
```
5. Trigger a payment action from the model output
In production, do not let Claude execute payments directly. Parse its structured recommendation, validate it in code, then call your payments service.
import json
import os
import requests
def execute_payment_action(decision_text: str):
# Example of strict downstream control.
if "approve" not in decision_text.lower():
return {"status": "skipped"}
payload = {
"amount": 700,
"currency": "USD",
"reason": "duplicate billing refund",
"reference": "refund_1042"
}
resp = requests.post(
os.environ["PAYMENTS_API_URL"],
headers={"Authorization": f"Bearer {os.environ['PAYMENTS_API_KEY']}"},
json=payload,
timeout=10,
)
resp.raise_for_status()
return resp.json()
## Testing the Integration
Run a single end-to-end check: retrieve context from pgvector, ask Anthropic for a decision, then assert the response contains an expected action keyword.
```python
query = "Approve refund for duplicate charge under $500?"
context = retrieve_context(query)
message = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=200,
messages=[{
"role": "user",
"content": f"Context:\n{chr(10).join(context)}\n\nQuestion: {query}\nRespond with APPROVE or REJECT."
}],
)
result = message.content[0].text.strip().upper()
print(result)
assert result in {"APPROVE", "REJECT"}
Expected output:
APPROVE
If you get empty context back from pgvector, check:
- •Your embeddings dimension matches the table definition.
- •The
vectorextension is enabled. - •Your similarity operator uses the same metric you indexed on.
- •You inserted real embeddings instead of placeholder zeros.
Real-World Use Cases
- •
Claims payout assistant
Retrieve claim policy clauses from pgvector, then use Anthropic to decide whether a payout request meets approval rules before calling your payments API. - •
Vendor payment copilot
Search invoice history and vendor terms in pgvector, then have Anthropic explain whether to pay now, hold for review, or escalate to finance ops. - •
Customer refund triage
Pull dispute history and refund policy snippets from pgvector, then let Anthropic produce a structured recommendation that your backend turns into an approved refund workflow.
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