Java SDK
使用构建器、记录类和 @Tool 注解在 Java 中编写 JamJet 工作流和代理。
Java SDK
JamJet Java SDK 让你能用 Java 编写工作流、智能体和工具。它编译为相同的规范 IR,并运行在与 Python SDK 相同的 Rust 运行时上。
安装
需要 Java 21+(虚拟线程支持)。
<dependency>
<groupId>dev.jamjet</groupId>
<artifactId>jamjet-sdk</artifactId>
<version>0.1.0</version>
</dependency>快速开始
import dev.jamjet.agent.Agent;
import dev.jamjet.ir.IrValidator;
var agent = Agent.builder("hello-agent")
.model("claude-haiku-4-5-20251001")
.instructions("清晰简洁地回答问题。")
.strategy("react")
.maxIterations(1)
.build();
var ir = agent.compile();
IrValidator.validateOrThrow(ir);
var result = agent.run("什么是 JamJet?");
System.out.println(result.output());工作流
构建带类型化状态的有向无环工作流。状态是 Java record——不可变、经过验证、可序列化。
import dev.jamjet.workflow.Workflow;
record ResearchState(String query, String results, String answer) {}
var wf = Workflow.builder("research-flow")
.version("0.1.0")
.state(ResearchState.class)
.step("search", state ->
new ResearchState(state.query(), "[搜索结果]", state.answer()))
.step("synthesize", state ->
new ResearchState(state.query(), state.results(), "最终答案:..."))
.build();
var result = wf.run(new ResearchState("最新的 AI 框架?", "", ""));
System.out.println(result.state().answer());
System.out.printf("执行了 %d 个步骤,耗时 %.1f 毫秒%n",
result.stepsExecuted(), result.totalDurationUs() / 1000.0);条件路由
import dev.jamjet.workflow.Step;
var route = Step.builder("route")
.handler(state -> state)
.when("approved", state -> state.approved())
.when("rejected", state -> !state.approved())
.defaultNext("escalate")
.timeout("30s")
.retryPolicy("exponential")
.build();编译为 IR
每个工作流都会编译为规范 IR,以便提交到运行时:
var ir = wf.compile();
System.out.println(ir.toJson());
// 提交前验证
var errors = IrValidator.validate(ir);
errors.forEach(System.err::println);智能体
智能体结合了模型、工具和推理策略。三种内置策略:
| 策略 | 行为 |
|---|---|
react | 思考 → 使用工具 → 观察循环 |
plan-and-execute | 规划 → 执行步骤 → 综合 |
critic | 起草 → 批判 → 修订循环 |
import dev.jamjet.agent.Agent;
var agent = Agent.builder("research-agent")
.model("claude-sonnet-4-6")
.tools(WebSearch.class, FetchPage.class)
.instructions("你是一个严谨的研究员。")
.strategy("plan-and-execute")
.maxIterations(8)
.maxCostUsd(0.50)
.timeoutSeconds(300)
.build();
var result = agent.run("比较 JamJet 和 LangGraph");
System.out.println(result.output());
System.out.printf("耗时:%.1f 毫秒%n", result.durationUs() / 1000.0);基于注解的 Agent
对于简单的 Agent,可以在接口上使用 @Task 注解:
import dev.jamjet.agent.JamjetAgent;
import dev.jamjet.agent.Task;
@Task(
model = "gpt-4o",
tools = { WebSearch.class },
strategy = "react",
maxIterations = 5,
instructions = "You are helpful.",
maxCostUsd = 1.0
)
interface ResearchTask {
String research(String topic);
}
// 直接运行
String result = JamjetAgent.run(ResearchTask.class, "What is JamJet?");
// 或获取可复用的代理
ResearchTask task = JamjetAgent.proxy(ResearchTask.class);
String answer = task.research("What is JamJet?");工具
工具是使用 @Tool 注解的 Java 记录,实现 ToolCall<T> 接口。SDK 会根据记录组件类型自动生成 JSON Schema。
import dev.jamjet.tool.Tool;
import dev.jamjet.tool.ToolCall;
@Tool(description = "Search the web for information")
record WebSearch(String query) implements ToolCall<String> {
@Override
public String execute() {
// 替换为实际实现
return "Results for: " + query;
}
}
@Tool(description = "Fetch page content from a URL")
record FetchPage(String url) implements ToolCall<String> {
@Override
public String execute() {
return "Page content for " + url;
}
}工具注册表
import dev.jamjet.tool.ToolRegistry;
// 全局注册
ToolRegistry.global()
.register(WebSearch.class)
.register(FetchPage.class);
// 查询
ToolRegistry.global().names(); // ["web_search", "fetch_page"]
ToolRegistry.global().toOpenAiFormat(); // OpenAI 函数调用 schema工具名称从记录类名派生(WebSearch → web_search)。
运行时客户端
JamjetClient 是一个阻塞式 HTTP 客户端(使用虚拟线程),用于调用 JamJet 运行时 API。
import dev.jamjet.JamjetClient;
import dev.jamjet.client.ClientConfig;
var client = new JamjetClient(
ClientConfig.builder()
.baseUrl("http://localhost:7700")
.apiToken("YOUR_TOKEN") // 或使用 JAMJET_TOKEN 环境变量
.timeoutSeconds(30)
.build()
);工作流生命周期
// 注册工作流
client.createWorkflow(ir.toMap());
// 启动执行
var execId = client.startExecution("research-flow", Map.of("query", "..."));
// 轮询状态
var status = client.getExecution(execId);
System.out.println(status.get("status")); // running | completed | failed
// 获取事件时间线
var events = client.getEvents(execId);人工干预
// Approve a paused execution
client.approve(execId, "approved", "Looks good", Map.of("priority", "high"));
// Send external event to wake a waiting execution
client.sendExternalEvent(execId, "payment-received", Map.of("amount", 500));Agent 管理
// Register agent
client.registerAgent(agentCard);
// Discovery
client.discoverAgent("https://remote-agent.example.com");
// Lifecycle
client.activateAgent(agentId);
client.deactivateAgent(agentId);
// List with filters
client.listAgents(); // all agents状态管理
状态是一个 Java record。步骤接收当前状态并返回新实例——状态始终是不可变的。
record OrderState(
String orderId,
double amount,
boolean approved,
String result
) {}
// Steps return new state instances
.step("validate", state ->
new OrderState(state.orderId(), state.amount(), state.amount() < 10000, state.result()))提示: Java record 为你免费提供了不可变性、equals/hashCode 和 toString。SDK 会根据 record 组件类型自动生成 JSON Schema,用于 IR 验证。
IR 编译与验证
工作流和 agent 都会编译为 WorkflowIr——这是与 Python SDK 和 YAML 工作流共享的规范中间表示。
import dev.jamjet.ir.IrCompiler;
import dev.jamjet.ir.IrValidator;
// Compile
var ir = IrCompiler.compileWorkflow(wf);
// or: var ir = IrCompiler.compileAgent(agent);
// Inspect
System.out.println(ir.id()); // workflow name
System.out.println(ir.version()); // version string
System.out.println(ir.nodes()); // node definitions
System.out.println(ir.toJson()); // canonical JSON
// Validate
var errors = IrValidator.validate(ir);
if (!errors.isEmpty()) {
errors.forEach(System.err::println);
System.exit(1);
}
// Or throw on first error
IrValidator.validateOrThrow(ir);评估
使用可插拔评分器对数据集测试 agent 和工作流:
import dev.jamjet.eval.EvalRunner;
import dev.jamjet.eval.Scorer;
var results = EvalRunner.builder()
.dataset(dataset)
.agent(myAgent)
.scorers(new Scorer.ExactMatchScorer("expected"))
.parallelism(4)
.failBelow(0.8) // fail if mean score < 0.8
.build()
.run();Python 与 Java 对比
| 特性 | Java SDK | Python SDK |
|---|---|---|
| 工作流定义 | 流式构建器 + 记录类 | 装饰器 + TypedDict |
| 工具定义 | @Tool 记录类 + ToolCall<T> | @tool 装饰器 / MCP |
| 代理定义 | Agent.builder() | @agent 装饰器 |
| 状态 | 不可变 Java 记录类 | TypedDict / Pydantic |
| HTTP 客户端 | 阻塞式(虚拟线程) | 异步(asyncio) |
| IR 编译 | workflow.compile() | @workflow 装饰器 |
| 最低版本 | Java 21 | Python 3.10 |
两者都编译为相同的规范 IR,并在相同的 Rust 运行时上执行。
示例
在 示例仓库 中的实际示例:
| 示例 | 演示内容 |
|---|---|
java-hello-agent | 单次模型调用的最小代理 |
java-research-agent | 工具 + 计划-执行策略 |
java-support-bot | 带条件路由的多步骤工作流 |
java-approval-workflow | 运行时集成 + 人工介入 |
java-multi-tenant | 租户隔离的工作流执行 |
java-data-governance | PII 检测和脱敏模式 |
java-oauth-agent | OAuth 委托 + 权限范围缩小 |
git clone https://github.com/jamjet-labs/examples
cd examples/java-hello-agent
mvn compile exec:java提示: 每个 Java 示例在同一仓库中都有对应的 Python/YAML 版本。