只做信息分流的 Java 多 Agent 水管
中文 | English
Jswarm 只描述 Agent 拓扑,并在运行时决定信息通过 handoff 或 delegate 流向哪个 Agent。模型、工具、数据库、权限、重试、日志、指标和容器装配仍由 LangChain4j、Spring AI 与宿主应用负责。
这不是一个 Agent 平台,也不是插件容器。它是一段尽量短、跨 provider 一致的路由水管。
handoff:把当前对话控制权交给目标 Agent。delegate:目标 Agent 执行一个子任务,结果回到原 Agent。
Jswarm 自动向模型提供这两个保留工具,并由拓扑白名单限制可达目标。
用户 ──> router ──handoff──> support ──> 用户
└──delegate──> lookup ──结果──┘
| 模块 | 唯一职责 |
|---|---|
jswarm-core |
Agent、Swarm、拓扑、路由授权与请求上下文(纯 JDK) |
jswarm-runtime |
provider-neutral 状态机,以及 provider、工具和事件扩展契约 |
jswarm-adapter-langchain4j |
LangChain4j codec、模型和工具桥接 |
jswarm-adapter-spring-ai |
Spring AI codec、模型和工具桥接 |
jswarm-adapter-tck |
Adapter 行为与规范兼容性测试套件(TCK) |
两个官方 adapter 会自动传递引入 jswarm-runtime 与 jswarm-core。普通应用只需根据使用的框架引入对应的 adapter。
Jswarm 不再提供 JDBC、Store TCK、Outbox、分布式幂等、Micrometer 扩展或 Spring Boot Starter。应用可以用自己的基础设施直接完成这些工作,无需等待框架增加模块。
要求 JDK 17+、Maven 3.8+。
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.acefun29.jswarm</groupId>
<artifactId>jswarm-adapter-langchain4j</artifactId>
<version>2.1.1</version>
</dependency>使用 Spring AI 时只把 artifactId 改为 jswarm-adapter-spring-ai。
import com.jswarm.adapter.lc4j.JAgent;
import com.jswarm.adapter.lc4j.run.SwarmRunner;
import com.jswarm.core.Swarm;
import com.jswarm.core.SwarmContext;
JAgent router = JAgent.builder("router", "分流员")
.description("判断问题应该交给谁")
.instructions("技术问题 handoff 到 tech。")
.model(model)
.build();
JAgent tech = JAgent.builder("tech", "技术支持")
.description("回答技术问题")
.instructions("直接回答用户的技术问题。")
.model(model)
.build();
Swarm swarm = Swarm.create("support")
.agent(router)
.agent(tech)
.entry("router")
.handoff("router", "tech")
.build();
String reply = SwarmRunner.create(swarm)
.run("服务启动失败", new SwarmContext());Spring AI 使用相同黄金路径,只替换两个 adapter 类型和模型类型:
import com.jswarm.adapter.springai.JAgent;
import com.jswarm.adapter.springai.run.SwarmRunner;
import com.jswarm.core.Swarm;
JAgent agent = JAgent.builder("support", "技术支持")
.description("回答技术问题")
.instructions("直接回答用户。")
.model(chatModel)
.build();
Swarm swarm = Swarm.create("support")
.agent(agent)
.entry("support")
.build();
String reply = SwarmRunner.create(swarm).run("你好");普通同步 run() 在调用线程执行,不创建框架线程池。流式运行才会按需创建一个 Runner 持有的守护编排线程;SwarmRunner 可关闭,但基础调用不强制使用 try-with-resources。
只需要回复时调用 run();需要运行 ID、当前 Agent、更新后的历史或完整 delegate 结果时调用 runDetailed()。delegate 写回父 Agent 的结果默认最多 32 KB,可通过 SwarmRunOptions.maxDelegateResultBytes(...) 调整;完整结果仍保留在 detailed result 中。
公开或内部上下文可用于动态 instructions:
SwarmContext context = new SwarmContext()
.put("locale", "zh-CN")
.putSecret("apiKey", System.getenv("API_KEY"));SECRET 可由当前进程内的工具和生命周期钩子读取,但不会投影到 prompt、delegate 或事件。instructions 引用 {apiKey} 会在模型调用前失败,异常只包含键名。
- 无存储续跑:调用方可把已有 provider 消息传给
runWithHistory(...),并自行保存返回历史。 - 外部工具:继续使用对应 adapter 的工具提取或
ExternalToolExecutor;工具结果不截断,真实工具异常会中断运行。 - 流式事件:
runStreaming(message, context, sink)返回可取消的RunHandle,sink 接收类型化SwarmEvent。 - 模型输出的非法路由或工具协议允许模型在有限次数内纠正;外部工具和 delegate 的真实执行异常不会伪装成工具结果。
- 跨运行会话、事务、Outbox、幂等、业务授权和人工确认由宿主实现。
不需要新的 plugin SDK。扩展只依赖 jswarm-runtime,实现 ModelGateway、ToolBridge 或 RunEventSink,再由宿主显式接入;classpath 中出现一个依赖不会自动改变运行行为。
完整接口清单和最小示例见 [Runtime]第三方扩展指南.md,模块边界见 [模块]职责与使用指南.md,2.0 升级说明见 [迁移]2.1精简说明.md。
./mvnw -B clean verify示例位于 jswarm-examples。项目采用 MIT License。
