Yandex Cloud
Search
Discuss with expertTry it for free
  • Customer Stories
  • Documentation
  • Blog
  • All Services
    • Cloud Interconnect
    • Cloud Backup
    • Cloud Registry
    • Yandex AI Studio
    • Compute Cloud
    • Object Storage
    • Managed Service for Kubernetes®
    • Yandex BareMetal
    • Smart Web Security
    • Security Deck
    • Managed Service for PostgreSQL
    • Managed Service for ClickHouse®
    • Monium
    • Cloud CDN
    • Network Load Balancer
    • Virtual Private Cloud
    • Cloud DNS
    • Application Load Balancer
    • Yandex Cloud Video
    • Stackland
    • Yandex Cloud Router
    • Yandex Managed Service for Trino
    • Managed Service for MySQL®
    • Managed Service for Valkey™
    • Managed Service for Apache Spark™
    • Yandex StoreDoc
    • Managed Service for OpenSearch
    • Managed Service for Apache Kafka®
    • Data Transfer
    • Yandex MPP Analytics Engine for PostgreSQL
    • Yandex Managed Service for Apache Airflow®
    • Data Processing
    • Yandex MetaData Hub
    • Managed Service for YDB
    • Managed Service for Sharded PostgreSQL
    • Managed Service for YTsaurus
    • Yandex WebSQL
    • DataLens
    • Yandex Search API
    • SpeechSense
    • SpeechKit
    • DataSphere
    • Vision OCR
    • Translate
    • Yandex Identity Hub
    • Key Management Service
    • Certificate Manager
    • Yandex Lockbox
    • Audit Trails
    • SmartCaptcha
    • Cloud Desktop
    • Yandex SIEM
    • SourceCraft Code Assistant
    • Container Registry
    • Managed Service for GitLab
    • Managed Service for Prometheus®
    • Cloud Functions
    • API Gateway
    • Yandex Cloud Postbox
    • Message Queue
    • Serverless Integrations
    • IoT Core
    • Data Streams
    • Serverless Containers
    • Cloud Notification Service
    • Yandex Query
    • Identity and Access Management
    • Yandex Cloud Console
    • Resource Manager
    • Yandex Cloud Billing
    • Yandex Cloud Quota Manager
    • Cloud Apps
  • System Status
  • Marketplace
    • Featured
    • Infrastructure & Network
    • Data Platform
    • AI for business
    • Security
    • DevOps tools
    • Serverless
    • Monitoring & Resources
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Start testing with double trial credits
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Center for Technologies and Society
    • Yandex Cloud Partner program
    • Price calculator
    • Pricing plans
  • Customer Stories
  • Documentation
  • Blog
© 2026 Direct Cursus Technology L.L.C.
Monium
  • Getting started
  • Overview
    • Getting started
    • Basic terms
      • Getting started
      • Auto-instrumentation of LLM applications
      • Manual instrumentation of LLM applications
      • Viewing and analyzing LLM traces
    • Limitations
  • Access management
  • Pricing policy
  • Terraform reference
  • Release notes

In this article:

  • Supported frameworks
  • Configuration example
  • Set up your environment
  • Create an agent file
  • Run the agent
  • Limitations
  1. Traces
  2. LLM monitoring
  3. Auto-instrumentation of LLM applications

Auto-instrumentation of LLM applications

Written by
Yandex Cloud
Updated at August 19, 2026
View in Markdown
  • Supported frameworks
  • Configuration example
    • Set up your environment
    • Create an agent file
    • Run the agent
  • Limitations

Auto-instrumentation is the fastest way to start sending LLM traces to Monium Traces. Auto-instrumentation libraries intercept calls to LLM providers and frameworks at the SDK level and automatically generate spans with the GenAI attributes: prompts, model responses, token count, model used. There is almost no need to modify the application code: just install the library and call a single function.

Supported frameworksSupported frameworks

There are auto-instrumentation libraries for popular agent SDKs. Install a package for your SDK to have all LLM calls automatically covered by traces:

  • OpenAI SDK: opentelemetry-instrumentation-openai-v2
  • OpenAI Agents SDK: opentelemetry-instrumentation-openai-agents
  • LangChain: opentelemetry-instrumentation-langchain

Configuration exampleConfiguration example

Below is a standalone example of a basic AI agent based on the OpenAI SDK (chat with tool calls) instrumented to automatically generate and send spans to Monium Traces.

The example is prepared in two versions:

  • Using a generative model by OpenAI. Availability depends on your location.
  • Using a generative model by Yandex Cloud AI Studio, subject to the pricing policy.

