跳到主要内容

Julep 是什么 · 全景与阅读地图

30 秒导读: Julep 是一个开源的 agent 工作流后端,自称"AI agent 界的 Firebase"。 你用一份 YAML 描述一个多步骤任务(带条件、循环、并行、工具调用),Julep 把它变成一条 Temporal 持久工作流去跑——逐步执行、每一步都落库,中途任何一步崩了都能从那一步续上。 你只写任务逻辑,基础设施(数据库、检索、重试、调度)它全包了。

本章是这套文档的门厅:先让完全不了解 Julep 的人搞清"这是什么、给谁用、解决什么"(Layer 0), 再给一张多服务全景图看懂大盘(Layer 1),最后给各章阅读顺序和"巧妙之处速览",告诉你想深入 时该翻哪一章。本章不进代码细节——细节都在后面各章。


1. 这是什么(零基础也能懂)

一句话定义

Julep 是一个跑 AI agent 工作流的后端平台。你把"让 agent 做的一长串事"写成 YAML,它负责 可靠地、一步步地把这串事执行完,并把每一步的状态存下来。

解决什么问题 / 给谁用

设想你要做一个"研究助手":搜网页 → 逐条抓正文 → 让 LLM 总结 → 存进知识库 → 发邮件汇报。 自己手写会遇到一堆脏活:

  • LLM 调一半超时了怎么重试?抓到第 7 条网页时进程挂了,重启后要从第 7 条接着跑,而不是从头。
  • 中间结果(每条摘要)得存哪?下次对话还想让 agent 记得上次聊过什么。
  • 想加个"如果搜到的结果 > 5 条就并行处理"这种分支/并行逻辑。

这些"编排 + 状态 + 检索 + 容错"的基础设施,就是 Julep 替你扛的部分。它面向要搭 agent / LLM 工作流、 但不想自己管 Temporal、向量库、重试队列的开发者和数据/ML 团队(README.md:75 把它定位为 "Firebase for AI agents")。

⚠️ 官方托管版已于 2025-12-31 停服(README.md:48),但项目 Apache-2.0 开源,可自托管继续用。 本文档只讲代码里真实存在的架构与原理,与托管服务是否运营无关。

它能做什么(功能一览)

能力白话
持久记忆agent 跨多轮对话记住上下文与长期知识(Sessions + Docs)
模块化工作流用 YAML 把任务拆成步骤,带条件、循环、并行、错误处理
工具编排agent 可调外部工具/API(网页搜索、浏览器、数据库……)
混合检索向量 + 全文/trigram 融合的 RAG 检索
可靠执行内建重试、自愈、断点续跑,长任务不怕崩

用起来什么样(最小示例)

一个 Julep 任务长这样——注意它就是声明式 YAML,不是命令式代码:

# 示意,非源码:一个最小任务定义(main 下每个 - 是一步)
name: research
main:
- prompt: "用三点总结:{{_.topic}}" # 步骤1:调 LLM,_ 是当前输入
- evaluate: # 步骤2:$ 开头是 Python 表达式
word_count: "$ len(_.split())" # _ 现在是上一步的输出
- if: "$ _.word_count > 100" # 步骤3:条件分支
then:
prompt: "太长了,压缩到 50 字"

你通过 SDK / REST 把它建为一个 task,再对它发起一次 execution(传入 topic),Julep 就会 逐步跑完并把每一步的输出存下来,你随时能查这次执行进行到哪、每步产出了什么。

一句话直觉

把 Julep 想成"给 AI agent 用的 GitHub Actions + 数据库":YAML 定义流水线(像 CI 的 steps), Temporal 保证它像持久后台作业一样可靠跑完,PostgreSQL 记住一切。


2. 顶层全景(它大概怎么转)

Julep 不是单个进程,而是 docker-compose.yml(第 6-17 行 include)编排的一组服务。 先看它们怎么连:

2.1 多服务拓扑

怎么读这张图: 请求从上方进来,agents-api 是心脏(读写数据、驱动工作流);真正 "一步步跑任务"的是右侧 Temporal + worker;下方几个是被调用的能力(存储、模型、工具)。

┌──────────────┐
用户 / SDK ─────▶│ gateway │ Traefik 反向代理 + 鉴权路由
│ (Traefik) │ src/gateway
└──────┬───────┘

┌───────────▼────────────┐
│ agents-api │ ← 心脏:FastAPI
│ REST 路由 + 查询层 + │ src/agents-api
│ 发起/推进 Temporal 工作流│
└──┬────────┬────────┬────┘
┌──────────────┘ │ └──────────────┐
▼ ▼ ▼
┌───────────────┐ ┌───────────────────┐ ┌────────────────────┐
│ memory-store │ │ scheduler │ │ integrations-svc │
│ PostgreSQL + │ │ Temporal 引擎 │ │ 外部工具适配器 │
│ pgvector/trgm │ │ (auto-setup) │ │ (浏览器/搜索/邮件) │
│ 持久化 + 检索 │ │ + agents-api │ │ src/integrations-… │
│ src/memory-… │ │ worker 跑步骤 │ └────────────────────┘
└───────────────┘ └─────────┬─────────┘
▲ │ 调模型
│ ▼
┌───────────────┐ ┌───────────────────┐
│ blob-store │ │ llm-proxy │
│ S3 兼容对象存储│ │ LiteLLM 统一模型网关│
│ 存大 payload │ │ src/llm-proxy │
└───────────────┘ └───────────────────┘

