← HowTo HT · 0002 · 2026-09-03
HOWTO / [论文复现实测] · SKILL.state v1 · 2026 · SEP 03
PAPER REPRO ARXIV:2608.26263 NO OFFICIAL CODE

SKILL.state:省 Token 的
Agent 执行架构(复现实测)

SKILL.state(Google LLC + Purdue,2026-08-26)说:别再往对话历史里追加执行记录了——每一步只喂给模型「不可变的 skill 规格 + 当前结构化 state + 最新一条 observation」,推理链用完即弃。 Google 没开源代码。 下面是按论文 Appendix A/B 重新实现的四个 runtime,在同一个仓库环境里真跑一遍 A/B。
复现 Runtime
4
T=50 累计 Token 削减
6.5×
实测环境
glm-4.5-flash
seed 42
LLM 调用
354 次·0失败
TL;DR
  1. prompt 恒定这条复现成功:T=10→50,SKILL.state 平均 prompt 是 1,582 / 1,620 / 1,620 字符,完全不随步数增长;同期 ReAct 从 3,555 涨到 20,000。
  2. 论文说的准确率提升没有复现出来:三个 horizon 上都是持平,一次没超过最好的 baseline。
  3. 省 token 的倍数是 horizon 的函数:T=10 只有 1.3×,T=50 才到 7.1×——短任务不值得引入。而且输出 token 会翻倍,按单价折算实际收益比总 token 比值小。
§ 01 / SETUP

三步跑起来

这套东西没有需要"安装"的部分。它不是框架也不是库,就是一条 prompt 构造规则加一个字典合并函数。只需要一个能跑 chat completion 的模型。

1

Key 进环境变量

export BIGMODEL_API_KEY=你的key

这次用智谱 BigModel 的 GLM 系列(glm-4.5-flash),因为 OpenRouter 上调 Gemini 被 provider ToS 403 拦了。

2

关掉 thinking 模式

GLM 系列默认开推理,content 字段会是空字符串——全部内容跑到 reasoning_content 里去了。请求体里必须显式关掉,否则动作解析全部拿到空值:

{"thinking": {"type": "disabled"}}
3

限流节流,别让 429 污染打分

免费档并发一高就 429,而失败调用如果返回空串,会被打分函数判成"答错"——最后拿到的是一张漂亮但完全错误的准确率表。第一次跑的时候我就吃了这个亏。处理方式:

_throttle = threading.Semaphore(2)      # 全局限并发
_last = [0.0]
def _pace(min_gap=1.2):                 # 全局最小请求间隔
    with _lock:
        wait = _last[0] + min_gap - time.time()
        if wait > 0: time.sleep(wait)
        _last[0] = time.time()
# retries=12,指数退避;硬失败次数单独统计打印
验收标准

跑完必须看日志末尾这一行,"0 hard failures" 不为 0,整组数据作废

wrote results.jsonl (354 LLM calls, 0 hard failures)
§ 02 / PROMPTS

四个 Runtime 的 Prompt 模板

对比的公平性全靠这一点:四个 runtime 拿到的 skill.instructions 完全一样,事件序列由同一个 seed 生成,唯一的自变量就是上下文管理方式。以下模板逐字来自论文 Appendix A(论文明确说 "exactly as they were dynamically constructed")。

A.1 Prompt(ReAct 式)—— 追加全部历史

Instructions:
{skill.instructions}

History:
Observation: {history[0].observation}
Reasoning & Action: {history[0].response}
[... 追加所有历史 observation 和 action ...]

Latest Observation: {observation}

Generate your next reasoning and action (format 'Action: <cmd>'):

A.2 Memory(摘要式)—— 滚动 3 步窗口 + 周期性摘要

把上面的 History: 换成 Summarized History: + Recent History:(只保留最近 3 轮)。

A.3 Stateful(LangGraph 式)—— 结构化 state + 完整历史

注意它同时有结构化 state 和完整历史,这是它和 SKILL.state 唯一的区别,也是论文要证的点:

Instructions:
{skill.instructions}

Current State:
{json.dumps(state, indent=2)}

History:
[... 依然追加所有历史 ...]

Latest Observation: {observation}

Update the state if necessary, provide reasoning, and output 'Action: <cmd>'.
To update state, use the format: StateUpdate: {"key": "value"}

A.4 SKILL.state —— 没有 History 这一节

Instructions:
{skill.instructions}

Skill Execution State:
```json
{json.dumps(state, separators=(',', ':'))}
```

Latest Observation: {observation}

Provide your response with:
1. Step-by-step reasoning (will be discarded after execution)
2. A JSON block fenced with ```json ... ``` containing both your State Patch and your Action.
   The JSON block MUST have exactly these two keys:
   { "state_patch": { <dict: your state updates, set keys to null to delete> },
     "action": "<string: the exact command you want to execute>" }

三个细节值得注意:

