How to Integrate Azure OpenAI for investment banking with CosmosDB for multi-agent systems
Combining Azure OpenAI with Cosmos DB gives you a practical agent backbone for investment banking workflows: one side handles analysis, summarization, and tool use; the other side stores agent state, trade context, compliance notes, and conversation history with low-latency retrieval.
For multi-agent systems, this matters because each agent needs durable memory. A research agent can pull market context, a risk agent can store approvals and exceptions, and an execution agent can read the latest validated state before acting.
Prerequisites
- •An Azure subscription
- •An Azure OpenAI resource deployed with:
- •
gpt-4o-minior another chat model deployment - •
text-embedding-3-smallor similar if you want vector memory later
- •
- •An Azure Cosmos DB account using the NoSQL API
- •Python 3.10+
- •Installed packages:
- •
openai - •
azure-cosmos - •
python-dotenv
- •
- •Environment variables configured:
- •
AZURE_OPENAI_ENDPOINT - •
AZURE_OPENAI_API_KEY - •
AZURE_OPENAI_API_VERSION - •
AZURE_OPENAI_DEPLOYMENT_NAME - •
COSMOS_ENDPOINT - •
COSMOS_KEY - •
COSMOS_DATABASE_NAME - •
COSMOS_CONTAINER_NAME
- •
Install dependencies:
pip install openai azure-cosmos python-dotenv
Integration Steps
1) Initialize Azure OpenAI and Cosmos DB clients
Start by wiring both services in the same Python process. Keep credentials in environment variables so your agents can run in containers or serverless jobs without code changes.
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=os.environ["AZURE_OPENAI_API_VERSION"],
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_NAME"]
container_name = os.environ["COSMOS_CONTAINER_NAME"]
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"),
offer_throughput=400
)
2) Define a shared memory schema for your agents
In investment banking workflows, you want each record to be auditable. Store who wrote it, which agent produced it, what task it belongs to, and a timestamp.
from datetime import datetime, timezone
import uuid
def build_memory_record(session_id: str, agent_name: str, role: str, content: str):
return {
"id": str(uuid.uuid4()),
"session_id": session_id,
"agent_name": agent_name,
"role": role,
"content": content,
"created_at": datetime.now(timezone.utc).isoformat()
}
record = build_memory_record(
session_id="deal-nyc-001",
agent_name="research_agent",
role="assistant",
content="Comparable company analysis suggests EV/EBITDA compression in regional banks."
)
container.upsert_item(record)
This structure works well for multi-agent coordination because every agent can write to the same container while staying isolated by partition key.
3) Call Azure OpenAI and persist the response in Cosmos DB
Use Azure OpenAI to generate a banking-specific response, then save both the prompt and the answer. That gives you replayability for audits and downstream agents.
def ask_azure_openai(prompt: str) -> str:
response = aoai_client.chat.completions.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
messages=[
{"role": "system", "content": "You are an investment banking analyst assistant."},
{"role": "user", "content": prompt}
],
temperature=0.2,
)
return response.choices[0].message.content
session_id = "deal-nyc-001"
prompt = "Summarize key diligence risks for a leveraged buyout of a mid-market software company."
answer = ask_azure_openai(prompt)
container.upsert_item(build_memory_record(
session_id=session_id,
agent_name="analysis_agent",
role="user",
content=prompt
))
container.upsert_item(build_memory_record(
session_id=session_id,
agent_name="analysis_agent",
role="assistant",
content=answer
))
print(answer)
4) Retrieve prior agent memory before generating the next response
A real multi-agent system should not answer from scratch every time. Pull recent context from Cosmos DB so the next agent sees prior decisions.
def get_session_memory(session_id: str, limit: int = 5):
query = """
SELECT TOP @limit c.id, c.agent_name, c.role, c.content, c.created_at
FROM c
WHERE c.session_id = @session_id
ORDER BY c.created_at DESC
"""
params = [
{"name": "@session_id", "value": session_id},
{"name": "@limit", "value": limit}
]
items = list(container.query_items(
query=query,
parameters=params,
enable_cross_partition_query=True
))
return items
memory = get_session_memory("deal-nyc-001")
context_block = "\n".join(
f"[{item['agent_name']}:{item['role']}] {item['content']}"
for item in reversed(memory)
)
follow_up_prompt = f"""
Use this deal context:
{context_block}
Now draft a concise risk note for the IC memo.
"""
follow_up_answer = ask_azure_openai(follow_up_prompt)
print(follow_up_answer)
5) Orchestrate multiple agents with shared Cosmos-backed state
The clean pattern is: one orchestrator writes task state to Cosmos DB, specialist agents read it, then each writes back their output. This keeps coordination explicit instead of hidden in memory.
def update_task_state(session_id: str, task_name: str, status: str):
container.upsert_item({
"id": f"{session_id}:{task_name}",
"session_id": session_id,
"task_name": task_name,
"status": status,
"created_at": datetime.now(timezone.utc).isoformat()
})
update_task_state("deal-nyc-001", "risk_review", "in_progress")
risk_prompt = """
Review this transaction for covenant risk, leverage risk, and disclosure gaps.
Return three bullet points.
"""
risk_note = ask_azure_openai(risk_prompt)
container.upsert_item(build_memory_record(
session_id="deal-nyc-001",
agent_name="risk_agent",
role="assistant",
content=risk_note
))
update_task_state("deal-nyc-001", "risk_review", "complete")
Testing the Integration
Run a simple end-to-end check:
test_session = "test-session-001"
test_prompt = "Write a one-paragraph summary of why stored memory matters in M&A diligence."
test_answer = ask_azure_openai(test_prompt)
container.upsert_item(build_memory_record(
session_id=test_session,
agent_name="test_agent",
role="assistant",
content=test_answer
))
saved_items = get_session_memory(test_session, limit=1)
print("MODEL OUTPUT:")
print(test_answer)
print("\nSAVED ITEM:")
print(saved_items[0]["content"])
Expected output:
MODEL OUTPUT:
Stored memory matters in M&A diligence because it preserves prior findings...
SAVED ITEM:
Stored memory matters in M&A diligence because it preserves prior findings...
If that round-trip works, your Azure OpenAI calls are generating content and Cosmos DB is persisting state correctly.
Real-World Use Cases
- •
Deal team copilot
One agent drafts management questions, another tracks diligence gaps in Cosmos DB, and a third generates IC memo sections from stored findings. - •
Risk and compliance workflow
Store every model output tied to a deal ID so legal and compliance teams can review decisions after the fact. - •
Multi-agent research pipeline
Build separate agents for market data synthesis, comp set analysis, and valuation commentary. Use Cosmos DB as the shared source of truth between them.
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