Skip to main content
Glama

polyflow

智能体已经可以恢复已暂停的运行。但它无法告诉你恢复后的运行被允许做什么。

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-approval

test/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 record
  • Kiro / 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

含义

默认值

POLYFLOW_WORKFLOWS

工作流库目录

./workflows

POLYFLOW_DB

sqlite 路径

.polyflow/polyflow.sqlite

POLYFLOW_AGENT

智能体类区域

default

POLYFLOW_INSTANCE

实例区域(工作区)

cwd 基名

POLYFLOW_POLYRUN

polygraph 检出

../polygraph

工具

工具

作用

workflow_list

该智能体知道如何做什么,以及每个工作流被接纳时附带的保证

workflow_start

启动或重新附加——运行的标识从已验证的输入派生,因此夜间任务会恢复而不是重启,智能体也无法通过重命名来获得第二次运行

workflow_report

报告工具结果,接收下一个指令

workflow_state

状态 + 未完成指令,不改变任何内容

workflow_signal

带外事件;不适用的操作是可观察的拒绝

workflow_journal

每一步,接受或拒绝,附原因——也是有效的 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

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Durable agent-to-agent handoffs and shared scratchpad for multi-agent workflows.

  • Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.

  • Build, validate, and deploy multi-agent AI solutions from any AI environment.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cognitive-fab/polyflow'

If you have feedback or need assistance with the MCP directory API, please join our Discord server