可观测性
聊天模型可观测性
某些 ChatLanguageModel
和 StreamingChatLanguageModel
的实现
(参见"可观测性"列)允许配置 ChatModelListener
(多个)来监听事件,例如:
- 向 LLM 发送的请求
- 来自 LLM 的响应
- 错误
这些事件包括各种属性,如 OpenTelemetry 生成式 AI 语义约定中所述,例如:
- 请求:
- 消息
- 模型
- 温度
- Top P
- 最大令牌数
- 工具
- 响应格式
- 等等
- 响应:
- 助手消息
- ID
- 模型
- 令牌使用情况
- 完成原因
- 等等
以下是使用 ChatModelListener
的示例:
ChatModelListener listener = new ChatModelListener() {
@Override
public void onRequest(ChatModelRequestContext requestContext) {
ChatRequest chatRequest = requestContext.chatRequest();
List<ChatMessage> messages = chatRequest.messages();
System.out.println(messages);
ChatRequestParameters parameters = chatRequest.parameters();
System.out.println(parameters.modelName());
System.out.println(parameters.temperature());
System.out.println(parameters.topP());
System.out.println(parameters.topK());
System.out.println(parameters.frequencyPenalty());
System.out.println(parameters.presencePenalty());
System.out.println(parameters.maxOutputTokens());
System.out.println(parameters.stopSequences());
System.out.println(parameters.toolSpecifications());
System.out.println(parameters.toolChoice());
System.out.println(parameters.responseFormat());
if (parameters instanceof OpenAiChatRequestParameters openAiParameters) {
System.out.println(openAiParameters.maxCompletionTokens());
System.out.println(openAiParameters.logitBias());
System.out.println(openAiParameters.parallelToolCalls());
System.out.println(openAiParameters.seed());
System.out.println(openAiParameters.user());
System.out.println(openAiParameters.store());
System.out.println(openAiParameters.metadata());
System.out.println(openAiParameters.serviceTier());
System.out.println(openAiParameters.reasoningEffort());
}
System.out.println(requestContext.modelProvider());
Map<Object, Object> attributes = requestContext.attributes();
attributes.put("my-attribute", "my-value");
}
@Override
public void onResponse(ChatModelResponseContext responseContext) {
ChatResponse chatResponse = responseContext.chatResponse();
AiMessage aiMessage = chatResponse.aiMessage();
System.out.println(aiMessage);
ChatResponseMetadata metadata = chatResponse.metadata();
System.out.println(metadata.id());
System.out.println(metadata.modelName());
System.out.println(metadata.finishReason());
if (metadata instanceof OpenAiChatResponseMetadata openAiMetadata) {
System.out.println(openAiMetadata.created());
System.out.println(openAiMetadata.serviceTier());
System.out.println(openAiMetadata.systemFingerprint());
}
TokenUsage tokenUsage = metadata.tokenUsage();
System.out.println(tokenUsage.inputTokenCount());
System.out.println(tokenUsage.outputTokenCount());
System.out.println(tokenUsage.totalTokenCount());
if (tokenUsage instanceof OpenAiTokenUsage openAiTokenUsage) {
System.out.println(openAiTokenUsage.inputTokensDetails().cachedTokens());
System.out.println(openAiTokenUsage.outputTokensDetails().reasoningTokens());
}
ChatRequest chatRequest = responseContext.chatRequest();
System.out.println(chatRequest);
System.out.println(responseContext.modelProvider());
Map<Object, Object> attributes = responseContext.attributes();
System.out.println(attributes.get("my-attribute"));
}
@Override
public void onError(ChatModelErrorContext errorContext) {
Throwable error = errorContext.error();
error.printStackTrace();
ChatRequest chatRequest = errorContext.chatRequest();
System.out.println(chatRequest);
System.out.println(errorContext.modelProvider());
Map<Object, Object> attributes = errorContext.attributes();
System.out.println(attributes.get("my-attribute"));
}
};
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName(GPT_4_O_MINI)
.listeners(List.of(listener))
.build();
model.chat("Tell me a joke about Java");
attributes
映射允许在同一 ChatModelListener
的 onRequest
、onResponse
和 onError
方法之间传递信息,以及在多个 ChatModelListener
之间传递信息。
监听器如何工作
- 监听器被指定为
List<ChatModelListener>
,并按照迭代顺序调用。 - 监听器同步调用,并在同一线程中调用。有关流式处理情况的更多详细信息,请参见下文。 第二个监听器直到第一个监听器返回后才会被调用。
ChatModelListener.onRequest()
方法在调用 LLM 提供商 API 之前立即调用。ChatModelListener.onRequest()
方法每个请求只调用一次。 如果在调用 LLM 提供商 API 时发生错误并进行重试,ChatModelListener.onRequest()
将不会为每次重试调用。ChatModelListener.onResponse()
方法只调用一次, 在从 LLM 提供商收到成功响应后立即调用。ChatModelListener.onError()
方法只调用一次。 如果在调用 LLM 提供商 API 时发生错误并进行重试,ChatModelListener.onError()
将不会为每次重试调用。- 如果从
ChatModelListener
方法之一抛出异常, 它将以WARN
级别记录。后续监听器的执行将照常继续。 - 通过
ChatModelRequestContext
、ChatModelResponseContext
和ChatModelErrorContext
提供的ChatRequest
是最终请求,包含在ChatLanguageModel
上配置的默认ChatRequestParameters
和特定于请求的ChatRequestParameters
合并在一起。 - 对于
StreamingChatLanguageModel
,ChatModelListener.onResponse()
和ChatModelListener.onError()
在与ChatModelListener.onRequest()
不同的线程上调用。 线程上下文目前不会自动传播,因此您可能希望使用attributes
映射 从ChatModelListener.onRequest()
传播任何必要的数据到ChatModelListener.onResponse()
或ChatModelListener.onError()
。 - 对于
StreamingChatLanguageModel
,ChatModelListener.onResponse()
在StreamingChatResponseHandler.onCompleteResponse()
被调用之前调用。ChatModelListener.onError()
在StreamingChatResponseHandler.onError()
被调用之前调用。
Spring Boot 应用程序中的可观测性
更多详细信息请参见此处。