Agent 开发框架

Julep|持久化可组合 AI Agent 数据流框架

Julep

Julep 是一个以 Python 声明式 @flow 编写、可崩溃恢复与安全重试的持久化 AI Agent 数据流框架,并提供 CLI 与自托管控制平面。

获取与使用

需要部署

按官方资料自行安装或部署

使用难度待核验
国内可用性待核验

2026-11-09 更新 · 本站尚未实测

项目介绍

Agent 开发框架 · 2026-11-09 更新 · 本站尚未实测

Julep 把 AI Agent 构建为「可组合、持久化的数据流」,而不是临时拼凑的循环。按 README 说明,流程可以崩溃后恢复、安全重试、通过派生的投影解释每一步,并拒绝模型未被明确允许调用的工具。主要编写方式是基于构造过程的 @flow:普通 Python 名称描述图步骤,注册的工具、pure 函数、reasoner、分支、扇出、重试与超时最终编译为同一套冻结的线格式 IR。纯核心不引入依赖,Temporal 层为可选项。

需要注意:README 中明确写明 Julep 3 是「ground-up rewrite」,与 v1(agents API 平台)属于不同产品,「there is no migration path」。因此旧版 Julep v1 的用法与本文不通用。

核心能力

点击能力名称查看输入、输出和原文依据。

  • 持久化执行:可通过可选扩展接入 Temporal 或 DBOS/Postgres,实现崩溃恢复、安全重试与超时控制。
  • 声明式流程:@flow 内的工具调用、think(...)、cond(...)、switch(...)、each(...)、reschedule(...) 等追加图步骤,| 合并记录、h["key"] 取字段。
  • 可解释性:每一步通过派生投影(projection)呈现,可导出到 OpenTelemetry 或 Langfuse。
  • 工具权限约束:deploy(...) 冻结工具与 reasoner 表面;MCP 引用来自冻结快照,worker 侧 MCP 预检校验可达工具面,默认精确 pin 比较。
  • 密钥管理:自托管控制平面提供只写 operator vault,值静态加密;支持 secret://name 形式的短期运行凭据绑定。
  • CLI 管理整个 Agent 模块:README 称其为「dbt for agents, terminal-native」,提供 ls、show、graph、run、lint、test、trace、doctor、deploy、serve 等命令。

实际应用场景

适用场景

适合需要长期运行、失败可恢复、可审计的 LLM Agent 或工作流,例如客服工单分诊(README 的 Quickstart 即为工单分诊示例)、多步推理后合并结果的流程、需要挂接 MCP 工具并约束可调用工具范围的场景。若只需一次性脚本式调用模型,本项目相对偏重。

安装与接入

README 给出的安装命令为:

pip install --pre julep

Julep 3 当前以候选发布(release candidate)形式提供,因此必须加 --pre;README 说明待 3.0.0 正式发布后该要求会取消。

基础安装仅为「编写 + 编译」(依赖 PyYAML)。运行时能力通过可选 extra 安装,README 表格列出 temporal、dbos、http、cma、mcp、server、dotctx、providers、otel、langfuse、store、wasm。例如 MCP 相关能力需 julep[mcp];S3 发布与 Temporal worker 需 julep[store,temporal]。

快速开始示例不需要 API Key:deploy(...) 后调用 dry_run(...),使用内存工具与确定性的假 reasoner 在本地执行。示例中使用的模型标识为 anthropic:claude-haiku-4-5-20251001,真实调用需自行核实所选模型与提供方接入方式。

生产部署涉及 Kubernetes、Helm、Temporal、S3 发布存储及 Ed25519 签名密钥(JULEP_BUNDLE_SIGNING_KEY)等,README 只描述了配置字段,未给出完整可复制的部署脚本,实际步骤需查阅其官方文档站点。

使用条件与限制

是否需要部署
需自行准备运行环境,具体要求见正文
是否需要注册
账号和认证要求见正文;未明确说明的项目仍待核验
是否需要 API Key
待核验
费用与额度
费用边界见正文,项目许可不代表模型或托管服务免费
所需权限
待核验
许可证与服务条款
待核验