2.2 各服务一句话职责

服务干什么关键位置 / 镜像
agents-api心脏:FastAPI 服务,提供 REST API、查询层,发起并推进任务工作流src/agents-api(docker-bake.hcl:21)
agents-api-workerTemporal worker:真正执行工作流每一步的活动(activity)src/agents-api + Dockerfile.worker(docker-bake.hcl:30)
memory-store持久化 + 检索:PostgreSQL(+ TimescaleDB、pgvector、pg_trgm),存所有领域对象与向量src/memory-store(docker-bake.hcl:39)
schedulerTemporal 引擎:编排长任务、保证持久与重试temporalio/auto-setup:1.25.2(scheduler/docker-compose.yml:4)
integrations-service工具:把外部服务(浏览器、Brave、Wikipedia、邮件……)包成 agent 可调的工具src/integrations-service(docker-bake.hcl:48)
gateway入口:Traefik 反向代理,做鉴权与路由(单/多租户两种模式)julepai/gateway(gateway/docker-compose.yml:5,14)
llm-proxy模型网关:LiteLLM,给上百种 LLM 一个统一 OpenAI 风格接口berriai/litellm(llm-proxy/docker-compose.yml:4)
blob-store大对象存储:S3 兼容,存放超大的步骤输入/输出 payloadsrc/blob-store(docker-bake.hcl:66)

一句话: agents-api 是唯一"懂业务"的心脏;其余服务要么给它存东西(memory-store / blob-store)、要么替它跑东西(scheduler / worker)、要么被它调用(integrations / llm-proxy)。

2.3 五大领域概念(数据模型骨架)

Julep 的业务由六个核心对象撑起来,它们的关系是理解一切的地基(详见 01-concepts-data-model.md):

Developer
│ 拥有

Agent ───────定义──────▶ Task ───发起──▶ Execution
│ (指令+模型) (YAML 步骤) (一次运行的状态)
│ │ │
├─挂载─▶ Tool └─每步产生─▶ Transition (执行日志/状态机)
│ (工具/集成)
├─拥有─▶ Docs ──chunk──▶ 向量+trigram 检索(RAG)

└─参与─▶ Session ──含──▶ Entry (对话消息历史)
概念是什么类比
Agent带指令、模型、工具的 AI 实体"一个配置好的助手"
Task一份多步 YAML 工作流定义"流水线的剧本"
ExecutionTask 的一次运行实例及其状态"剧本的一场演出"
Session一段有上下文的对话容器(含 Entry 消息)"一次聊天会话"
Toolagent 能用的一个能力/集成"agent 的手脚"
Docs挂在 agent/user 下、可被检索的知识文档"agent 的资料库"

⚠️ 源码优先提醒: src/agents-api/README.md 里那张数据库 schema(CozoDB / models 模块) 已过时。现实现是 PostgreSQL,数据访问在 src/agents-api/agents_api/queries/(不是 models/), 检索用 pgvector + pg_trgm。凡该 README 与源码冲突,一律以源码为准


3. 主线:一份 YAML 怎么变成一次持久执行

如果只记住一件事,记这条主线——"YAML 任务 → Temporal 持久工作流,逐步执行、逐步落库"。 这是整个平台价值的核心,详见 02-task-execution-engine.md

高层走一遍(不进代码):

  1. 定义:你把 YAML 任务建成一个 task,main: 下每个 - 是一步(prompt / evaluate / if-else / foreach…)。
  2. 发起:对 task 发起 execution,agents-apiTemporal 里启动一条 TaskExecutionWorkflow
  3. 执行一步:工作流取当前步,查表 STEP_TO_ACTIVITY (workflows/task_execution/__init__.py:108)决定跑哪个 activity;PromptStep 走 activity 调 LLM, 纯表达式步则在工作流内直接求值。
  4. 落库为 transition:每步结果都写成一条 transition(init/step/finish/error/wait…), 既是执行日志也是状态机——合法流转在 common/protocol/tasks.py:71valid_transitions 里定义。
  5. 续跑下一步:关键设计——每一步都作为一条新的子工作流/continue-as-new 接力 (continue_as_child,workflows/task_execution/helpers.py:77),而不是一个大循环。这样单个工作流 的历史不会无限膨胀,且天然获得断点续跑。
  6. 收尾:最后一步产出 finish transition,execution 状态变为完成,输出可通过 API 查回。
YAML task
│ 发起 execution

