帮你快速理解、总结文档立即下载

接入 Spring AI 数据

最近更新时间:2026-10-23 16:43:31
我的收藏

操作场景

Spring AI 是 Java 生态中常用的 AI 应用开发框架,Agent 运行时会产生多轮 ReAct 推理、模型调用、工具调用、向量检索和子 Agent 调用等数据。在 Spring AI 应用中引入腾讯云 Agent 可观测 SDK tencentcloud-agentobs-sdk-springai-java 后,只需将 SDK 注册到 Spring AI 使用的 ObservationRegistry 上,即可自动采集 Spring AI 原生产出的 Micrometer Observation,还原完整调用链路,并通过 OTLP/HTTP 协议将 Trace 上报到 腾讯云 Agent 可观测。产品能力介绍请参见 Agent 可观测产品页,如需对比其他接入方式,请参见 选择接入方式。
接入完成后,您可以在 Agent 可观测控制台查看以下信息:
每次顶层 ChatClient 调用的完整调用链,以及入口、Agent、推理轮次(Step)、模型调用、工具调用、Embedding 和向量检索之间的父子关系。
模型调用的请求模型、请求参数(如 temperature、max_tokens)、输入/输出 Token、结束原因(finish_reason)、耗时和输入/输出消息。
工具名称、调用参数、返回结果、耗时、错误类型和错误信息。
工具内部嵌套调用的子 Agent,以及多层子 Agent 的嵌套关系。
.call() 同步调用与 .stream() 流式调用的完整链路,流式调用跨 Reactor 线程时仍归属于同一条 Trace。
按会话(Session)和用户(User)聚合的多轮请求关联关系。
SDK 具有以下特点:
无字节码增强:纯 SDK 依赖,不依赖 javaagent,业务代码无需修改。
无需开启 Spring AI 隐私开关:SDK 直接从 Observation 上下文读取 Prompt、Completion 和工具参数,无需开启 Spring AI 的 include-prompt 配置。
可与其他 OTel 实现共存:SDK 内置的 OpenTelemetry 依赖已做隔离,可与应用中已有的 APM javaagent 或其他 OpenTelemetry 实现安全共存。
本文提供以下两种接入方式,您可根据实际情况选择:
接入方式
说明
推荐场景
使用支持 Skill 的 AI 工具,由 AI 创建或复用日志主题,并完成 SDK 引入、配置和验证。
希望减少手动配置,并在接入后通过自然语言分析 Trace 数据。
引入 Maven 依赖,配置 Endpoint、日志主题和访问凭证,并在代码中注册 SDK。
需要精细控制接入参数,或所用工具不支持 Skill。

前提条件

接入前,请确认已完成以下准备工作:
已准备具备 AgentObs。写入权限的访问凭证,例如 CAM 子账号、CAM 角色或临时密钥。云 API 密钥信息请前往 API 密钥管理 获取,密钥需对目标主题有写入权限,权限模板参见 采集 Agent 可观测数据。
已获取接入所需的地域接入点(Endpoint):即 Agent 应用所在地域的接入点域名,请参见 地域和访问域名。以广州地域为例:
方式一填写地域:ap-guangzhou。
方式二填写域名:内网为 ap-guangzhou.cls.tencentyun.com,外网为 ap-guangzhou.cls.tencentcs.com。
已基于 Spring AI 开发应用,且应用可以正常运行。版本要求如下:
组件
支持版本
JDK
17及以上
Spring AI
1.0.x、2.0.x
Spring Boot
3.x、4.x
Micrometer Observation
跟随应用使用的 Spring Boot 版本

方式一:通过 Skill 快速接入与分析

如果您使用支持 Skill 的 AI 工具,可使用 腾讯云 Agent 可观测助手 自动完成接入与分析。该 Skill 可创建或复用日志主题,识别 Spring AI 项目并完成 Maven 依赖引入、配置和验证。
在 AI 工具中输入以下内容:
请使用腾讯云 Agent 可观测助手 Skill:
https://skillhub.cn/skills/tencentcloud-cls-agent-obs
帮我把当前 Spring AI 项目接入腾讯云 Agent 可观测,地域为 ap-guangzhou。
接入完成后,您还可以直接描述分析需求。例如:
分析这个 Agent 最近 1 小时的运行情况,定位耗时最高、Token 消耗最多和失败最多的模型或工具调用,并给出可能原因。

