Annotations
Overview
Pay-i provides four complementary approaches for adding metadata to your GenAI requests. Each method operates at a different scope and is ideal for different use cases.
The Four Annotation Approaches
Approach | Scope | Best For | Documentation |
---|---|---|---|
Global Defaults | Application-wide | Default parameters for the entire application | payi_instrument() |
@track Decorator | Function | Function-level annotations that propagate through the call tree | track_decorator |
track_context() | Code Block/Request | Arbitrary code blocks and request-specific annotations in Python | track_context |
Custom Headers | Request | Request annotations in non-Python environments | Custom Headers |
Choosing the Right Approach
Each annotation approach has different strengths and is suited for different types of tasks:
Global Defaults with payi_instrument()
payi_instrument()
Use when you need:
- Application-wide defaults that apply to all requests
- Consistent base values across your entire application
- A simple foundation for all other annotations to build upon
Example:
from payi.lib.instrument import payi_instrument
# Set global defaults for the entire application
payi_instrument(config={
"use_case_name": "my_application",
"limit_ids": ["application_budget"],
"proxy": False # Direct Provider Call with Telemetry
})
Function-Level with @track
@track
Use when you need:
- Function-level annotations that apply to all API calls within a function
- Parameter inheritance across a call tree
- Consistent business context across related operations
- User attribution from application context (like session data)
Example:
from payi.lib.instrument import track
@track(use_case_name="summarization", limit_ids=["daily_budget"])
def process_document(client, text):
# All API calls inside this function inherit the parameters
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": text}]
)
return response
Block-Level with track_context()
track_context()
Use when you need:
- Code block-specific annotations without creating a function
- Support for additional parameters like
request_tags
- Temporary parameter overrides within a larger function
- Dynamic user attribution that changes during execution
Example:
from payi.lib.instrument import track_context
def process_multiple_documents(client, documents):
for i, doc in enumerate(documents):
# Each document gets its own tracking context
with track_context(
use_case_name="doc_processing",
request_tags=[f"document_{i}"]
):
process_document(client, doc)
Learn more about track_context()
Request-Level with Custom Headers
In Python applications, track_context()
is generally cleaner and more explicit for request-level annotations. Custom headers are primarily useful in:
- Non-Python environments (JavaScript, Java, etc.) where Pay-i Python SDK isn't available
- Systems already working extensively with headers (like API gateways or proxies)
- Existing code where header manipulation is already part of the workflow
Example:
from payi.lib.helpers import create_headers
def process_priority_request(client, query, priority_level):
# Parameters specific to this individual request
headers = create_headers(
request_tags=[f"priority_{priority_level}", "customer_support"],
limit_ids=["priority_requests", "support_team"]
)
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": query}],
extra_headers=headers
)
return response
Learn more about Custom Headers
Combined Approaches
These approaches can be combined to provide comprehensive annotation at every level of your application. For example:
- Set application defaults with
payi_instrument()
- Use
@track
for function-level business context - Apply
track_context()
for specific code blocks with additional parameters - Use custom headers for request-specific values
This creates a layered approach to annotations, allowing you to control metadata at every level of your application.
Learn more about combining annotation approaches
Parameter Precedence
When using multiple annotation methods together, Pay-i follows a "latest wins" strategy:
- Whichever context is created later in the execution flow takes precedence
- Custom headers have final say at the individual request level
- Some parameters (like
limit_ids
andrequest_tags
) combine values rather than strictly overriding
For detailed information on parameter precedence, see Combined Annotations and Parameter Precedence in Pay-i Instrumentation.
Parameter Documentation
Each parameter has dedicated documentation with comprehensive implementation details:
- Business Context: See Use Cases for using the
use_case_name
parameter - Budget Management: See Limits for using the
limit_ids
parameter - User Attribution: See User-level Attribution for using the
user_id
parameter - Request Metadata: See Request Tags for using the
request_tags
parameter
Related Resources
- Combined Annotations - How to effectively combine different annotation approaches
- User-level Attribution - Guide to tracking GenAI usage by individual users
- Use Cases - Managing business-level context with use case parameters
- Limits - Implementing usage budgets and quotas
Updated 4 days ago