核心概念
理解 JamJet 中的 agents、nodes、state 和持久性。
核心概念
JamJet 是一个原生支持智能体的运行时 —— 专为需要容错、跨工作节点扩展以及与其他智能体组合的 AI 工作流而构建。本页介绍关键原语。
工作流
工作流是一个有向节点图。它包含:
- 唯一的
id和version state_schema—— 流经图的数据的类型化结构- 执行开始的
start节点 - 一个或多个
end节点
workflow:
id: my-agent
version: 0.1.0
state_schema:
query: str
answer: str
confidence: float
start: think工作流在执行前会被编译为**中间表示(IR)**图。IR 是 Rust 调度器实际运行的内容 —— YAML 和 Python 只是创作界面。
节点
节点是工作流中的计算单元。每个节点都有一个 type 来决定它的功能:
| 节点类型 | 功能 |
|---|---|
model | 调用大语言模型(Claude、GPT-4、Gemini 等) |
tool | 通过 MCP 调用外部工具 |
http | 发起 HTTP 请求 |
branch | 基于条件路由执行 |
parallel | 同时扇出到多个分支 |
wait | 暂停直到外部事件触发 |
eval | 评估输出质量(评分标准、断言、延迟) |
end | 终止工作流 |
每个节点都从状态读取数据并写入状态。
状态
状态是工作流执行的共享数据存储。它在节点之间以及重启后保持持久化。
state_schema:
query: str # 来自用户的输入
search_results: list[str] # 中间数据
answer: str # 最终输出状态是类型化的 —— 模式在编译时验证。在运行时,每个节点都可以读取任何状态键,并写入其 output_key。
提示: 状态存储在数据库中,而非内存。如果运行时在执行过程中崩溃,状态会完全恢复,并从最后的检查点继续执行。
执行
**执行(execution)**是使用特定输入运行工作流的单次实例。每次执行都有一个唯一的 ID(例如 exec_01JM4X8NKWP2)。
执行具有以下特性:
- 持久化 — 存储在数据库中,不受重启影响
- 可观测 — 每次状态转换都被记录为事件
- 可检查 — 使用
jamjet inspect查看完整状态、事件时间线和 token 使用情况
持久性
持久性是 JamJet 的核心保证:即使运行时崩溃,执行也始终会完成。
这通过事件溯源实现:
- 在每个节点运行前,将
node_started事件写入数据库 - 在每个节点完成后,将
node_completed事件与状态补丁一起写入 - 重启时,调度器重放事件日志,精确重建执行停止的位置
- 从第一个未完成的节点恢复执行
不会丢失任何工作。不会重复运行任何节点。
注意: 这与"至少一次"交付不同。JamJet 的调度器使用分布式锁来确保每个节点恰好运行一次,即使有多个工作进程也是如此。
Agent
Agent 是一个可以执行以下操作的工作流:
- 被其他 agent 发现和调用(通过 Agent Card)
- 将任务委托给其他 agent(通过 A2A 协议)
- 在多次用户交互中维护长期运行的状态
每个 agent 都有一个 Agent Card — 对其能力、端点和输入/输出模式的机器可读描述。这是 A2A 协议的基础。
调度器
JamJet 调度器使用 Rust 编写,作为 jamjet dev(本地)或托管运行时(生产环境)的一部分运行。
它的工作流程:
- 轮询执行队列以获取待处理的工作
- 对执行加锁以防止重复运行
- 将节点分派到工作线程
- 在每个节点之后写入检查点
调度器是 JamJet 工作流默认持久化的原因 — 它从不会忘记任何执行。
本地与生产环境
| 功能 | jamjet dev(本地) | 托管 / 自托管 |
|---|---|---|
| 存储 | SQLite | PostgreSQL |
| Workers | 单进程 | 分布式 |
| MCP 服务器 | 本地 stdio | 远程 SSE/HTTP |
| 认证 | 无 | mTLS / API 密钥 |
编程模型完全相同——相同的 YAML 或 Python 代码在两种环境中均可无需修改直接运行。