How to Integrate OpenAI for lending with Pinecone for RAG

By Cyprian AaronsUpdated 2026-04-21
openai-for-lendingpineconerag

OpenAI for lending gives you the generation and reasoning layer for credit workflows. Pinecone gives you the retrieval layer so your agent can pull the right policy docs, underwriting rules, and product terms before it answers a borrower or loan officer.

That combination is what you want for RAG in lending: grounded answers, fewer hallucinations, and a clean path from internal knowledge to production agent behavior.

Prerequisites

  • Python 3.10+
  • An OpenAI API key with access to your lending model or lending-specific endpoint
  • A Pinecone account and API key
  • A Pinecone index created with the right embedding dimension for your embedding model
  • A document set to index:
    • loan policies
    • underwriting guides
    • rate sheets
    • compliance FAQs
  • Installed packages:
    • openai
    • pinecone
    • python-dotenv
pip install openai pinecone python-dotenv

Integration Steps

  1. Set up your environment

Keep secrets in env vars. Don’t hardcode keys into notebooks or agent code.

import os
from dotenv import load_dotenv

load_dotenv()

OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
PINECONE_API_KEY = os.getenv("PINECONE_API_KEY")
PINECONE_INDEX_NAME = os.getenv("PINECONE_INDEX_NAME", "lending-rag")
  1. Create clients for OpenAI and Pinecone

For OpenAI, use the standard SDK client. For Pinecone, initialize the client and connect to your index.

from openai import OpenAI
from pinecone import Pinecone

openai_client = OpenAI(api_key=OPENAI_API_KEY)
pc = Pinecone(api_key=PINECONE_API_KEY)

index = pc.Index(PINECONE_INDEX_NAME)
  1. Embed lending documents and store them in Pinecone

In a lending setup, chunk by policy section, not by arbitrary token count only. Store metadata like document type, version, and jurisdiction so retrieval can filter correctly.

def embed_text(text: str):
    resp = openai_client.embeddings.create(
        model="text-embedding-3-small",
        input=text,
    )
    return resp.data[0].embedding

docs = [
    {
        "id": "policy_001",
        "text": "Personal loans require minimum FICO 680 unless manual underwriting approves an exception.",
        "metadata": {"doc_type": "policy", "jurisdiction": "US", "version": "2024-10"}
    },
    {
        "id": "policy_002",
        "text": "Debt-to-income ratio must be below 43% for standard unsecured lending products.",
        "metadata": {"doc_type": "underwriting", "jurisdiction": "US", "version": "2024-10"}
    },
]

vectors = []
for doc in docs:
    vectors.append({
        "id": doc["id"],
        "values": embed_text(doc["text"]),
        "metadata": {**doc["metadata"], "text": doc["text"]}
    })

index.upsert(vectors=vectors)
  1. Retrieve relevant context from Pinecone

At query time, embed the user question, search Pinecone, then pass the top matches into OpenAI for lending as grounded context.

def retrieve_context(query: str, top_k: int = 3):
    query_vec = embed_text(query)
    result = index.query(
        vector=query_vec,
        top_k=top_k,
        include_metadata=True,
        filter={"jurisdiction": {"$eq": "US"}}
    )

    contexts = []
    for match in result["matches"]:
        md = match["metadata"]
        contexts.append(md["text"])
    return "\n".join(contexts)

query = "What FICO score is required for a personal loan?"
context = retrieve_context(query)
print(context)
  1. Generate the final answer with OpenAI for lending

Send the retrieved context to your generation model. Keep the prompt strict: answer only from retrieved policy text, and say when the docs do not contain enough information.

def answer_with_rag(question: str):
    context = retrieve_context(question)

    response = openai_client.responses.create(
        model="gpt-4.1-mini",
        input=[
            {
                "role": "system",
                "content": (
                    "You are a lending assistant. Answer only using the provided policy context. "
                    "If the context is insufficient, say so."
                )
            },
            {
                "role": "user",
                "content": f"Context:\n{context}\n\nQuestion:\n{question}"
            }
        ]
    )
    return response.output_text

print(answer_with_rag("What FICO score is required for a personal loan?"))

Testing the Integration

Run a simple end-to-end test that checks retrieval plus generation.

test_question = "What DTI threshold applies to standard unsecured loans?"
answer = answer_with_rag(test_question)

print("QUESTION:", test_question)
print("ANSWER:", answer)

Expected output:

QUESTION: What DTI threshold applies to standard unsecured loans?
ANSWER: Debt-to-income ratio must be below 43% for standard unsecured lending products.

If your output starts inventing thresholds or policy exceptions not present in Pinecone, your prompt is too loose or your retrieval is pulling weak chunks.

Real-World Use Cases

  • Loan officer copilot
    • Answer policy questions from internal underwriting manuals with citations from retrieved docs.
  • Borrower support agent
    • Explain eligibility rules, required documents, and next steps without exposing raw internal systems.
  • Compliance-aware decision support
    • Combine policy retrieval with structured loan data so reviewers can see why an application passed or failed against current rules.

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