可观测与调试¶
AgentScope Java 提供了多种机制来观测和调试智能体的执行过程:
Studio(可视化调试):通过 Web 界面实时可视化和交互式调试
OpenTelemetry 链路追踪:通过 OTLP 协议将 Trace 数据导出到外部可观测性平台(如 Langfuse、Jaeger)
Studio(可视化调试)¶
Studio 提供 Web 界面实时可视化 Agent 执行过程,支持交互式调试和消息追踪。
核心特性¶
实时可视化:Web 界面展示 Agent 推理和执行过程
交互式输入:通过 Web UI 与 Agent 对话
消息追踪:查看完整的消息流和Trace
多 Run 管理:支持多个实验运行的组织和比较
快速开始¶
1. 启动 Studio Server¶
从源码启动
git clone https://github.com/agentscope-ai/agentscope-studio
cd agentscope-studio
npm install
npm run dev
npm安装
npm install -g @agentscope/studio # or npm install @agentscope/studio
as_studio
Studio 将运行在 http://localhost:5173(前端开发服务器)

2. Java 应用集成¶
import io.agentscope.core.studio.StudioManager;
import io.agentscope.core.studio.StudioMessageHook;
import io.agentscope.core.studio.StudioUserAgent;
// 初始化 Studio 连接
StudioManager.init()
.studioUrl("http://localhost:3000")
.project("MyProject")
.runName("demo_" + System.currentTimeMillis())
.initialize()
.block();
// 创建带 Hook 的 Agent
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.model(model)
.hook(new StudioMessageHook(StudioManager.getClient()))
.build();
// Agent 消息自动发送到 Studio
agent.call(msg).block();
// 清理资源
StudioManager.shutdown();
3. 在AgentScope Studio 查看Trace信息¶

StudioUserAgent¶
通过 Web UI 接收用户输入。
import io.agentscope.core.studio.StudioUserAgent;
// 创建用户 Agent
StudioUserAgent user = StudioUserAgent.builder()
.name("User")
.studioClient(StudioManager.getClient())
.webSocketClient(StudioManager.getWebSocketClient())
.build();
// 等待 Web UI 用户输入
Msg userInput = user.call(null).block();
您可以在Studio中的Projects中找到该Project,通过WebUI的方式进行调试