方式二:手动配置接入

如果您需要精细控制 SDK、日志主题或访问凭证等参数,或者所用工具不支持 Skill,请按以下步骤手动完成接入。

步骤1:创建 Agent 可观测应用

1. 进入 Agent 可观测 页面。
2. 单击应用接入,根据页面提示创建应用。
3. 在新创建的应用右侧单击编辑,复制 Trace 日志主题 ID。该 ID 用于后续配置中的 CLS_TOPIC_ID。

步骤2:引入 SDK 依赖

在 Spring AI 项目的 pom.xml 中添加以下依赖:
<dependency>
<groupId>com.tencentcloudapi.observability</groupId>
<artifactId>tencentcloud-agentobs-sdk-springai-java</artifactId>
<version>1.0.1</version>
</dependency>
说明:
SDK 以 provided 方式依赖 spring-ai-client-chat、spring-ai-model 和 micrometer-observation,不会强制指定这些组件的版本,请确保应用中已引入上述依赖。
SDK 源码和示例工程请参见 tencentcloud-agentobs-sdk-springai-java。

步骤3:配置环境变量

设置 Endpoint、日志主题 ID 和腾讯云访问密钥。以下示例以广州地域外网为例:
macOS / Linux
Windows(PowerShell)
export CLS_ENDPOINT=ap-guangzhou.cls.tencentcs.com
export CLS_TOPIC_ID=<Trace 日志主题 ID>
export CLS_SECRET_ID=<SecretId>
export CLS_SECRET_KEY=<SecretKey>
$env:CLS_ENDPOINT = "ap-guangzhou.cls.tencentcs.com"
$env:CLS_TOPIC_ID = "<Trace日志主题ID>"
$env:CLS_SECRET_ID = "<SecretId>"
$env:CLS_SECRET_KEY = "<SecretKey>"
环境变量
是否必填
说明
CLS_ENDPOINT
是
地域接入点域名,须与 Trace 日志主题位于同一地域。未填写协议前缀时,SDK 自动补全 https://。
CLS_TOPIC_ID
是
步骤1中获取的 Trace 日志主题 ID。请勿填写应用 ID。
CLS_SECRET_ID
是
腾讯云访问密钥 ID,需具备目标日志主题的写入权限。请前往 API 密钥管理 获取。
CLS_SECRET_KEY
是
腾讯云访问密钥 Key。
以上4项必填配置缺少任意一项时,SDK 初始化会抛出 IllegalStateException 并列出缺失项。
除环境变量外,您也可以将配置写入 .env 文件。SDK 依次查找应用工作目录下的 ./.env 和 ~/.agentobs-springai/config.env,读取最先找到的一个文件,且不会覆盖已设置的环境变量。
CLS_ENDPOINT=ap-guangzhou.cls.tencentcs.com
CLS_TOPIC_ID=<Trace 日志主题 ID>
CLS_SECRET_ID=<SecretId>
CLS_SECRET_KEY=<SecretKey>
注意:
访问凭证属于敏感信息,建议通过环境变量或不提交到代码仓库的 .env 文件注入,并使用最小权限、可轮换的临时凭证,避免将 SecretKey 硬编码到代码中。

步骤4:初始化采集

根据应用类型,将 SDK 注册到 Spring AI 使用的 ObservationRegistry 上。原有 ChatClient、ChatModel、@Tool 等业务代码无需修改。
Spring Boot 应用
非 Spring Boot 应用
新增一个配置类,声明 ClsObservability Bean:
import com.tencentcloudapi.observability.springai.ClsObservability;
import io.micrometer.observation.ObservationRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ClsObservabilityConfig {

// 容器关闭时自动上报剩余的 Span
@Bean(destroyMethod = "shutdown")
public ClsObservability clsObservability(ObservationRegistry observationRegistry) {
// 从环境变量或 .env 文件读取 CLS 配置
ClsObservability obs = ClsObservability.install();
// 注册到 Spring AI 实际使用的 ObservationRegistry
obs.registerOn(observationRegistry);
return obs;
}
}
在应用启动时初始化 SDK,并注册到 ChatClient / ChatModel 所使用的 ObservationRegistry 上:
ClsObservability obs = ClsObservability.install();
obs.registerOn(registry);