合并语义

state 更新按 Σ_t+1 = Σ_t ⊕ ΔΣ_t 进行, 是带 null 删除语义的字典合并:

def merge_patch(state, patch):
    for k, v in (patch or {}).items():
        if v is None:
            state.pop(k, None)
        elif isinstance(v, dict) and isinstance(state.get(k), dict):
            merge_patch(state[k], v)
        else:
            state[k] = v
    return state
§ 03 / ENV

环境与打分

Warehouse Management(论文 Appendix B.1 Environment 1):500 个货架,每架最多一件货。动作空间 Store / Ship / Move / Wait。事件有三类:

事件正确动作
Shipment arrived containing item_N.Store 到一个空货架
Customer ordered item_N.从当初放它的那个货架 Ship 出去
Maintenance required on shelf_M.把那架上的货 Move 到别的空架

打分 = 成功动作数 / 可动作事件数。往占用的货架上 Store、从错误的货架 Ship、Move 不存在的货,都算失败。

这个环境的巧妙之处在于:它逼着 agent 维护 500 个互不重叠的状态变量,而早期的 observation 会随着 horizon 增长滑出上下文窗口。不记住 item_12 放在 shelf_42,后面接到订单就必然出错。

§ 04 / RESULTS

实测结果

模型 glm-4.5-flash,temperature 0.0 / top_p 1.0,seed 42,横轴是执行步数 T:

TRuntimeScore平均 prompt(字符)最大 promptprompt tokens总 tokens
10Prompt (ReAct)0.703,5556,1478,84110,016
10Memory (Summary)0.702,5843,1996,5987,813
10Stateful (LangGraph)0.704,4158,24111,61413,505
10SKILL.state0.701,5821,6393,7807,566
25Prompt (ReAct)0.728,53216,84756,88060,420
25Memory (Summary)0.682,9534,34619,70023,140
25Stateful (LangGraph)0.729,07116,97165,86970,110
25SKILL.state0.721,6201,6699,86418,991
50Prompt (ReAct)0.6020,00042,836264,466274,112
50Memory (Summary)0.565,4928,87778,76398,978
50Stateful (LangGraph)0.6016,56131,812243,184250,902
50SKILL.state0.601,6201,65719,69938,377

O(1) prompt 这条复现得很干净

SKILL.state 的平均 prompt 是 1,582 → 1,620 → 1,620 字符,最大值 1,639 → 1,669 → 1,657。步数翻了五倍,prompt 一动不动。同期 ReAct 的最大 prompt 从 6,147 涨到 42,836,Stateful 从 8,241 涨到 31,812。这不是"压缩得比较狠",是根本不积累

省 token 的幅度随 horizon 增长

Horizonvs ReActvs Memoryvs Stateful
T=101.32×1.03×1.78×
T=253.18×1.22×3.69×
T=507.14×2.58×6.54×

T=10 上它几乎不省钱(对 Memory 只有 1.03×)。这是最容易被论文标题里的 16.2× 数字掩盖掉的一点:短任务上这套架构不值得引入。收益要到几十步以上才开始明显。

§ 05 / FINDINGS

六个发现

1 · 它把成本从输入侧挪到了输出侧

T=50prompt tokenscompletion tokens
Prompt (ReAct)264,4669,646
SKILL.state19,69918,678

SKILL.state 的输出 token 是 ReAct 的近两倍——因为它每一步都要额外生成一份 state_patch JSON。而多数模型的 output 定价是 input 的 3–5 倍。按 4× 折算成"输入等价 token":ReAct ≈ 303k,SKILL.state ≈ 94k,仍然领先 3.2×,但不是表面上的 7.1×。报价的时候别只看 total tokens。

2 · 准确率:持平,没有超越

三个 horizon 上 SKILL.state 的得分都等于当轮最好的 baseline(0.70 / 0.72 / 0.60),一次都没超过。论文声称的是 "improves task accuracy",这一轮只复现出"不降低"。倾向于认为这是模型能力的差异:论文用 Gemini-3-Flash 在 T=100 拿到 0.94,而 glm-4.5-flash 在 T=50 已经掉到 0.60。基础能力不足以稳定执行时,上下文管理方式带来的边际收益会被噪声淹没。

3 · O(1) 的隐藏前提:状态本身要有界

记录了每一步 Σ_tinventory 的条目数,整个 T=50 过程中它在 1 到 5 之间波动——因为 Ship 事件会把货从架上拿走,库存不是单调增长的。SKILL.state 的 O(1) 成立的前提是 state 本身有界。如果任务里状态只增不减(比如爬虫累积 URL、调查类 agent 累积证据),|Σ_t| 会随 t 增长,prompt 也就跟着涨,只是常数比全历史小而已。

4 · 结构化输出的可靠性比预期好

