Skip to content

Commit 69b19cb

Browse files
committed
add who-is-spy vibe rl (prompt+result+blog)
1 parent 78182cd commit 69b19cb

15 files changed

Lines changed: 1748 additions & 3 deletions

File tree

ajet/copilot/write-swarm-client/SKILL.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ Below are some reference materials.
194194
Please run `ajet-swarm overwatch` during training, this panel displays everything about the weight update timing, transparently.
195195
When opening this panel, you can see 3 modes which you can select from: "rollout_until_finish_enough_episodes"(only count episodes), "rollout_until_finish_enough_tasks" (+consider task group), "rollout_until_finish_enough_non_dummy_tasks" (+consider group reward)
196196

197+
Another important thing to notice: each task must have a valid task_id (str), which is used to:
198+
- Group up epsiodes that belong to same task inside swarm server (you do not have to worry about that).
199+
- Used as a random seed if the task is a game requires random initialization. (e.g. werewolves game's player identity)
200+
197201

198202
### 2-3. Intergrate with your agent loop.
199203

ajet/tuner_lib/experimental/swarm_client.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ def end_episode(self, task:Task, episode_uuid: str, workflow_output: WorkflowOut
356356
return
357357

358358
task_id = task.task_id
359+
assert task_id, "task.task_id must be valid!"
359360
workflow_output.metadata["task_id"] = task_id
360361
req_obj = EndEpisodeRequest(
361362
client_uuid=self.client_uuid,
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Vibe RL 实例:不写一行代码,从零构建一个会玩“谁是卧底”的 Agent 训练器
2+
3+
4+
摘要:强化学习研究中,从灵感迸发,到编写代码,再到第一条成功的训练曲线产生,这个过程是漫长、乏味的。
5+
幸运的是,如今在 AgentJet 框架中,从想法到训练成功,你只需要动动嘴,花几分钟写一点点提示词,
6+
然后只需要等待片刻,然后你就可以看到**完整、简洁、人类易读易改的训练程序** + **初次训练的训练曲线** 展现在你面前了。
7+
接下来,我们以经典的“谁是摸底”桌游游戏为例,从零展示不写代码训练Agent的全过程。
8+
9+
10+
## 安装 AgentJet 环境
11+
12+
您可以选择[手动安装](https://doc.agentjet.top/en/installation/),或者使用skills安装。运行以下指令将skills复制到claude code或者 opencode中。
13+
```bash
14+
npx skills add modelscope/agentjet
15+
npx skills add binary-husky/Vibe-RL
16+
```
17+
在skill添加完成之后,你可以指挥claude code或者opencode使用uv(或者conda / docker)安装 AgentJet。
18+
19+
## 撰写提示词
20+
21+
在安装完成 AgentJet 之后,就可以直接开始工作了,打开OpenCode(尽管ClaudeCode比OpenCode更加强大,但笔者还是喜欢完全开源的东西;再者,在AgentJet中Vibe RL的难度很低,我们也不需要非常强的agent),
22+
然后选择 claude-4.5-sonnet 模型 (这个模型在推理速度比opus更快,对于不太困难的问题已经足够了),开始执行任务:
23+
24+
```txt
25+
你的任务:
26+
- 编写一个学习"谁是卧底"任务的智能体,通过强化学习和监督学习相结合的方式训练,游戏规则如下:
27+
- 游戏共有 N 名玩家,其中大多数人是**平民**,少数人是**卧底**
28+
- 游戏开始时,每位平民会收到同一个**平民词**,每位卧底会收到一个与平民词相近但不同的**卧底词**(例如平民词为"苹果",卧底词为"梨")
29+
- 每轮游戏中,所有玩家依次对自己拿到的词进行**口头描述**,描述必须真实反映自己的词,但不能直接说出词语本身,也不能过于明显地暴露自己的身份
30+
- 全部玩家描述完毕后,进入**投票环节**,所有玩家投票选出自己认为最可疑的卧底,得票最多的玩家被淘汰出局
31+
- 游戏持续多轮,直到满足以下任一结束条件:
32+
- **平民获胜**:所有卧底均被淘汰
33+
- **卧底获胜**:卧底人数 ≥ 平民人数(卧底在数量上取得优势)
34+
- 智能体需要通过大量对局训练掌握两种核心能力:
35+
- **描述策略学习**:学会根据自己的词语和当前局势,生成既不暴露身份、又能让同阵营玩家认同的最优描述
36+
- **推理决策学习**:学会根据历史对话、其他玩家的描述模式和行为特征,准确识别卧底并做出最优投票决策
37+
- 训练目标:最大化智能体在不同角色(平民/卧底)下的游戏胜率,通过自对弈和奖励机制不断优化策略
38+
- 我希望使用基础模型 `/mnt/data_cpfs/model_cache/modelscope/hub/Qwen/Qwen/Qwen2.5-7B-Instruct`
39+
- 使用 8 GPU 训练
40+
- Batch Size 16
41+
- 我目前没有数据集,你需要帮助我 mock 少量游戏对局数据以供测试和初始训练
42+
- 使用OpenAI SDK,灵活使用Tools
43+
- 代码中不得出现中文
44+
45+
你的 skill(首先读取该 SKILL 文件,获取必要知识):
46+
./ajet/copilot/write-swarm-client/SKILL.md
47+
48+
- 追加要求:
49+
- optional 0. (agent_roll) team A 平民 共享一个7B模型, team B卧底使用qwen-max (DASHSCOPE_API_KEY已经在环境变量中),
50+
每个episode随机分配每个所有人的ID和名字(随机生成一个长长的随机姓名名字清单),胜者奖励 1,败者奖励 0
51+
- optional 1. (agent_roll_adv) 对抗式训练,team A 平民 共享一个7B模型(swarm server 1), team B卧底共享另一个7B模型(swarm server 2),
52+
每个episode随机分配每个所有人的ID和名字(随机生成一个长长的随机姓名名字清单),胜者奖励 1,败者奖励 0
53+
54+
- 追加要求:
55+
agent_roll: 使用4个显卡
56+
agent_roll_adv:swarm server 1 和 swarm server 2 分别使用4个显卡(一共8个显卡)
57+
58+
- 追加要求:使用 tmux + uv 的 .venv 调试,直到所有Bug都已经排除 & 训练正常开始。你可以使用 `spy-swarm-server`, `spy-swarm-server-2`, `spy-swarm-client` 三个 tmux session
59+
60+
- 当前调试阶段:
61+
调试 agent_roll 【执行调试】
62+
调试 agent_roll_adv 【跳过调试】
63+
```
64+
65+
66+
## 检查结果
67+
68+
### 生成的训练代码
69+
70+
在agentjet skill的指导下,OpenCode会在 tutorial/opencode_build_*** 生成训练的全部代码:
71+
72+
```bash
73+
(base) ➜ agentjet git:(main) ✗ tree tutorial/opencode_build_spy_game
74+
tutorial/opencode_build_spy_game/
75+
├── mock_dataset.py # Generate mock game configurations
76+
├── mock_game_dataset.json # 200 game scenarios with word pairs
77+
├── game_engine.py # Core game mechanics and player logic
78+
├── agent_run.py # Agent executor for agent_roll mode
79+
├── agent_roll.py # Training script for agent_roll mode
80+
├── agent_run_adv.py # Agent executor for adversarial mode
81+
├── agent_roll_adv.py # Training script for adversarial mode
82+
└── readme.md # This file
83+
```
84+
85+
### 检查训练蜂群,发现并引导智能体修复训练的Bug
86+
87+
88+
等了一会,运行 `ajet-swarm overwatch` 命令,看一下现在训练运行到第几步了,结果发现 claude-sonnet 搞出了一个令人难绷错误:
89+
90+
```bash
91+
Completed Episode Pool Summary (Progress to Hit Next Weight Update)
92+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
93+
┃ Metric ┃ Current ┃ Target ┃ Progress ┃ Bar ┃
94+
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
95+
│ Completed Episodes │ 140 │ 16 │ 875.0% │ █████████████████████████████████████████████████████████████████████ │
96+
│ │ │ │ │ █████████████████████████████████████████████████████████████████████ │
97+
│ │ │ │ │ █████████████████████████████████████ │
98+
│ -> *Completed Tasks (chosen)* │ 1 │ 4 │ 25.0% │ █████░░░░░░░░░░░░░░░ │
99+
│ Completed Non-Dummy Tasks │ 1 │ 4 │ 25.0% │ █████░░░░░░░░░░░░░░░ │
100+
│ Average Episode Per Task │ 140.00 │ 4 │ - │ - │
101+
└────────────────────────────────────────┴─────────────┴─────────────┴──────────────┴───────────────────────────────────────────────────────────────────────┘
102+
103+
Task Completion Details
104+
┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
105+
┃ Task ID ┃ Episodes ┃ Reward ┃ Episode UUIDs (first 3) ┃
106+
┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
107+
│ │ 140 │ 0.779 ± 0.448 │ b47d7b96..., 8caec2d7..., b48bd9fb... (+137 more) │
108+
└──────────────┴───────────────┴───────────────────────┴───────────────────────────────────────────────────────────────────────────┘
109+
```
110+
111+
从蜂群监视表格可以看出,现在样本池已经累计了 875.0%(140个)的回合样本,但AgentJet并没有开始训练。
112+
仔细一看,CompletedTasks 进度只有 1个,说明140个回合都被识别成一个task了。这些样本的task id,哎,怎么是空字符串?
113+
毫无疑问,claude mock的数据集出了很搞笑的问题,直接给OpenCode下达新指令:
114+
115+
```txt
116+
task.task_id 有严重的问题,task_id应该是每个episode的随机数种子,不能为空!
117+
```
118+
119+
顺便修改了一下参数,batchsize从4改成32,grpo_n从4改成6,然后喝杯茶,再回来看看。不错,这次正常了。
120+
121+
![alt text](https://img.alicdn.com/imgextra/i4/O1CN01cQny931D4FI93OwyB_!!6000000000162-2-tps-2445-1227.png)
122+
123+
124+
为了保证agent运行逻辑是准确无误的,我们再打开 beast_logger (和agentjet配套的日志监视组件) 看一眼:
125+
126+
![alt text](https://img.alicdn.com/imgextra/i3/O1CN01w7QLeg26hS3yIma36_!!6000000007693-2-tps-3782-1963.png)
127+
128+
看了一眼,果然还是有问题(有点后悔没用opus了)。我们的要求是team A平民共享大脑用一个7B模型, team B卧底使用qwen-max。但平民队伍里面怎么混进来一个间谍?
129+
这回得让claude-sonnet好好反省一下了:
130+
131+
![alt text](https://img.alicdn.com/imgextra/i3/O1CN01ECZFjI286viB25hk1_!!6000000007884-2-tps-1079-498.png)
132+
133+
等一会,再看了一下,问题都已经修复了
134+
135+
### 检查训练曲线
136+
137+
去SwanLab看看,不错,奖励平稳上升。
138+
139+
![alt text](https://img.alicdn.com/imgextra/i2/O1CN01qFvfeU20XTkCW2H89_!!6000000006859-2-tps-1994-522.png)

docs/en/installation.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,8 @@ AgentJet supports multiple backbones, you can choose any of them depending on yo
8787

8888
!!! warning "flash-attn Installation"
8989
- `flash-attn` must be installed **after** other dependencies.
90-
- Ensure a healthy connection to GitHub to install pre-compiled wheels.
91-
- If you find your machine spend a long time installing flash-attn, ensure a healthy connection to GitHub.
92-
- To build faster, export `MAX_JOBS=${N_CPU}`.
90+
- Please ensure a **healthy connection to GitHub** to install pre-compiled wheels to install faster.
91+
- If the connection to github is unstable, it automatically falls back to building from source, export `MAX_JOBS=${N_CPU}` to install faster.
9392

9493

9594
=== "Trinity"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Spy Game RL Agent

0 commit comments

Comments
 (0)