在 LangChain4j 中构建可观测性体系,需要从指标采集、链路追踪、事件监听三个维度入手。以下结合框架特性与业界实践,梳理关键指标和实现方案。
一、核心监控指标体系
1.1 性能指标
| 请求延迟 | AiServiceCompletedEvent / @Timed 注解 | 端到端响应时间,含模型调用+工具执行 |
| Token 吞吐量 | ChatModelResponseContext 中的 TokenUsage | 输入/输出 Token 数,可用于计算成本 |
| 首次 Token 时间 | 自定义监听器记录流式响应首包时间 | 衡量流式体验的关键指标 |
| 错误率 | AiServiceErrorEvent / @Counted 注解 | 区分业务错误、模型超时、限流等异常 |
1.2 成本指标
- 模型输入 Token 数:ChatResponseMetadata.tokenUsage().inputTokenCount()
- 模型输出 Token 数:tokenUsage().outputTokenCount()
- 工具调用次数:从 ToolExecutedEvent 中统计
- 缓存命中率:若启用了 Embedding 缓存,可统计
1.3 质量指标
- 工具执行成功率:通过 ToolExecutedEvent 中的异常信息判断
- 上下文利用率:RAG 场景下检索到的文档块被实际引用的比例
- 用户反馈分:需业务层埋点,与调用链关联
二、三层监控实现方案
2.1 基础层:请求/响应日志
适合快速定位问题,暴露敏感数据(谨慎用于生产)。
ChatLanguageModel model = OpenAiChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.logRequests(true) // 开启请求日志
.logResponses(true) // 开启响应日志
.build();
配合 SLF4J 可输出结构化 JSON 日志 。
2.2 业务层:AI Service 事件监听
LangChain4j 0.31+ 提供了完整的事件监听体系,涵盖服务调用全生命周期 。
public class MyMonitoringListener implements
AiServiceStartedListener,
AiServiceCompletedListener,
AiServiceErrorEvent,
ToolExecutedListener {
@Override
public void onEvent(AiServiceStartedEvent event) {
InvocationContext ctx = event.invocationContext();
// 记录开始时间,存入 attributes 传递
ctx.attributes().put("startNanos", System.nanoTime());
}
@Override
public void onEvent(AiServiceCompletedEvent event) {
InvocationContext ctx = event.invocationContext();
long start = (long) ctx.attributes().get("startNanos");
long durationMs = (System.nanoTime() – start) / 1_000_000;
// 输出指标:服务名、方法名、耗时、Token用量
System.out.printf("ai_service_duration{service='%s',method='%s'} %d%n",
ctx.interfaceName(), ctx.methodName(), durationMs);
event.result().ifPresent(result -> {
// 可从 result 中提取输出内容长度
});
}
@Override
public void onEvent(ToolExecutedEvent event) {
// 统计工具调用次数和结果
metrics.counter("tool.calls", "tool", event.toolName()).increment();
}
}
// 注册监听器
AiServices.builder(Assistant.class)
.chatModel(model)
.registerListener(new MyMonitoringListener())
.build();
事件类型详解 :
| AiServiceStartedEvent | 调用开始 | 调用上下文(含方法名、参数) |
| AiServiceRequestIssuedEvent | 即将请求 LLM | 系统消息、用户消息 |
| AiServiceResponseReceivedEvent | LLM 响应到达 | 模型回复、Token 用量 |
| AiServiceCompletedEvent | 调用成功完成 | 最终结果 |
| AiServiceErrorEvent | 调用失败 | 异常信息 |
| ToolExecutedEvent | 工具执行完成 | 工具请求、返回结果 |
2.3 模型层:ChatModel 监听器
当需要更细粒度的模型调用跟踪(如重试、多个请求合并),可实现 ChatModelListener 。
ChatModelListener listener = new ChatModelListener() {
@Override
public void onRequest(ChatModelRequestContext ctx) {
// 记录请求参数:model, temperature, messages
metrics.counter("model.requests", "model", ctx.chatRequest().parameters().modelName()).increment();
}
@Override
public void onResponse(ChatModelResponseContext ctx) {
TokenUsage tokens = ctx.chatResponse().metadata().tokenUsage();
// 上报 Token 用量
metrics.summary("model.tokens", "type", "input").record(tokens.inputTokenCount());
metrics.summary("model.tokens", "type", "output").record(tokens.outputTokenCount());
}
@Override
public void onError(ChatModelErrorContext ctx) {
metrics.counter("model.errors", "reason", ctx.error().getClass().getSimpleName()).increment();
}
};
ChatModel model = OpenAiChatModel.builder()
.apiKey("…")
.listeners(List.of(listener))
.build();
三、集成外部监控系统
3.1 Micrometer 指标暴露(Quarkus/Spring Boot)
在 Quarkus 中,引入 quarkus-micrometer 后,AI Service 方法自动生成 @Timed 和 @Counted 指标 。
# application.properties
quarkus.micrometer.export.prometheus.enabled=true
自动生成的指标示例 :
langchain4j_aiservices_timed_seconds_count{aiservice="PoemAiService",method="writeAPoem"} 1.0
langchain4j_aiservices_counted_total{aiservice="PoemAiService",exception="none",result="success"} 1.0
3.2 OpenTelemetry 链路追踪
添加依赖 quarkus-opentelemetry 后,LangChain4j 自动为每个 AI Service 调用创建 Span 。
# 开启详细追踪
quarkus.langchain4j.tracing.include-prompt=true
quarkus.langchain4j.tracing.include-completion=true
quarkus.langchain4j.tracing.include-tool-arguments=true
quarkus.langchain4j.tracing.include-tool-result=true
# 导出到 Jaeger/Langfuse
quarkus.otel.exporter.otlp.endpoint=http://jaeger:4318
Span 层级结构:
- 父 Span:AI Service 方法调用
- 子 Span:模型 API 调用
- 孙 Span:工具执行
3.3 Langfuse 集成示例
通过 OpenTelemetry 将追踪数据发送到 Langfuse :
quarkus.otel.exporter.otlp.endpoint=https://cloud.langfuse.com/api/public/otel
quarkus.otel.exporter.otlp.headers=Authorization=Basic <base64编码的公钥:密钥>
Langfuse 会自动解析 Token 用量、工具调用等语义属性,生成成本分析和模型卡。
四、监控看板设计建议
4.1 实时监控看板
- 服务健康度:QPS、错误率、P95/P99 延迟
- 成本看板:每日 Token 消耗、各模型费用占比
- 调用详情:按用户、按方法聚合的调用次数
4.2 离线分析
- 失败模式分析:错误类型分布(超时/拒绝/无效参数)
- 质量追踪:用户反馈差评对应的调用链
4.3 告警规则
- 延迟突增:P99 > 5s 持续 5 分钟
- 错误率飙升:> 5%
- Token 异常:单次调用输出 Token > 10k
五、总结
LangChain4j 的监控体系分为三层:
| 基础日志 | .logRequests(true) | 开发调试 |
| 业务事件 | AiService*Listener | 业务指标、成本核算 |
| 模型追踪 | ChatModelListener / OpenTelemetry | 全链路分析、性能优化 |
生产环境推荐组合使用:
- Micrometer 暴露实时指标
- OpenTelemetry 导出链路到 Langfuse 或 Jaeger
- 自定义监听器 补充业务维度的统计
这样既能满足 SRE 的监控需求,也能为算法工程师提供模型调优的数据支撑。




![[LangChain RAG] 01 大模型为什么需要 RAG:四个问题与标准流程-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260825035331-6a8d11bb97bca-220x150.png)
