商业产业 Hacker News Agent 2026-08-24T18:21 正文 ok 1776 words

🔶 StateM:面向长程 Agent 的有状态控制

英文标题:🔶 StateM: Stateful Control for Long-Horizon Agents

StateM 将 Agent 工作流组织为可检查的状态、转换和可执行验证检查图,以避免规划、执行、验证、修复与交接全部混入一段长提示词。该项目通过版本化 runbook 和持久化运行时历史,将流程状态从模型上下文中移出,支持上下文刷新、修复循环、动态检查及可恢复的长程运行。论文在 Terminal-Bench 2.1 上报告了系统级执行框架结果:GPT-5.6 Sol xhigh 配合冻结版 StateM profile 的公开提交原始分数为 95.28%,DeepSeek-V4-Flash 配合适配 profile 的标准超时成绩为 88.09%。对开发者而言,StateM 提供了仅依赖 Python 3.11+ 的 CLI 工具,可将 Agent 的关键流程边界、验证门槛和运行记录纳入可版本控制、可审计的工程实践。
打开原文相关 3 · 机会 1
media1.2 KB media1.2 KB media5.3 KB media1.7 KB media1.3 KB media1.3 KB media1.3 KB media211.3 KB media112.1 KB

中文

[2026-08-18]🤗 StateM 在 Hugging Face Daily Papers 排名第 #1。

[2026-08-18]🔥 我们发布了 DeepSeek-V4-Flash 的 StateM runbook 与可复现性发布包,在 Terminal-Bench 2.1 上达到 88.8% 描述性准确率(395/445 次试验;未取整为 88.76%)。所有人都可以试用!

StateM 将 Agent 工作流转化为由状态、转换和可执行检查构成的可检查图。它避免规划、执行、验证、修复和交接全部坍缩为一段长提示词。

长时间运行的 Agent 往往因一些普通原因而失败:原始目标逐渐脱离注意力范围,进度只存在于聊天记录中,验证被推迟,或者新会话无法重建此前发生的过程。StateM 将这类过程状态从模型上下文移至轻量级、版本化的 runbook 中。

prepare -> execute -> verify -> handoff
              ^          |
              +-- repair-+

在每个状态中,Agent 都可以询问:

  • 我现在应该做什么?
  • 哪些转换是合法的?
  • 在我转换前需要什么证据?
  • 此前在这次运行中发生了什么?

答案存储在文件和运行时历史中,而不是依赖模型记住一切。

方案 记住阶段 阻止无效转换 支持修复循环 经受上下文刷新 Agent 可编辑
仅提示词工作流 部分 否 非正式 否 是
TODO 列表 部分 否 非正式 是 是
CI 流水线 是 是 有限 是 通常否
通用工作流引擎 是 是 是 是 很少
StateM 是 是 是 是 是

StateM 有意比工作流引擎更小。它是一个具备状态感知能力的 runbook,Agent 可以通过命令行读取、编写、检查和修复它。

  • 明确的阶段边界 —— 将模型规划、实现、审查、恢复和交接设为真实状态。
  • 可执行的转换门槛 —— 在离开状态前使用清单、命令、谓词、人工审批和 LLM 审查。
  • 动态检查 —— 允许 Agent 为当前状态条目注册任务专属检查,而无需修改共享 runbook。
  • 持久化运行时历史 —— 持久保存当前节点、转换、hook 结果、证据、时间戳和 spec 身份。
  • 上下文生命周期支持 —— 为长时间循环运行生成安全的恢复和压缩提示词。
  • 零运行时依赖 —— 核心包仅要求 Python 3.11 或更高版本。

克隆仓库并以可编辑模式安装:

git clone https://github.com/henryqin1997/statem.git
cd statem
python3 -m pip install -e .

检查 CLI:

验证并启动随附的 coding-agent runbook:

statem validate examples/coding-agent.yaml
statem start examples/coding-agent.yaml --run-id demo
statem cur --run-id demo
statem next --run-id demo

仅当当前状态的检查通过时才进行转换:

