@@ -4,29 +4,164 @@ This package provides OpenTelemetry instrumentation for various LLM providers an
44
55## Available Instrumentors
66
7- - OpenAI (` v0.27.0+ ` and ` v1.0.0+ ` )
7+ - ** OpenAI** (` v0.27.0+ ` and ` v1.0.0+ ` )
8+ - ** Anthropic** (` v0.7.0+ ` )
9+ - ** Google GenAI** (` v0.1.0+ ` )
10+ - ** IBM WatsonX AI** (` v0.1.0+ ` )
11+ - ** CrewAI** (` v0.56.0+ ` )
12+ - ** AG2/AutoGen** (` v0.3.2+ ` )
13+ - ** Google ADK** (` v0.1.0+ ` )
14+ - ** Agno** (` v0.0.1+ ` )
15+ - ** Mem0** (` v0.1.0+ ` )
16+ - ** SmolAgents** (` v0.1.0+ ` )
817
18+ ## Common Module Usage
919
10- ## Usage
20+ The ` agentops.instrumentation.common ` module provides shared utilities for creating instrumentations:
1121
12- ### OpenAI Instrumentation
22+ ### Base Instrumentor
23+
24+ Use ` BaseAgentOpsInstrumentor ` for creating new instrumentations:
25+
26+ ``` python
27+ from agentops.instrumentation.common import BaseAgentOpsInstrumentor, InstrumentorConfig, WrapConfig
28+
29+ class MyInstrumentor (BaseAgentOpsInstrumentor ):
30+ def __init__ (self ):
31+ config = InstrumentorConfig(
32+ library_name = " my-library" ,
33+ library_version = " 1.0.0" ,
34+ wrapped_methods = [
35+ WrapConfig(
36+ trace_name = " my.method" ,
37+ package = " my_library.module" ,
38+ class_name = " MyClass" ,
39+ method_name = " my_method" ,
40+ handler = my_attribute_handler
41+ )
42+ ],
43+ dependencies = [" my-library >= 1.0.0" ]
44+ )
45+ super ().__init__ (config)
46+ ```
47+
48+ ### Attribute Handlers
49+
50+ Create attribute handlers to extract data from method calls:
51+
52+ ``` python
53+ from agentops.instrumentation.common import AttributeMap
54+
55+ def my_attribute_handler (args = None , kwargs = None , return_value = None ) -> AttributeMap:
56+ attributes = {}
57+
58+ if kwargs and " model" in kwargs:
59+ attributes[" llm.request.model" ] = kwargs[" model" ]
60+
61+ if return_value and hasattr (return_value, " usage" ):
62+ attributes[" llm.usage.total_tokens" ] = return_value.usage.total_tokens
63+
64+ return attributes
65+ ```
66+
67+ ### Span Management
68+
69+ Use the span management utilities for consistent span creation:
70+
71+ ``` python
72+ from agentops.instrumentation.common import create_span, SpanAttributeManager
73+
74+ # Create an attribute manager
75+ attr_manager = SpanAttributeManager(service_name = " my-service" )
76+
77+ # Use the create_span context manager
78+ with create_span(
79+ tracer,
80+ " my.operation" ,
81+ attributes = {" my.attribute" : " value" },
82+ attribute_manager = attr_manager
83+ ) as span:
84+ # Your operation code here
85+ pass
86+ ```
87+
88+ ### Token Counting
89+
90+ Use the token counting utilities for consistent token usage extraction:
1391
1492``` python
15- from opentelemetry.instrumentation.openai import OpenAIInstrumentor
93+ from agentops.instrumentation.common import TokenUsageExtractor, set_token_usage_attributes
94+
95+ # Extract token usage from a response
96+ usage = TokenUsageExtractor.extract_from_response(response)
97+
98+ # Set token usage attributes on a span
99+ set_token_usage_attributes(span, response)
100+ ```
101+
102+ ### Streaming Support
16103
17- from agentops.telemetry import get_tracer_provider()
104+ Use streaming utilities for handling streaming responses:
18105
19- # Initialize and instrument
20- instrumentor = OpenAIInstrumentor(
21- enrich_assistant = True , # Include assistant messages in spans
22- enrich_token_usage = True , # Include token usage in spans
23- enable_trace_context_propagation = True , # Enable trace context propagation
106+ ``` python
107+ from agentops.instrumentation.common import create_stream_wrapper_factory, StreamingResponseHandler
108+
109+ # Create a stream wrapper factory
110+ wrapper = create_stream_wrapper_factory(
111+ tracer,
112+ " my.stream" ,
113+ extract_chunk_content = StreamingResponseHandler.extract_generic_chunk_content,
114+ initial_attributes = {" stream.type" : " text" }
24115)
25- instrumentor.instrument(tracer_provider = tracer_provider) # <-- Uses the global AgentOps TracerProvider
116+
117+ # Apply to streaming methods
118+ wrap_function_wrapper(" my_module" , " stream_method" , wrapper)
26119```
27120
121+ ### Metrics
122+
123+ Use standard metrics for consistency across instrumentations:
124+
125+ ``` python
126+ from agentops.instrumentation.common import StandardMetrics, MetricsRecorder
127+
128+ # Create standard metrics
129+ metrics = StandardMetrics.create_standard_metrics(meter)
130+
131+ # Use the metrics recorder
132+ recorder = MetricsRecorder(metrics)
133+ recorder.record_token_usage(prompt_tokens = 100 , completion_tokens = 50 )
134+ recorder.record_duration(1.5 )
135+ ```
136+
137+ ## Creating a New Instrumentor
138+
139+ 1 . Create a new directory under ` agentops/instrumentation/ ` for your provider
140+ 2 . Create an ` __init__.py ` file with version information
141+ 3 . Create an ` instrumentor.py ` file extending ` BaseAgentOpsInstrumentor `
142+ 4 . Create attribute handlers in an ` attributes/ ` subdirectory
143+ 5 . Add your instrumentor to the main ` __init__.py ` configuration
144+
145+ Example structure:
146+ ```
147+ agentops/instrumentation/
148+ ├── my_provider/
149+ │ ├── __init__.py
150+ │ ├── instrumentor.py
151+ │ └── attributes/
152+ │ ├── __init__.py
153+ │ └── handlers.py
154+ ```
28155
29- > To add custom instrumentation, please do so in the ` third_party/opentelemetry ` directory.
156+ ## Best Practices
30157
158+ 1 . ** Use Common Utilities** : Leverage the common module for consistency
159+ 2 . ** Follow Semantic Conventions** : Use attributes from ` agentops.semconv `
160+ 3 . ** Handle Errors Gracefully** : Wrap operations in try-except blocks
161+ 4 . ** Support Async** : Provide both sync and async method wrapping
162+ 5 . ** Document Attributes** : Comment on what attributes are captured
163+ 6 . ** Test Thoroughly** : Write unit tests for your instrumentor
31164
165+ ## Examples
32166
167+ See the ` examples/ ` directory for usage examples of each instrumentor.
0 commit comments