Project 5: 用大语言模型做积木世界规划

Due: 2026.06.28.

Blocksworld planning


简介

在过去的项目中,我们用搜索和强化学习让智能体完成任务。本次项目,我们换一个主角:让 大语言模型(LLM) 来做符号规划——给定一个"积木世界(Blocksworld)"的初始摆放和目标摆放,让模型规划出一串合法动作,把积木按要求堆好。

本项目你只写 Prompt 和少量胶水代码,不用自己实现环境,也不用写 BFS/DFS/A* 这类搜索算法。核心是学习提示词工程(Prompt Engineering):怎样把任务讲清楚、怎样约束输出格式、怎样让模型把自然语言准确翻译成结构化状态。

你要完成两道题,两题共用同一套环境和 25 个任务,最后用 evaluate.py 统一打分:

题目做法你要改的文件
Q1让 LLM 直接输出动作序列my_planner/q1_llm_prompt_planner.py
Q2让 LLM 生成 PDDL,再交给规划器求解my_planner/q2_llm_pddl_planner.py

本次作业所需的文件为:blockworld_student.zip。解压后阅读其中的 STUDENT_GUIDE.md 获取完整说明(含提交要求)。

规则:

  • 不能写 BFS / DFS / A* 等搜索算法;不能按 task_id 硬编码答案。
  • 不能修改 env/pddl/tasks/run_*.pyevaluate.py
  • 只动 my_planner/ 一个目录。

你需要编辑的文件

文件作用
my_planner/q1_llm_prompt_planner.pyQ1:填 3 个函数(拼 Prompt、解析输出、串流程)。
my_planner/q2_llm_pddl_planner.pyQ2:填 4 个函数(生成 PDDL、清洗、调规划器、串流程)。
my_planner/prompt_templates/Prompt 草稿(可选,便于组织结构)。

积木世界长什么样

状态由 5 个谓词描述:ontable(A)(A 在桌上)、on(A,B)(A 摞在 B 上)、clear(A)(A 顶上没东西)、holding(A)(手拿着 A)、handempty(手空)。

只有 4 个动作,且必须满足前提条件才合法:

动作什么时候能用
PICKUP(x)x 在桌上、顶上没东西、手是空的
PUTDOWN(x)手正拿着 x
UNSTACK(x,y)x 摞在 y 上、x 顶上没东西、手是空的
STACK(x,y)手拿着 x、y 顶上没东西

LLM 最常犯的错就是用了不满足前提的动作——这正是你要在 Prompt 里解决的问题。

任务分层(25 个任务)

层级目录数量状态形式
公开tasks/public/4结构化状态 + 自然语言(调试用)
纯自然语言tasks/nl_only/5仅自然语言
隐藏tasks/hidden/3仅自然语言
困难tasks/hard/3仅自然语言
极限tasks/extreme/10仅自然语言(最多 9 块、26 步)

注意: 只有 4 个公开任务带结构化的 initial_state/goal_state,其余 21 个任务在评测时只给自然语言。你的 Prompt 必须能从自然语言里准确读出状态——这才是真正拉开差距的地方。

环境与配置

安装依赖(Q2 需要 PDDL 规划器 pyperplan):

pip install -r requirements.txt   # 含 openai、pyperplan 等

为保证评测公平,本项目统一使用 deepseek-chat 模型,模型名与接口地址已固定,你只需提供自己的 API Key。先到 https://platform.deepseek.com/api_keys 注册并创建一个 API Key,然后通过环境变量配置(避免把 Key 写进代码):

export OPENAI_API_KEY="你的deepseek-key"   # 只需改这一行
export LLM_PROVIDER="openai-compatible"
export LLM_BASE_URL="https://api.deepseek.com"   # 固定,请勿修改
export LLM_MODEL="deepseek-chat"                 # 固定,请勿修改

注意: 评测模型与接口地址固定为 deepseek-chat / https://api.deepseek.com,请勿改用其它模型或服务,以保证所有同学在同一模型上公平评测。跑完全部 25 个任务(Q1+Q2)的 API 花费不到 1 元人民币,新注册账号通常带有免费额度即可正常完成本项目。每次关闭终端后环境变量会失效,重新打开终端需再次 export

Q1:让 LLM 直接输出动作

填好 q1_llm_prompt_planner.py 中的 3 个函数(签名已给好,不要改):

def build_prompt(task) -> str:           # 拼出发给 LLM 的 Prompt
def parse_llm_output(response) -> list:  # 从回复里抽出动作序列
def plan_with_llm(task, llm_client):     # build -> llm_client.chat() -> parse

