Guides

Instrumentation for Azure OpenAI

Overview

Azure OpenAI is unique among AI providers in the way it handles referencing the model being used at runtime. Before you can use any LLMs, you must first deploy them as Azure resources. The deployment itself has a deployment name, which is a completely custom string, that is used instead of the model name when making requests through the SDK. This means that Pay-i cannot automatically infer the Resource, or model, that is being used.

Further, Azure allows you to specify a deployment scope from a list of several choices (e.g., global, datazone, region). These scopes impact pricing. Since they are a part of the underlying deployment metadata, they are not referenced at runtime, and so Pay-i cannot automatically infer the scope.

In order for Pay-i to provide accurate pricing data, you will need to provide a mapping between the deployment name used at runtime to the Resource name and scope defined in the Azure portal.

Methods of Providing the Mapping

There are three ways to provide the mapping to Pay-i.

  1. As part of the payi_instrument() configuration.
    1. This mapping will apply to all Azure OpenAI calls made in the executable.
    2. This is the simplest and most preferred method to begin.
  2. As part of track_context()
    1. This mapping will apply to all Azure OpenAI calls made within the context manager.
    2. This is best for when you want to override the default mappings made in payi_instrument() for a series of requests.
  3. By using custom headers on an individual request.
    1. This mapping will only apply to that specific request.
    2. This is best for when you want to override the mapping in either track_context() or payi_instrument() for a single request.

Mapping via payi_instrument()

from payi.lib.instrument import PayiInstrumentModelMapping

#Begin by creating the mapping between the model name, the deployment name, and the scope
#The below is organized as (real model name, deployment name, scope)
azure_openai_mapping = [
        ("gpt-4o-2024-11-20", "gpt-4o-2024-11-20-global-r2d2", "global"),
        ("gpt-4o-mini", "my_custom_deployment_name", "datazone"),
        ("gpt-4o-mini", "gpt-4o-mini-region", "region"),
        ("o3-2025-04-16", "o3-global-completions", "global"),
    ]

#This transforms the mapping into the required format, using the PayiInstrumentModelMapping helper
azure_deployments = []
	for model, deployment, scope in azure_openai_mapping
		azure_deployments.append(PayiInstrumentModelMapping(
			model=deployment,
			price_as_resource=model,
			resource_scope=scope
		))

#When doing the payi_instrument init, specify the mapping configuration. 
payi_instrument(
	config={
          "azure_openai_config": { "model_mappings": azure_deployments },
})

Mapping via track_context()

When using [track_context()](https://docs.pay-i.com/docs/day-2-tracking-users#/), you can specify the price_as_resource and price_as_category parameters to directly specify the Category and Resource that should be used for pricing the calls made within the context manager. Note that this will override any mappings defined in payi_instrument().

from payi.lib.instrument import track_context

def my_function(prompt):
    
    with track_context(price_as_resource="gpt-3.5-turbo", price_as_category="system.openai"):
        response = client.chat.completions.create(
            model="my_custom_azure_deployment",
            messages=[{"role": "user", "content": prompt}]
        )
    return response.choices[0].message.content

Mapping via Custom Headers

When making requests, you can specify additional HTTP headers that only Pay-i will interrogate and use. Two of those headers are xProxy-PriceAs-Category and xProxy-PriceAs-Resource, which directly specify the Category and Resource that should be used for pricing this specific request. Note that this will override any mappings in any parent context managers or in payi_instrument().

The create_headers helper function makes it easy to define the HTTP headers correctly with simple syntax and auto-complete.

from payi.lib.helpers import create_headers

response = oai_client.chat.completions.create(
    model="my_custom_azure_deployment",
    messages=[{"role": "user", "content": "Say 'this is a test'"}],
    extra_headers=create_headers(
      price_as_resource="gpt-3.5-turbo", 
			price_as_category="system.openai"
    )
)