Set up your environmentSet up your environment

Set up your infrastructureSet up your infrastructure

OpenAI
Yandex Cloud AI Studio
  1. Create a service account and assign the monium.traces.writer role to it.
  2. Create an API key with the yc.monium.traces.write scope.
  1. Create a service account and assign the following roles to it:

    • monium.traces.writer
    • ai.languageModels.user
  2. Create an API key with the following scopes:

    • yc.monium.traces.write
    • yc.ai.languageModels.execute

Install the dependenciesInstall the dependencies

pip install openai \
    opentelemetry-sdk \
    opentelemetry-exporter-otlp-proto-grpc \
    opentelemetry-instrumentation-openai

Configure the environment variablesConfigure the environment variables

OpenAI
Yandex Cloud AI Studio
  • Set values for the variables required to connect to Monium Traces:

    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Api-Key <your_API_key>,x-monium-project=<project_name>,x-monium-service=my-ai-agent"
    
    export OTEL_SERVICE_NAME="my-ai-agent"
    
    export OTEL_EXPORTER_OTLP_ENDPOINT="ingest.monium.yandex.cloud:443"
    

    Where:

    • <your_API_key>: Service account API key you created earlier.
    • <project_name>: Project name in folder__<folder_ID> format, e.g., folder__b1g2e3abc4def5ghij6k.

    Learn more about special Monium headers Headings.

  • Create an additional variable to capture the contents of prompts and model responses:

    export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
    

    Without this variable, traces will feature the model, token count, and call duration but not the texts of prompts and responses.

  • Create a variable containing your OpenAI API key:

    export OPENAI_API_KEY="<your_OpenAI_key>"
    
  • Set values for the variables required to connect to Monium Traces:

    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Api-Key <your_API_key>,x-monium-project=<project_name>,x-monium-service=my-ai-agent"
    
    export OTEL_SERVICE_NAME="my-ai-agent"
    
    export OTEL_EXPORTER_OTLP_ENDPOINT="ingest.monium.yandex.cloud:443"
    

    Where:

    • <your_API_key>: Service account API key you created earlier.
    • <project_name>: Project name in folder__<folder_ID> format, e.g., folder__b1g2e3abc4def5ghij6k.

    Learn more about special Monium headers Headings.

  • Create an additional variable to capture the contents of prompts and model responses:

    export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
    

    Without this variable, traces will feature the model, token count, and call duration but not the texts of prompts and responses.

  • Create a variable containing the service account API key created earlier:

    export API_KEY="<your_API_key>"
    
  • Create a variable containing the ID of the folder in which the agent will access the Yandex Cloud AI Studio generative model:

    export YANDEX_FOLDER_ID="<folder_ID>"
    

Create an agent fileCreate an agent file

Save the code below to the agent.py file. This example uses SimpleSpanProcessor, which sends each span immediately after completion. Therefore, by the time of exiting the script, all traces are already gone to Monium Traces.

OpenAI
Yandex Cloud AI Studio
import json
import os
from openai import OpenAI

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource

from opentelemetry.instrumentation.openai import OpenAIInstrumentor

resource = Resource(attributes={"service.name": os.getenv("OTEL_SERVICE_NAME", "my-ai-agent")})
exporter = OTLPSpanExporter()
provider = TracerProvider(resource=resource)
provider.add_span_processor(SimpleSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my-ai-agent")

OpenAIInstrumentor().instrument()

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Returns current weather in the specified city.",
            "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
        },
    }
]


def get_weather(city: str) -> str:
    """Returns current weather in the specified city."""
    return f"It is 18°C and cloudy in {city} right now."


def run_agent(user_query: str) -> str:
    client = OpenAI()
    messages = [
        {"role": "system", "content": "You are a helpful assistant. Answer briefly. Use the get_weather tool to retrieve weather information."},
        {"role": "user", "content": user_query},
    ]
    while True:
        response = client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
            tools=TOOLS,
        )
        msg = response.choices[0].message
        if not msg.tool_calls:
            return (msg.content or "").strip()
        messages.append({
            "role": "assistant",
            "content": msg.content or "",
            "tool_calls": [
                {"id": t.id, "type": "function", "function": {"name": t.function.name, "arguments": t.function.arguments}}
                for t in msg.tool_calls
            ],
        })
        for tc in msg.tool_calls:
            args = json.loads(tc.function.arguments) if isinstance(tc.function.arguments, str) else tc.function.arguments
            result = get_weather(args.get("city", ""))
            messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})


