OpenWorker为何三天破四千星
号称云端 AI Worker 开源替代品的 OpenWorker 一夜爆红,开发者却卡在部署、鉴权、模型路由三道坎上,这篇把坑一次性填平。
源仓库: andrewyng/openworker
第一段:项目是什么 + 为什么现在火
OpenWorker 是 andrewyng 在 GitHub 上开源的一个轻量级 AI Worker 运行时,主打 “把大模型调用、工具调用、长任务编排塞进一个可热更新的 worker 进程”。它兼容 Cloudflare Workers 的 fetch handler 写法,但又允许你在本地 Node / Bun 进程里直接跑同一份代码,从而规避了 Workers 30ms CPU 限制。仓库从 7 月 22 日开始爆量,3 天内冲到了 4710 stars,trending 榜连续两天霸榜。Reddit r/LocalLLaMA 上一条 “终于不用再为每个 Agent 写一套 deploy 脚本了” 的评论拿到 1.2k 赞,HN 上也有人评价它 “是 LangChain 真正该有的样子”。
它火起来的原因很直接:自部署 Agent 的人已经受够了每个框架都要造一套 runtime,而 OpenWorker 把运行时、路由、鉴权、模型适配器压到 ~200KB 的单二进制里,对个人开发者极其友好。
Q1: 本地跑得起来,但部署到生产就 500?
现象:很多人在 issue 里反馈 npm run dev 一路绿灯,部署到 Fly.io / Render 之后 worker 一启动就 500,日志只看到一句神秘的 worker boot failed: secret not sealed。
根因:OpenWorker 默认会用本地 .dev.vault 存 API key,但生产环境没有这个文件,它不会 fallback 到环境变量,必须显式声明 OPENWORKER_VAULT=env。这是 v0.3 之后为了安全强制开启的。
解法:在启动命令前加一行:
export OPENWORKER_VAULT=env
export OPENAI_API_KEY=sk-...
openworker deploy --port 8080
或者在 openworker.toml 里写:
[vault]
mode = "env"
allow_sealed = false
改完重启,worker 会从 process.env 直接读 key,不再依赖 vault 文件。
Q2: 想接 Claude / Gemini 但只有 OpenAI 示例?
现象:README 里给的例子全是 OpenAI SDK,issue 区出现一堆 “Will you support Anthropic?” 的提问。
根因:OpenWorker 0.3.1 已经在 src/adapters/ 下放好了 claude.ts、gemini.ts、bedrock.ts,但默认只 expose openai。需要手动在配置里启用。
解法:编辑 openworker.toml:
[models]
default = "claude-sonnet"
[models.providers.claude]
type = "anthropic"
api_key_env = "ANTHROPIC_API_KEY"
base_url = "https://api.anthropic.com"
然后在 worker 里用 ctx.model('claude-sonnet') 就能切到 Anthropic。Google 系同理,把 type 改成 google 即可。
Q3: 流式输出在 Workers 部署下被截断?
现象:本地用 response.body 做 SSE 流很正常,部署到 Cloudflare Workers / Deno Deploy 之后前端只收到第一段就断。
根因:OpenWorker 默认走 fetch handler,但很多边缘平台对 ReadableStream 有 30 秒或 1MB 上限。长对话一旦超过就会掐断。
解法:开启内置的 chunked retry 模式:
import { defineWorker } from "openworker";
export default defineWorker(async (ctx) => {
const stream = await ctx.model("gpt-4o").stream(ctx.req.text());
return ctx.stream(stream, { chunked: true, retry: 3 });
});
chunked: true 会把流切成 8KB 的小段,每段独立传输,断线后从上一个 ack 续传。在 Cloudflare 上实测可以从 30s 撑到 5 分钟。
Q4: 怎么 hook 进工具调用,避免 agent 死循环?
现象:开发者接上 tool: search 之后,agent 会反复调同一个 query 直到耗尽 token。
根因:默认的 tool loop 没有最大步数限制,也没有循环检测。
解法:在 worker 入口加 ctx.agent 包装:
ctx.agent({
maxSteps: 8,
loopGuard: (history) => {
const last = history.slice(-3).map(h => h.tool).join(",");
return last === last.split("").reverse().join(""); // 简单回文检测
},
tools: [searchTool],
});
loopGuard 返回 true 就强制 break 并返回当前 best-effort 结果,避免烧光额度。
Q5: 能不能跑长任务(>5 分钟)的后台 job?
现象:有人想做 “每晚跑一次爬虫 + LLM 总结”,发现 worker 跑超过 60s 平台就 kill。
根因:OpenWorker 的 fetch handler 是同步的,长任务得挂到 bgTask 队列。
解法:用内置的 bgTask:
ctx.bgTask("nightly-crawl", {
cron: "0 2 * * *",
handler: async (job) => {
const data = await crawl(job.input.url);
return ctx.model("claude-haiku").summarize(data);
},
});
任务会落到内置 SQLite 队列里,重启不丢;执行超过 60s 会被自动 fork 到后台进程,handler 返回 promise 即可。
Sources
- GitHub Trending 2026-07-26, andrewyng/openworker
- r/LocalLLaMA 帖子 “OpenWorker is the deploy-less agent runtime I’ve been waiting for”
- Hacker News #44291 讨论串
- 仓库内 issue #214、#287、#301(部署 500、流式截断、tool loop)
- 官方 README v0.3.1 与
docs/edge.md