权限费用与限制

  • 费用:README 未说明任何价格或商业授权方案,费用与是否存在收费模块需向官方核验。
  • 模型与 API Key:仅 dry_run 示例明确无需 API Key;实际调用模型的凭据形式、支持的提供方完整列表未在 README 中完整列出,需以 providers extra 与任何-llm 的文档为准,待核验。
  • 权限:项目强调工具权限白名单、MCP 冻结快照校验、运行凭据绑定,但这些机制的具体默认行为与限制需以控制平面文档为准。
  • 平台:README 以 pip install 与 Python 为主,未声明 Windows 支持情况,Windows 与国内网络环境可用性待核验。
  • 版本状态:当前为主版本候选发布,接口可能变动。

国内使用情况

网友核验 用户经验分享

与站长实测独立,不代表官方认证或本站已实测。

我要核验
0 位参与者0 份有效分项记录

最近核验:暂无有效核验。参与人数按当前项目有效身份去重;不同核验项分别统计,不合并成用户总结果。仅统计审核通过且未过期的记录。

分项统计、有效期与样本量
核验项目有效人数成功 / 部分 / 失败 / 无法判断成功率最近核验 / 有效期
官方网站访问00 / 0 / 0 / 0样本不足暂无 / 7 天
GitHub 仓库访问00 / 0 / 0 / 0样本不足暂无 / 7 天
安装与运行00 / 0 / 0 / 0样本不足暂无 / 30 天
官方服务国内连接 / MCP 连接00 / 0 / 0 / 0样本不足暂无 / 30 天
国内网络情况00 / 0 / 0 / 0样本不足暂无 / 7 天
国内模型兼容性00 / 0 / 0 / 0样本不足暂无 / 30 天
自定义 API00 / 0 / 0 / 0样本不足暂无 / 30 天
海外服务依赖
00 / 0 / 0 / 0样本不足暂无 / 30 天
海外账号要求
00 / 0 / 0 / 0样本不足暂无 / 30 天
中文界面
00 / 0 / 0 / 0样本不足暂无 / 30 天
客户端兼容性00 / 0 / 0 / 0样本不足暂无 / 30 天
账号及费用信息
00 / 0 / 0 / 0样本不足暂无 / 30 天

成功率 = 成功 ÷(成功 + 部分成功 + 失败);无法判断不计入分母。至少 5 份可判断结果才显示成功率。账号、费用、海外依赖与语言等事实项,成功表示核查结论与资料吻合,具体观察另行统计;不表示免费或没有海外依赖。不同网络、客户端和版本的结果不能直接等同。

最近有效核验

暂无审核通过且未过期的网友核验。欢迎提交真实使用记录。

查看全部有效核验 →

国内实测状态:国内可用性待核验。协议兼容和官方资料说明不等于国内网络可用。

官方网站访问
尚未实测 待核验
GitHub 仓库访问
尚未实测 待核验
官方服务国内连接
尚未实测 待核验
国内网络情况
尚未实测 待核验
国内模型兼容性
尚未实测 待核验
自定义 API
尚未实测 待核验
海外服务依赖
尚未实测 待核验
海外账号要求
尚未实测 待核验
中文界面
尚未实测 待核验
国内最后核验时间
尚未实测

许可与国内使用

仓库 LICENSE 文件为 Apache License 2.0,README 亦声明「This project is licensed under Apache-2.0」。该许可适用于仓库代码;商业模块、托管服务、第三方模型及可选依赖(如 Temporal、云对象存储、模型提供方)各自遵循不同条款,需分别核实。公开仓库与 Apache-2.0 授权不代表相关云服务或模型免费。

文档站点为 docs.julep.ai,README 未说明服务部署地域或国内访问可用性,域名不等于部署地域,国内使用合规性与可达性待核验。

项目资料与来源

官方网站 ↗

GitHub 仓库 ↗

官方文档 ↗

字段依据与待核验事项

