Statewright 完全指南:用可视化状态机让 AI Agent 更可靠
发布: 2026-05-13 • 阅读: 12 分钟 • 标签: AI Agent, 状态机, LLM 可靠性, Statewright, 可视化工作流, MCP, Agent 控制流
- 是什么: Statewright — 开源可视化状态机工具 用确定性状态转换约束 AI Agent 的行为
- 数据: Hacker News 70+ 分 在 SWE-bench 子集测试中 两模型从 2/10 提升到 10/10
- 核心理念: 与其把模型做大 不如把问题做小 — 状态机限制 Agent 的工具和动作空间
- 底层引擎: Rust 构建 零 LLM 参与 纯确定性逻辑
- 支持平台: Claude Code / Codex / Cursor / opencode / Pi 通过 MCP 插件层集成
- 可视化编辑: 拖拽式工作流编辑器 非开发者也能用
问题:AI Agent 天生不可预测
用 LLM 构建 Agent 的人都懂一个扎心事实:每条 prompt 都是"建议"而不是"命令"。给模型 40+ 个工具和一个开放式任务,它大概率还在原地打转 — 同一个文件反复读 5 遍以上 调工具的顺序乱七八糟 "验证"了自己的输出然后返回幻觉 自作聪明跳过你标注"MANDATORY"的步骤
这不是 LLM 的错 这是架构问题 LLM 是生成式的 — 它产出的是"合理的延续" 不是"保证正确的输出" 当你给 LLM 自由选择工具 自由决定执行顺序 自由判断什么时候该做什么的时候 你实际上在赌那个还不存在的 alignment
常规解法是什么?换更大的模型 堆更长的 prompt 有时候管用 可观测性工具能告诉你哪里出了问题 但无法阻止问题发生 那么 与其把模型做大 不如把问题做小?
解法:用状态机构建守卫护栏
这就是 Statewright 的切入点 它有一句精辟的标语:"Agent 是建议 状态机是法律"(Agents are suggestions, states are laws)
有限状态机(FSM)是软件工程里最可靠的工具之一 它定义一组状态、合法的转换路径、每个状态下可执行的动作 关键性质:状态转换是确定性的 机器不会"猜测"下一步做什么 — 它严格遵循你定义的规则
Statewright 把这个原则应用到了 AI Agent 上 不是让 LLM 自己决定调什么工具、按什么顺序调 而是你定义一个状态机 在每个阶段限制可用的工具、命令和动作 LLM 只能在当前状态允许的范围内操作 需要切换阶段时触发状态转换 — 如果条件满足的话
效果:Agent 只看到 5 个工具而不是 30 个 当前阶段有明确指令 对"能做什么不能做什么"没有任何歧义 模型用更少的 token 完成任务 小模型(13B+)开始解决它们原本搞不定的任务
Statewright 的工作原理
Statewright 分两层 底层是一个 Rust 引擎 负责评估状态机定义 它是确定性的 — 完全不依赖 LLM 上层是一个插件层 通过 MCP(Model Context Protocol)与你的编码 Agent 集成 激活工作流后 hooks 自动按状态强制实施工具限制
下面是一个 bug 修复工作流的 JSON 定义示例:
{
"id": "bugfix",
"initial": "planning",
"states": {
"planning": {
"allowed_tools": ["Read", "Grep", "Glob"],
"max_iterations": 8,
"on": { "READY": "implementing" }
},
"implementing": {
"allowed_tools": ["Read", "Edit", "Write"],
"max_edit_lines": 20,
"max_files_per_state": 3,
"on": { "DONE": "testing" }
},
"testing": {
"allowed_tools": ["Read", "Bash"],
"allowed_commands": ["pytest", "cargo test", "npm test"],
"on": {
"PASS": { "target": "completed", "guard": "tests_passed" },
"FAIL_TEST": "implementing"
}
},
"completed": { "type": "final" }
},
"guards": {
"tests_passed": { "field": "test_result", "op": "eq", "value": "pass" }
}
}
这个工作流中 每个阶段各有明确的职责和限制:
- 规划阶段: Agent 只能读文件(Read / Grep / Glob)不能编辑不能运行代码 先搞清楚问题在哪
- 实现阶段: 编辑工具解锁 但限制每次最多改 20 行 每个状态最多改 3 个文件 禁止破坏性操作
- 测试阶段: 只允许指定的测试命令(pytest / cargo test / npm test)测试失败则回到实现阶段
- 完成: 终态 Agent 无法继续执行任何操作
状态机和有向无环图(DAG)的关键区别在于:状态机会循环和重试 上面的例子中测试失败就把 Agent 送回实现阶段 它能迭代、修复、重新测试 — 这才是 Agent 工作真正需要的 而 DAG 表达不了这种能力
实测数据:模型性能的真实提升
Statewright 团队在 SWE-bench 的 5 个任务子集上做了测试 用本地模型跑 结果很有说服力:
| 模型 | 大小 | Bug 修复 | SWE-bench (5 任务) |
|---|---|---|---|
| gemma3 | 3.3GB | 失败 | 失败 |
| gemma4:e2b | 7.2GB | 通过* | 失败 |
| gpt-oss:20b | 13.8GB | 通过 | 通过 (5/5) |
| gemma4:31b | 19.9GB | 通过 | 通过 (5/5) |
| llama3.3 | 42.5GB | 通过 | 通过 (2/2)† |
* 需要专门的 edit_line 工具适配 † 后续补充测试了 2 个任务
最亮眼的数据:两个模型(13.8GB 和 19.9GB)从 2/10 提升到 10/10 — 相同的任务 相同的硬件 只加了 Statewright 的状态机约束 13GB 以下模型能产生工具调用但记不住足够的文件上下文来做精确编辑 这是模型能力的天花板 不是 Statewright 的局限
对于前沿模型来说 更大的价值在结构性改进:打破"读取循环死螺旋"(模型反复读同一个文件 5 次以上却从不编辑)以及让工具空间足够小 让模型真正去推理而不是瞎撞
守卫护栏列表:Statewright 能强制什么
Statewright 提供了一整套生产级守卫:
- 按状态限制工具 — 不在当前状态
allowed_tools里的工具对 Agent 完全不可见 - Bash 辨别 — 重定向(
>>)、破坏性操作(rm、shred)和脚本解释器在非写入状态下被阻止 - 编辑守卫 — 拒绝超过
max_edit_lines的 diff 限制每个状态可编辑的文件数 - 命令白名单 — 每个状态只允许前缀匹配的命令(如测试阶段只允许 pytest)
- 条件转换 — 基于上下文数据的守卫断言(相等/大于/存在判断)
- 审批关卡 —
requires_approval在高风险转换前暂停等待人工审批 - 环境隔离 — 每个状态可设置
blocked_env和环境变量覆盖 - 会话隔离 — 通过
CLAUDE_SESSION_ID实现每会话独立状态
可视化编辑器:拖拽式工作流设计
Statewright 的一大亮点是 可视化工作流编辑器 在 statewright.ai/workflows 你可以通过拖拽来创建、编辑和可视化状态机工作流 不需要手写 JSON
这对团队意义重大:领域专家(而非开发者)也能定义 Agent 行为 客服主管可以设计客服机器人的工作流 流水线操作员可以可视化规划 ETL 阶段 可视化编辑器自动生成 JSON 定义 再由 Rust 引擎强制执行
对开发者来说 JSON 定义始终是数据源 你可以手写工作流 用可视化编辑器 甚至让 AI Agent 通过 statewright_create_workflow 帮你生成 — 把 JSON schema 丢给它 它就帮你写好工作流定义
实际应用场景
1. 客服机器人
状态路径:识别问题 → 收集上下文 → 提出方案 → 升级(如需)→ 确认解决 每个状态下 LLM 只有一套狭窄的工具:读取知识库文章、查订单状态、起草回复 它不可能意外删用户账号或过早升级 — 因为这些工具在当前状态下根本不存在
2. 数据处理流水线
ETL 工作流:提取 → 校验 Schema → 转换 → 加载 → 验证 LLM 在验证阶段只有读权限 在转换阶段只看到转换工具 必须通过验证才能进入下一阶段 验证失败回退到提取阶段重做
3. 表单填写与文档生成
表单完成 Agent:收集需求 → 起草 → 校验字段 → 人工审核 → 提交 每个状态限制 Agent 能读写的内容 人工审核阶段需要审批才能提交 — 防止提前或错误的表单提交
4. 工作流自动化
复杂业务流程:带分支逻辑 重试循环和升级路径 条件转换让工作流能适应真实世界的情况 — 支付失败就转换到重试状态 重试超限就升级到人工
Statewright vs LangGraph vs Vellum vs Temporal
2026 年的 Agent 编排赛道已经相当拥挤 以下是 Statewright 和主要竞争对手的对比:
| 特性 | Statewright | LangGraph | Vellum | Temporal |
|---|---|---|---|---|
| 可视化编辑器 | ✅ 拖拽式 | ❌ 纯代码 | ✅ 可视化画布 | ❌ 纯代码 |
| 硬性工具强制 | ✅ 协议层 | ❌ 建议性 | ❌ 建议性 | N/A |
| 循环与重试 | ✅ 原生支持 | ✅ 原生支持 | ⚠️ 有限 | ✅ 完善 |
| 确定性引擎 | ✅ Rust(无 LLM) | ⚠️ Python 运行时 | ⚠️ Python 运行时 | ✅ Go/Java |
| 非开发者友好 | ✅ 可视化编辑器 | ❌ 需要 Python | ✅ 低代码 | ❌ 需要 SDK |
| 编码 Agent 专注 | ✅ 主打 Claude Code 等 | ✅ 通用 Agent | ⚠️ Prompt 工程 | ❌ 工作流引擎 |
| 定价 | 免费版(3 工作流) | 开源免费 | 付费 | 开源 + 云服务 |
核心差异: Statewright 在协议层(MCP)硬性拦截工具调用 模型甚至看不到不允许的工具 LangGraph 和 Vellum 只是把指令注入上下文 — 模型仍然可以忽略它们 这是"建议性守卫"和"硬性守卫"的区别
快速上手 Statewright
安装非常简单 特别是 Claude Code 用户:
# 在 Claude Code 中执行:
/plugin marketplace add statewright/statewright
/plugin install statewright
/reload-plugins
# 然后启动 bug 修复工作流:
/statewright start bugfix
这会打开浏览器 在 statewright.ai 注册、生成 API key、粘贴回来 激活后 每个工具调用都会被当前工作流的状态机拦截检查
Statewright 也支持 Codex / opencode / Pi / Cursor(Cursor 因 MCP 架构限制为建议性)各平台集成状态:
| Agent | 集成方式 | 强制类型 |
|---|---|---|
| Claude Code | Hooks + MCP | ✅ 硬性 |
| Codex | Hooks | ✅ 硬性(alpha) |
| opencode | TS 插件 | ✅ 硬性(alpha) |
| Pi | Skills 扩展 | ✅ 硬性(alpha) |
| Cursor | MCP + rules | ⚠️ 建议性(alpha) |
硬性强制指在协议层直接拦截工具调用 模型无法绕过 建议性指在上下文中注入规则但不强制 — 模型理论上仍可能违反
定价
Statewright 的引擎是开源的(Apache 2.0 / FSL-1.1-ALv2)托管云服务负责工作流存储、运行历史记录和 MCP 网关:
| 方案 | 工作流数 | 月转换次数 | 运行历史 | 价格 |
|---|---|---|---|---|
| 免费版 | 3 | 200 | 72 小时 | $0 |
| 专业版 | 10 | 2,500 | 7 天 | $29/月 |
| 团队版 | 30 | 10,000 | 90 天 | $99/月 |
| 企业版 | 不限 | 不限 | 自定义 | 联系销售 |
个人开发者可以在 FSL 许可下自托管完整服务栈 Rust 引擎(crates/engine)是 Apache 2.0 协议 可以独立嵌入使用 无运行时依赖
对开发者的价值:可调试 可回溯 行为可控
除了可靠性 状态机给了开发者三件纯 prompt Agent 给不了的东西:
可调试性
Agent 出错时 你知道它在哪个状态出了错 尝试调用了什么工具 哪个转换被拦住了 每次运行产生一条状态转换链 — 清晰的审计轨迹 对比纯 prompt Agent 你只有一堆原始 LLM 调用日志 还得自己推断意图
可回溯性
每个工具调用都能追溯到具体状态 你可以按步骤回放工作流执行过程 看到模型在哪卡住了 理解为什么 Statewright 的托管云记录每次运行历史 包含每次转换的时间戳和 token 用量
行为可控
需要加安全检查?加一个状态就行 需要限制某个工具只有生产管理员能用 加进一个状态的 allowed_tools 就行 需要阻止 Agent 在规划阶段运行任意 shell 命令?从 allowed_tools 里去掉 Bash 就行 全是 JSON 定义的数据变更 — 不需要改代码 不需要改 prompt 不需要重新训练模型
需要注意的限制
Statewright 不是银弹 以下几点需要注意:
- 要求 Agent 支持 MCP(或非 MCP Agent 如 Codex 的 hooks 支持)
- 工作流定义需要手动编写(虽然 Agent 可以通过 statewright_create_workflow 生成)
- Cursor 是建议性强制 — MCP 架构本身无法在 Cursor 中拦截工具调用
- 测试数据来自 5 个任务的 SWE-bench 子集 不是完整 2294 任务基准
- 工作流限制太紧 模型可能卡住 —
statewright_deactivate是逃生出口
总结
AI Agent 圈子花了两年的时间试图让模型"更聪明"地不跑偏 Statewright 走了相反的路:与其把模型做大 不如把问题做小
用确定性的状态机约束 Agent — 在协议层强制执行 用拖拽式可视化编辑 完整的可调试追溯能力 — Statewright 提供了一条通往真正可投产的可靠 AI Agent 的路径
不管你是在构建客服机器人、数据流水线、表单自动化还是复杂工作流 状态机模式给了你 prompt 永远给不了的东西:保证 而不是建议
免费试用:statewright.ai | 开源仓库:GitHub
相关阅读:
- AI Agent 控制流实战指南:别再堆 Prompt 了 写代码吧 — 同样的控制流哲学 实用代码示例
- Statewright 研究报告 — 详细 SWE-bench 测试数据
- Statewright 文档 — 安装指南 工作流编写 schema 参考
- Hacker News 讨论:Statewright GitHub Show HN