FEATURED · 精选文章

Electric Agents:基于 Stream 的持久化 Agent 运行时(The Durable Runtime for Long-Lived Agents)

发布时间 / 2026/9/16 18:56:19
来源 / 创域科博编辑部
栏目 / 资讯中心
Electric Agents:基于 Stream 的持久化 Agent 运行时(The Durable Runtime for Long-Lived Agents) Electric Agents基于 Stream 的持久化 Agent 运行时The Durable Runtime for Long-Lived Agents【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric导读本文围绕 Electric 仓库中 Electric Agents 产品的核心定位展开它是一个为长生命周期 Agent设计的持久化运行时durable runtime让 Agent 在空闲时休眠、按需唤醒、崩溃后从流stream中恢复而不是长期驻留的常驻进程。你会掌握其实体 持久化流的编程模型、SDK 与控制平面分离的架构、scale-to-zero 的运行机制以及如何用npx electric-ax agents quickstart一条命令把运行时和内置 Horton 助手跑起来并自定义属于自己的实体类型。一、一张社交卡片背后的完整产品叙事仓库中的 website/og/agents.md 是一个 VitePress 的 Open GraphOG页面它为/agents落地页生成 1200×630 的社交分享卡片frontmatter 中description一句话点明了整个产品的定位The durable runtime for long-lived agents.卡片本体由 website/src/components/og/OgAgents.vue 渲染——它把线上落地页真实的AgentsHero组件直接装进统一的 OG 画框OgFrame.vue设置paused、hideActions、hideCopy属性让截图成为一张静止、确定性的画面。这种复用线上 Hero 生成社交卡的做法意味着任何对落地页文案或布局的调整都会自动同步到分享卡片上。卡片上展示的核心要素正是我们需要展开的主题产品名Electric Agents一句话定位The durable runtime for long-lived agents官方安装命令npx electric-ax agents quickstart也就是说这张卡片是整条产品叙事的浓缩入口而其背后完整的内容体系落地页 HomePage.vue、Quickstart 文档、CLI 源码 start.ts才是我们这篇文章要展开的实质。二、为什么要把 Agent 循环带上线落地页的第一屏正文HomePage.vue中#come-online区块提出了一个很具体的问题今天的 Agent 活在笔记本电脑里或聊天窗口后面而真正的工作发生在业务系统内部——由 webhook 触发、7×24 小时无人值守地运行。Electric Agents 给出的答案是把**持久化durable、可组合composable、无服务器serverless**的 Agent 带到你已经运行的基础设施上它建立在 Electric Streams 之上——每个 Agent 空闲即睡、按需唤醒、重启后依然存活。这一产品归属也在 AgentsHero.vue 与仓库根 README.mdThe agent platform built on sync.中得到印证Agent 的持久化能力不是额外加装的而是从底层的同步/流式基础设施生长出来的。三、运行时架构SDK 与控制平面落地页#inside-runtime区块把运行时拆成两个部分这也是理解 Electric Agents 的第一把钥匙组成部分位置与职责SDK运行在你的应用进程里用纯 TypeScript 定义实体entity并编写 handler。工具、模型、密钥都留在你自己的进程中。控制平面control plane负责生命周期lifecycle、路由routing、调度scheduler把每个 Agent 持久化到其专属的 durable stream。它接管生命周期所以你的 handler 不需要在两次调用之间保持存活。对应到代码层面落地页给出了agent.ts的定义骨架import { defineEntity } from electric-agents defineEntity(assistant, { state: { … }, async handler(ctx) { ctx.useAgent({ … }) await ctx.agent.run() }, })在 HomePage.vue 的运行时示意图中控制平面里呈现的是若干实例 状态的组合/assistant/r-1live、/assistant/r-2idle、/coder/refactorlive、/researcher/xidle下方挂载着 Electric Streams。这套实例路径 生命周期状态的表达方式与 CLI 中实体的寻址方式完全一致见第六节。3.1 你的栈不是我们的栈落地页#your-stack区块强调无厂商锁定Express、Next.js、Hono、TanStack Start——Agent 本质上是 webhook handler。应用进程通过createRuntimeHandler挂接 webhook控制平面通过 HTTP 流与底层 Electric Streams 通信// server.ts import { createRuntimeHandler } from electric-agents import { registry } from ./entities const runtime createRuntimeHandler({ baseUrl: STREAMS_URL, serveEndpoint: WEBHOOK_URL, registry, }) app.post(/webhook, (req, res) { await runtime.onEnter(req, res) }) app.listen(PORT, () runtime.registerTypes())// entities.ts import { createEntityRegistry } from electric-agents export const registry createEntityRegistry() registry.define(assistant, { description: A general-purpose AI assistant, async handler(ctx) { ctx.useAgent({ systemPrompt: You are a helpful assistant., model: claude-sonnet-4-5-20250929, tools: [...ctx.agentTools], }) await ctx.agent.run() }, })createEntityRegistry()持有全部实体定义并把它们接线到 Electric StreamscreateRuntimeHandler则把 webhook 入口、实体注册表与流地址绑定在一起启动时通过runtime.registerTypes()向控制平面注册类型。四、核心抽象每个 Agent 都是一个实体 一条流落地页#entity-stream区块总结了最核心的抽象你定义实体类型entity types——比如assistant、researcher——然后按需派生出实例。每个实例背后是一条专属的 durable stream一个 append-only 日志同时充当 Agent 的记忆memory、收件箱inbox和完整审计轨迹audit trail——它做过的每一件事都记录在案。这套模型在 Quickstart 文档 与 CLI 参考 中落地为非常直观的路径寻址实例以/类型/实例ID形式存在例如/horton/onboarding、/assistant/my-assistant。一条路径就是一个实体一条路径背后就是一条流。五、持久化状态而非持久化执行#durable-state区块把这一节的主题钉得很准你的 Agent 不需要一直活着它需要的是状态存活。流stream是唯一事实来源source of truth。当 handler 崩溃或进程重启时什么都不丢——流会重放replayAgent 精确地从上次离开的地方继续不需要 checkpoint、不需要快照、不需要任何协调逻辑。这在#first-agent区块对await ctx.agent.run()的注解里有更完整的表述读取流 → 调用 LLM → 追加事件 → 然后休眠。通过从流重放来挺过崩溃。这是durable runtime与普通进程内循环的本质差异运行时保证的是状态持久性而不是执行持久性。控制平面持有生命周期handler 只需在唤醒时幂等地重放并继续。六、Scale to zero空闲零成本唤醒按需#scale-to-zero区块描述了它的弹性模型每个实体空闲时不花一分钱。一千个 Agent你只为真正在思考的那几个付费。实现上实体在两次调用之间休眠sleep——没有长驻进程没有闲置 VM。当一条消息到达时handler 被唤醒从流中重放然后继续。配合第四节的实例 状态示意live/idle两种状态点可以看到控制平面如何同时管理成百上千个休眠实体而只对活跃实体做调度。七、缓存友好的上下文组合#context区块给出一个对 LLM 成本非常敏感的细节每个上下文源context source声明自己多久变化一次运行时把这些源从最稳定到最易变排序从而让 LLM 能在每次请求间缓存共享前缀更少的重复处理、更低的延迟、更低的成本。这是持久化运行时在工程上的一个具体收益点由于流和实体状态是稳定可寻址的上下文组合可以做到构造即缓存友好cache-friendly by construction而不是事后优化。八、三种接入方式CLI / 桌面应用 / TypeScript落地页#three-ways区块列出了与运行时交互的三种途径全部围绕同一条实体路径展开8.1 CLI终端直连$ electric-agents spawn /assistant/research-1 ✓ Spawned /assistant/research-1 $ electric-agents send /assistant/research-1 summarise the docs → message delivered, entity woke $ electric-agents observe /assistant/research-1 ← reasoning · tool_call(read_file) · text…支持派生实体、发送消息、列出运行中的实体以及实时 tail 某条实体流——推理过程、工具调用和文本都内联渲染在终端里。8.2 桌面应用观察与聊天跨平台桌面应用中你可以浏览运行中的实体、实时查看它们的时间线更新、检查工具调用并发送后续消息——界面呈现的正是assistant/research-1、assistant/support-bot、coder/refactor这类路径 live/idle 状态的列表。8.3 TypeScript从你的应用里嵌入import { createClient } from electric-agents import { useChat } from electric-agents/react const client createClient({ baseUrl: RUNTIME_URL }) await client.spawn(/assistant/research-1) function Chat() { const { messages, send } useChat(/assistant/research-1) return Timeline messages{messages} onSend{send} / }任何 TypeScript 服务都能spawn/sendReact 侧用useChathook 渲染实体的实时流。九、端到端实战从 quickstart 到自己的第一个 Agent9.1 环境要求依据 Quickstart 文档Node.js 18Docker——运行时服务器、Postgres 和 Electric 都以容器方式运行Anthropic API key——内置的 Horton 助手使用它可选Brave Search API key用于让 Horton 联网搜索。9.2 配置 API Key在 shell 中导出export ANTHROPIC_API_KEYsk-ant-...或写入运行 CLI 所在目录的.env文件cat EOF .env ANTHROPIC_API_KEYsk-ant-... # BRAVE_SEARCH_API_KEYBS... EOFCLI 也支持--anthropic-api-key key内联传入。9.3 一条命令启动开发环境npx electric-ax agents quickstart这条命令的实际行为可以从 start.ts 的源码得到印证——它依次做了几件事拉起基础设施startElectricAgentsDevEnvironment调用docker compose -f docker-compose.full.yml up -d启动 Postgres、Electric 与 Electric Agents 运行时服务器packages/electric-ax/docker-compose.full.yml。运行时同时承载 API 与 Web UI默认端口4437源码常量DEFAULT_ELECTRIC_AGENTS_PORT 4437可通过ELECTRIC_AGENTS_PORT环境变量覆盖resolveElectricAgentsPort会校验必须为正整数。等待服务就绪waitForElectricAgentsServer以 1 秒间隔轮询/_electric/health健康检查端点默认超时 60 秒。启动内置 Horton 运行时startBuiltinAgentsServer在前台运行注册horton与worker两个实体类型并注册一个 pull-wake runner默认 runner id 为builtin-agents可被ELECTRIC_AGENTS_PULL_WAKE_RUNNER_ID/PULL_WAKE_RUNNER_ID覆盖。打印第二终端可复制的引导命令。注意这个终端要一直开着。Ctrl-C只停掉内置 Horton 运行时容器会继续在后台运行直到你调用electric agents stop见 9.6 节。9.4 和 Horton 聊天Web UI打开 http://localhost:4437从仪表盘派生一个horton实体并发消息时间线会随 Agent 思考、调用工具、作答实时更新。CLI在另一个终端npx electric-ax agents spawn /horton/onboarding npx electric-ax agents send /horton/onboarding Walk me through Electric Agents npx electric-ax agents observe /horton/onboardingspawn在给定路径下创建一个新的实体实例其 durable stream 从此开始send向实体的收件箱投递一条消息唤醒它的 handlerobserve实时把实体的事件流渲染到终端——推理、工具调用、文本增量都内联展示。9.5 定义自己的实体并部署初始化项目并安装运行时 SDKmkdir my-agents-app cd my-agents-app npm init -y npm install electric-ax/agents-runtime npm install --save-dev tsx创建server.ts完整示例见 Quickstart 文档import http from node:http import { createEntityRegistry, createRuntimeHandler, } from electric-ax/agents-runtime const ELECTRIC_AGENTS_URL process.env.ELECTRIC_AGENTS_URL ?? http://localhost:4437 const PORT Number(process.env.PORT ?? 3000) const SERVE_URL process.env.SERVE_URL ?? http://localhost:${PORT} const registry createEntityRegistry() registry.define(assistant, { description: A general-purpose AI assistant, async handler(ctx) { ctx.useAgent({ systemPrompt: You are a helpful assistant., model: claude-sonnet-4-6, tools: [...ctx.electricTools], }) await ctx.agent.run() }, }) const runtime createRuntimeHandler({ baseUrl: ELECTRIC_AGENTS_URL, serveEndpoint: ${SERVE_URL}/webhook, registry, }) const server http.createServer(async (req, res) { if (req.url /webhook req.method POST) { await runtime.onEnter(req, res) return } res.writeHead(404) res.end() }) server.listen(PORT, async () { await runtime.registerTypes() console.log(App server ready on port ${PORT}) })这段代码的四步与第三节的架构一一对应定义实体类型 → 创建 runtime handler 连接运行时服务器 → 起 HTTP 服务接收 webhook 回调 → 启动时向运行时注册实体类型。ctx.electricTools落地页写作agentTools向 Agent 提供spawn、send、observe等运行时工具你也可以把自定义 MCP 工具、API 传进去。确保当前 shell 导出了ANTHROPIC_API_KEY或把.env拷进my-agents-app在运行时服务器已就绪的前提下启动npx tsx server.ts然后通过 CLI 与你的自定义实体交互npx electric-ax agents spawn /assistant/my-assistant npx electric-ax agents send /assistant/my-assistant Hello! npx electric-ax agents observe /assistant/my-assistant或在 http://localhost:4437 新建会话从实体列表中选择assistant类型。补充npx electric-ax init也能用模板快速脚手架项目——init.ts 通过npx gitpick拉取examples/agents-chat-starter模板随后pnpm install、复制.env.example为.env、填写ANTHROPIC_API_KEY再分别运行npx electric-ax agents quickstart与pnpm dev。9.6 停止环境与独立运行各组件npx electric-ax agents stop # 停止容器保留数据 npx electric-ax agents stop --remove-volumes # 停止容器并清除数据源码中stopElectricAgentsDevEnvironment对应docker compose down--remove-volumes追加--volumes参数。quickstart本质上等于startstart-builtin的组合你也可以分开运行npx electric-ax agents start # 运行时服务器 UI后台、Docker npx electric-ax agents start-builtin # 内置 Horton 和 worker前台当你想跨多个会话保持运行时服务器或用自己的 Agent 进程替代内置实体时分别执行这两条命令即可。十、源码视角quickstart 背后的关键链路从 start.ts 可以梳理出一条完整启动链这也是理解整套工具链最有价值的部分配置解析readDotEnvFile读取当前目录.env环境变量优先级高于文件resolveAnthropicApiKey、resolveElectricAgentsPort等都遵循先 env 后 fileEnv的顺序。容器编排runDockerCompose以stdio: inherit的方式直接执行docker compose因此你会在终端看到完整的容器输出COMPOSE_PROJECT_NAME默认electric-agents可通过ELECTRIC_AGENTS_COMPOSE_PROJECT覆盖。健康检查waitForElectricAgentsServer轮询/_electric/health超过 60 秒抛错。pull-wake 机制startBuiltinAgentsServer会以runnerId默认builtin-agents和 owner principal默认取user:用户名主机名见defaultPullWakeOwnerPrincipal注册一个pull-wake runner——这正是实体空闲休眠、消息到达即唤醒这一能力在控制平面的实现入口。优雅停机waitForShutdown监听SIGINT/SIGTERMCtrl-C会触发server.stop()并正常收尾。十一、附这张 OG 卡片在仓库里是如何实现的回到关联文档本身website/og/agents.md 的正文只做了一件事——渲染OgAgents /。拆开 OgAgents.vue 可以看到几个对理解该页面有价值的实现细节复用线上组件直接import AgentsHero from ../agents-home/AgentsHero.vueOG 卡片与线上落地页共用同一份 Hero任何文案改动自动同步四个开关paused冻结背景网络的随机唤醒/级联动画保证截图是确定性静止画面、hideActions隐藏 Quickstart/Docs 按钮行、hideCopy把安装命令从可复制按钮降级为静态展示、extraExcludeRects把左上角 wordmark 的包围盒传给背景画布避免网络网格画到品牌标识底下画框 OgFrame.vue把渲染表面锁定为精确的1200×630与 Playwright 截图视口一致免裁剪并叠印/img/brand/logo.svg的 Electric wordmarkwordmark 的包围盒由 ogLogoRect.ts 按top: 32px; left: 40px; height: 48px的实际渲染几何约 173px 宽加 12px 内边距计算得出字号放大OG 卡片内把 headline 放大到 80px、tagline 放大到 36pxfont-size: 80px / 36px的:deep()覆盖并整体下移 32px让文字在缩略图尺寸下依然可读。如果你要把这套模式复用到自己的站点核心经验是社交卡片应该复用线上组件的真实内容而不是单独维护一份容易过期的静态文案同时用暂停动画 隐藏交互 品牌留白三个开关保证截图质量。十二、延伸阅读Quickstart 文档一条命令跑起运行时与 Horton 助手Agents 文档总览实体、handler、唤醒wake的心智模型Walkthrough 指南从 Web/移动应用逐步构建多 Agent 系统定义实体实体类型、schema 与配置编写 handlerhandler 生命周期与ctxAPI配置 AgentuseAgent、模型、工具与流式输出内置 Agent随运行时一同发布的 Horton 与 WorkerCLI 实现源码packages/electric-ax/src/start.ts 与 packages/electric-ax/src/index.ts官方示例examples/agents-chat-starter 与 examples/agents-playground可直接克隆本地运行学习。【免费下载链接】electricThe agent platform built on sync.项目地址: https://gitcode.com/GitHub_Trending/el/electric创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