statem goto plan --run-id demo
statem history --run-id demo

运行时数据默认存放在 .statem/ 中。若需要可跨一次性检出环境保留的、机器本地持久状态,请将其置于仓库外:

export STATEM_STATE_DIR="$HOME/.local/state/statem/my-project"
statem start examples/coding-agent.yaml --run-id demo

name: implementation-loop
initial: plan

nodes:
  plan:
    prompt: |
      Read the task and write a concrete implementation plan.
    before_transfer:
      type: checklist
      items:
        - Scope and constraints are recorded
        - Verification steps are defined

  execute:
    prompt: |
      Implement the plan and keep the change scoped.
    before_transfer:
      - type: command
        run: "python3 -m pytest -q"
      - type: checklist
        items:
          - Relevant tests pass
          - Unrelated files were not changed

  handoff:
    prompt: |
      Summarize the change, verification, and remaining risks.

edges:
  - from: plan
    to: execute
    condition: The plan is ready.
  - from: execute
    to: plan
    condition: Verification found a fixable gap.
  - from: execute
    to: handoff
    condition: The implementation and verification are complete.

将其保存为 runbook.yaml,然后运行:

statem validate runbook.yaml
statem start runbook.yaml --run-id my-run
statem cur --run-id my-run

StateM 将共享工作流定义与每次运行的执行状态分离:

层级 内容 提交到 git?
静态 runbook 节点、边、提示词、hook、门槛 是
运行时状态 当前节点、历史、结果、时间戳 否
动态检查 任务专属的当前条目验证 否
持久项目笔记 计划、决策、进度、产物 通常是

一次转换是一个事务:

  1. 解析请求的出站边。
  2. 运行当前节点的 before_transfer 检查。
  3. 加载并运行当前条目的动态检查。
  4. 评估该边的 condition。
  5. 运行当前节点的 out_hook 和该边的 hook。
  6. 记录此次转换,创建新的目标条目,并运行目标节点的 in_hook。

如果一个阻塞性检查失败,Agent 将停留在当前状态,失败结果会被记录以供修复。

字段 用途
name 人类可读的图名称
initial 新运行启动时进入的节点
nodes 已命名的状态定义
edges 状态之间的有向转换
字段 运行时机 典型用途
prompt / pre_request 节点处于活动状态时 状态本地指令
in_hook 进入后 加载上下文或初始化证据
before_transfer 离开前 对必要验证进行阻断
dynamic_before_transfer 离开前 运行任务专属的当前条目检查
out_hook 转换提交前 持久保存进度或交接说明
字段 用途
from / to 源节点和目标节点
condition 转换专属的阻塞门槛
hook 退出门槛通过后执行的转换准备工作
max_attempts 此边及源节点条目的可选正数重试上限

省略 max_attempts 会保留默认的无限重试行为。配置后,每次实际的 goto 都会消耗一次尝试;被阻塞的检查同样计入,而新的源节点条目会获得新的尝试额度。

类型 行为
message 显示非阻塞性指导
manual 请求明确确认
checklist 确认一组完成条件
command 运行 shell 命令并使用其退出码
predicate 以声明式方式检查文件
llm_review 将结构化审查委托给外部命令或模型

检查可配置 blocking、on_failure、timeout 和 cwd 等字段。应优先使用能检验任务承诺给最终使用者的相同接口的检查。

命令 用途
statem start SPEC 创建或恢复一次运行
statem cur 显示当前节点及其提示词
statem state 显示完整图
statem ls NODE 检查一个节点
statem next 显示出站转换
statem goto TARGET 尝试一次经过检查的转换
statem save 持久保存状态并运行当前 out_hook
statem history 检查此前的转换和结果
statem prompt 生成持久的清空后恢复提示词
statem compact-prompt 生成安全的压缩提示词
statem validate SPEC 验证图结构和引用
statem validate SPEC --strict 同时拒绝未知或位置错误的 runbook 关键字
statem dynamic ... 管理当前条目的动态检查

大多数命令接受 --run-id、--state-dir 和 --json,分别用于显式选择运行、隔离状态以及机器可读输出。

