import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import com.arize.instrumentation.OITracer;
import com.arize.instrumentation.TraceConfig;
import com.arize.semconv.trace.SemanticConventions;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
public class LLMClient {
private final OITracer tracer;
private final ObjectMapper mapper = new ObjectMapper();
public LLMClient() {
Tracer otelTracer = GlobalOpenTelemetry.getTracer("llm-client");
this.tracer = new OITracer(otelTracer);
}
public String chat(String userMessage) throws Exception {
Span span = tracer.spanBuilder("chat")
.setSpanKind(SpanKind.CLIENT)
.startSpan();
try (Scope scope = span.makeCurrent()) {
// Set span kind
span.setAttribute(
SemanticConventions.OPENINFERENCE_SPAN_KIND,
SemanticConventions.OpenInferenceSpanKind.LLM.getValue()
);
// Set model information
span.setAttribute(SemanticConventions.LLM_MODEL_NAME, "gpt-4");
span.setAttribute(SemanticConventions.LLM_PROVIDER, "openai");
span.setAttribute(SemanticConventions.LLM_SYSTEM, "openai");
// Set input messages
List<Map<String, String>> messages = List.of(
Map.of("role", "user", "content", userMessage)
);
span.setAttribute(
SemanticConventions.INPUT_VALUE,
mapper.writeValueAsString(messages)
);
span.setAttribute(
SemanticConventions.INPUT_MIME_TYPE,
"application/json"
);
// Set invocation parameters
Map<String, Object> params = Map.of(
"temperature", 0.7,
"max_tokens", 1000
);
span.setAttribute(
SemanticConventions.LLM_INVOCATION_PARAMETERS,
mapper.writeValueAsString(params)
);
// Call LLM (replace with actual implementation)
String response = callOpenAI(userMessage);
// Set output
List<Map<String, String>> responseMessages = List.of(
Map.of("role", "assistant", "content", response)
);
span.setAttribute(
SemanticConventions.OUTPUT_VALUE,
mapper.writeValueAsString(responseMessages)
);
span.setAttribute(
SemanticConventions.OUTPUT_MIME_TYPE,
"application/json"
);
// Set token counts
span.setAttribute(SemanticConventions.LLM_TOKEN_COUNT_PROMPT, 150L);
span.setAttribute(SemanticConventions.LLM_TOKEN_COUNT_COMPLETION, 75L);
span.setAttribute(SemanticConventions.LLM_TOKEN_COUNT_TOTAL, 225L);
span.setStatus(StatusCode.OK);
return response;
} catch (Exception e) {
span.recordException(e);
span.setStatus(StatusCode.ERROR, e.getMessage());
throw e;
} finally {
span.end();
}
}
private String callOpenAI(String message) {
// Implement actual OpenAI API call
return "This is a response from GPT-4";
}
}