// ... 原有 Spring AI 业务代码 ...

obs.flush(); // 可选,立即上报缓冲区中的 Span
obs.shutdown(); // 可选,JVM 退出时 SDK 会自动执行
注意:
SDK 必须注册到 Spring AI 实际使用的同一个 ObservationRegistry 实例上,自行通过 ObservationRegistry.create() 新建的实例无法接收 Spring AI 的事件。Spring Boot 应用通常由 spring-boot-starter-actuator 自动装配该 Bean;如果应用未引入 Actuator,可使用 @ConditionalOnMissingBean 声明一个兜底 Bean:
@Bean
@ConditionalOnMissingBean
public ObservationRegistry observationRegistry() {
return ObservationRegistry.create();
}
如需在代码中显式指定参数,可以传入 ClsConfig,未填写的字段会回退读取环境变量:
import com.tencentcloudapi.observability.springai.ClsConfig;
import com.tencentcloudapi.observability.springai.ClsObservability;

ClsObservability obs = ClsObservability.install(
ClsConfig.builder()
.serviceName("order-assistant")
.serviceVersion("2.3.0")
.deploymentEnvironment("prod")
.customAttribute("project_id", "proj_001")
.build()); // 访问凭证仍从环境变量或 .env 文件读取
配置优先级为:ClsConfig 显式传入的值 > 环境变量 > .env 文件 > 默认值。ClsConfig 支持的可选参数如下:
Builder 方法
环境变量
默认值
说明
serviceName
CLS_SERVICE_NAME
springai-app
服务或应用名称。
serviceVersion
CLS_SERVICE_VERSION
无
服务版本。
serviceInstanceId
CLS_SERVICE_INSTANCE_ID
<主机名>@<进程号>
服务实例 ID。
deploymentEnvironment
CLS_DEPLOYMENT_ENVIRONMENT
无
部署环境,例如 prod、test。
source
CLS_SOURCE
本机 IP
上报来源 IP。
batchSize
CLS_BATCH_SIZE
32
每批上报的 Span 数量,取值范围为1 - 1000。
sampleRatio
CLS_SAMPLE_RATIO
1.0
Trace 采样率,取值范围为0.0 - 1.0,详见 Trace 采样。
debug
CLS_DEBUG
false
是否以 DEBUG 级别输出每个 Observation 的开始和结束日志。
reactorContextPropagation
CLS_SPRINGAI_REACTOR_CONTEXT_PROPAGATION
true
是否自动开启 Reactor 上下文传播,详见 流式调用。
customAttribute(key, value)
CLS_CUSTOM_<KEY>
无
自定义属性,以 agent.custom.<key> 写入 Span,key 自动转为小写。

步骤5:关联会话与用户(推荐)

在调用 ChatClient 前,通过 ClsBaggage 设置会话 ID 和用户 ID,即可在 Agent 可观测控制台按会话或用户聚合分析 Trace:
import com.tencentcloudapi.observability.springai.ClsBaggage;

@PostMapping("/chat")
public String chat(@RequestHeader("X-Session-Id") String sessionId,
@RequestHeader("X-User-Id") String userId,
@RequestBody String prompt) {
ClsBaggage.set(sessionId, userId); // 或 ClsBaggage.set(sessionId, userId, userName)
try {
return chatClient.prompt().user(prompt).call().content();
} finally {
ClsBaggage.clear();
}
}
方法
写入的 Span 字段
ClsBaggage.set(sessionId, userId[, userName])
同时设置会话 ID、用户 ID 和用户名称。
ClsBaggage.setSession(id)
gen_ai.session.id
ClsBaggage.setUser(id)
gen_ai.user.id
ClsBaggage.setUserName(name)
gen_ai.user.name
说明:
SDK 在每轮对话开始时读取并固化 Baggage,.stream() 流式调用无需在 Reactor 算子间手动传递。
未调用 ClsBaggage 时,SDK 会自动生成 sess-<16位十六进制> 格式的会话 ID,Trace 仍然完整,但无法按真实会话或用户聚合。

步骤6:运行 Agent 并验证结果

