本地 Worker (CLI)
概述
本地 Worker 是你电脑上某个文件中的函数。3Min API CLI(npm 包 @3minapi/cli)在这台电脑上运行,取走 AI 发送的任务,用每个任务的输入运行函数并报告结果。AI 和你的电脑从不直接通信 — 中间由 3Min API 转接。
- 无需公开 URL,无需开放端口。 CLI 只发出对外请求
- 函数读取的内容留在你的电脑上,只有它返回的内容除外
- 一个文件 = 一个函数 = 一个 Worker
在公开 URL 上运行的服务器请参阅任务(公共 Worker)。
| 术语 | 含义 |
|---|---|
| 主机 | 运行 CLI 的电脑。在仪表盘 → 任务 → 本地 中为每台电脑添加一个 |
| 主机令牌 | tm_host_…。用于在那台电脑上登录 CLI。只显示一次 |
| 项目文件夹 | 默认为 ~/3minapi:3minapi.json、workers/、data.db、.gitignore。每台主机一个 |
data.db |
项目中的 SQLite 文件。所有结果都保存在这里;你的 Worker 也可以保存自己的数据 |
| 结果读取器 | CLI 注册的内置本地 Worker,让 AI 能读取保存在 data.db 中的结果 |
| 种类 | worker_list 中的 kind |
任务如何到达 | Free | API 调用 |
|---|---|---|---|---|
| 公共 Worker | "public" |
3Min API 以 POST 发送到你的 URL | 1 个 | 投递计 0 次 |
| 本地 Worker | "local" |
CLI 取走(默认实时通知,或定期检查) | 无限制 | 实时:空闲时不计调用。定期检查:每次获取计 1 次,即使没有任务 |
安装与更新
命令在你电脑上的终端中运行 — Windows 上是 终端 或 PowerShell(开始菜单),macOS 上是 终端(应用程序 → 实用工具)。
- Node.js 24.12 或更高版本。
node -v显示版本。如果没有安装或版本较旧,请从 nodejs.org 安装 LTS 版(Windows 上也可以用winget install OpenJS.NodeJS.LTS),然后打开一个新的终端 - CLI:
npm install -g @3minapi/cli
3minapi --version
- Windows PowerShell 可能会以 "running scripts is disabled on this system" 拒绝运行。请输入
3minapi.cmd代替3minapi—— 无需更改任何设置即可运行。如果想为自己的账户允许脚本,可以使用Set-ExecutionPolicy -Scope CurrentUser RemoteSigned(该设置会一直保留,直到你改回) npx @3minapi/cli <command>无需安装即可运行- 更新使用同一条命令:
npm install -g @3minapi/cli 3minapi doctor会检查 Node.js、配置、令牌、网络和代理设置,并告诉你需要修复什么。在代理后面时,请设置NODE_USE_ENV_PROXY=1
快速开始
与 本地 标签上的设置卡片顺序相同。
npm install -g @3minapi/cli
3minapi init
3minapi worker new hello
3minapi worker run hello --input '{"message":"hi"}'
3minapi login
3minapi start
3minapi init在~/3minapi创建项目(3minapi init <folder>可指定位置)。之后在任何文件夹中都能使用命令3minapi worker new hello根据模板创建workers/hello.mjs。先修改描述,再修改 handler3minapi worker run hello --input '…'在你的电脑上运行一次 — 不创建任务,不产生 API 调用。反复运行直到结果正确- 仪表盘 → 任务 → 本地 →
添加主机,复制令牌,然后运行3minapi login并在提示时粘贴 3minapi start把你的 Worker 文件注册为本地 Worker 并运行它们的任务。现在 AI 会在worker_list中以kind: "local"看到它们
如果没有任何 Worker 文件,start 会立即退出。
命令
所有命令都可以在任何文件夹中运行。--json 输出机器可读格式;3minapi help <command> 显示所有参数。
主机
| 命令 | 作用 |
|---|---|
3minapi init [folder] |
创建主机的项目。可以重复运行。没有终端时需要 --yes;--move 用于移动项目 |
3minapi login |
保存主机令牌(输入时隐藏)。脚本中可用 --with-token 从 stdin 读取 |
3minapi logout |
仅从这台电脑删除已保存的令牌 |
3minapi start |
注册 Worker 文件并运行其任务,直到停止。--mode poll 会改为按间隔获取,而不是默认的实时模式。按 Ctrl+C 停止 |
3minapi start --detach |
同上,但在后台运行。重启电脑后不会自动启动 |
3minapi reload |
让正在运行的 start 重新读取 Worker 文件并注册。正在运行的任务继续执行。1 次调用 |
3minapi stop |
停止这台电脑上的 start,无论它是从哪里启动的 |
3minapi status |
start 是否在运行、本地 Worker、重复任务、剩余额度。1 次调用 |
3minapi logs [-f] |
CLI 自身的日志 — 获取、停止、错误 |
3minapi doctor |
环境检查。不发送令牌,不消耗额度 |
3minapi paths |
项目文件和 CLI 自身文件夹的绝对路径 |
Worker
| 命令 | 作用 |
|---|---|
3minapi worker new <name> [--ts] |
创建 workers/<name>.mjs(加 --ts 则为 .mts)。如果 start 正在运行会立即注册(--no-reload 跳过) |
3minapi worker run <name> --input '<json>' |
在本地运行一次。--input-file <file> 可避免 Windows 上的 shell 引号问题 |
3minapi worker list |
项目中的 Worker,并逐个检查能否加载。不产生 API 调用 |
3minapi worker logs <name> [-f] |
单个 Worker 的日志:ctx.log、控制台输出、带堆栈跟踪的错误 |
3minapi worker delete <name> |
从 3Min API 删除该本地 Worker 及其任务历史,然后删除文件。无法撤销 |
结果与历史
| 命令 | 作用 |
|---|---|
3minapi worker results list |
已保存的结果,最新的在前。--worker、--since、-n |
3minapi worker results show <task_id> |
完整显示一条已保存的结果。--run <n> 用于重复任务的某次运行 |
3minapi worker results runs <task_id> |
重复任务的各次运行 |
3minapi worker results describe <task_id> |
一条结果包含的路径。--worker <name> 按结构对 Worker 的结果分组 |
3minapi worker results query "<SQL>" |
对已保存结果执行只读 SQL。不产生 API 调用 |
3minapi worker results prune --before <date> |
从 data.db 删除该日期之前的已保存结果 |
3minapi tasks prune --before <date> |
删除这台主机上该日期之前已结束任务的记录。最近的和未结束的任务会保留 |
3minapi dashboard |
在浏览器中打开只读页面:运行记录、结果、Worker、日志。无需登录,不产生 API 调用 |
dashboard --detach在后台持续运行;dashboard url再次显示链接;dashboard stop结束它dashboard --lan还会通过明文 HTTP 向你网络中的其他设备提供页面。只在你信任的网络中使用- 破坏性命令和
--lan会要求确认。 没有终端(或使用--json)时需要--yes
编写 Worker
workers/ 中的一个文件就是一个 Worker,以文件名命名。
- 名称:小写字母、数字、
_和-,最多 50 个字符,不能以_开头,不能是 Windows 设备名(con、aux等)。在你的所有 Worker 中唯一(包括公共 Worker 和你其他电脑上的 Worker),不区分大小写 .mjs(默认)或.mts/.ts— TypeScript 无需构建即可运行(不支持enum和namespace)
// workers/rename_photos.mjs
export const description =
'Renames the photos in a folder by the date taken. input: { folder: string }';
export const timeoutMs = 10 * 60_000; // 可选 — 默认 60 秒,最长 23 小时
export async function handler(input, ctx) {
await ctx.report('Scanning the folder'); // 进度 — task_get 可以看到
if (ctx.signal.aborted) return; // 已取消,或即将超时
// … 实际工作 …
return { renamed: 42 }; // → completed;这就是结果
// throw new Error('Folder not found') // → failed;消息即为错误
}
| 导出 | 规则 |
|---|---|
description |
必填。AI 在 worker_list 中看到的内容,最多 500 个字符。请在这里写明输入结构 |
timeoutMs |
可选。默认 60 秒,最长 23 小时 |
inputSchema |
可选。JSON Schema 的一个小子集(type、properties、required、enum、items),只在你的电脑上检查 |
handler |
必填。async (input, ctx) => result |
ctx |
说明 |
|---|---|
ctx.report(message) |
进度消息,超过 256 个字符会被截断。每次 1 次调用 |
ctx.log(message) |
只写入 Worker 日志 |
ctx.env |
系统环境变量 + 项目的 .env(.env 优先)。以 THREEMINAPI_ 开头的变量会被移除 |
ctx.signal |
在取消或超时时触发的 AbortSignal |
| handler 的结束方式 | 任务变为 |
|---|---|
return value |
completed。返回值必须是 JSON |
throw |
failed。消息(含 cause),令牌会被遮盖,超过 4,000 个字符会被截断。堆栈留在本地日志中 |
| 超时 | failed(timeout) |
| 取消 | 触发 ctx.signal;2 秒后结束运行。其返回值不会被发送 |
- 应用修改:handler 代码和
.env的修改从下一个任务开始生效。添加或重命名文件、修改描述需要运行3minapi reload(或等下次start);worker new会自动 reload - 删除文件不会从 3Min API 删除该 Worker — 它的任务会失败。请使用
3minapi worker delete <name> - 密钥(你自己的 API 密钥)放在项目的
.env中,.gitignore已经包含它。请以 UTF-8 保存(UTF-16 会被拒绝) - 同一任务可能到达两次(at-least-once)。有副作用的 Worker 应能承受重复执行
- 结果的顶层含有
_3minapi键时,会以reserved_result_key失败 - 你的 Worker 可以在
data.db中保存自己的数据:用node:sqlite打开new URL('../data.db', import.meta.url)。以_3minapi_开头的表属于 CLI — 只能读取
从 AI 运行
start 运行后,像平常一样向 AI 提出请求即可 — 无需知道工具名称。
- “把 D:\Photos\2026 中的照片按日期重命名”
- “每分钟查一次 BTC 价格,共 10 次”
- “停止价格查询”
AI 会依次使用 worker_list → task_create → task_get。任务在 3Min API 上等待,直到 CLI 取走它——以实时模式(默认)运行的 CLI 收到通知后取走,定期检查模式则在下一次检查时取走。在此之前 task_get 显示 delivery: "pending",之后显示 "delivered"。
重复任务
仅限本地 Worker:task_create 接受 repeat,按固定间隔用相同的输入运行 — 一个任务,所有运行共用一个任务 ID。
{
"worker": "price-feed",
"input": { "symbol": "BTC" },
"repeat": { "interval_seconds": 60, "max_runs": 10 }
}
| 字段 / 规则 | 值 |
|---|---|
interval_seconds |
10 到 604,800(7 天)。下一次到期时上一次仍在运行,则跳过这一次 |
max_runs |
可选。省略时会一直重复,直到取消 — 让 AI 取消即可停止 |
| 状态 | 保持 working;repeat 显示 runs、failed 和 last_run_at。最后一次运行后变为 completed,附带摘要 |
| 失败 | 某次运行失败不会停止重复。连续 5 次运行失败 → failed(repeat_failed) |
| 费用 | 除 CLI 接收任务所用的调用之外,每次运行计 1 次调用。每分钟一次且不设结束 ≈ 每月 43,200 次 |
| 修改 | 取消后重新创建 |
| CLI 未运行时 | 暂停。24 小时加一个间隔内没有任何运行报告 → failed |
| 公共 Worker | 不允许 — repeatRequiresLocalWorker |
每次运行的结果都作为单独的一行保存在你的电脑上(run_no 1、2、…)。
读取结果
所有结果都保存在你电脑上的 data.db 中。 约 100 KB 以内的结果也会发送到 3Min API,并通过 task_get 传给 AI。更大的结果不会发送:任务以 result._3minapi 中的替代内容完成(stored_locally: true、任务 ID、大小、shape 摘要和 reader 名称)。
AI — 通过主机的结果读取器读取。它是名为 _results_ + 主机 ID 后 8 个字符的内置本地 Worker。worker_list 把它列在 hosts 中该主机的 results_reader 下,而不是 Worker 列表中。它在你的电脑上完成计算,只返回答案。下面的 task_result_* 工具会把每一步交给它,并根据给定的 task_id 或 worker 选择电脑,因此 AI 无需知道它的名称。
| 顺序 | 工具 | 用途 |
|---|---|---|
| 1 | task_result_describe (task_id 或 worker) |
先了解结构。 结果中不存在的路径读作 NULL,结构混杂时求和会出错 |
| 2 | task_result_query (sql, worker) |
对视图 results 执行只读 SQL。聚合后只返回答案 |
| 3 | task_result_read (task_id, path, offset) |
约 90 KB 的原始数据片段,仅在确实需要原始数据时使用 |
- 每个读取器任务至少消耗 4 次调用,并等待 CLI 取走它
- 读取器在
start运行且至少有一个 Worker 文件时注册
你自己 — 使用 3minapi worker results list/show/describe/query 或 3minapi dashboard。data.db 不会自动清理,请使用 worker results prune。其中可能包含个人信息。
让 AI 运行 CLI
有些 AI 客户端在你允许后可以在你的电脑上运行命令 — 例如 Claude Code、Codex 等编码代理,以及部分桌面应用。另一些则不能,例如网页版 ChatGPT:请自己运行命令,再把输出粘贴回对话。
| AI 可以做的 | AI 不应触碰的 |
|---|---|
编辑 workers/*.mjs(描述、handler)和 3minapi.json |
主机令牌 — 绝不能出现在对话或命令行中(3minapi login 会提示输入) |
运行 worker new、worker run、reload、status、doctor、logs、worker results … |
CLI 自身的文件夹(credentials.json、control.db)— 见 3minapi paths |
先询问位置,再运行 init <folder> 或 init --yes |
data.db 中以 _3minapi_ 开头的表 |
- 没有终端时,破坏性命令需要
--yes,因此--yes就是唯一的确认。运行worker delete --yes之前请先征得用户同意 — 它会删除 Worker 及其任务历史 --json输出 AI 可解析的格式。错误以{ "error": { "kind", "message", "exitCode", "code"?, "resetAt"? } }返回。因配额停止且已知重置时间时,还会带有resetAt
主机与令牌
| 情况 | 怎么做 |
|---|---|
| 多台电脑 | 每台电脑添加一个主机。一台电脑 = 一个主机 = 一个项目。不同电脑上的 Worker 名称必须不同 |
| 令牌丢失或泄露 | 在主机页面轮换令牌。旧令牌立即失效,使用它的 CLI 会停止 |
| 迁移到另一台电脑 | 轮换令牌 → 复制项目文件夹 → 用新令牌运行 3minapi login → 3minapi start。Worker 和历史都会保留 |
| 删除主机 | 会删除其本地 Worker 及其任务历史。仅在想重新开始时使用;正在运行的 CLI 会停止 |
| 移动文件夹 | 3minapi stop → 移动 → 在文件夹内运行任意命令,或运行 3minapi init <folder> --move |
主机页面显示 CLI 接收任务的方式(实时或定期检查)、最近一次连接或检查、检查间隔(仅定期检查)、并发数、版本和平台 — 这些是 CLI 上报的事实,不是当前状态。
限制与额度
| 项目 | 值 |
|---|---|
| 本地 Worker | 所有方案均无限制 |
| 接收(实时,默认) | 保持连接本身不产生调用。 每次连接或重连计 1 次,之后的补取获取再计 1 次,收到任务或取消通知而获取时每次计 1 次。连接会因网络原因每天断开几次并自动重连,所以即使没有任务也会用掉一些调用——每天断开 6 次约为每天 12 次、每月 360 次 |
| 接收(定期检查) | 即使没有等待的任务,每次获取也计 1 次调用。 默认每 60 秒一次 ≈ 每天 1,440 次 ≈ 每月 43,200 次 |
| 其他调用 | 每次接收确认 1 次,每次报告 1 次(ctx.report 和最终结果),每次重复运行 1 次,每次 reload/status 1 次 |
| 并发运行 | concurrency,默认 4(1–50)。每次获取最多 concurrency 个任务 |
| 期限 | 创建后 24 小时内未被取走 → failed(每小时检查一次,最长约 25 小时) |
| 任务历史 | 付费方案至少 60 天。Free 方案在 Worker 注册 7 天后删除本地 Worker 及其运行记录;reload 或下次 start 会重新注册 |
| 额度用完 | CLI 自行停止(退出码 5),不会重启。报告永远不会被阻止 |
| 发送到 3Min API 的结果 | 约 100 KB;更大的结果留在你的电脑上(发送替代内容) |
| 本地日志 | 默认保留 30 天 / 300 MB(logRetentionDays、logMaxBytes) |
如需减少调用,请使用默认的实时模式。如果网络环境需要定期检查,可以在 3minapi.json 中调大 pollIntervalMs(任务会更晚被取走)并重启。
concurrency 个任务全部在运行时,CLI 不会取走新任务——这些任务保持 pending(仍会收到取消通知)。由此决定的处理量会显示在 3minapi start 和 3minapi status 中。
状态与故障排除
是否在运行? 请在那台电脑上用 3minapi status 确认。网页上的 CLI 接收,以及 worker_list 告诉 AI 的最近检查或连接,都是过去的事实,不是当前状态。
| 现象 | 原因与解决方法 |
|---|---|
任务一直是 working 且 delivery: "pending"(网页上显示 等待电脑) |
CLI 还没有取走它。在那台电脑上运行 3minapi start |
3minapi start 提示无法打开实时连接 |
公司的代理或防火墙阻止了它。用 3minapi doctor 检查;以 --mode poll 启动(或设置 receiveMode: "poll")即可按间隔获取 |
Not picked up within 24 hours — the 3Min API CLI on the user's PC did not fetch it. |
CLI 关闭了 24 小时。启动它并重新发送任务 |
No run was reported for 24 hours — the 3Min API CLI on the user's PC stopped running it. |
重复任务失去了运行它的 CLI。启动 CLI 并重新创建任务 |
Worker did not respond within 24 hours. |
CLI 已取走但始终未回报结果的本地任务——崩溃后电脑一直未开机。不会再次运行 |
以 host_stopped 失败 |
运行期间你停止了 CLI(Ctrl+C 或 stop)。重复任务只会失去那一次运行 |
以 host_restarted 失败 |
电脑或 CLI 在任务中途终止。无法确定是否已执行,并且不会重新执行 |
| AI 按旧的结构发送输入 | 修改了描述但没有运行 3minapi reload |
worker_list 中没有某个 Worker |
新文件没有 reload、加载错误(3minapi worker list),或 Free 7 天删除(reload) |
CLI 以 worker_name_taken 拒绝某个名称 |
另一个 Worker(公共 Worker 或其他电脑上的 Worker)已使用该名称。请重命名文件 |
| CLI 以退出码 4 或 5 退出 | 4:令牌无效或没有方案 — 重新 login。5:本月额度已用完 |
退出码
| 代码 | 含义 |
|---|---|
| 0 | 正常 |
| 1 | 失败 |
| 2 | 用法错误(包括缺少 --yes) |
| 3 | 环境或配置错误 |
| 4 | 已停止:令牌无效,或账号没有方案(Free 也算一种方案) |
| 5 | 已停止:本月额度已用完 |
| 130 | 被中断(Ctrl+C) |
退出码为 4 或 5 后,不会自动重启。
本地 Worker 任务失败时的 error.data.reason
| 原因 | 含义 |
|---|---|
handler_error |
handler 抛出了错误 |
timeout |
运行超过了 timeoutMs |
invalid_input |
不符合 inputSchema — 未运行 |
invalid_worker |
文件存在但无法使用 — 没有 handler、名称重复或导入错误 |
worker_not_found |
那台电脑上没有该文件 |
unsupported_syntax |
CLI 无法在不构建的情况下运行的 TypeScript(例如 enum) |
result_too_large |
超过约 100 KB,且无法保存在电脑上 |
reserved_result_key |
结果的顶层含有 _3minapi 键 |
host_stopped |
运行中途 CLI 被停止 |
host_restarted |
运行中途电脑或 CLI 终止;在下一次 start 时报告 |
repeat_failed |
重复任务连续 5 次运行失败 |
协议摘要
CLI 与 3Min API 如何协作,供参考。
投递
- Pull:实时模式下 CLI 保持连接,收到通知时(以及每次连接后一次)向 3Min API 请求等待中的任务;定期检查模式下每隔
pollIntervalMs请求一次。两种方式都只取当前能运行的数量 - Ack:立即确认接收(
delivery变为"delivered")。60 秒内未确认时任务会再次发出 — 最多 6 次,之后failed - At-least-once:同一任务可能到达两次
- 取消:实时模式通过通知传达,定期检查模式在下一次获取时通知 →
ctx.signal。任务保持cancelled - 报告:进度和最终结果用主机令牌发回。因网络失败的报告会重试,最长 24 小时
大小
| 项目 | 限制 |
|---|---|
input |
100 KB |
| 发送的结果 | 约 100 KB(100 KiB 减去 1 KiB 的信封) |
ctx.report |
256 个字符 |
| 错误消息 | 4,000 个字符 |
| Worker 描述 | 500 个字符 |
| Worker 名称 | 50 个字符 |
3minapi.json(优先级:参数 > 环境变量 > 项目文件 > 默认值)
| 键 | 默认值 | 范围 | 环境变量 |
|---|---|---|---|
workersDir |
workers |
项目内 | — |
receiveMode |
live |
live 或 poll |
THREEMINAPI_RECEIVE_MODE |
pollIntervalMs |
60000 | 5000–3600000(仅定期检查模式) | THREEMINAPI_POLL_INTERVAL_MS |
concurrency |
4 | 1–50 | THREEMINAPI_CONCURRENCY |
localServerPort |
3180 | 1024–65535 | THREEMINAPI_LOCAL_SERVER_PORT |
logRetentionDays |
30 | 1–365 | THREEMINAPI_LOG_RETENTION_DAYS |
logMaxBytes |
300 MB | 10 MB–1 GB | THREEMINAPI_LOG_MAX_BYTES |
修改 receiveMode、pollIntervalMs 或 concurrency 需要重启。未知的键只会产生警告。
文件夹 — 3minapi paths 会显示它们。
| OS | 令牌和设置 | 控制数据库和日志 |
|---|---|---|
| macOS | ~/Library/Application Support/3minapi |
~/Library/Application Support/3minapi、~/Library/Logs/3minapi |
| Windows | %APPDATA%\3minapi |
%LOCALAPPDATA%\3minapi |
| Linux | $XDG_CONFIG_HOME/3minapi(~/.config) |
$XDG_STATE_HOME/3minapi(~/.local/state) |
令牌保存在这些文件夹中,而不是项目中,因此复制项目不会复制令牌。
隐私说明
- Worker 的
result和error会原样进入 AI 对话。只返回需要的内容 data.db会在你的电脑上保留所有结果(包括其中的个人信息),直到你清理它