How to Integrate Azure OpenAI for wealth management with CosmosDB for startups
Wealth management agents need two things: a model that can reason over client context, and a durable store that keeps portfolios, preferences, and interaction history. Azure OpenAI gives you the reasoning layer; CosmosDB gives you low-latency state for customer profiles, suitability rules, and audit trails.
For startups, this combo unlocks an agent that can answer portfolio questions, draft personalized recommendations, and persist every decision for compliance review.
Prerequisites
- •An Azure subscription with:
- •Azure OpenAI resource
- •Azure Cosmos DB account
- •Python 3.10+
- •
pipinstalled - •An Azure OpenAI deployment name for a chat model like
gpt-4o-mini - •Cosmos DB SQL API enabled
- •Environment variables configured:
- •
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
- •Set up the clients
Use the Azure OpenAI chat client for generation and the Cosmos client for persistence. Keep both in one module so your agent can read state, generate advice, then write back the interaction.
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(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="/customerId"),
)
- •Create a portfolio profile in Cosmos DB
Store structured wealth data in Cosmos DB. For an agent system, this is better than stuffing everything into prompts because you can update it independently and query it cheaply.
portfolio_doc = {
"id": "cust-1001",
"customerId": "cust-1001",
"name": "Amina Patel",
"riskProfile": "moderate",
"age": 38,
"goals": ["retirement", "education_fund"],
"assets": {
"equities": 0.55,
"bonds": 0.30,
"cash": 0.15
},
"constraints": {
"no_crypto": True,
"max_drawdown_tolerance": 0.12
}
}
container.upsert_item(portfolio_doc)
stored = container.read_item(item="cust-1001", partition_key="cust-1001")
print(stored["name"], stored["riskProfile"])
- •Pull client context and ask Azure OpenAI for a recommendation draft
Fetch the latest profile from Cosmos DB, then pass only the relevant fields into the model. In wealth workflows, keep prompts narrow and explicit so the output stays auditable.
client_profile = container.read_item(item="cust-1001", partition_key="cust-1001")
messages = [
{
"role": "system",
"content": (
"You are a wealth management assistant for a startup advisory platform. "
"Provide concise, compliant investment guidance based on client profile data. "
"Do not invent facts."
),
},
{
"role": "user",
"content": f"""
Client profile:
Name: {client_profile['name']}
Age: {client_profile['age']}
Risk profile: {client_profile['riskProfile']}
Goals: {', '.join(client_profile['goals'])}
Assets: {client_profile['assets']}
Constraints: {client_profile['constraints']}
Draft a short portfolio review and one rebalancing suggestion.
""",
},
]
response = aoai_client.chat.completions.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
messages=messages,
temperature=0.2,
)
recommendation = response.choices[0].message.content
print(recommendation)
- •Persist the recommendation and audit trail back to Cosmos DB
In regulated workflows, every model output should be traceable. Store the prompt summary, response text, timestamp, and any downstream action your agent took.
from datetime import datetime, timezone
audit_record = {
"id": f"audit-{client_profile['id']}-{datetime.now(timezone.utc).isoformat()}",
"customerId": client_profile["customerId"],
"type": "portfolio_review",
"modelDeployment": os.environ["AZURE_OPENAI_DEPLOYMENT"],
"inputSummary": {
"riskProfile": client_profile["riskProfile"],
"goals": client_profile["goals"],
"constraints": client_profile["constraints"],
},
"recommendation": recommendation,
"createdAtUtc": datetime.now(timezone.utc).isoformat(),
}
container.upsert_item(audit_record)
print("Audit record saved.")
- •Wrap it as an agent function
Your application will usually call this through an API route or orchestration layer. Keep the flow deterministic: load profile, generate advice, save audit record.
def generate_wealth_review(customer_id: str) -> str:
profile = container.read_item(item=customer_id, partition_key=customer_id)
messages = [
{"role": "system", "content": "You are a wealth management assistant."},
{
"role": "user",
"content": f"Review this client and suggest one action:\n{profile}",
},
]
result = aoai_client.chat.completions.create(
model=os.environ["AZURE_OPENAI_DEPLOYMENT"],
messages=messages,
temperature=0.2,
)
text = result.choices[0].message.content
container.upsert_item({
"id": f"audit-{customer_id}",
"customerId": customer_id,
"type": "review_snapshot",
"resultText": text,
"_ts_note": int(datetime.now(timezone.utc).timestamp()),
})
return text
Testing the Integration
Run a simple end-to-end check against one stored customer record.
if __name__ == "__main__":
output = generate_wealth_review("cust-1001")
print("\n--- MODEL OUTPUT ---\n")
print(output)
Expected output:
--- MODEL OUTPUT ---
Client has a moderate risk profile with long-term goals.
Current allocation is slightly equity-heavy relative to constraints.
Consider trimming equities by 5% and increasing bonds or cash reserves to reduce drawdown risk while maintaining growth exposure.
If you want to verify persistence too, query the latest audit item:
query = """
SELECT TOP 1 * FROM c
WHERE c.customerId = @customerId AND c.type = @type
ORDER BY c.createdAtUtc DESC
"""
items = list(container.query_items(
query=query,
parameters=[
{"name": "@customerId", "value": "cust-1001"},
{"name": "@type", "value": "portfolio_review"},
],
))
print(items[0]["type"], items[0]["customerId"])
Real-World Use Cases
- •Personalized portfolio review agents that summarize holdings, flag concentration risk, and store every recommendation for compliance.
- •Client onboarding assistants that collect goals and constraints through chat, then write structured profiles into Cosmos DB.
- •Advisor copilots that retrieve historical interactions from Cosmos DB before generating next-step recommendations with Azure OpenAI.
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