1. 启动应用,在启动日志中确认出现 installed (service=..., endpoint=..., topic=..., sampleRatio=...),表示 SDK 初始化成功。
2. 运行一次包含模型调用的 Agent 任务。建议同时触发一个工具调用,以便检查完整调用树。
3. 登录 Agent 可观测控制台,进入步骤1创建的应用。
4. 打开调用链页面,选择包含测试请求的时间范围。
5. 打开最新 Trace,检查是否包含 Entry、Agent、Step、Chat、Tool 等 Span。
6. 选择具体 Span,检查其耗时、状态、输入输出、Token 用量和模型请求参数等数据。

采集数据说明

Span 层级与采集属性

SDK 将 Spring AI 的 Observation 映射为以下调用树结构:
enter_application ← 入口,每次顶层 ChatClient 调用生成一个
└─ invoke_agent main ← 主 Agent
├─ react round_1 ← 第1轮推理
│ ├─ chat <model> ← 模型调用(ChatModel)
│ ├─ execute_tool <tool> ← 工具调用(ToolCallback)
│ │ └─ invoke_subagent <tool> ← 工具内部嵌套调用的 ChatClient
│ │ └─ react round_1 ─ chat / execute_tool ...
│ ├─ embedding ← 向量化(EmbeddingModel)
│ └─ retrieval <store> ← 向量检索(VectorStore)
└─ react round_2 .. N ← 每多一轮工具调用,新增一个推理轮次
└─ chat <model> / execute_tool <tool> ...
Span 类型(gen_ai.span.kind)
对应操作
主要采集属性
entry
应用入口
会话 ID、轮次 ID、用户 ID、输入/输出消息。Agent 执行出错时,错误状态会传播到该 Span。
agent
主 Agent 或子 Agent
Agent 名称、Agent 范围(main 或 subagent)、输入/输出消息。子 Agent 通过 gen_ai.subagent.parent_tool_call.id 关联触发它的工具调用。
step
ReAct 推理轮次、Embedding 及其他操作
推理轮次编号、Step ID、结束原因;Embedding 的输入内容、向量数量和向量维度。
chat
模型调用
请求模型、temperature、top_p、max_tokens 等请求参数,结束原因,输入/输出 Token,调用耗时,输入/输出消息。
tool
工具调用
工具名称、调用 ID、调用参数、返回结果、调用耗时,异常时记录错误类型。
retriever
向量检索
检索语句、top_k、返回文档数量、检索耗时。
调用树的识别规则如下:
ReAct 多轮推理:某次模型调用以 finish_reason=tool_calls 结束后,下一次模型调用会开启新的推理轮次 react round_N。
子 Agent:工具内部调用的 ChatClient 识别为 invoke_subagent <工具名>,与外层共享会话 ID 和轮次 ID,支持任意嵌套深度,内外层 .call() 与 .stream() 可任意组合。
多个顶层 ChatClient:同一请求内先后调用多个顶层 ChatClient 时,每次调用生成独立的 Trace。
输入/输出消息采用 OpenAI Chat 格式的 JSON 数组记录,单个字段超过8000字符时截断。Spring AI 原生附带的 Micrometer 标签也会一并写入对应 Span。完整字段定义请参见 Agent Trace 字段定义说明。

Trace 采样

SDK 默认全量上报 Trace。如需降低上报量和存储成本,可调低采样率:
环境变量
代码配置
# 大约每 10 轮对话保留 1 轮
export CLS_SAMPLE_RATIO=0.1
ClsObservability.install(
ClsConfig.builder()
.sampleRatio(0.1)
.build());
采样率配置优先级为:ClsConfig 显式传入的值 > JVM 参数 -Dcls.springai.sample-ratio > 环境变量 CLS_SAMPLE_RATIO > .env 文件 > 默认值 1.0。超出0.0 - 1.0范围的值会被修正为边界值,无法解析的值按 1.0 处理。
注意:
采样以单轮对话(一次顶层 ChatClient 调用)为单位,同一轮对话内的所有 Span(包括嵌套的子 Agent)要么全部保留,要么全部丢弃,不会出现残缺的调用树。
采样按轮次而非按会话进行,开启采样后,同一会话的多轮对话之间可能出现缺失。如需完整审计会话,请保持采样率为 1.0。
采样仅减少上报量和存储量,被丢弃的轮次仍会在应用内完成采集处理。
采样率设置为 0 时将丢弃全部 Trace,SDK 会在启动时输出告警日志。

