源文件:chapter1/learning-from-experience/README.md 从经验中学习:RL 与 LLM 上下文学习的对比 本实验对比传统强化学习(Q-learning)与基于 LLM 的上下文学习(in-context learning),复现 Shunyu Yao 博文 "The Second Half" 中的核心洞见。 🎯 实验概览 实验展示了 LLM 如何通过推理进行泛化,而传统 RL 方法需要大量训练才能学会游戏机制。我们使用一个带有隐藏机制的文字寻宝游戏,让 Agent 通过经验来发现这些机制。
源文件:chapter1/learning-from-experience/README.md
本实验对比传统强化学习(Q-learning)与基于 LLM 的上下文学习(in-context learning),复现 Shunyu Yao 博文 "The Second Half" 中的核心洞见。
实验展示了 LLM 如何通过推理进行泛化,而传统 RL 方法需要大量训练才能学会游戏机制。我们使用一个带有隐藏机制的文字寻宝游戏,让 Agent 通过经验来发现这些机制。
运行 LLM 实验时,你会看到完整的决策过程:
============================================================ LLM DECISION PROCESS ============================================================ 📊 Experiences in memory: 15 🎮 Current room: hallway 🎯 Available actions: 8 💡 Recent successful patterns learned: • take red key → +5.0 reward • try crafting → +10.0 reward 🤔 LLM is thinking... 📝 LLM Reasoning: ---------------------------------------- Based on my past experiences, I've learned that: 1. The red key opens the locked door to the guard room 2. Crafting rusty sword + magic crystal creates a silver sword 3. The silver sword can defeat the strong guard Since I have the silver sword and I'm in the hallway... ---------------------------------------- ✅ Chosen action: go north
这种透明度精确展示了 LLM 如何学习与推理,而 Q-learning 则是典型的黑盒!
一个文字版寻宝游戏,Agent 必须:
# Navigate to the project directory cd chapter1/learning-from-experience # Install dependencies pip install -r requirements.txt
对应书中实验 7-1(Q-learning 在寻宝游戏中的表现)与实验 7-2(传统 RL 与 LLM Agent 的对比研究)。
Q-learning 部分完全离线运行、无需任何 API Key;LLM 部分需要 Moonshot/Kimi API Key。
要运行 LLM 实验,你需要一个 Kimi(Moonshot)API Key:
export MOONSHOT_API_KEY="your-api-key-here"
或创建 .env 文件:
echo "MOONSHOT_API_KEY=your-api-key-here" > .env
通用兜底(OpenRouter):若未设置 MOONSHOT_API_KEY 但设置了 OPENROUTER_API_KEY,
LLM 部分会自动改走 OpenRouter。由于 Kimi 模型在 OpenRouter 上不稳定可用,兜底时会使用OPENROUTER_MODEL(默认 openai/gpt-5.6-luna):
export OPENROUTER_API_KEY=sk-or-v1-your-key-here python quick_demo.py # MOONSHOT_API_KEY 缺失时自动经 OpenRouter 运行
python quick_demo.py
这会详细展示 LLM 如何通过推理学习,包括:
experiment.py)experiment.py 现在提供带中文帮助的完整 CLI。查看所有参数:
python experiment.py --help
主要参数:
| 参数 | 说明 | 默认值 |
|---|---|---|
--mode {both,qlearning,rl,llm} |
运行哪种智能体:qlearning/rl 只跑 Q-learning(离线)、llm 只跑 LLM Agent、both 两者对比 |
both |
--rl-episodes |
Q-learning 训练局数(实验 7-1 用 10000) | 10000 |
--llm-episodes |
LLM Agent 训练局数 | 20 |
--eval-episodes |
Q-learning 训练后贪婪评估局数 | 100 |
--checkpoint-interval |
学习曲线采样间隔(每 N 局记录一次胜率/Q 表规模) | 1000 |
--model |
LLM 模型名(也可用 MOONSHOT_MODEL 环境变量) |
kimi-k3 |
--output |
结果输出目录 | results |
--seed |
随机种子,用于复现 Q-learning 学习曲线 | 不固定 |
--learning-rate / --discount / --epsilon-decay / --epsilon-min |
Q-learning 超参数 | 0.2 / 0.99 / 0.9995 / 0.1 |
--stochastic |
使用随机环境 | 确定性 |
--skip-llm |
兼容旧用法,等价于 --mode qlearning |
— |
python experiment.py --mode qlearning --rl-episodes 10000 --seed 42
训练不到 3 秒即可完成,并打印学习曲线表格,直观展现智能体如何在近万局试错中从
0% 胜率逐步学会通关(见下方"Experiment Results")。
python experiment.py --mode both --model kimi-k3
该命令会:
results/ 目录注意:LLM 训练会完整展示前 3 局和最后 1 局的推理过程,让你看清它到底是怎么学的!每局 LLM 推理约需 1–2 分钟(真实 API 调用),与实验 7-2 中讨论的成本权衡一致。
python experiment.py --mode llm --llm-episodes 20
手动测试游戏:
from game_environment import TreasureHuntGame game = TreasureHuntGame() print(game.get_state_description()) print("Available actions:", game.get_available_actions()) # Try an action feedback, reward, done = game.execute_action("take rusty sword") print(f"Feedback: {feedback}") print(f"Reward: {reward}")
实验会生成多份产出:
样本效率
表现
计算成本
实验会生成对比图,展示:
--mode qlearning --rl-episodes 10000 --seed 42)实测学习曲线(确定性环境,胜率按最近 1000 局滑动窗口统计,整段训练约 3 秒):
| Episodes | Victory rate | Q-table states | epsilon |
|---|---|---|---|
| 1000 | 0.1% | 124 | 0.606 |
| 2000 | 0.0% | 129 | 0.368 |
| 3000 | 0.0% | 130 | 0.223 |
| 5000 | 0.0% | 132 | 0.100 |
| 7000 | 0.0% | 138 | 0.100 |
| 8000 | 0.0% | 140 | 0.100 |
| 9000 | 9.3% | 143 | 0.100 |
| 10000 | 99.8% | 143 | 0.100 |
训练后贪婪评估(--eval-episodes 100)胜率为 100%,平均 15 步通关。这正是实验 7-1
的核心现象:前 8000 局几乎 0% 胜率、只在盲目探索,价值信号需要近万局试错才传播到位。
(因随机探索有方差,未固定 --seed 时各次运行的拐点会略有不同,但整体形态一致。)
learning-from-experience/ ├── game_environment.py # Text-based game with hidden mechanics ├── rl_agent.py # Q-learning implementation ├── llm_agent.py # LLM with in-context learning ├── experiment.py # Main experiment runner ├── requirements.txt # Python dependencies ├── README.md # This file └── results/ # Experiment outputs (created on run) └── [timestamp]/ ├── rl_agent.pkl # Trained Q-learning agent ├── llm_experiences.json # LLM's collected experiences ├── experiment_results.json # Numerical results └── comparison_plots.png # Visualization
--learning-rate 配置)--discount 配置)--epsilon-decay(0.9995)衰减到 --epsilon-min(0.1)kimi-k3(Kimi K3;可用 --model 或 MOONSHOT_MODEL 覆盖)message.content)之前先输出一段思维链message.reasoning_content),因此代码使用较大的 max_tokens=2048,确保ACTION: 行不会被推理预算截断。temperature=1,因此代码会对这类模型自动强制为 1(见 _reasoning_safe_temperature)编辑 game_environment.py 来:
本实验展示了:
欢迎:
本项目用于教学目的,灵感来自 AI 与强化学习领域的学术研究。