access:来源确认 · pip install --pre julep

project_type:来源确认 · Julep builds agents as **composable, durable dataflows** instead of ad-hoc loops

原始 README(折叠技术参考)
# Julep

Julep — durable, composable AI agents. Flows that crash and resume, retry safely, and explain every step.

Julep builds agents as **composable, durable dataflows** instead of ad-hoc loops: flows can crash and resume, retry safely, explain every step through a derived projection, and deny any tool the model was not explicitly allowed to call. The primary authoring surface is define-by-construction `@flow`: ordinary Python names graph steps while registered tools, pures, reasoners, branches, fan-out, retries, and timeouts compile to the same frozen wire-format IR. The pure core stays dependency-free, while the Temporal layer is optional.

---

## Install

```bash
pip install --pre julep
```

Julep 3 currently ships as a release candidate, so the `--pre` flag is required; it drops once `3.0.0` is final.

---

## Quickstart

10 minutes, no API key. Install the base package and run this as a normal Python script:

```python
from typing import TypedDict

from julep import Reasoner, deploy, flow, pure, think, tool


class SupportReply(TypedDict):
    reply: str


@tool(effect="read", idempotent=True)
def lookup_ticket(ticket: str) -> dict[str, str]:
    return {
        "ticket": ticket,
        "queue": "billing",
        "summary": "Use the duplicate-charge runbook.",
    }


@pure("ticket_prompt")
def ticket_prompt(hit: dict[str, str]) -> dict[str, str]:
    return {"queue": hit["queue"], "context": hit["summary"]}


support_reply = Reasoner(
    name="support_reply",
    model="anthropic:claude-haiku-4-5-20251001",
    system="Draft one concise support reply as JSON.",
    reply=SupportReply,
)


@flow
def triage(ticket: str) -> dict[str, str]:
    hit = lookup_ticket(ticket, retries=2, timeout_s=5)
    prompt = ticket_prompt(hit)
    answer = think(support_reply, prompt, timeout_s=10)
    return hit | answer


def fake_support_reply(value: dict[str, str]) -> SupportReply:
    return {"reply": f"{value['queue']}: {value['context']}"}


deployment = deploy(triage, tools=[lookup_ticket], reasoners=[support_reply])
result = deployment.dry_run(
    "Customer was charged twice.",
    reasoners={"support_reply": fake_support_reply},
)

print(result.value)
```

`@flow` runs once at definition time with data handles. Registered tools, registered pures, `think(...)`, `cond(...)`, `switch(...)`, `each(...)`, and `reschedule(...)` append graph steps instead of doing runtime work; `|` merges records and `h["key"]` plucks fields. `deploy(..., tools=..., reasoners=...)` freezes the tool and reasoner surface, and `dry_run(...)` executes locally with in-memory tools and deterministic fake reasoners. See the larger `@flow` examples in `examples/episode_summary_flow.py` and `examples/cluster_labeling_flow.py`.

Use `mcp_tool(server, tool)` inside `@flow` for an MCP reference. Its schemas
and behavior contract come from the frozen MCP snapshot; handle-valued keyword
arguments build its input record directly. `examples/episode_summary_flow.py`
shows snapshot-backed MCP reads and writes with a local `mcp_call` fake.

## Production secrets and MCP safety

The self-hosted control plane includes a write-only operator vault whose values
are encrypted at rest. Callers can also bind short-lived, per-run credentials to
whole-string `secret://name` MCP header references; those values travel only in
encrypted Temporal payloads and are excluded from stored run data and
projections. Before user effects, worker-side MCP preflight checks the frozen,
transitively reachable tool surface. New releases default to exact `pin`
comparison, with explicit `names` and `off` escape hatches; mid-run tool removal
or post-validation schema rejection fails terminally as typed surface drift.

See the **[control-plane guide](docs-site/content/docs/deploy/control-plane.md)**
for vault configuration, run-secret limits and binding rules, MCP policy
behavior, and the administration API.

---

## The CLI