TaskExecutionWorkflow.run ──取当前步──▶ STEP_TO_ACTIVITY?
│ │有→execute_activity(调LLM/工具)
│ │无→工作流内 eval 表达式
│◀──────────────── 结果 ─────────────────┘
▼ 写 transition(init/step/finish/error…) ← 既是日志又是状态机
▼ 还有下一步?
├─有→ continue_as_child(下一步作为新工作流) ← 每步一个子工作流
└─无→ finish,execution 完成

4. 各章阅读顺序

由浅入深,建议按序读;也可按 keyTopics 直接跳到关切的章:

顺序章节讲什么什么时候读
0index.md(本章)全景 + 阅读地图先读,建立大盘认知
101-concepts-data-model.md六大领域对象及关系、PostgreSQL 数据模型想搞清"名词"含义与表结构
202-task-execution-engine.md主线:Temporal 工作流、transition 状态机、每步续跑想懂"任务到底怎么被跑起来"
303-workflow-steps-expressions.md步骤类型全集、$ 表达式的 simpleeval 沙箱求值写 YAML 任务、调表达式时
404-tools-and-integrations.md工具类型、integrations-service 适配器想给 agent 加外部能力
505-memory-and-hybrid-search.mdDocs 分块、向量 + trigram 混合检索(RAG)做记忆/知识库检索时
606-platform-architecture.mdagents-api 内部:路由 / 查询层 / worker 分工想读源码、部署或改平台

5. 巧妙之处速览(读各章时重点看)

这几处是 Julep 值得带走的"精华",本章只点名,细节在对应章:

  • 每步一个子工作流(continue-as-new / child workflow) —— 不用一个长循环跑完整个任务,而是 每步把控制权交给一条新工作流(continue_as_child,workflows/task_execution/helpers.py:77)。 好处:Temporal 事件历史不膨胀、天然断点续跑。→ 见第 02 章。

  • transition 即执行日志 —— 状态推进和审计日志是同一个东西:每步都落一条 transition, 合法流转由 valid_transitions(common/protocol/tasks.py:71)约束,查这张表就能重放整次执行。→ 见第 02 章。

  • $ 表达式沙箱 —— YAML 里 $ 开头的字符串是真正的 Python 表达式,但跑在 simpleeval 沙箱里(activities/task_steps/base_evaluate.py,SimpleEval),限制可用函数/模块,防止任意代码执行。→ 见第 03 章。

  • 向量 + trigram 混合检索 —— RAG 检索不是纯向量,而是语义(pgvector)+ 字面(pg_trgm)融合, 用 DBSF(Distribution-Based Score Fusion)归一化两路分数(dbsf_normalize, memory-store/migrations/000018_doc_search.up.sql:325);融合函数 search_hybrid 迭代近 10 版, 以最终版 memory-store/migrations/000044_search_optimize.up.sql:484 为准(勿被 000018/000028 等旧版本误导,详见第 05 章)。→ 见第 05 章。


6. 边界与诚实说明

  • 托管版已停服(README.md:48):文档描述的是代码事实,不代表有官方服务在跑。
  • agents-api/README.md 的 schema 过时:那是旧的 CozoDB 时代文档;当前是 PostgreSQL + queries/, 凡冲突以源码为准(本章 §2.3 已标注)。
  • continue_as_child 里有一处 # FIXME: This doesn't actually work (workflows/task_execution/helpers.py:85)——continue-as-new 分支实际未按预期触发,当前主要走 child-workflow 路径;这是源码里的真实注释,细节留给第 02 章展开,别当成理想化设计。
  • 本章为门厅,不含深入代码走读;每个"巧妙之处"的 file:line 已给出锚点,深挖请进对应章。

7. 代码地图(导航索引)

从这里直接跳进源码。符号名比行号抗漂移,优先用符号 grep

主题文件路径(相对克隆根)符号 / 锚点
服务编排(全景)docker-compose.ymlinclude:(第 6-17 行)
镜像构建目标docker-bake.hclgroup "default" / 各 target
任务工作流主线src/agents-api/agents_api/workflows/task_execution/__init__.pyTaskExecutionWorkflow.run(:738)
步骤→活动映射src/agents-api/agents_api/workflows/task_execution/__init__.pySTEP_TO_ACTIVITY(:108)
每步续跑src/agents-api/agents_api/workflows/task_execution/helpers.pycontinue_as_child(:77)
transition 状态机src/agents-api/agents_api/common/protocol/tasks.pyvalid_transitions(:71)
$ 表达式求值src/agents-api/agents_api/activities/task_steps/base_evaluate.pybase_evaluate / SimpleEval
混合检索 SQL(最终版)src/memory-store/migrations/000044_search_optimize.up.sqlsearch_hybrid(:484)
DBSF 归一化src/memory-store/migrations/000018_doc_search.up.sqldbsf_normalize(:325)
混合检索查询层src/agents-api/agents_api/queries/docs/search_docs_hybrid.pysearch_docs_hybrid(:44)
worker 注册src/agents-api/agents_api/worker/worker.pycreate_worker
REST 路由入口src/agents-api/agents_api/routers/agents/ tasks/ sessions/ docs/
数据访问层src/agents-api/agents_api/queries/按对象分目录(非旧 models/)