How to Integrate Azure OpenAI for investment banking with CosmosDB for AI agents

By Cyprian AaronsUpdated 2026-04-21
azure-openai-for-investment-bankingcosmosdbai-agents

Azure OpenAI gives you the reasoning layer for banking workflows: summarizing deal docs, extracting covenants, drafting client responses, and powering analyst copilots. CosmosDB gives you the durable memory layer: storing deal context, user preferences, audit trails, and retrieval data for agents that need to stay consistent across sessions.

Together, they let you build investment banking agents that can answer with context from prior interactions, persist structured deal data, and keep a full trace of what the model saw and returned.

Prerequisites

  • Python 3.10+
  • An Azure OpenAI resource deployed with:
    • a chat model deployment name
    • endpoint
    • API key
  • An Azure Cosmos DB for NoSQL account with:
    • database
    • container
    • partition key design decided
  • pip installed
  • Network access to Azure endpoints
  • Environment variables set:
    • AZURE_OPENAI_ENDPOINT
    • AZURE_OPENAI_API_KEY
    • AZURE_OPENAI_DEPLOYMENT
    • COSMOS_ENDPOINT
    • COSMOS_KEY
    • COSMOS_DATABASE
    • COSMOS_CONTAINER

Install the SDKs:

pip install openai azure-cosmos python-dotenv

Integration Steps

  1. Set up your clients and load configuration.
import os
from dotenv import load_dotenv
from openai import AzureOpenAI
from azure.cosmos import CosmosClient, PartitionKey

load_dotenv()

aoai_client = AzureOpenAI(
    api_key=os.environ["AZURE_OPENAI_API_KEY"],
    api_version="2024-02-15-preview",
    azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
)

cosmos_client = CosmosClient(
    url=os.environ["COSMOS_ENDPOINT"],
    credential=os.environ["COSMOS_KEY"],
)

db_name = os.environ["COSMOS_DATABASE"]
container_name = os.environ["COSMOS_CONTAINER"]
database = cosmos_client.create_database_if_not_exists(id=db_name)
container = database.create_container_if_not_exists(
    id=container_name,
    partition_key=PartitionKey(path="/session_id"),
)
  1. Create a simple agent memory record in CosmosDB.

Use CosmosDB to store conversation state, extracted entities, and model outputs. For banking use cases, keep a record per deal or per analyst session.

from datetime import datetime, timezone

def save_agent_turn(session_id: str, user_input: str, model_output: str):
    item = {
        "id": f"{session_id}-{int(datetime.now(timezone.utc).timestamp())}",
        "session_id": session_id,
        "user_input": user_input,
        "model_output": model_output,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "source": "azure-openai",
        "workflow": "investment-banking-agent",
    }
    container.upsert_item(item)
    return item

def get_session_history(session_id: str):
    query = """
    SELECT * FROM c
    WHERE c.session_id = @session_id
    ORDER BY c.created_at ASC
    """
    params = [{"name": "@session_id", "value": session_id}]
    items = list(container.query_items(
        query=query,
        parameters=params,
        enable_cross_partition_query=True,
    ))
    return items
  1. Call Azure OpenAI with retrieved context from CosmosDB.

This is the core pattern: fetch prior deal context from CosmosDB, send it into the chat completion request, then write the response back to CosmosDB.

def build_messages(session_id: str, user_prompt: str):
    history = get_session_history(session_id)

    context_text = "\n".join([
        f"User: {item['user_input']}\nAssistant: {item['model_output']}"
        for item in history[-5:]
    ])

    messages = [
        {
            "role": "system",
            "content": (
                "You are an investment banking assistant. "
                "Be concise, factual, and avoid unsupported claims."
            ),
        },
        {
            "role": "user",
            "content": f"Conversation history:\n{context_text}\n\nCurrent request:\n{user_prompt}",
        },
    ]
    return messages

def ask_banking_agent(session_id: str, user_prompt: str):
    messages = build_messages(session_id, user_prompt)

    response = aoai_client.chat.completions.create(
        model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
        messages=messages,
        temperature=0.2,
        max_tokens=500,
    )

    answer = response.choices[0].message.content
    save_agent_turn(session_id, user_prompt, answer)
    return answer
  1. Add structured extraction for banking documents.

For investment banking workflows, you usually need more than free-form text. Extract fields like company name, transaction type, revenue range, and risks into a CosmosDB document that downstream systems can query.

def extract_deal_fields(deal_text: str):
    response = aoai_client.chat.completions.create(
        model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
        messages=[
            {
                "role": "system",
                "content": (
                    "Extract structured investment banking fields as JSON only."
                ),
            },
            {
                "role": "user",
                "content": deal_text,
            },
        ],
        temperature=0,
        max_tokens=400,
    )

    return response.choices[0].message.content

def store_deal_summary(session_id: str, deal_text: str):
    extracted_json = extract_deal_fields(deal_text)

    item = {
        "id": f"deal-{session_id}",
        "session_id": session_id,
        "document_type": "deal_summary",
        "raw_text": deal_text,
        "extracted_json": extracted_json,
        "created_at": datetime.now(timezone.utc).isoformat(),
    }
    container.upsert_item(item)
  1. Wire the flow into an agent function.

This gives you one entry point for your application or orchestration layer.

def run_investment_banking_agent(session_id: str, prompt: str):
    answer = ask_banking_agent(session_id=session_id, user_prompt=prompt)
    
    return {
        "session_id": session_id,
        "answer": answer,
    }

if __name__ == "__main__":
    result = run_investment_banking_agent(
        session_id="ib-session-001",
        prompt="Summarize this acquisition memo and highlight the top three diligence risks.",
    )
    print(result["answer"])

Testing the Integration

Run a simple end-to-end test that writes memory to CosmosDB and gets a response from Azure OpenAI.

test_session = "ib-test-001"

save_agent_turn(
    test_session,
    "Company ABC reported $120M revenue with strong recurring SaaS income.",
    "Noted. Revenue profile suggests stable recurring cash flows."
)

answer = ask_banking_agent(
    test_session,
    "Based on prior context, what should I flag in an IC memo?"
)

print(answer)

Expected output:

You should flag revenue concentration risk, customer retention assumptions, margin quality, and any gaps in diligence around working capital or debt terms.

If this works end to end:

  • CosmosDB is persisting session state correctly.
  • Azure OpenAI is receiving retrieved context.
  • Your agent can maintain continuity across turns.

Real-World Use Cases

  • Deal memo copilot
    Store analyst notes in CosmosDB and use Azure OpenAI to draft IC memo sections with consistent context across revisions.

  • Diligence Q&A agent
    Persist extracted facts from CIMs, financial models, and legal docs in CosmosDB so the agent can answer follow-up questions without losing state.

  • Banker workflow assistant
    Track client conversations, action items, and entity-level metadata in CosmosDB while using Azure OpenAI to summarize calls and generate next-step emails.


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