Statewright: 为 AI Agent 引入确定性护栏

AI Agent 通常被描述为强大但脆弱。当被赋予大量工具和开放式目标时,即使是最先进的模型也会感到吃力,经常陷入“读取循环死亡螺旋”,即不断重复分析同一个文件而从未采取行动。行业的默认响应通常是部署更大的模型或编写更长的系统提示词,但这些对于确保生产级可靠性往往是不够的。

Statewright 引入了一种不同的哲学:“Agent 是建议,状态是法律。” Statewright 并不试图让模型变得更聪明,而是通过实现状态机护栏来缩小问题规模,这些护栏严格控制 Agent 在工作流特定阶段可以访问哪些工具。

核心方法:约束解空间

Statewright 的核心是一个评估状态机定义的确定性 Rust 引擎。它不使用 LLM 来管理状态;相反,它充当协议层的门卫。通过约束工具和解空间,模型被迫在每一步都在专注的上下文中进行推理。

例如,一个典型的修复 Bug 的工作流可以分为几个不同的状态:

  • 规划 (Planning): Agent 被授予只读工具(例如,Read, Grep, Glob)。它不能修改代码,从而确保在尝试修复之前完全理解问题。
  • 实施 (Implementing): 一旦 Agent 过渡到此状态,编辑工具将被解锁。但是,Statewright 可以应用进一步的约束,例如阻止破坏性的 shell 操作(如 rmshred)或限制每个状态编辑的行数上限。
  • 测试 (Testing): 仅允许指定的测试命令(例如,pytestnpm test)。如果 Agent 尝试使用当前阶段不允许的工具,请求将被拒绝,并附带一条解释可用工具及如何进行状态转换的说明消息。

模型性能的可衡量提升

Statewright 最引人注目的方面之一是其对较小、本地模型的影响。根据开发者的研究,约束显著降低了完成复杂任务所需的“智能门槛”。

在 SWE-bench 基准测试的一个包含 5 个任务的子集中,两个模型(大小在 13.8GB 到 19.9GB 之间)在使用 Statewright 约束时,其成功率从 2/10 跳升至 10/10。虽然由于文件内容保留能力有限(这是硬件/模型限制,而非状态机限制),低于 13GB 的模型仍然面临困难,但结果表明,结构化约束可以使中型本地模型在特定工作流中表现得像前沿模型一样。

对于前沿模型,收益更多不在于基础能力,而在于效率。通过将可用工具的数量从 30 多个减少到少数几个,Statewright 减少了 Token 使用量并防止模型“乱动”或陷入重复循环。

技术实现与护栏

Statewright 通过 Model Context Protocol (MCP) 或特定的插件钩子与 Agent 集成。强制执行的程度因 Agent 而异:

  • 硬性强制 (Hard Enforcement): 在像 Claude Code 这样的 Agent 中,工具调用在模型看到它们之前就会在协议层被拦截。
  • 建议性强制 (Advisory Enforcement): 在像 Cursor 这样的 Agent 中,规则被注入到上下文中,但架构不允许进行硬性的协议级拦截。

关键护栏功能

护栏 功能
按状态执行工具约束 除非工具在 allowed_tools 列表中,否则对 Agent 是不可见的。
Bash 辨别力 在非写入状态下阻止重定向 (>>) 和破坏性操作。
编辑护栏 限制 max_edit_lines 和每个状态编辑的文件数量。
条件转换 使用程序化谓词(例如,eq, gt)来触发状态变更。
审批门控 在进行高风险转换之前暂停执行以供人工审核。

定义自定义工作流

工作流使用 JSON schema 定义,允许开发者创建循环、迭代的过程,而不仅仅是简单的有向无环图 (DAGs)。这对于 Agentic 工作至关重要,因为 Agent 的工作很少是线性的;它通常需要重试失败的测试或在实施失败后返回到规划阶段。

开发者可以手动编写这些工作流,使用可视化编辑器,或者甚至让 Agent 通过 statewright_create_workflow 工具生成工作流定义。

权衡与考虑因素

虽然 Statewright 提供了显著的可靠性提升,但它并非没有代价。该系统需要 MCP 支持(或特定的钩子)才能运行。此外,如果工作流定义得过于严格,Agent 可能变得卡住,因此需要使用 statewright_deactivate 转义机制来返回到不受约束的状态。

通过将重心从模型规模转向结构化约束,Statewright 提供了一个框架,使 AI Agent 变得可预测、可验证,并且——最重要的是——足够可靠,以应对自主软件工程任务。

Sources