JamJet

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

工具名称从记录类名派生(WebSearchweb_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 SDKPython SDK
工作流定义流式构建器 + 记录类装饰器 + TypedDict
工具定义@Tool 记录类 + ToolCall<T>@tool 装饰器 / MCP
代理定义Agent.builder()@agent 装饰器
状态不可变 Java 记录类TypedDict / Pydantic
HTTP 客户端阻塞式(虚拟线程)异步(asyncio)
IR 编译workflow.compile()@workflow 装饰器
最低版本Java 21Python 3.10

两者都编译为相同的规范 IR,并在相同的 Rust 运行时上执行。


示例

示例仓库 中的实际示例:

示例演示内容
java-hello-agent单次模型调用的最小代理
java-research-agent工具 + 计划-执行策略
java-support-bot带条件路由的多步骤工作流
java-approval-workflow运行时集成 + 人工介入
java-multi-tenant租户隔离的工作流执行
java-data-governancePII 检测和脱敏模式
java-oauth-agentOAuth 委托 + 权限范围缩小
git clone https://github.com/jamjet-labs/examples
cd examples/java-hello-agent
mvn compile exec:java

提示: 每个 Java 示例在同一仓库中都有对应的 Python/YAML 版本。

On this page