`julep` is the developer CLI for a whole **module of agents** — "dbt for agents, terminal-native." Point it at a directory; it discovers every `@flow`/`Agent(...)`, treats each as a node in a cross-agent graph, and gives you one selection grammar across every verb:

```bash
julep ls                                  # list agents (name · kind · tags)
julep show triage                         # one agent's kind, source location, tags, calls
julep graph                               # the cross-agent DAG as Graphviz DOT
julep run triage --input '"TICKET-42"'    # execute locally, stream the trace tree
julep lint +triage                        # validate an agent and everything it depends on
julep test triage                         # run pytest for the selected agents
julep trace <run-id>                      # render a cached run's trace tree + Langfuse link
julep doctor                              # preflight: discovery, secret refs, git, Langfuse, Temporal
julep deploy triage --env staging         # freeze → publish → record in the deploy ledger
julep serve api --migrate                 # run the self-hosted FastAPI control plane
```

Selectors compose: `tag:support`, `state:modified` (Slim-CI), `+agent`/`agent+`/`@agent` graph traversal, `a,b` intersection, `--exclude`. Full reference: **[docs-site/content/docs/guides/using-the-cli.md](docs-site/content/docs/guides/using-the-cli.md)**.

For production applications, declare an explicit object instead of adding a
second discovery convention:

```python
from collections.abc import Mapping

from julep import Application, CapabilityManifest, McpSnapshot, PipelineSpec


def load_live_memory_tools_snapshot(
    environment: Mapping[str, str],
) -> McpSnapshot:
    # Use the selected deployment environment to call tools/list.
    ...

application = Application("memory", [
    PipelineSpec(
        name="episode_summary",
        flow=summary_flow,
        reasoners=(summary_reasoner,),
        capabilities=CapabilityManifest.from_file("summary-capabilities.yaml"),
        lane="summary",
        eval_packages=("prompts/episode_summary.ctx",),
        snapshot=memory_tools_snapshot,
        snapshot_source=load_live_memory_tools_snapshot,
    ),
])
```

For `julep plan`, `apply`, and application-level `status`, each
`snapshot_source` receives a read-only mapping made from the selected
environment's `[vars]` followed by `[worker_environment]` (worker values win on
duplicate names). Secret-backed worker variables are intentionally absent:
`worker_secret_environment` contains Kubernetes Secret references, not values,
and those values exist only in the worker at runtime. The callback must return
an `McpSnapshot`; pass any credential needed for schema discovery through a
non-secret control-plane mechanism rather than expecting a Secret value here.

Point `[tool.julep].application` at that object with a `module:attribute` value.
Each deployable environment also names the worker's explicit context factory;
ordinary and Secret-backed worker environment can be reconciled with the lane:

```toml
[tool.julep.env.staging]
temporal_address = "temporal-frontend.temporal.svc.cluster.local:7233"
release_store = "s3://julep-releases/julep"
worker_image = "registry.example/memory@sha256:<digest>"
worker_context_factory = "memory.worker:build_context"
worker_service_account = "julep-worker"
worker_priority_class = "julep-model-worker"
payload_encryption_secret = "temporal-payload-codec"

[tool.julep.env.staging.worker_environment]
MEMORY_TOOLS_MCP_URL = "http://memory-tools/mcp-internal"
JULEP_BUNDLE_ALLOWED_SIGNERS = "<64-hex-ed25519-public-key>"

[tool.julep.env.staging.worker_secret_environment.MEMORY_TOOLS_JWT_PRIVATE_KEY]
secret_name = "memory-tools-jwt"
key = "private-key"
```

`payload_encryption_secret` is required for application releases and names an
existing Kubernetes Secret in `kubernetes_namespace` with `keyring` and
`active-key-id` entries. The PriorityClass is optional: set
`worker_priority_class` only when shared cluster infrastructure provisions it
(the EKS demo does); omit it on ordinary clusters.

