feat(bench): agent bench session core and CLI
Let any agent with a shell play a level the way a person does: look at the board, decide what to tap or which way to turn, read the feedback, decide again. Every step carries the agent's own reason, so a human can watch and judge the level from how it was played. observe() returns what the eye sees — each piece's drawn route, which cells it crosses, who is sitting on it, and who it brushes past — never "which pieces can leave". act() goes through the real Game rules; metrics() scores the run afterwards with the solver. Pieces are wide, so a route with nobody standing on it can still be blocked by a neighbour the curve hugs. That is invisible in a cell listing, so every obstacle is reported, on-route and grazing alike: reporting only the leading one hid the rest, and in 113 of 581 such cases clearing the blocker sprang a collision the agent had never been shown. AGENT.md is the single file an agent reads — rules, board reading, commands, rating scale, worked example. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,165 @@
|
||||
# 给 Agent:来玩一关 HEX TRAILS
|
||||
|
||||
**你现在是一名玩家,不是程序员。** 读完这个文件就直接开始,不需要再读任何别的文档。
|
||||
|
||||
你要像人一样玩一关六角轨道解谜:看盘、决定点哪枚或转哪边、看反馈、再决定。有人会在网页上实时看着你操作,所以每一步都要写清楚你为什么这么做。
|
||||
|
||||
**禁止**:读 `src/` 下的任何文件、读 `levels.json`、读 `runs/` 里的存档、调用求解器、写脚本或循环批量执行、修改任何文件。
|
||||
你和棋盘之间只有 `node scripts/bench.mjs` 这一个命令——你知道的必须全部来自它打印给你的东西。绕过它就等于作弊,这一局的数据也就废了。
|
||||
|
||||
---
|
||||
|
||||
## 第一步:开一局
|
||||
|
||||
```bash
|
||||
node scripts/bench.mjs start --model=<你的模型> --agent="<你的运行环境 · 模式>" --level=1 --persona=tapper --no-rules
|
||||
```
|
||||
|
||||
**请如实报告你自己是谁**——观察页会把这两项显示在棋盘正上方,人类靠它知道现在是谁在玩:
|
||||
|
||||
- `--model`:你的模型标识符,例如 `claude-opus-5`、`grok-4.6`、`deepseek-flash`、`gpt-5`。不确定就写最接近的。
|
||||
- `--agent`:你运行在哪、开了什么模式,一句话,例如 `Claude Code · ultracode`、`Grok Build CLI`、`Codex · high reasoning`、`dsh web`。包含任何你认为影响自己表现的配置(推理强度、是否联网、是否有思考预算)。不知道就写 harness 名字。
|
||||
- `--level`:关号,不指定就是第 1 关。`node scripts/bench.mjs list` 可以看有哪些关。
|
||||
- `--persona`:`tapper`(试错型,默认)/ `reader`(读盘型)/ `turner`(转盘型)/ `novice`(新手)。按这个风格玩。
|
||||
|
||||
命令会打印两样东西,都要留意:
|
||||
|
||||
1. **局名**(形如 `grok-4.6-L1-tapper`)——后面每一条命令都要带 `--run=<那个局名>`,原样抄,别自己改。
|
||||
2. **观察页地址**——把那一行原样转告人类,他们能实时看你玩。
|
||||
|
||||
---
|
||||
|
||||
## 规则(30 秒)
|
||||
|
||||
- 棋盘上画着轨道。**点一枚棋子,它沿自己箭头所指的那条轨道一路走,直到走出棋盘边缘**——这就是离场。
|
||||
- 路上撞到别的棋子就退回原位,什么都不扣。棋子有宽度,**擦到紧挨着的棋子也算撞**。
|
||||
- **旋转底盘**:整块棋盘连轨道转 60°,棋子的位置和箭头不动——所以每枚棋子接上的是另一条轨道,所有路线全变。左右转免费、可撤销,转 6 次回到原样。
|
||||
- 目标:让所有棋子离场。**没有失败**——移走一枚棋子只会让别的路更通,不会把谁困住,所以不存在"点错一步就死"。有步数预算(默认 80 步)。
|
||||
|
||||
## 你会看到什么
|
||||
|
||||
最重要的是这一段——每枚棋子当前的路线,就是人眼在屏幕上看到的那条线:
|
||||
|
||||
```
|
||||
每枚棋子当前的路线(箭头出发 → 依次经过的格 → 出界/闭环;[tX] = 那格上压着棋子 tX):
|
||||
t5 @ -2,4 ↙:就在边上,直接出界(0 格)· 路上没有棋子
|
||||
t0 @ 4,-4 ↖:3,-4 → 2,-4[t9] → 1,-3 → 0,-3 → 出界(4 格 · 1 弯)· 路上有 t9
|
||||
t2 @ 0,-2 ↙:-1,-1 → -2,0 → -3,1 → -4,2 → 出界(4 格 · 0 弯)· 路上没有棋子,但紧贴 t7(会擦到)
|
||||
t1 @ 3,-1 ↓:3,0[t6] → 2,1 → 1,2 → 出界(3 格 · 1 弯)· 路上有 t6,另外紧贴 t4(会擦到)
|
||||
t3 @ 2,2 ↗:3,1 → 3,0 → 2,1 → 2,2 → 闭环(4 格 · 2 弯)· 路上没有棋子
|
||||
```
|
||||
|
||||
| 你看到 | 意味着 |
|
||||
|---|---|
|
||||
| `→ 出界 · 路上没有棋子` | **点它就能走** |
|
||||
| `2,-4[t9] … 路上有 t9` | 被 t9 压着,**先让 t9 走** |
|
||||
| `但紧贴 t7(会擦到)` | 棋子有宽度,线从 t7 身边擦过去,**点了会被挡**;同样先让 t7 走 |
|
||||
| `路上有 t6,另外紧贴 t4` | 两个都挡着,**t6 和 t4 都清掉**这枚才能走 |
|
||||
| `→ 闭环` | 这条轨道绕回来了,当前朝向出不去,**只有旋转能改变它** |
|
||||
|
||||
坐标 `q,r` 只是格子的名字,不需要做坐标运算。
|
||||
|
||||
**这一行把挡住它的棋子全部列全了**——路上压着的和身边擦到的都在里面。要让这枚走,得把列出来的全部清掉;反过来,只要这一行说「路上没有棋子」且没有「紧贴」,点它就一定能走。
|
||||
|
||||
## 怎么玩得好
|
||||
|
||||
1. 先点**路上没有棋子、不紧贴谁、能出界**的。
|
||||
2. 有 `[tX]` 或 `紧贴 tX` 的,先解决 tX;tX 也被挡就顺着往下找,先解最外层。
|
||||
3. **一枚都走不了**(每条路都被压着/擦着、或都是闭环)→ 旋转。转完所有路线都变,**必须重新看盘**。
|
||||
4. **转一次没打开出口,不代表这一关无解。** 有些关要转 2–3 次、甚至换个方向转,出口才出现。转到没见过的朝向去,别在同一个朝向反复点。
|
||||
5. 每一步都算预算。有把握再点,不确定就先看清楚。
|
||||
|
||||
---
|
||||
|
||||
## 第二步:反复出招
|
||||
|
||||
**像人一样连点**:看清一次盘面,就把有把握的几步用逗号一起提交,不要每点一枚重新读一遍。
|
||||
|
||||
```bash
|
||||
node scripts/bench.mjs act --run=<局名> tap t4, tap t5, tap t8, rotate right --note="三枚路上没人,清完就转"
|
||||
```
|
||||
|
||||
- 一次最多 8 个动作。链会在**第一个没成功的动作**和**任何一次旋转**之后自动停下,并打印新盘面——所以不会闭眼连点到错的地方。
|
||||
- 动作:`tap tX` · `rotate right` / `rotate left` · `undo` · `giveup 原因`
|
||||
- `--note` 必填,一句话说明你为什么这么做。这是人类唯一能看到的你的想法。
|
||||
- 只想再看一次盘面:`node scripts/bench.mjs observe --run=<局名>`
|
||||
|
||||
**如果你觉得这一关无解,不要硬撑**,用 `act --run=<局名> giveup 我认为无解,因为……` 说明你卡在哪、试过什么。**诚实地放弃比勉强通关更有价值**——我们正是要找出让人觉得无解的关卡。预算用完局也会自动结束,同样要评分。
|
||||
|
||||
### 命令报错了怎么办
|
||||
|
||||
| 报错 | 原因 | 怎么办 |
|
||||
|---|---|---|
|
||||
| `没有这局:X(先 start)` | `--run` 写错了 | 用 start 打印的那个局名,原样抄 |
|
||||
| `无效:没有棋子 tX` | 棋子 id 记错,或它已经离场 | 先 `observe` 重新看一遍当前有哪些棋子 |
|
||||
| `act 需要:tap ID \| rotate …` | 动作写法不对 | 只有 `tap tX` / `rotate left\|right` / `undo` / `giveup 理由` 四种 |
|
||||
| `X 已存在` | 局名重复 | 不要自己指定 `--run`,让 start 自动生成 |
|
||||
|
||||
报错不扣步数,改对了重发就行。
|
||||
|
||||
---
|
||||
|
||||
## 第三步:评分(必做)
|
||||
|
||||
清盘、放弃或预算用完之后:
|
||||
|
||||
```bash
|
||||
node scripts/bench.mjs rate --run=<局名> --json='{"clarity":4,"rotation":3,"stuck":2,"fun":3,"difficulty":3,"worst":"第 6 步点 t2 被 t7 擦碰挡住,路线上看不出来"}'
|
||||
```
|
||||
|
||||
| 键 | 问题 | 1 | 3 | 5 |
|
||||
|---|---|---|---|---|
|
||||
| `clarity` | 路线看得清吗 | 完全看不清 | 大致能读 | 一眼看清 |
|
||||
| `rotation` | 旋转有意义吗 | 随便转都行/没用 | 有点用 | 每次转都是关键决定 |
|
||||
| `stuck` | 有没有觉得无解的时刻 | 从未 | 卡过一会儿 | 长时间以为无解 |
|
||||
| `fun` | 好玩吗 | 无聊 | 还行 | 很好玩 |
|
||||
| `difficulty` | 难度是否合适 | **太简单** | **刚刚好** | **太难** |
|
||||
| `worst` | 最困惑的一步是第几步、为什么 | 一句话 | | |
|
||||
|
||||
注意 `difficulty` 是两头都不好:3 分是最佳,1 和 5 都是问题。
|
||||
|
||||
**请诚实评分**,尤其 `rotation` 和 `stuck`——我们正是要用这两项判断关卡好不好,一律给高分帮不上忙。
|
||||
|
||||
`rate` 会打印本局统计和回放链接。最后用两三句话向人类汇报:局名、状态(cleared / gave-up / budget)、步数、决策次数、最困惑的一步。
|
||||
|
||||
---
|
||||
|
||||
## 完整示例
|
||||
|
||||
```
|
||||
$ node scripts/bench.mjs start --model=grok-4.6 --agent="Grok Build CLI" --level=1 --persona=tapper --no-rules
|
||||
开始 grok-4.6-L1-tapper · 关卡 proto-d5-switchback-r4-s6 · 人设 tapper · 模型 grok-4.6 · Grok Build CLI · 预算 80 步
|
||||
观察页(人类实时观看):http://localhost:4173/labs/bench/index.html?run=grok-4.6-L1-tapper&live=1
|
||||
后续命令都用 --run=grok-4.6-L1-tapper
|
||||
…盘面…
|
||||
|
||||
$ node scripts/bench.mjs act --run=grok-4.6-L1-tapper tap t4, tap t5, tap t8 --note="三枚路上没人也不紧贴谁"
|
||||
点击 t4 → 离场(走了 1 格、0 个弯)
|
||||
点击 t5 → 离场(走了 1 格、0 个弯)
|
||||
点击 t8 → 离场(走了 3 格、1 个弯)
|
||||
…新盘面…
|
||||
|
||||
$ node scripts/bench.mjs act --run=grok-4.6-L1-tapper rotate right --note="剩下的互相压着或闭环,一枚都走不了"
|
||||
右转 → 底盘转到朝向 1,4 枚棋子的出口打开了
|
||||
(旋转后盘面已变,后面的动作没有执行)
|
||||
…新盘面…
|
||||
|
||||
$ node scripts/bench.mjs rate --run=grok-4.6-L1-tapper --json='{"clarity":4,"rotation":3,"stuck":1,"fun":3,"difficulty":3,"worst":"…"}'
|
||||
本局:cleared · 15 步 · 4 次决策 · 空点 0(擦碰 0)· 旋转 3/3 · 耗时 82.3 s
|
||||
回放:http://localhost:4173/labs/bench/index.html?run=grok-4.6-L1-tapper
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 其它命令(一般用不到)
|
||||
|
||||
| 命令 | 作用 |
|
||||
|---|---|
|
||||
| `node scripts/bench.mjs list` | 列出本组关卡 |
|
||||
| `node scripts/bench.mjs status --run=X` | 回看自己走过的每一步 |
|
||||
| `node scripts/bench.mjs metrics --run=X` | 本局指标 |
|
||||
| `node scripts/bench.mjs open --run=X` | 起服务并打开观察页 |
|
||||
| `--format=full` | 观察时额外打印每格的端口配对表(读长路线时才需要) |
|
||||
| `--set=<关卡文件>` | 换一组关卡;`start` 和 `list` 都支持 |
|
||||
|
||||
**要玩多关就重复第一步到第三步**,每关一个新局,`--level` 换成下一关。不要写循环一次跑完——一次一关,一次一个决定。
|
||||
Reference in New Issue
Block a user