if __name__ == "__main__":
    with tracer.start_as_current_span("agent.run"):
        answer = run_agent("What is the weather like in Moscow now?")
        print(answer)
    provider.shutdown()
import json
import os
from openai import OpenAI

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource

from opentelemetry.instrumentation.openai import OpenAIInstrumentor

resource = Resource(attributes={"service.name": os.getenv("OTEL_SERVICE_NAME", "my-ai-agent")})
exporter = OTLPSpanExporter()
provider = TracerProvider(resource=resource)
provider.add_span_processor(SimpleSpanProcessor(exporter))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("my-ai-agent")

OpenAIInstrumentor().instrument()

YANDEX_MODEL = "yandexgpt-lite"
YANDEX_API_KEY = os.getenv("API_KEY")
YANDEX_FOLDER_ID = os.getenv("YANDEX_FOLDER_ID")
model=f"gpt://{YANDEX_FOLDER_ID}/{YANDEX_MODEL}"

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Returns current weather in the specified city.",
            "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
        },
    }
]


def get_weather(city: str) -> str:
    """Returns current weather in the specified city."""
    return f"It is 18°C and cloudy in {city} right now."


def run_agent(user_query: str) -> str:
    client = OpenAI(
        api_key=YANDEX_API_KEY,
        base_url="https://ai.api.cloud.yandex.net/v1",
        project=YANDEX_FOLDER_ID
    )
    messages = [
        {"role": "system", "content": "You are a helpful assistant. Answer briefly. Use the get_weather tool to retrieve weather information."},
        {"role": "user", "content": user_query},
    ]
    while True:
        response = client.chat.completions.create(
            model=model,
            messages=messages,
            tools=TOOLS,
        )
        msg = response.choices[0].message
        if not msg.tool_calls:
            return (msg.content or "").strip()
        messages.append({
            "role": "assistant",
            "content": msg.content or "",
            "tool_calls": [
                {"id": t.id, "type": "function", "function": {"name": t.function.name, "arguments": t.function.arguments}}
                for t in msg.tool_calls
            ],
        })
        for tc in msg.tool_calls:
            args = json.loads(tc.function.arguments) if isinstance(tc.function.arguments, str) else tc.function.arguments
            result = get_weather(args.get("city", ""))
            messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})


if __name__ == "__main__":
    with tracer.start_as_current_span("agent.run"):
        answer = run_agent("What is the weather like in Moscow now?")
        print(answer)
    provider.shutdown()

Run the agentRun the agent

python agent.py

Once the script is executed, the Monium Traces interface will show a new trace with spans covering the agent's activity: model calls, optional tool calls and repeat requests, final response. For each generation span, the auto-instrumentation will extract the following:

  • Prompts and model responses (if message content capture is enabled).
  • Model used (gen_ai.request.model).
  • Number of input and output tokens (gen_ai.usage.input_tokens and gen_ai.usage.output_tokens).
  • Execution time of each step.

This data will be shown conveniently formatted in a dedicated LLM monitoring interface. For more information on how to use the interface, see Viewing and analyzing LLM traces.

LimitationsLimitations

While auto-instrumentation makes it easy to get started quickly, it follows the "black box" principle by intercepting only standardized calls from supported libraries. In practical terms, however, this entails a number of limitations.

Lack of business context.: Auto-instrumentation is unaware of your subject domain. If you want to link a trace to a specific user, chat session ID, prompt version, or A/B experiment, you have to add these attributes manually.

Invisible logic between calls.: Everything that takes place between LLM calls (input preprocessing, response postprocessing, agent routing, database access) is left outside the auto-generated spans.

Custom tools.: Auto-instrumentation generates spans for LLM calls, but if your agent calls custom functions (access to an external API, knowledge base query, code execution), they will not be fully traced.

Limited configurability.: The attributes to collect and the span structure are decided by the auto-instrumentation library. You cannot rename spans, add random attributes, or modify the span hierarchy without manual intervention.

For complete control over traces – adding business attributes, using custom logic for the agent, or instrumenting an unsupported framework, etc. – use manual instrumentation.

A role is a set of permissions that defines the allowed scope of operations with Yandex Cloud resources. For more information, see Roles.

A scope is the total of the actions a service account is allowed to perform with the service's resources. You cannot use an API key with specified scopes in other services or scopes. For more information, see API keys with scope and validity limits.

Was the article helpful?

Previous
Getting started
Next
Manual instrumentation of LLM applications
© 2026 Direct Cursus Technology L.L.C.