调用 LLM 只需一行:response = llm_client.chat(prompt)。写好 Prompt 的关键:把每个动作的前提条件写进 Prompt;给一个"输入 → 正确输出"的示例(few-shot);要求一行一个动作、只输出动作(不要解释、不要 markdown)。

Q2:让 LLM 写 PDDL,规划器来解

LLM 不直接想答案,只负责把题目"翻译"成 problem.pddl,正确性交给规划器保证。填好 4 个函数:

def build_pddl_prompt(task, domain_pddl) -> str:           # 生成 problem.pddl 的 Prompt
def generate_problem_pddl(task, domain_pddl, llm_client):  # 调 LLM 并清洗输出
def solve_pddl(domain_path, problem_path) -> list:         # 用 pyperplan 求解
def plan_with_llm_pddl(task, domain_path, llm_client):     # 串起全流程

一个合法的 problem.pddl 示例(参数用空格分隔,(on A B) ✅ / (on A,B) ❌;所有积木都要写进 :objects;域名固定 blocksworld):

(define (problem task_02)
  (:domain blocksworld)
  (:objects A B C - block)
  (:init (on C A) (ontable A) (ontable B) (clear C) (clear B) (handempty))
  (:goal (and (on A B) (on B C) (ontable C))))

怎么跑

student/ 目录下:

# 调试单个任务
python run_q1.py --task tasks/public/task_01.json
python run_q2.py --task tasks/public/task_02.json

# 一键自测全部 25 个任务,生成 results.json(提交用)
python evaluate.py --output results.json

开发节奏:先用公开任务跑通流程 → 改 Prompt 提高通过率 → 最后攻克"只有自然语言"的任务。


🌟 附加题(3 分):用世界模型做规划

本项目里 LLM 是在符号层上规划(谓词 / PDDL)。附加题让你换一个视角:直接在像素/状态空间里用一个"世界模型"(World Model)做规划,体会基于学习的规划与符号规划的差别。

任务:部署 LeWorldModel(LeWM)环境,加载老师提供的预训练权重,在 TwoRoom 任务上跑通评估流程(基于世界模型的 MPC 规划 + 成功率指标)。无需训练模型,有 GPU 用 GPU,没 GPU 用 CPU 也能跑通。

  • 代码与详细步骤:lewm_challenge.zip,解压后阅读其中的 LEWM_GUIDE.md
  • 模型权重与数据集:tworoom_student_data.zip,按 LEWM_GUIDE.md 解压到仓库内 data/ 即可,无需自己下载或训练。

通过标准: 终端打印出 success_rate,并在 data/tworoom/ 下生成结果文件与可视化视频 env_*.mp4,即视为跑通。

附加题提交(并入实验报告或单独附页):①运行截图(含 success_rate 那一行);②结果文件 tworoom(_cpu)_results.txt;③任意一个 env_*.mp4;④一段简短说明:部署步骤、遇到的问题及解决,以及你对"世界模型 + MPC 规划"与本项目"LLM + 符号规划"两种思路的对比理解。


代码提交与评分

将以下内容打包为 学号_姓名.zip 提交(细节见 STUDENT_GUIDE.md 第 7 节):my_planner/(两个 .py + prompt 模板)、evaluate.py 跑出的 results.json、以及 实验报告.pdf

                    学号_姓名.zip
                    │
                    ├── my_planner/
                    │   ├── q1_llm_prompt_planner.py
                    │   ├── q2_llm_pddl_planner.py
                    │   └── prompt_templates/
                    ├── results.json
                    └── 实验报告.pdf
                    

报告建议包含:Q1/Q2 各自的 Prompt 设计、25 个任务的结果表、2–3 个失败案例分析、Q1 vs Q2 对比、总结。

评分模块分值
Q1 Prompt 规划25
Q2 LLM + PDDL30
接口规范(不改教师代码、不硬编码)15
实验分析(对比 + 失败诊断)20
报告质量10
小计100
🌟 附加题:LeWM 世界模型评估+3

附加题为加分项,与日常课堂问答加分累计计算,一共不超过3分,不做附加题不影响主项目满分。

注意: results.json 必须由 evaluate.py 生成,不要手动编辑。教师会用相同的 LLM 后端重新评测以验证结果真实性;如发现硬编码答案或结果造假,按学术不端处理。

致谢

本项目积木世界规划部分参考了经典 Blocksworld / PDDL 教学设计;附加题基于 LeWorldModel(LeWM)及 stable-worldmodel 相关工作改写,所有使用及改写均遵循相关协议。感谢相关社区的贡献。