静态门槛覆盖编写 runbook 时已知的不变量。动态检查覆盖具体任务期间发现的验证需求——例如,恰好针对刚刚修复的 bug 的回归测试。

statem dynamic path --run-id demo
statem dynamic write checks.json --run-id demo --agent-id implementer
statem dynamic list --run-id demo --json

动态检查限定在当前节点条目的作用域内。StateM 会记录是谁注册了这些检查,并在允许转换提交之前运行它们。

长时间运行应将持久事实保存在项目文件中,并将模型上下文用于当前决策。StateM 通过以下方式支持这种分工:

  • 使用 statem history 获取持久的转换记录;
  • 使用 statem prompt 在已清空的会话后恢复注意力;
  • 使用 statem compact-prompt 在循环 runbook 内进行安全压缩;
  • 在其他循环应继续时使用显式恢复节点或会话刷新节点;
  • 使用 spec 哈希和运行标识符检测或有意重新绑定已编辑的 runbook。

Runbook 应纳入版本控制,运行时状态则不应如此。使用默认本地状态目录时,请将 .statem/ 添加到 .gitignore。

持续至完成模式(可选)

StateM 无需宿主 hook 也能工作。若要让 Agent 在原本会结束其回合后继续推进,可将可选的 Stop hook 注册为持续至完成模式。当活跃运行仍位于一个具有出站转换的非终止节点时,该 hook 会返回一条继续提示词,要求 Agent 检查 StateM 并从持久状态继续。

  1. 使用 statem start 正常启动运行。
  2. 对于 Codex,将 codex-stop-autoloop.hooks.json 合并至 .codex/hooks.json 或 ~/.codex/hooks.json。
  3. 对于 Claude Code,将 claude-stop-autoloop.settings.json 合并至项目或用户设置文件。
  4. 如果 hook 在此仓库外运行,请将其命令替换为 integrations/hooks/statem_stop_hook.py 的绝对路径。当运行不使用默认 .statem/ 目录时,也请设置 STATEM_STATE_DIR。

该 hook 不会自行推进 StateM、绕过转换检查、运行 /clear 或运行 /compact。当不存在活跃运行、当前状态为终止状态,或图中没有出站转换时,它允许宿主停止。请参阅完整的设置与行为参考。

StateM 的核心保持宿主无关:任何能够运行 shell 命令的 Agent 都可以查询并推进一个 runbook。

如需了解有关证据回执、面向消费者的检查、自适应验证器计划、新鲜度、恢复及基准完整性的高级指导,请阅读验证指南。

随附论文将 StateM 作为 Terminal-Bench 2.1 上的执行框架进行评估。这些是系统层面的结果,并非关于新基础模型的主张:

配置 结果 运行条件
GPT-5.5 xhigh + StateM 92.1% 89 个任务,445 次试验;88/89 五次试验覆盖
GPT-5.6 Sol xhigh + 冻结版 StateM profile 95.28% 原始分数 424/445 次公开提交试验;89/89 覆盖
DeepSeek-V4-Flash + 适配版 StateM profile 88.09% 标准超时条件下的 392/445
DeepSeek-V4-Flash + 适配版 StateM profile 88.76% 描述性结果 395/445,以披露的延长超时试验替换一个任务

95.28% 的数值是裁决前的公开提交原始分数。DeepSeek 的描述性汇总结果与标准超时结果分开报告。实验协议、参考文献、成本和局限性请参见论文。

DeepSeek policy-v9 产物

policy-v9 产物发布包提供:

结果产物涵盖 88 个任务,排除 gpt2-codegolf:记录了 392/440 次原始通过(89.09%)。上表采用论文中的标准 89 任务分母,即 392/445(88.09%)。这些大型产物托管为发布资源,在克隆或安装 StateM 时不会下载。

statem/                  核心状态机和 CLI
examples/                Runbook 和 hook 示例
integrations/            宿主适配器
plugins/statem/          Codex skill 打包内容
tests/                   单元测试和集成测试
design.md                详细的运行时与 schema 设计
docs/verification-guide.md
                        高级验证模式