对话循环¶
Msg msg = null;
while (true) {
// 从 Web UI 获取用户输入
msg = user.call(msg).block();
if (msg == null || "exit".equalsIgnoreCase(msg.getTextContent())) {
break;
}
// Agent 处理
msg = agent.call(msg).block();
}
完整示例¶
package io.agentscope.examples;
import io.agentscope.core.ReActAgent;
import io.agentscope.core.message.Msg;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.core.studio.StudioManager;
import io.agentscope.core.studio.StudioMessageHook;
import io.agentscope.core.studio.StudioUserAgent;
public class StudioExample {
public static void main(String[] args) throws Exception {
String apiKey = System.getenv("DASHSCOPE_API_KEY");
System.out.println("Connecting to Studio at http://localhost:3000...");
// 初始化 Studio
StudioManager.init()
.studioUrl("http://localhost:3000")
.project("JavaExamples")
.runName("studio_demo_" + System.currentTimeMillis())
.initialize()
.block();
System.out.println("Connected to Studio\n");
try {
// 创建 Agent(带 Studio Hook)
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.sysPrompt("You are a helpful AI assistant.")
.model(DashScopeChatModel.builder()
.apiKey(apiKey)
.modelName("qwen3-max")
.build())
.hook(new StudioMessageHook(StudioManager.getClient()))
.build();
// 创建用户 Agent
StudioUserAgent user = StudioUserAgent.builder()
.name("User")
.studioClient(StudioManager.getClient())
.webSocketClient(StudioManager.getWebSocketClient())
.build();
// 对话循环
System.out.println("Starting conversation (type 'exit' to quit)");
System.out.println("Open http://localhost:3000 to interact\n");
Msg msg = null;
int turn = 1;
while (true) {
System.out.println("[Turn " + turn + "] Waiting for user input...");
msg = user.call(msg).block();
if (msg == null || "exit".equalsIgnoreCase(msg.getTextContent())) {
System.out.println("\nConversation ended");
break;
}
System.out.println("[Turn " + turn + "] User: " + msg.getTextContent());
msg = agent.call(msg).block();
if (msg != null) {
System.out.println("[Turn " + turn + "] Agent: "
+ msg.getTextContent() + "\n");
}
turn++;
}
} finally {
System.out.println("\nShutting down...");
StudioManager.shutdown();
System.out.println("Done\n");
}
}
}
高级用法¶
手动推送消息¶
StudioClient client = StudioManager.getClient();
Msg customMsg = Msg.builder()
.role(MsgRole.ASSISTANT)
.content(TextBlock.builder().text("自定义消息").build())
.build();
client.pushMessage(customMsg).block();
多 Agent 可视化¶
// 为每个 Agent 添加 Hook
ReActAgent agent1 = ReActAgent.builder()
.name("Agent1")
.hook(new StudioMessageHook(client))
.build();
ReActAgent agent2 = ReActAgent.builder()
.name("Agent2")
.hook(new StudioMessageHook(client))
.build();
// Studio 将分别显示两个 Agent 的消息
OpenTelemetry 链路追踪¶
AgentScope Java 集成了 OpenTelemetry,提供分布式链路追踪能力。你可以将 Trace 导出到任何支持 OTLP 协议的平台,如 Langfuse。
快速开始¶
使用 TelemetryTracer 并通过 TracerRegistry 注册,即可自动追踪所有智能体调用、模型调用和工具执行:
import io.agentscope.core.tracing.TracerRegistry;
import io.agentscope.core.tracing.telemetry.TelemetryTracer;
// 注册 TelemetryTracer,配置 OTLP 端点
TracerRegistry.register(
TelemetryTracer.builder()
.endpoint("https://your-otlp-endpoint/v1/traces")
.build()
);
// 注册后,所有智能体活动将自动被追踪
ReActAgent agent = ReActAgent.builder()
.name("Assistant")
.model(model)
.build();
注册后,追踪器会自动捕获:
智能体调用 — 每次
agent.call()生成一个 Span模型调用 — 每次 LLM 调用生成一个 Span
工具执行 — 每次工具调用生成一个 Span
格式化 — 消息格式化生成一个 Span
无需额外代码 — 追踪在全局范围内自动生效。
配置选项¶
TelemetryTracer 支持以下 Builder 选项:
选项 |
描述 |
默认值 |
|---|---|---|
|
OTLP 端点 URL |
— |
|
添加单个 HTTP 请求头(如用于认证) |
— |
|
以 |
— |
|
启用或禁用追踪 |
|
|
使用自定义的 OpenTelemetry |
— |
接入 Langfuse¶
Langfuse 是一个开源的可观测性平台,支持 OpenTelemetry 协议。你可以将 Trace 发送到 Langfuse Cloud 或自部署的实例。
import io.agentscope.core.tracing.TracerRegistry;
import io.agentscope.core.tracing.telemetry.TelemetryTracer;
import java.util.Base64;
// 将 Langfuse API Key 编码为 Base64
String publicKey = "pk-lf-xxxxxxxx";
String secretKey = "sk-lf-xxxxxxxx";
String encoded = Base64.getEncoder().encodeToString((publicKey + ":" + secretKey).getBytes());
TracerRegistry.register(
TelemetryTracer.builder()
.endpoint("https://cloud.langfuse.com/api/public/otel/v1/traces")
.addHeader("Authorization", "Basic " + encoded)
.addHeader("x-langfuse-ingestion-version", "4")
.build()
);
注意:使用 Langfuse 的 OTLP 端点时,
x-langfuse-ingestion-version请求头是必需的,请确保包含此头部。
运行智能体后,你可以在 Langfuse 控制台中查看 Trace,包括完整的调用链、延迟以及每一步的输入/输出。
接入其他 OTLP 后端¶
任何支持 OTLP 协议的平台都可以使用。例如,将 Trace 发送到本地 Jaeger 实例:
TracerRegistry.register(
TelemetryTracer.builder()
.endpoint("http://localhost:4317")
.build()
);
更多资源¶
Studio 完整示例: StudioExample.java
Studio 仓库: https://github.com/agentscope-ai/agentscope-studio
Hook 文档: hook.md