polyflow
Officialpolyflow
智能体已经可以恢复已暂停的运行。但它无法告诉你恢复后的运行被允许做什么。
polyflow 是一个面向 AI 智能体的工作流引擎。智能体推理的是工作流,而不是下一个工具调用;polyflow 仅在该工作流通过模型检查后才予以接纳,然后持久地运行它,并一次向智能体下发一个工作指令。
它以 MCP 服务器形式发布,因此任何支持 MCP 的智能体——OpenWorker、Claude Code、Cursor——都可以使用它,而无需修改该智能体的核心。
实验性、未经证实、未经同行评审。该检查是一致性检查,而非证明,并且“穷尽”始终意味着在契约声明的有限域内穷尽。每个发现都是线索,而非结论。
循环
tools → observe → reason → WORKFLOW ──▶ polyflow admits it (or refuses)
│
┌───────────────────┘
▼
one work order → the agent runs the tool, through its own
permission gates, with its own credentials
→ workflow_report
→ next work order … until terminal智能体从不决定接下来发生什么。它只推理如何完成一个指令——而这正是模型真正擅长的——并报告结果。排序、重试、定时器、重复抑制和终止条件都属于机器。
Related MCP server: nano-vm-mcp
为什么这样做,而不是常驻授权
如今,无人值守的自动化按动词获得批准:“允许 slack_send 到 #cs”,永远有效,无论模型决定用它做什么。当计划是每次运行都重新规划的散文式指令字符串时,这就是上限。
polyflow 批准的是计划。workflows/customer-brief/effect-invariants.mjs 保存了用户实际可以同意的句子:
{ name: 'no-post-without-prior-approval',
pred: (path) => path.emitted.every((e, i) =>
e.kind !== 'post_brief' || path.actionBefore('APPROVED', i)) }启动时枚举契约声明域内每条可达的发射路径并检查它们。未通过的工作流不会被注册——不是被标记,而是不可运行:
[polyflow] admitted: customer-brief — paths explored: 5 · states seen: 10 · exhaustive within declared domains
[polyflow] REFUSED: unsafe-brief
[polyflow] no-post-without-prior-approvaltest/fixtures/unsafe-brief 是刻意制造的损坏孪生:它在进入审核时、在人类回答之前就发帖。它仍然调用 ask_user,仍然针对同一频道,仍然满足常驻授权。阅读 diff 的审查者很容易漏掉它。而门禁不会。
快速开始
npm install # pulls polygraph (polyrun) as a dependency
npm test # 14 tests, no API key, deterministic
node bin/polyflow-mcp.mjs # MCP stdio server与 OpenWorker 一起运行
先决条件: Node 22+(polyflow 使用 node:sqlite),并且已安装 OpenWorker。polyflow 本身不需要 API 密钥——它从不调用模型。
1. 注册它。 从 polyflow 目录:
node bin/polyflow-install.mjs --agent openworker/cowork --workspace acme
# --print shows the entry and the target path without writing anything这会将 polyflow 条目合并到 OpenWorker 的全局 mcpServers 文件中——与 Connectors 页面编辑的是同一个文件(Windows 上为 %APPDATA%\coworker\mcp.json,其他系统为 ~/.config/coworker/mcp.json,$COWORKER_STATE_DIR 可覆盖两者)。它是合并而非替换,并且拒绝触碰无法解析的文件。
2. 重启 OpenWorker。 没有需要启动或监督的 polyflow 守护进程:OpenWorker 在会话打开时通过 stdio 生成 bin/polyflow-mcp.mjs,并在会话结束时将其拆除。运行状态保存在 POLYFLOW_DB 处的 SQLite 文件中,因此两者都能存活。
3. 检查它是否启动。 六个工具以 mcp__polyflow__* 形式出现。让智能体*“列出你可以运行的工作流”*——它应该返回 customer-brief、其 admitted: true,以及它被接纳时附带的五项保证。如果没有,Connectors 页面会显示持续错误,服务器的启动行(admitted: / REFUSED:)会输出到 stderr。
4. 使用它。 无需特殊操作:给智能体一个工作流覆盖的任务,它会自行拾取该工作流——这正是 FINDINGS-phase3.md 所衡量的。要为其安排定期任务,请创建一个普通的 OpenWorker 自动化,其指令描述该任务;工作流会在每次触发时按派生键重新附加,而不是重新开始。
区域。 --agent 是智能体类区域(这类智能体使用哪个工作流库),--workspace 是实例区域(这些运行属于谁)。一个 polyflow 安装可以服务多个工作区——为每个工作区注册一次,使用不同的 --workspace,指向相同的 POLYFLOW_DB 以共享存储,或使用不同文件以保持隔离。
添加你自己的工作流。 复制 workflows/customer-brief/ 并编辑六个文件(见下文 工作流)。重启服务器:未通过发射检查的工作流会在启动时被拒绝,并且根本无法启动,因此错误的编辑会响亮地失败,而不是在凌晨 3 点失败。
权限。 安装的条目有意设置 requires_approval: false——polyflow 工具不会触及机器之外的任何东西,运行的真实副作用是智能体自己的工具,这些工具保留自己的门禁。每次 workflow_report 都弹出提示会在智能体与其自身记账之间放置一个对话框。该条目还为只读工具声明了 tool_risk,在应用 upstream/0001-mcp-per-tool-risk-level.patch 时会被尊重,没有它则被无害地忽略。
polyrun 从何而来。 polyflow 在进程中嵌入 polyrun,从 node_modules/polygraph 解析,然后是同级检出;POLYFLOW_POLYRUN 可覆盖两者。
其他智能体宿主
polyflow 是一个普通的 MCP stdio 服务器,因此任何支持 MCP 的东西都可以使用它。安装程序为每个宿主写入正确的文件:
node bin/polyflow-install.mjs --host kiro # ~/.kiro/settings/mcp.json
node bin/polyflow-install.mjs --host kiro --scope workspace # ./.kiro/settings/mcp.json
node bin/polyflow-install.mjs --host claude-code # ./.mcp.json
node bin/polyflow-install.mjs --host generic # prints the entry, writes nothing两个宿主形状不同,会打印而不是写入:
node bin/polyflow-install.mjs --host nemo # YAML for a NeMo Agent Toolkit workflow
node bin/polyflow-install.mjs --host registry # AWS CLI call to publish an Agent Registry recordKiro / Kiro Crew 从
~/.kiro/settings/mcp.json(用户)或.kiro/settings/mcp.json(工作区,名称冲突时工作区优先)读取mcpServers。Kiro Crew 的定期无人值守任务与 OpenWorker 的定时任务形状相同,这正是FINDINGS-phase3.md中结果所涉及的情况。NVIDIA NeMo Agent Toolkit 通过其
mcp_client函数组连接(需要nvidia-nat-mcp)。打印的块声明了该组并将其添加到工作流的tool_names中。NeMo 本身也可以作为 MCP 服务器运行,因此 NeMo 工作流可以成为 polyflow 工作指令命名的工具之一。AWS Agent Registry 是目录而非运行时:发布记录可让组织中的其他人和其他智能体发现 polyflow。记录可以从 HTTPS 端点同步,而 stdio 服务器无法提供该端点,因此打印的命令会创建手动 MCP 记录。
只有 OpenWorker 路径经过了端到端测试(见 FINDINGS-phase2.md)。其他路径是根据每个宿主的文档化配置格式构建的,尚未运行。
无论使用哪个宿主,环境变量如下:
env | 含义 | 默认值 |
| 工作流库目录 |
|
| sqlite 路径 |
|
| 智能体类区域 |
|
| 实例区域(工作区) | cwd 基名 |
| polygraph 检出 |
|
工具
工具 | 作用 |
| 该智能体知道如何做什么,以及每个工作流被接纳时附带的保证 |
| 启动或重新附加——运行的标识从已验证的输入派生,因此夜间任务会恢复而不是重启,智能体也无法通过重命名来获得第二次运行 |
| 报告工具结果,接收下一个指令 |
| 状态 + 未完成指令,不改变任何内容 |
| 带外事件;不适用的操作是可观察的拒绝 |
| 每一步,接受或拒绝,附原因——也是有效的 Polygraph 轨迹语料库 |
区域
两个层级,不需要在 OpenWorker 中添加新字段:
智能体区域 — 每个智能体类一个(
openworker/cowork)。拥有工作流库:这类智能体知道如何做什么。映射到ScheduledTask.agent。实例区域 — 每个正在运行的副本一个(
workspace)。拥有活动运行及其日志。映射到workspace,它已经是coworker.memory.Scope.WORKSPACE。
实例 id 从 agent | instance | workflow | key 派生,这就是为什么启动和附加是同一个调用。
工作流
目录中的六个文件:
polyflow.workflow.json name, area, tools{effect kind -> agent tool},
key{template,fields} — the run's identity, derived
contract.json states, actions, finite data domain
machine.cjs SAM v2 strict-profile module
effects.cjs pure mapper: transition -> work orders
effects.manifest.json completion actions + retry policy per kind
effect-invariants.mjs what may be EMITTED, on every reachable path使这对智能体有效的反转:在 polyrun 中,运行时执行效果。polyflow 没有凭据、没有连接器、没有权限引擎——智能体三者都有。因此,效果是交回的工作指令。处理器暂停;智能体认领指令,在其自己的门禁下运行工具,并报告。只有在那之后,完成动作才会分发。
持久性来自租约机制。待处理映射在内存中,因此崩溃会丢失 promise,租约过期,效果被重新认领,指令被重新提供——相同的意图 id,至少一次,由机器吸收。
测试证明了什么
✔ the admission gate certifies the demo workflow exhaustively
✔ workflow_list reports the guarantees the run was admitted under
✔ happy path: one order at a time, ending posted
✔ the run key is derived from input, not chosen by the caller
✔ an invalid key field is refused with an instruction, not honoured
✔ a finished run says so, and says not to start another
✔ start is idempotent: re-attaching returns the run in progress
✔ a denial is a result, not a fault — and no post is ever ordered
✔ zero tickets ends the run rather than posting an empty brief
✔ a duplicate report is refused, not double-executed
✔ an out-of-band action that does not apply is an observable reject
✔ a workflow that can post before approval is REFUSED and cannot be started
✔ a run outlives the process: restart re-offers the open work order
✔ initialize, tools/list, tools/call over stdio重启测试才是关键:会话 1 将运行驱动到审批步骤然后死亡;会话 2 是另一个进程,没有对话、没有转录、没有重放——因为状态从一开始就不在消息中。它从原处精确地拾取运行,并且两个会话中恰好发生一次发帖。
尚未构建
提升。 工作流在这里是手工编写的。计划是从日志中挖掘重复的运行形状,并提出一个机器供审查——从历史归纳,而非预见。除非被重用,否则为每个任务编写机器的成本高于它所替代的工具调用。
版本控制。 polyvers 将更改后的工作流与进行中的运行进行门控;尚未接入。
审计。 日志已经是轨迹语料库;针对它的
polyrun audit尚未接入。需要核心更改的 OpenWorker 接缝: 将暂停的指令路由到收件箱,以及
ScheduledTask上的workflow_ref。见FINDINGS-phase0.md。
This server cannot be deployed
Maintenance
Related MCP Connectors
Durable background job execution, async task scheduling, and state persistence for AI agents.
Durable agent-to-agent handoffs and shared scratchpad for multi-agent workflows.
Hosted runtime for persistent agent teams, durable workflows, memory, schedules, and goals.
Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables AI coding agents to execute formal, stateful workflows with typed contracts, postcondition enforcement, and structured retry logic.1-
- AlicenseAqualityBmaintenanceGoverned agent execution gateway for LLM workflows, providing deterministic FSM-based execution, audit trails, and idempotency guarantees via MCP.5MIT
- FlicenseNot gradedqualityDmaintenanceLease governed AI agent instances without hand-built runner queues.-
- AlicenseNot gradedqualityCmaintenanceProvides durable queues, human-in-the-loop approval gates, and an audit trail for AI agent fleets, enabling blocking approval requests and reliable work handoffs.2 npmMIT