论文 §5.7 给了开源模型的错误分布:Gemma-4-31B 在 T=100 上,68% 的错误是"更新 state 时误删了已有 key"。这轮 glm-4.5-flash 在 T=10/25/50 三个 horizon 上的非法 patch 数都是 0——85 步、每步一个 JSON 块,全部解析成功且结构合法。说明论文这条结论对模型代际比较敏感,但确定性校验层还是要写,代价接近零。

§ 06 / VS PAPER

和论文数据的对照

指标论文(Gemini-3-Flash)本次(glm-4.5-flash)是否复现
ReAct 平均 prompt @T=103,249 字符3,555 字符 同量级
SKILL.state prompt 保持恒定1,775→1,811(T=10→200)1,582→1,620(T=10→50)
累计 token 削减16.2×(T=100, vs Stateful)6.5×(T=50, vs Stateful) 趋势一致,倍数随 horizon 增长
准确率优于 baseline0.94 vs 0.91 @T=100持平,未超越
小模型 68% 错误是 state 覆盖Gemma-4-31B0 次非法 patch

论文里没有复现的部分:噪声鲁棒性实验(Experiment 2)、状态恢复实验(Experiment 3)、公开 benchmark(InterCode CTF / τ-Bench)、以及 budget-matched 对照组(Truncated / LLMLingua)。其中 budget-matched 那组最值得单独验证——论文说把 ReAct 压到同样 1,800 token 预算时,滑动窗口掉到 0.18、LLMLingua 掉到 0.22,而 SKILL.state 是 0.94。如果这条成立,说明省 token 的功劳来自结构化而不仅仅是变短

§ 07 / WHEN

什么时候该用、什么时候别用

论文 §7 Limitations 给了三个明确的失效场景,这是全文最该先读的一节:

  1. schema 无法预先确定,状态结构必须在执行中动态发现——这时不知道该往 Σ 里投影什么。
  2. 正确的状态更新依赖某条早期 observation,而它当时的相关性没被识别出来——没投影进去,就永久丢了。这是 SKILL.state 最本质的风险:它是有损的,损失点在"当时没意识到重要"。
  3. 任务目标本身就定义在历史轨迹上——审计、调试溯源、解释过去的动作。这类任务里交互历史是产出物,不是开销。

加上实测得到的两条:

  1. 步数不到几十步,收益抵不上改造成本(T=10 只省 3%)。
  2. 状态单调增长的任务,O(1) 不成立。

反过来,最适合的场景是:长流程、状态可 schema 化、动作有明确成败反馈的执行类任务——论文选的仓库管理、Git 仓库操作、CTF、客服工单都是这个模子。

§ 08 / APPLY

怎么套到自己的 Agent

不需要换框架,四步:

1

写一个 state schema,一次就够

不要按任务写。问自己:"下一步决策需要知道什么?"只留这些字段。论文的 CTF schema 只有 5 个字段。

2

把 prompt 改成三段式

删掉 History:,换成 Skill Execution State: + Latest Observation:。这是唯一必须改的地方。

3

要求模型输出补丁 + 声明会被丢弃

每步输出 {"state_patch": ..., "action": ...},并在 prompt 里明说推理会被丢弃。这句话是有效的——模型知道推理不留存,才会主动往 state 里写。

4

runtime 侧做确定性校验 + 合并

校验不通过就丢弃补丁、重试当前步,绝不把畸形输出写进持久状态。schema 的所有权在代码这一侧,不在模型那一侧——这是整个架构安全性的来源。

§ 09 / PITFALLS

踩坑对照表

现象原因修法
GLM 返回的 content 为空默认开着 thinking,内容全跑到 reasoning_content请求体加 thinking: {"type": "disabled"}
并发一高就 429,准确率表却"正常"跑完失败调用返回空串被打分函数判成"答错",静默污染数据全局限流 + 指数退避 + 单独统计硬失败次数,非 0 就整组数据作废
以为"已经有 state 了"就等于用上省 tokenStateful (LangGraph 式) 同时保留完整历史,T=50 实测烧了 250,902 token省钱的关键动作是删历史,不是加 state;对照组必须包含 Stateful,不能只对比裸 ReAct
拿 16.2× 当自己能拿到的数字那是论文 T=100、特定模型、特定环境下对特定 baseline 的比值倍数是 horizon 的函数,T=10 上可能只有 1.3×,自己的任务要重新测
总 token 降了但账单没降多少SKILL.state 的输出 token 会翻倍,output 定价通常是 input 的 3–5 倍报价时把 completion tokens 单独折算,别只看 total tokens
跑长任务发现 prompt 还是涨了状态本身单调增长(如累积证据列表),O(1) 假设不成立先确认 |Σ_t| 有界,state 只增不减的任务这套架构帮不上忙
§ 10 / REFS

参考

SKILL.state: Scalable Long-Horizon Agent Skills — arXiv:2608.26263 论文全文 HTML 版(v3, 2026-09-02)