流式调用

ChatClient.stream() 会将 Spring AI 内部的 Observation 派发到 Reactor 调度线程。为确保流式调用的 Span 归属于同一条 Trace,SDK 初始化时会自动开启 Reactor 自动上下文传播(Hooks.enableAutomaticContextPropagation())。该设置对 JVM 全局生效且可重复调用;应用中未引入 Reactor 时不执行任何操作。
如果应用已自行开启该设置,可通过以下任一方式关闭 SDK 的自动开启:
代码配置:ClsConfig.builder().reactorContextPropagation(false)
JVM 参数:-Dcls.springai.reactor-context-propagation=false(优先于环境变量)
环境变量:CLS_SPRINGAI_REACTOR_CONTEXT_PROPAGATION=false

常见问题

启动时报错 IllegalStateException: CLS configuration incomplete

缺少必填配置。请检查 CLS_ENDPOINT、CLS_TOPIC_ID、CLS_SECRET_ID、CLS_SECRET_KEY 是否已通过环境变量、.env 文件或 ClsConfig 全部配置,报错信息中会列出缺失项。

AgentObs 中没有 Trace 数据

请按以下顺序检查:
1. 确认 registerOn() 传入的是 Spring AI 实际使用的 ObservationRegistry,而不是自行新建的实例。
2. 查看启动日志中的 installed (service=..., endpoint=..., topic=..., sampleRatio=...),确认 Endpoint、日志主题 ID 和采样率是否正确。
3. 确认 CLS_ENDPOINT 与 Trace 日志主题位于同一地域。
4. 确认 CLS_TOPIC_ID 为 Trace 日志主题 ID,而不是 Agent 可观测应用 ID。
5. 确认访问密钥具备目标日志主题的写入权限。
6. 确认运行环境能够访问所配置的 Endpoint。使用内网域名时,需确保应用运行在同地域的腾讯云内网环境中。
7. 完成测试任务后,等待至少一个刷新周期再查询数据。
如仍无法定位,可设置 CLS_DEBUG=true,并将 com.tencentcloudapi.observability 的日志级别调整为 DEBUG,查看 onStart TURN session=... turn=... traceId=... 等 SDK 日志。

AgentObs 中只有部分对话的 Trace

可能已开启 Trace 采样。请查看启动日志中的 sampleRatio 取值,如需全量上报,请设置 CLS_SAMPLE_RATIO=1.0。

流式调用的 Span 被拆分为多条 Trace

Reactor 上下文传播被关闭或开启失败。请检查启动日志中是否有 enabled Reactor automatic context propagation,并确认未 reactorContextPropagation 设置为 false。

Trace 中的会话 ID 显示为 sess-xxx

未设置会话信息。请在调用 ChatClient 前调用 ClsBaggage.set(...) 传入业务会话 ID 和用户 ID,详见步骤5。

Spring AI 原生的 gen_ai.prompt 字段为空

Spring AI 的 include-prompt 配置默认关闭,因此原生字段为空。SDK 会直接读取对话内容并写入 gen_ai.input.messages 和 gen_ai.output.messages 字段,请查看这两个字段。

Trace 中缺少 Token 或部分模型属性

Token 用量、结束原因等数据来自模型服务的返回结果。如果模型服务或对应的 Spring AI 模型集成未返回 Usage、结束原因等字段,SDK 无法采集。

应用中已使用 APM javaagent 或其他 OpenTelemetry 实现,是否冲突

不冲突。SDK 内置的 OpenTelemetry 依赖已重定位到独立包名,APM javaagent 的字节码增强不会作用于 SDK 的 Tracer;SDK 也不会注册全局 GlobalOpenTelemetry 实例,不会影响应用已有的 OpenTelemetry 配置。
如果某个工作线程上同时存在 APM 注入的父上下文和上一次流式调用的残留状态,SDK 会以独立的根上下文开启新一轮对话,以确保 AgentObs 中的 Trace 完整独立,此时该请求与 APM 链路的关联会丢失。

相关文档