1
1
package datadog .trace .llmobs .domain ;
2
2
3
3
import datadog .trace .api .DDSpanTypes ;
4
+ import datadog .trace .api .llmobs .LLMObs ;
4
5
import datadog .trace .api .llmobs .LLMObsSpan ;
5
6
import datadog .trace .api .llmobs .LLMObsTags ;
6
7
import datadog .trace .bootstrap .instrumentation .api .AgentSpan ;
7
8
import datadog .trace .bootstrap .instrumentation .api .AgentTracer ;
8
9
import datadog .trace .bootstrap .instrumentation .api .Tags ;
9
- import java .util .Arrays ;
10
10
import java .util .Collections ;
11
11
import java .util .HashMap ;
12
- import java .util .HashSet ;
13
12
import java .util .List ;
14
13
import java .util .Map ;
15
- import java .util .Set ;
16
14
import javax .annotation .Nonnull ;
17
15
import org .slf4j .Logger ;
18
16
import org .slf4j .LoggerFactory ;
19
17
20
18
public class DDLLMObsSpan implements LLMObsSpan {
21
-
22
- private enum State {
23
- VALID ,
24
- INVALID_IO_MESSAGE_KEY
25
- }
26
-
27
- private static final String MESSAGE_KEY_ROLE = "role" ;
28
- private static final String MESSAGE_KEY_CONTENT = "content" ;
29
-
30
- private static final Set <String > VALID_MESSAGE_KEYS =
31
- new HashSet <>(Arrays .asList (MESSAGE_KEY_ROLE , MESSAGE_KEY_CONTENT ));
19
+ private static final String LLM_MESSAGE_UNKNOWN_ROLE = "unknown" ;
32
20
33
21
// Well known tags for LLM obs will be prefixed with _ml_obs_(tags|metrics).
34
22
// Prefix for tags
@@ -92,35 +80,15 @@ public String toString() {
92
80
+ this .span .getTag (SPAN_KIND );
93
81
}
94
82
95
- private static State validateIOMessages (List <Map <String , Object >> messages ) {
96
- for (Map <String , Object > message : messages ) {
97
- for (String key : message .keySet ()) {
98
- if (!VALID_MESSAGE_KEYS .contains (key )) {
99
- return State .INVALID_IO_MESSAGE_KEY ;
100
- }
101
- }
102
- }
103
- return State .VALID ;
104
- }
105
-
106
83
@ Override
107
- public void annotateIO (
108
- List <Map <String , Object >> inputData , List <Map <String , Object >> outputData ) {
84
+ public void annotateIO (List <LLMObs .LLMMessage > inputData , List <LLMObs .LLMMessage > outputData ) {
109
85
if (finished ) {
110
86
return ;
111
87
}
112
88
if (inputData != null && !inputData .isEmpty ()) {
113
- State inputState = validateIOMessages (inputData );
114
- if (validateIOMessages (inputData ) != State .VALID ) {
115
- LOGGER .debug ("malformed/unexpected input message, state={}" , inputState );
116
- }
117
89
this .span .setTag (INPUT , inputData );
118
90
}
119
91
if (outputData != null && !outputData .isEmpty ()) {
120
- State outputState = validateIOMessages (outputData );
121
- if (validateIOMessages (outputData ) != State .VALID ) {
122
- LOGGER .debug ("malformed/unexpected output message, state={}" , outputState );
123
- }
124
92
this .span .setTag (OUTPUT , outputData );
125
93
}
126
94
}
@@ -130,24 +98,31 @@ public void annotateIO(String inputData, String outputData) {
130
98
if (finished ) {
131
99
return ;
132
100
}
101
+ boolean wrongSpanKind = false ;
133
102
if (inputData != null && !inputData .isEmpty ()) {
134
103
if (Tags .LLMOBS_LLM_SPAN_KIND .equals (this .spanKind )) {
104
+ wrongSpanKind = true ;
135
105
annotateIO (
136
- Collections .singletonList (Collections . singletonMap ( MESSAGE_KEY_CONTENT , inputData )),
106
+ Collections .singletonList (new LLMObs . LLMMessage ( LLM_MESSAGE_UNKNOWN_ROLE , inputData )),
137
107
null );
138
108
} else {
139
109
this .span .setTag (INPUT , inputData );
140
110
}
141
111
}
142
112
if (outputData != null && !outputData .isEmpty ()) {
143
113
if (Tags .LLMOBS_LLM_SPAN_KIND .equals (this .spanKind )) {
114
+ wrongSpanKind = true ;
144
115
annotateIO (
145
116
null ,
146
- Collections .singletonList (Collections . singletonMap ( MESSAGE_KEY_CONTENT , outputData )));
117
+ Collections .singletonList (new LLMObs . LLMMessage ( LLM_MESSAGE_UNKNOWN_ROLE , outputData )));
147
118
} else {
148
119
this .span .setTag (OUTPUT , outputData );
149
120
}
150
121
}
122
+ if (wrongSpanKind ) {
123
+ LOGGER .warn (
124
+ "the span being annotated is an LLM span, it is recommended to use the overload with List<LLMObs.LLMMessage> as arguments" );
125
+ }
151
126
}
152
127
153
128
@ Override
0 commit comments