README 媒体由独立的 henryqin1997.github.io 仓库提供服务,因此克隆或安装 StateM 不会下载演示视频。

  1. 从 examples/coding-agent.yaml 开始,并删除工作流不需要的任何状态。
  2. 当需要完整的运行时、转换、hook 和恢复语义时,阅读 design.md。
  3. 在关键边界处添加确定性的 before_transfer 检查。
  4. 仅当具体任务揭示出共享 runbook 无法预先知晓的验证需求时,才使用动态检查。
  5. 将大型输出和持久决策保存在文件中;让活跃模型上下文聚焦于当前状态。
@misc{qin2026statemreaching953raw,
  title         = {StateM: Reaching 95.3\% Raw Accuracy, or a \$15 Frontier Run,
                   on Terminal-Bench 2.1 via Harness Scaling},
  author        = {Ziheng Qin and Yaxin Lu and Zhangyang Atlas Wang and Kai Wang},
  year          = {2026},
  eprint        = {2608.15089},
  archivePrefix = {arXiv},
  primaryClass  = {cs.AI},
  url           = {https:

English / 原文

[2026-08-18]🤗 StateM ranked #1 on Hugging Face Daily Papers.

[2026-08-18]🔥 We released the DeepSeek-V4-Flash StateM runbook and reproducibility release, reaching 88.8% descriptive accuracy on Terminal-Bench 2.1 (395/445 trials; 88.76% unrounded). Everyone can try!

StateM turns an agent workflow into an inspectable graph of states, transitions, and executable checks. It keeps planning, execution, verification, repair, and handoff from collapsing into one long prompt.

Long agent runs often fail for ordinary reasons: the original goal fades from attention, progress lives only in chat history, verification is postponed, or a new session cannot reconstruct what happened. StateM moves that procedural state out of the model context and into a lightweight, versioned runbook.

prepare -> execute -> verify -> handoff
              ^          |
              +-- repair-+

At every state, the agent can ask:

  • What should I do now?
  • Which transitions are legal?
  • What evidence is required before I move?
  • What happened earlier in this run?

The answer is stored in files and runtime history rather than relying on the model to remember everything.

Approach Remembers phase Blocks invalid transitions Supports repair loops Survives context refresh Agent-editable
Prompt-only workflow Partial No Informal No Yes
TODO list Partial No Informal Yes Yes
CI pipeline Yes Yes Limited Yes Usually no
General workflow engine Yes Yes Yes Yes Rarely
StateM Yes Yes Yes Yes Yes

StateM is deliberately smaller than a workflow engine. It is a state-aware runbook that an agent can read, author, inspect, and repair from the command line.

  • Explicit phase boundaries — model planning, implementation, review, recovery, and handoff as real states.
  • Executable transition gates — use checklists, commands, predicates, manual approval, and LLM review before leaving a state.
  • Dynamic checks — let an agent register task-specific checks for the current state entry without mutating the shared runbook.
  • Durable runtime history — persist the current node, transitions, hook results, evidence, timestamps, and spec identity.
  • Context lifecycle support — generate safe resume and compaction prompts for long cyclic runs.
  • Zero runtime dependencies — the core package requires only Python 3.11 or newer.

Clone the repository and install it in editable mode:

git clone https://github.com/henryqin1997/statem.git
cd statem
python3 -m pip install -e .

Check the CLI:

Validate and start the included coding-agent runbook:

statem validate examples/coding-agent.yaml
statem start examples/coding-agent.yaml --run-id demo
statem cur --run-id demo
statem next --run-id demo

Move only when the current state's checks pass:

statem goto plan --run-id demo
statem history --run-id demo

Runtime data defaults to .statem/. For durable machine-local state that survives disposable checkouts, place it outside the repository:

export STATEM_STATE_DIR="$HOME/.local/state/statem/my-project"
statem start examples/coding-agent.yaml --run-id demo


name: implementation-loop
initial: plan

nodes:
  plan:
    prompt: |
      Read the task and write a concrete implementation plan.
    before_transfer:
      type: checklist
      items:
        - Scope and constraints are recorded
        - Verification steps are defined

  execute:
    prompt: |
      Implement the plan and keep the change scoped.
    before_transfer:
      - type: command
        run: "python3 -m pytest -q"
      - type: checklist
        items:
          - Relevant tests pass
          - Unrelated files were not changed

  handoff:
    prompt: |
      Summarize the change, verification, and remaining risks.

edges:
  - from: plan
    to: execute
    condition: The plan is ready.
  - from: execute
    to: plan
    condition: Verification found a fixable gap.
  - from: execute
    to: handoff
    condition: The implementation and verification are complete.

Save it as runbook.yaml, then run:

statem validate runbook.yaml
statem start runbook.yaml --run-id my-run
statem cur --run-id my-run

StateM separates the shared workflow definition from per-run execution state:

Layer Contents Commit to git?
Static runbook Nodes, edges, prompts, hooks, gates Yes
Runtime state Current node, history, results, timestamps No
Dynamic checks Task-specific current-entry verification No
Durable project notes Plans, decisions, progress, artifacts Usually yes

A transition is a transaction:

  1. Resolve the requested outgoing edge.
  2. Run the current node's before_transfer checks.
  3. Load and run current-entry dynamic checks.
  4. Evaluate the edge's condition.
  5. Run the current node's out_hook and the edge hook.
  6. Record the transition, create a new target entry, and run the target node's in_hook.

If a blocking check fails, the agent remains in the current state with the failure recorded for repair.

Field Purpose
name Human-readable graph name
initial Node entered when a new run starts
nodes Named state definitions
edges Directed transitions between states
Field When it runs
--- ---
prompt / pre_request While the node is active
in_hook After entering
before_transfer Before leaving
dynamic_before_transfer Before leaving
out_hook Before the transition commits
Field Purpose
--- ---
from / to Source and target nodes
condition Transition-specific blocking gate
hook Prepare-transfer work after exit gates pass
max_attempts Optional positive retry ceiling for this edge and source-node entry

Leaving out max_attempts preserves the default unbounded retry behavior. When configured, each real goto consumes one attempt; blocked checks count, and a fresh source-node entry receives a fresh budget.

Type Behavior
message Display non-blocking guidance
manual Ask for explicit confirmation
checklist Confirm a set of completion conditions
command Run a shell command and use its exit code
predicate Inspect files declaratively
llm_review Delegate a structured review to an external command/model

Checks can be configured with fields such as blocking, on_failure, timeout, and cwd. Prefer checks that exercise the same interface the task promises to its eventual consumer.

Command Purpose
statem start SPEC Create or resume a run
statem cur Show the current node and its prompt
statem state Show the full graph
statem ls NODE Inspect one node
statem next Show outgoing transitions
statem goto TARGET Attempt a checked transition
statem save Persist state and run the current out_hook
statem history Inspect prior transitions and results
statem prompt Generate a durable post-clear resume prompt
statem compact-prompt Generate a safe compaction prompt
statem validate SPEC Validate graph structure and references
statem validate SPEC --strict Also reject unknown or misplaced runbook keywords
statem dynamic ... Manage current-entry dynamic checks

Most commands accept --run-id, --state-dir, and --json for explicit run selection, isolated state, and machine-readable output.

Static gates cover invariants known when the runbook is authored. Dynamic checks cover verification discovered during the concrete task—for example, a regression test for the exact bug just fixed.

statem dynamic path --run-id demo
statem dynamic write checks.json --run-id demo --agent-id implementer
statem dynamic list --run-id demo --json

Dynamic checks are scoped to the current node entry. StateM records who registered them and runs them before the transition is allowed to commit.

Long runs should keep durable facts in project files and use the model context for the current decision. StateM supports that split with:

  • statem history for the durable transition record;
  • statem prompt for restoring attention after a cleared session;
  • statem compact-prompt for safe compaction inside cyclic runbooks;
  • explicit recovery or session-refresh nodes when another loop should continue;
  • spec hashes and run identifiers to detect or deliberately rebind edited runbooks.

Runbooks belong in version control. Runtime state does not. Add .statem/ to .gitignore when using the default local state directory.

Till-finish mode (optional)

StateM works without a host hook. To keep an agent moving after it would otherwise end its turn, register the optional Stop hook as a till-finish mode. When an active run is still on a non-terminal node with outgoing transitions, the hook returns a continuation prompt that tells the agent to inspect StateM and continue from the durable state.

  1. Start the run normally with statem start.
  2. For Codex, merge codex-stop-autoloop.hooks.json into .codex/hooks.json or ~/.codex/hooks.json.
  3. For Claude Code, merge claude-stop-autoloop.settings.json into a project or user settings file.
  4. If the hook runs outside this repository, replace its command with the absolute path to integrations/hooks/statem_stop_hook.py. Set STATEM_STATE_DIR too when the run does not use the default .statem/ directory.

The hook does not advance StateM by itself, bypass transition checks, run /clear, or run /compact. It allows the host to stop when no active run exists, the current state is terminal, or the graph has no outgoing transition. See the complete setup and behavior reference.

StateM's core remains host-agnostic: any agent that can run shell commands can query and advance a runbook.

For advanced guidance on evidence receipts, consumer-facing checks, adaptive verifier plans, freshness, recovery, and benchmark integrity, read the verification guide.

The accompanying paper evaluates StateM as an execution harness on Terminal-Bench 2.1. These are system-level results, not claims about a new base model:

Configuration Result Operating condition
GPT-5.5 xhigh + StateM 92.1% 89 tasks, 445 trials; 88/89 five-trial coverage
GPT-5.6 Sol xhigh + frozen StateM profile 95.28% raw 424/445 public-submission trials; 89/89 coverage
DeepSeek-V4-Flash + adapted StateM profile 88.09% 392/445 under standard timeouts
DeepSeek-V4-Flash + adapted StateM profile 88.76% descriptive 395/445, replacing one task with disclosed extended-timeout trials

The 95.28% value is the raw pre-adjudication public-submission score. The DeepSeek descriptive aggregate is reported separately from the standard-timeout result. See the paper for experimental protocol, references, costs, and limitations.

DeepSeek policy-v9 artifacts

The policy-v9 artifact release provides:

The result artifact covers 88 tasks and excludes gpt2-codegolf: it records 392/440 raw passes (89.09%). The table above uses the paper's standard 89-task denominator, 392/445 (88.09%). These large artifacts are hosted as release assets and are not downloaded when cloning or installing StateM.

statem/                  Core state machine and CLI
examples/                Runbooks and hook examples
integrations/            Host adapters
plugins/statem/          Codex skill packaging
tests/                   Unit and integration tests
design.md                Detailed runtime and schema design
docs/verification-guide.md
                        Advanced verification patterns

README media is served from the separate henryqin1997.github.io repository, so cloning or installing StateM does not download the demo video.

  1. Start with examples/coding-agent.yaml and remove any states your workflow does not need.
  2. Read design.md when you need the full runtime, transition, hook, and recovery semantics.
  3. Add deterministic before_transfer checks at consequential boundaries.
  4. Use dynamic checks only when the concrete task reveals a verification need the shared runbook could not know in advance.
  5. Keep large outputs and durable decisions in files; keep the active model context focused on the current state.
@misc{qin2026statemreaching953raw,
  title         = {StateM: Reaching 95.3\% Raw Accuracy, or a \$15 Frontier Run,
                   on Terminal-Bench 2.1 via Harness Scaling},
  author        = {Ziheng Qin and Yaxin Lu and Zhangyang Atlas Wang and Kai Wang},
  year          = {2026},
  eprint        = {2608.15089},
  archivePrefix = {arXiv},
  primaryClass  = {cs.AI},
  url           = {https://arxiv.org/abs/2608.15089}
}

We thank Zekai Li and Mengxuan Wu for discussions and feedback on this work.

StateM is released under the Apache License 2.0.