`julep plan --env staging` reports artifact, MCP-schema, Helm/KEDA, and runtime
drift; `julep apply --env staging` publishes an immutable S3-artifact store release and
reconciles one digest-pinned Helm release per lane and immutable release on a
release-specific task queue, without changing traffic;
`julep status --env staging` aggregates the release and live lane state. That
application-level status path is selected only when `[tool.julep].application` is
configured and no selector or `--exclude` is supplied; selected status queries
continue to inspect the legacy per-agent deploy ledger.

Application publishing requires a 64-hex Ed25519 seed (or a file containing
one) in `JULEP_BUNDLE_SIGNING_KEY`. In production, set the corresponding 64-hex
public key in the non-secret `JULEP_BUNDLE_ALLOWED_SIGNERS` worker environment;
`apply` rejects a configured allow-list that does not contain the publishing
key. Read-only `plan` and application-level `status` need that public allow-list
(or the private key as a local fallback). Install `julep[store,temporal]` for
S3 publication and Temporal workers, plus any pipeline-specific extras. The
control-plane host also needs authenticated `helm`, `kubectl`, and `temporal`
CLIs; `apply --publish-only` skips Helm reconciliation.

`julep worker` runs continuously from its environment contract. A positive
`--smoke-test-seconds N` verifies Temporal connectivity, polls the configured
queue for `N` seconds, drains, and exits; the default `0` keeps serving.

---

## Extras

The base install is authoring + compile only (PyYAML). Optional extras add runtime surfaces:

| Extra | `pip install --pre 'julep[...]'` | Adds |
|---|---|---|
| `temporal` | `julep[temporal]` | durable execution on Temporal (workflows, activities, worker, client helpers) |
| `dbos` | `julep[dbos]` | durable execution on DBOS / Postgres (steps, flow workflow, chaining runner) |
| `http` | `julep[http]` | native HTTP tool calls from the `callTool` activity |
| `cma` | `julep[cma]` | httpx transport for the CMA HTTP adapter |
| `mcp` | `julep[mcp]` | official MCP SDK, httpx, PyJWT, and cryptography for MCP references, snapshots, calls, and auth |
| `server` | `julep[server]` | FastAPI/Uvicorn control plane, SSE, Postgres store, Temporal gateway, cryptography, and httpx |
| `dotctx` | `julep[dotctx]` | rich `.ctx` layout (Jinja2 templates compiled into registered renderers); native `!? $env.get(...)` settings support needs no extra |
| `providers` | `julep[providers]` | multi-provider `LlmCaller` via any-llm (pair with provider extras) |
| `otel` | `julep[otel]` | OpenTelemetry span export of the projection |
| `langfuse` | `julep[langfuse]` | Langfuse OTLP/HTTP export of the projection |
| `store` | `julep[store]` | artifact distribution stores + bundle signing primitives |
| `wasm` | `julep[wasm]` | sandboxed wasm execution of bundle-sourced pures (wasmtime host) |

`julep.HAVE_TEMPORAL` reports whether the runtime is available; the package imports and compiles flows either way.

---

## Looking for Julep v1?

Julep v1 (the agents API platform) is preserved on the [`v1` branch](https://github.com/julep-ai/julep/tree/v1) and its docs at v1.docs.julep.ai. Julep 3 is a ground-up rewrite; there is no migration path — v1 and v3 are different products.

---

## License

This project is licensed under Apache-2.0. See [LICENSE](LICENSE).
历史前置条件说明(补充参考)

Python 环境与 pip;基础包仅需 PyYAML,运行时能力需按需安装 extra(如 julep[temporal]、julep[mcp]、julep[server] 等)。真实模型调用需配置相应模型提供方与凭据,形式待核验;README 的 Quickstart 使用假 reasoner,无需 API Key。生产部署需 Kubernetes、Helm、kubectl、temporal CLI、S3 兼容发布存储及 Ed25519 签名密钥。费用、Windows 支持、国内网络可用性均待核验。

项目来源与清单版权许可

https://github.com/julep-ai/julep

整理来源:https://github.com/slavakurilyak/awesome-ai-agents

清单版权与许可:

MIT License

Copyright (c) 2024 Slava Kurilyak

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.