菜单路径: 仪表盘 > 任务 > 本地

本地 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 上是 终端(应用程序 → 实用工具)。

  1. Node.js 24.12 或更高版本。 node -v 显示版本。如果没有安装或版本较旧,请从 nodejs.org 安装 LTS 版(Windows 上也可以用 winget install OpenJS.NodeJS.LTS),然后打开一个新的终端
  2. 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
  1. 3minapi init 在 ~/3minapi 创建项目(3minapi init <folder> 可指定位置)。之后在任何文件夹中都能使用命令
  2. 3minapi worker new hello 根据模板创建 workers/hello.mjs。先修改描述,再修改 handler
  3. 3minapi worker run hello --input '…' 在你的电脑上运行一次 — 不创建任务,不产生 API 调用。反复运行直到结果正确
  4. 仪表盘 → 任务 → 本地 → 添加主机,复制令牌,然后运行 3minapi login 并在提示时粘贴
  5. 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 会在你的电脑上保留所有结果(包括其中的个人信息),直到你清理它