本文档属于 Robotics Tutorial 项目,作者:Pengfei Guo,达妙科技。采用 CC BY 4.0 协议,转载请注明出处。
TAMP_T7 大模型任务规划 (LLM Task Planning)¶
难度: ⭐⭐⭐ (前沿专题;概念与工程为主,数学不深但需要扎实的符号规划基础打底) 前置知识: TAMP_T1(PDDL/FF、TAMP 核心挑战、符号-几何鸿沟)、TAMP_T0 总论(尤其 §3.6 板块⑤、§5 历史钟摆)、Transformer/LLM 基本概念(知道"自回归生成""提示词""上下文学习"即可,不需要会训练) 核心参考: Ahn et al. (2022, CoRL) SayCan;Huang et al. (2022, CoRL) Inner Monologue;Liang et al. (2023, ICRA) Code as Policies;Liu et al. (2023) LLM+P;Guan et al. (2023, NeurIPS) LLM 构建世界模型;Valmeekam et al. (2023, NeurIPS) LLM 规划能力的批判性研究 与既有章节的关系: 本章是总论 §3.6 板块⑤(学习式)的纵深展开,落实总论反复强调的核心边界——LLM 增强而非取代经典规划。它把语言/常识当作①符号规划(T1/T2)的"前端",把可行性校验交还给经典规划器(T1)、几何采样器(T3 PDDLStream)、轨迹优化(T4 LGP)与执行监控(T5 行为树)。本章与 06_具身智能线的 VLA(端到端动作模型)划清边界:本章只讲 LLM 作任务规划器,不讲端到端策略。
0. 前置自测¶
开始本章之前,请完成下面五道自测题。它们检验本章依赖的三块基础——符号规划(PDDL/FF,T1)、TAMP 的核心难题(符号-几何鸿沟,T0/T1)、以及 LLM 的基本工作方式(自回归生成、上下文学习)。如果三道以上答不出来,先回对应前置章节,否则本章很多论证(尤其 §7 LLM 生成 PDDL、§10 可行性校验)会读得很费力。
| # | 问题 | 期望掌握程度 | 答不出来回到 |
|---|---|---|---|
| Q1 | 一个 PDDL 的 domain 文件和 problem 文件各自描述什么?一个 action 的 :precondition 和 :effect 是什么意思? |
能说出 domain 定义动作模型、problem 定义初末状态;前提决定动作何时可用、效果决定动作改变什么 | T1 §3 |
| Q2 | TAMP 的"符号-几何鸿沟"指什么?为什么纯符号规划器(FF)判断不了"机械臂够不够得到架子"? | 能说出离散命题 vs 连续几何,规划器看不到几何 | T0 §1.3、T1 §2 |
| Q3 | 经典符号规划器(如 FF、Fast Downward)给定一个合法的 PDDL domain+problem,能保证什么?(提示:完备性/最优性) | 能说出在可解时一定找到解、可配置求最优,且解一定满足所有前提约束 | T1 §5、T2 §3 |
| Q4 | LLM 是怎么生成文本的?"它在续写下一个最可能的 token"和"它在执行逻辑推理"这两种描述,哪个更接近底层机制? | 能意识到 LLM 本质是条件概率下的自回归续写,不是符号推理引擎——这是本章理解"为什么会幻觉"的起点 | LLM 入门、本章 §2.3 |
| Q5 | 下面三件事,哪些是经典符号规划器做不到、需要别的东西补的?(a) 把"帮我把厨房收拾干净"翻译成形式化目标;(b) 在合法 PDDL 上搜出满足约束的动作序列;(c) 判断"杯子在书后面、先得移书"这类需要常识的隐含前提。 | 能看出 (a)(c) 缺的是语言理解与常识,(b) 正是经典规划器的强项 | 本章 §2(学完即可) |
参考答案 (点击展开)
**Q1**: `domain` 文件描述一个领域里**有哪些动作、每个动作的前提与效果、有哪些谓词/类型**——它是"物理规律",与具体问题无关。`problem` 文件描述**一个具体任务的初始状态(`:init`)和目标(`:goal`)**——它是"这一局的开局与胜利条件"。`:precondition` 是一组必须为真才能执行该动作的命题(如 `pick` 要求 `(handempty)`);`:effect` 是执行后世界状态的增删(如 `pick` 后 `(holding ?x)` 为真、`(handempty)` 为假)。 **Q2**: 符号-几何鸿沟指任务层用**离散命题**描述世界(`(on cup table)`),运动层用**连续向量**描述世界(`cup.pose = (0.3, 0.2, 1.2)`)。纯符号规划器的世界里只有有限个命题,没有几何信息——它知道"架子是空的",但不知道"架子高 1.2 米、机械臂臂展 0.8 米",所以判断不了"够不够得到"。这道鸿沟是 TAMP 全部困难的根源(T0 §1.3)。本章的 LLM **也不解决这道鸿沟**——它只补语言/常识,几何可行性仍要交给 T3/T4。 **Q3**: 给定合法的 PDDL,经典规划器保证:**可解时一定能找到解**(完备性)、可配置为**找到代价最优解**(如 A\* + 可采纳启发式)、并且找到的解**一定满足所有前提与约束**(soundness)。这三条正是 LLM 不具备、却又是机器人系统刚需的——记住这一点,你就理解了为什么本章反复强调"把校验交还给经典规划器"。 **Q4**: "续写下一个最可能的 token"更接近底层机制。LLM 是在海量文本上训练的**自回归语言模型**,给定上文,它输出下一个 token 的概率分布,再采样/取最大。它**没有**显式的逻辑推理引擎、没有真值表、不做约束传播。它之所以"看起来会推理",是因为推理过程在训练语料里大量出现、被它统计性地模仿了。这一本质决定了:它能生成**像样**的计划(符合常识的概率高),但**不保证**计划合法、可行、最优——这正是 §2.3 和 §10 幻觉问题的根源。 **Q5**: (a) 和 (c) 是经典规划器做不到、需要 LLM(或人)补的。(a) "把自然语言翻译成形式化目标"——经典规划器只接受已经写好的 PDDL `:goal`,它不懂自然语言;这正是 §7 LLM-as-Modeler 要做的。(c) "杯子在书后面、先得移书"——这是个**常识隐含前提**,经典 domain 若没人手写这条规则就推不出来;LLM 的海量常识恰好能补。(b) "在合法 PDDL 上搜出满足约束的动作序列"是经典规划器的**主场**,LLM 反而做不好(§3、§10 会给出 ~3% 成功率的实证)。**这道题的本质:LLM 与经典规划器是互补的两半,不是替代关系——这就是全章的主线。**1. 本章目标¶
学完本章后,你应当能够:
- 解释 LLM 在任务层的正确定位——"有常识但不严谨的任务规划器",并说清总论反复强调的核心边界(增强而非取代经典规划)在技术上具体意味着什么、为什么不能让 LLM 独自把关可行性。
- 区分 LLM 任务规划的两大范式——LLM-as-Planner(让 LLM 直接输出动作序列)与 LLM-as-Modeler(让 LLM 生成 PDDL/目标,再交经典规划器求解),说出各自的信息流、强弱项与适用场景。
- 推导 SayCan 的语言-可行性联合打分公式 \(p(\text{选某技能}) \propto p_{\text{LLM}}(\ell\mid i)\cdot p_{\text{affordance}}(c\mid s,\ell)\),理解"语言说该做"与"物理能做到"为什么必须相乘,并把它与 Grounded Decoding、SayCanPay 放进同一谱系。
- 描述 开环规划与闭环规划的区别,讲清 ReAct(推理-行动交替)和 Inner Monologue(三类环境反馈)如何用执行反馈实现自纠错。
- 对比 Code-as-Policies(计划即程序)与符号计划(计划即动作序列)两种输出形态,理解程序形态如何天然表达循环、条件与反馈。
- 实现(在伪代码层面)一个 LLM-as-Modeler 的最小闭环:自然语言 → 提示 LLM 生成 PDDL → 语法/语义/几何三层校验 → 经典规划器求解 → 失败时把报错喂回 LLM 自纠错。
- 诊断 LLM 任务规划的典型失败——幻觉动作、违反前提、忽略几何、目标翻译走样——并说清三层可行性校验(语法、语义、几何)各拦住哪一类。
- 判断一个真实任务该用 LLM-as-Planner、LLM-as-Modeler、还是干脆不用 LLM;并把 LLM 前端正确地接到 ①符号规划(T1/T2)、③PDDLStream(T3)、④行为树(T5)组成的完整系统里。
本章知识导航¶
本章只回答一个问题,但回答得很完整:怎么让大语言模型在机器人任务规划里既出得上力、又不闯祸? 总论 §3.6 给了一句话定位("有常识但不严谨"),§5 给了历史钟摆(扩大范围 vs 保持可验证性),本章把这句话和这个钟摆落实成可操作的方法、可运行的闭环、可判断的边界。全章围绕一条主线展开——LLM 补语言与常识,经典方法守可行与最优,两者拼成完整的大脑:
根问题:怎么让 LLM 在任务规划里既出力又不闯祸?
│
┌───────────────────────┼───────────────────────┐
│ │ │
【为什么 / 定位】 【两大范式怎么做】 【怎么不闯祸 / 怎么接】
│ │ │
§2 为什么需要 LLM §4 SayCan(可行性加权) §9 提示工程与结构化输出
├─ 语言/常识缺口 ├─ Say×Can 公式 ├─ few-shot/CoT/约束解码
└─ 经典规划的两软肋 └─ Grounded Decoding 谱系 │
│ §5 ReAct/Inner Monologue §10 幻觉与可行性校验
§3 增强而非取代 ├─ 开环 vs 闭环 ├─ 三层校验:语法/语义/几何
├─ LLM 定位:有常识不严谨 └─ 反馈驱动自纠错 └─ 自纠错闭环+经典验证器
├─ as-Planner §6 Code-as-Policies │
│ vs as-Modeler 二分 └─ 计划即程序 §11 与符号规划的前端关系
└─ 历史钟摆拉回 §7 LLM-as-Modeler(生成PDDL) ├─ 串起 T1-T5 数据流
├─ LLM+P / 世界模型 / 目标翻译 └─ 贯穿场景"收拾厨房"
└─ 验证闭环 │
§8 VLM 接地(语言↔像素/三维) §12 最小可运行原型
└─ VoxPoser/开放词汇检测 └─ 80 行 LLM→PDDL→规划器
│ │
└───────────────────────┴── §13 研究地图与选型
2022-2025 时间线/象限/选型
怎么读这张图:左列回答"为什么要用、用在哪个位置"(§2-§3,定位,⭐⭐~⭐⭐⭐);中列是本章主体——两大范式各自怎么做(§4-§8,方法);右列回答"怎么不闯祸、怎么接进系统"(§9-§13,工程与边界)。⭐⭐⭐⭐ 的 §7(LLM 生成 PDDL)和 §10(可行性校验)是本章的硬核与灵魂——它们恰恰是"增强而非取代"这条边界在技术上的落点。
主干与分支:第一遍务必拿下 §3(定位与两范式)、§4(SayCan 公式)、§7(LLM-as-Modeler)、§10(校验闭环)、§11(怎么接进系统)。§5/§6/§8(闭环、程序、VLM 接地)是三条并列的"as-Planner"技术,可按兴趣选读;§12 最小原型、§13 选型可第二遍深入。
前置知识桥接¶
本章站在两块基石上,各用几行重新激活——它们决定了本章为什么这样设计。
回顾 T0 §3.6 与 §5:板块⑤的定位与历史钟摆。 总论把 LLM 任务规划定为板块⑤"学习式",一句话定位是"有常识但不严谨的任务规划器":它擅长生成像样的候选,但不做几何可行性检查、不解组合优化、不保证最优。总论 §5 还给了一条历史钟摆——符号规划可验证但范围窄,TAMP 集成扩大到几何但要手写模型,LLM 扩大到开放语言却牺牲了可验证性;最前沿的研究正想把钟摆拉回来。本章就是这条钟摆的"拉回"细节:怎么既要 LLM 的开放性、又要经典方法的可验证性。
回顾 T1:PDDL 与经典规划器。 T1 教过:PDDL 用 domain(动作模型)+ problem(初末状态)描述规划问题;FF/Fast Downward 这类规划器在合法 PDDL 上能完备地搜出满足约束的计划、可配置求最优。本章的 LLM-as-Modeler(§7)正是把 LLM 当作"PDDL 的写手",把搜索与验证仍交给这些经典规划器——所以不懂 PDDL,你连 LLM 生成的 PDDL 对不对都判断不了(这也是总论 §5.3 强调"先经典后学习"的原因)。
本质洞察:本章与 T1-T5 的关系,可以用一句话概括——T1-T5 教的是"机器人怎么严谨地想、稳地做",本章教的是"怎么让机器人听得懂人话、补得上常识,又不因此变得不严谨"。LLM 不是来取代前五章的,它是来给前五章装一个"自然语言 + 常识"的前端,同时小心翼翼地不破坏前五章辛苦建立的可验证性。读完本章你会明白:把 LLM 用对的关键,不在于让它多聪明,而在于给它划清能力边界、把它接到正确的下游。
如果跳过本章会怎样¶
- 场景一(只学了经典规划 T1-T4):你能写出漂亮的 PDDL、跑通 FF、缝合符号与几何,但用户给你的从来不是 PDDL,而是"帮我把桌子收拾一下"。你卡在最前面那一步——没有自然语言前端,每个新任务都要你手写 domain 和 goal。缺了本章,你的系统"听不懂话",只能在实验室里用形式化输入跑 demo。
- 场景二(直接上手用 LLM、跳过经典基础):你让 GPT 直接输出动作序列,仿真里偶尔能跑,一到真实任务就频繁出事——它"幻觉"出机器人没有的动作、忽略"手不空不能抓"这种前提、把"够不到的架子"当成够得到。你不知道这是因为 LLM 本质是续写而非推理(§2.3)、不做可行性检查(§10),更不知道该把校验交还给经典规划器。缺了本章的边界意识,你会误以为"大模型无所不能",在部署时反复栽跟头,还找不到病根。
- 场景三(想做"听得懂话又跑得稳"的系统):你知道要结合 LLM 和经典方法,但不知道怎么接——LLM 输出该喂给谁、可行性谁来把关、几何谁来管、执行出意外谁来兜。缺了 §11 的完整数据流和 §10 的校验闭环,你会把 LLM 和经典规划器拼成一个"接缝漏风"的系统:要么 LLM 的幻觉直接漏到执行层,要么经典规划器拿到 LLM 写错的 PDDL 直接报错却无人修复。
预计阅读时间¶
| 模式 | 覆盖范围 | 预计时间 |
|---|---|---|
| 精读 | 全部小节 + §4 公式推导 + §7 LLM-as-Modeler + §10 校验闭环 + §12 原型复现 + 练习 | 14-18 小时 |
| 速读 | §2/§3 定位 + §4 SayCan + §7 主干 + §10 三层校验 + §11 数据流 + 跳过 §5/§6/§8 细节 | 6-7 小时 |
| 实战 | §3 范式判断 + §7 生成 PDDL + §9 提示工程 + §10 校验 + §12 原型 + 故障排查 | 7-9 小时 |
| 速查 | 知识导航 + §3 两范式表 + §4 公式 + §10 校验三层 + §13 选型 + 各节小结 | 2 小时 |
针对不同目标:想建立全局认知与边界感走速读;想动手把 LLM 接进规划系统走实战路径(重点 §7 + §10 + §12);想追研究前沿走精读并配合 §13 的时间线与延伸阅读。
2. 为什么需要 LLM:从"会跑步不会过日子"说起 ⭐⭐¶
总论 §1.1 用一个反差开场:会后空翻的机器人收拾不了厨房。前六章(T1-T6)补的是"收拾厨房"里算法那一半——怎么排动作顺序(T1/T2)、怎么缝合几何(T3/T4)、怎么稳健执行(T5)、怎么处理不确定(T6)。但还有一半一直被搁置:人是怎么把"收拾厨房"这四个字交给机器人的? 这一节讲清这半块缺口的形状,以及为什么偏偏是 LLM 来补。
2.1 经典规划的两个软肋:语言缺口与常识缺口¶
回顾 T1 的工作流:你要让经典规划器干活,得先做两件准备——写一份 domain(动作模型)、写一份 problem(初始状态 + 目标)。这两份文件都是形式化的 PDDL,由人手写。这就暴露了经典符号规划(板块①)的两个软肋。
软肋一:语言缺口(the language gap)。 经典规划器只吃 PDDL,不吃自然语言。用户说"帮我把厨房收拾干净",规划器看不懂——必须有人先把这句话翻译成形式化的 :goal,比如:
这个翻译过去全靠人。每来一个新任务、换一句新指令,工程师就得重写 goal。对实验室 demo(任务固定)这不是问题,但对"听用户指挥"的真实机器人,这是个致命瓶颈——机器人听不懂话。
软肋二:常识缺口(the commonsense gap)。 即便目标写好了,经典 domain 也只知道你显式写进去的规则。考虑"把杯子放到架子上"——如果杯子被一本书挡在角落,人都知道"得先把书挪开",但 PDDL domain 里若没人手写"被遮挡的物体不可直接抓取、需先移开遮挡物"这条规则,规划器就推不出来。真实世界里这类隐含的常识前提多如牛毛:热的锅要用隔热垫、易碎的杯子要轻放、开抽屉前要先松手、倒水时杯口朝上……把它们全部手写进 domain,工程量爆炸,且永远写不全。
本质洞察:经典符号规划的两个软肋,本质是同一个根源——它的全部知识都来自人手工编码的形式化模型。模型写多详细,它就懂多少;模型没写的,它一概不知。它的严谨性(完备、最优、可验证)正是建立在"世界被一个有限、封闭的形式化模型完整描述"这个假设上。可现实世界既开放(指令五花八门)又充满常识(规则写不尽),这个封闭假设在真实部署里频频破裂。语言缺口和常识缺口,就是封闭模型撞上开放世界时裂开的两道缝。
2.2 LLM 恰好补这两道缝¶
为什么是大语言模型来补?因为 LLM 的本事恰好长在经典规划的短板上。
- 补语言缺口:LLM 在海量自然语言上训练,把自然语言映射到结构化输出正是它最擅长的事之一。"把厨房收拾干净"→一串子目标、或一段 PDDL goal、或一段机器人 API 代码——这种"翻译"对 LLM 近乎本能。
- 补常识缺口:LLM 把互联网级文本里的常识压进了参数。"杯子被书挡住要先移书""热锅要用隔热垫""倒水杯口朝上"——这些没人专门教它、但它从语料里统计性地学到了。Huang 等人 2022 年那篇开创性工作("Language Models as Zero-Shot Planners",ICML 2022)就发现:只要预训练语言模型足够大、提示得当,它们就能把"做早餐"这类高层任务零样本地分解成"打开冰箱"这样的一串低层步骤,无需任何额外训练——这正是常识缺口被填上的第一个信号。
把这两点放回总论 §1.1 的反差:会后空翻是运动层(小脑发达),收拾不了厨房是任务层缺了"听懂话 + 补常识"这块(大脑空白)。LLM 补的就是这块大脑里"语言 + 常识"的部分。注意这个限定——是"语言 + 常识",不是"严谨推理与可行性保证"。后者依旧是经典方法的地盘。这个限定,就是下一节"增强而非取代"的伏笔。
2.3 但 LLM 不是规划器:续写不等于推理¶
补缺口是真的,但有个同样真实、且更容易被忽视的事实:LLM 本质上不是一个规划器,它是一个语言模型。 这个区别是本章一切边界论证的物理基础,必须讲透。
回顾 Q4:LLM 的底层机制是自回归续写——给定上文 \(x_{1:t}\),它输出下一个 token 的条件概率分布 \(p_\theta(x_{t+1}\mid x_{1:t})\),再采样或取最大,循环往复。它没有显式的状态表示、没有真值表、不做约束传播、不回溯搜索。它"看起来会规划",是因为训练语料里有大量计划、推理链、步骤分解,它把这些模式统计性地学会并模仿了出来。
这带来一个关键后果:LLM 生成的计划,是"在语料分布下最像一个好计划的 token 串",而不是"经过验证、保证合法可行的动作序列"。两者经常一致(常识场景下,像样的计划往往真的合法),但没有任何机制保证它们一致。于是:
- 它可能生成机器人根本没有的动作("用微波炉解冻"——但这台机器人没有微波炉技能);这叫幻觉动作。
- 它可能违反前提约束(手里已经拿着书,又去"抓"杯子——但
pick要求handempty);它不查前提。 - 它可能忽略几何可行性(让机械臂去够 1.2 米高的架子——但臂展只有 0.8 米);它看不到几何,和符号规划器一样,但符号规划器至少不会无中生有,LLM 会。
这些不是"模型不够大"能根治的偶发 bug,而是"续写而非推理"这个本质带来的系统性风险。Valmeekam 等人 2023 年在 NeurIPS 用一个专门的规划基准做了批判性测量:在常识规划任务上,GPT 系列模型自主生成可执行计划的成功率极低,平均只有约 3%。3% 这个数字,是对"LLM 是个好规划器"这一幻觉最直接的证伪。
本质洞察:把 LLM 当规划器用,错在哪?错在混淆了"生成一个像样的候选"和"保证一个正确的解"。LLM 在前者上极强(它生成的计划常识上很合理),在后者上无能为力(它不验证)。经典规划器恰好相反——它不会无中生有地"创造"计划(要靠搜索),但只要给它合法的模型,它找到的解一定合法、可行、可最优。两者的能力曲线几乎正交:一个长于开放生成,一个长于严谨求解。 看清这条正交性,你就自然得出本章的核心结论——不是二选一,而是让 LLM 生成、让经典方法把关。这就是 §3 的"增强而非取代"。
2.4 一张图:缺口、补给与代价¶
把本节收束成一张对照图,它也是理解全章的"问题侧"地图:
经典符号规划(板块①, T1-T2)
强: 完备/最优/可验证 弱: 语言缺口 + 常识缺口
│
│ LLM 来补这两道缝
▼
大语言模型(板块⑤, 本章)
强: 语言映射 + 海量常识 弱: 不验证/会幻觉/不保证可行(~3%)
│
│ 但 LLM 自己又带来"不严谨"的新代价
▼
┌──────────────────────────────────────────────┐
│ 出路: LLM 补语言/常识(强) + 经典守可行/最优(强) │
│ 让两者各干各擅长的, 这就是 §3 "增强而非取代" │
└──────────────────────────────────────────────┘
2.5 哪些任务最需要 LLM、哪些根本不需要¶
讲清了"LLM 补什么缝",自然要问:是不是所有机器人任务都该上 LLM? 答案是否定的——LLM 不是默认选项,它的价值取决于任务有没有"语言/常识缺口"。把任务按"对 LLM 的需求强度"排成一条谱,能帮你在工程上做出清醒判断(这也是总论 §6 选型树 Q2 的细化):
| 需求强度 | 任务特征 | 例子 | 该不该用 LLM |
|---|---|---|---|
| 几乎不需要 | 目标已形式化、领域固定、无自然语言、无开放常识 | 固定流水线的抓放、给定 PDDL 的仓库调度 | 不用——纯经典规划更稳、更快、可验证 |
| 弱需求 | 目标基本固定,偶有少量参数化指令 | "把 3 号货架的货搬到 5 号"(模板能覆盖) | 可用可不用——模板/规则也能凑合 |
| 中需求 | 指令是自然语言但领域封闭、常识需求有限 | "把红色的零件挑出来放左边" | 推荐用——LLM 翻译指令,as-Modeler 更稳 |
| 强需求 | 开放自然语言 + 大量隐含常识 + 多变场景 | "帮我把厨房收拾干净""客人来了准备一下" | 必须用——这正是 LLM 不可替代的甜区 |
这条谱给出一个实用判据:任务里"自然语言 + 开放常识"的成分越重,LLM 的价值越大;成分越轻,越该回退到纯经典方法。 别因为"LLM 很火"就给一个目标已经形式化、领域固定的任务硬塞 LLM——那只会引入幻觉风险、推理延迟、不可验证性,却换不来任何它本不需要的"语言/常识"收益。
本质洞察(对比性思维):决定要不要用 LLM,不看"LLM 强不强",而看"任务缺不缺 LLM 能补的那两样东西(语言、常识)"。这是一个常被颠倒的判断逻辑——新手容易从"LLM 很强大"出发想"哪里都能用它",正确的逻辑应该从"任务缺什么"出发想"该不该用它"。一个目标已是 PDDL、领域固定的任务,它不缺语言理解、不缺常识,那 LLM 补的两样东西它都用不上,引入 LLM 纯属增加风险与成本(呼应总论 §6.3 须知三"先定问题类别,再选方法")。记住这条判据:LLM 是来补"语言/常识缺口"的特效药,不是包治百病的万能药——没有那道缺口的任务,不该吃这味药。 这与全章"LLM 增强而非取代"的主线一脉相承:增强是有的放矢地补短板,不是无差别地替换一切。
⚠️ 常见陷阱
- 陷阱 2-1:以为"模型够大就能直接规划"。 这是最普遍的误区。3% 的实证(Valmeekam 2023)说明,自主规划的失败是机制性的(续写不等于推理),不是规模能根治的。后续模型会让 3% 涨一些,但"不验证、会幻觉"的本质不变——本章的方法(让经典方法把关)才是正道,而非"等更大的模型"。
- 陷阱 2-2:以为 LLM 看得到几何。 LLM 和符号规划器一样看不到连续几何(够不够得到、抓取位姿),且比符号规划器更危险——它会自信地生成几何上不可行的步骤而不自知。几何可行性必须交给 T3(PDDLStream 采样)/T4(LGP 优化)。
- 陷阱 2-3:把"语言缺口"和"常识缺口"混为一谈。 两者不同:语言缺口是"听不懂指令"(输入侧),常识缺口是"不懂隐含规则"(知识侧)。LLM 同时补两者,但有的方法侧重前者(目标翻译,§7)、有的侧重后者(动作分解 + 常识,§4-§6)。分清它们,才能选对方法。
练习
- 举三个"常识隐含前提"的例子(除了正文的"杯子被书挡住"),说明若不写进 PDDL domain,经典规划器会犯什么错,而 LLM 为什么大概率能补上。
- "LLM 自主规划成功率只有约 3%"——这个数字是在什么任务上测的(提示:Valmeekam 2023 用的基准)?它能不能推广到"LLM 在所有规划任务上都只有 3%"?为什么不能(提示:考虑 LLM-as-Modeler 与 as-Planner 的区别,§3 会展开)?
- 用你自己的话解释"续写不等于推理"(即 \(\text{续写} \neq \text{推理}\)),并据此预测:给 LLM 一个它训练语料里罕见的、需要多步严谨推理的规划问题,它的表现会偏好还是偏坏?为什么?
3. LLM 在任务层的定位:增强而非取代 ⭐⭐⭐¶
§2 已经把结论的轮廓画出来了:LLM 补语言与常识,经典方法守可行与最优。这一节把这个轮廓精确化——给出 LLM 在任务层的准确定位,并引出全章的组织骨架:两大范式 LLM-as-Planner 与 LLM-as-Modeler。这是本章最重要的概念节,⭐⭐⭐。
3.1 准确定位:一个"有常识但不严谨的前端"¶
总论 §3.6 给的定位是"有常识但不严谨的任务规划器"。结合 §2 的分析,我们可以把它说得更精确:
LLM 在任务层的定位 = 一个把"开放自然语言 + 海量常识"转成"结构化候选"的前端;它负责生成,不负责把关。
这里每个词都有讲究:
- 前端(front-end):它站在整个任务层流水线的最前面,紧贴用户那一侧(接住"收拾厨房"这句话)。它的下游是经典规划器、几何采样器、执行器。它不是流水线的全部,更不是终点。
- 生成(generation):它的职责是产出候选——候选动作序列、候选 PDDL、候选目标、候选代码。候选意味着"待验证",不是"已保证"。
- 不负责把关(not the verifier):可行性、合法性、最优性的把关,交给下游的经典方法。让 LLM 自己给自己把关,等于让续写者审查续写——§10 会展示这条路为什么靠不住。
这个定位直接否定了两种常见的极端用法:
| 极端用法 | 错在哪 | 正确做法 |
|---|---|---|
| LLM 全包:让 LLM 从指令直接输出最终可执行计划,不经任何验证 | 幻觉、违反前提、忽略几何直接漏到执行(§2.3 的 3%) | LLM 生成候选,经典方法验证(§10) |
| LLM 无用:坚持纯经典方法,拒绝 LLM | 语言缺口、常识缺口无解,机器人"听不懂话"(§2.1) | 用 LLM 做前端补这两道缝(§2.2) |
本质洞察:理解 LLM 的定位,关键在于把"规划"这个动作拆成两步——"提出候选"和"验证/求解"。新手容易把这两步当成一件事("规划=输出一个计划"),于是要么指望 LLM 一步到位(全包),要么否定 LLM(无用)。一旦你把它拆开,定位就清晰了:LLM 强在第一步(提出候选)、弱在第二步(验证求解);经典方法恰好相反。 让各自做各自强的那一步,就是"增强而非取代"在操作层面的全部含义。本章后面所有方法,无论 SayCan、Code-as-Policies 还是 LLM+P,本质都是这条"LLM 提出 + 经典把关"原则的不同实现。
3.2 两大范式:LLM-as-Planner vs LLM-as-Modeler¶
"LLM 提出候选"具体提什么?这里分出了 LLM 任务规划的两大范式,也是全章后半的组织骨架。区别在于:LLM 的输出,是计划本身,还是规划问题的模型?
范式一:LLM-as-Planner(大模型即规划器)。 让 LLM 直接输出计划——动作序列、或下一个动作、或一段策略代码。LLM 既"读懂任务"又"产出计划",经典方法主要在事后或循环中校验/接地/执行。
自然语言指令
│
▼
┌─────────┐ 直接产出
│ LLM │──────────────► 动作序列 / 下一动作 / 策略代码
└─────────┘ │
▲ ▼
│ 执行反馈(闭环) 可行性接地 + 执行(SayCan/ReAct/Code-as-Policies)
└───────────────────────────┘
本范式的代表(本章 §4-§6、§8):SayCan(可行性加权选技能)、ReAct/Inner Monologue(闭环自纠错)、Code-as-Policies(计划写成程序)、VoxPoser(VLM 接地的值图)。它们的共同点:计划是 LLM 直接生成的,可行性靠 affordance 打分、执行反馈、API 约束来兜。
范式二:LLM-as-Modeler(大模型即建模器)。 让 LLM 输出规划问题的形式化模型——PDDL domain、PDDL goal、或状态描述——然后把这份模型交给经典规划器去搜索求解。LLM 只做"翻译/建模",规划本身交还给经典规划器。
自然语言指令 + 领域描述
│
▼
┌─────────┐ 生成形式化模型 ┌──────────────┐ 完备/最优搜索
│ LLM │───────────────────► │ 经典规划器 │──────────────► 计划
└─────────┘ PDDL domain/goal │ (FF/FastDownward)│ (保证合法可行)
▲ └──────────────┘
│ 校验失败把报错喂回(自纠错, §10) │
└───────────────────────────────────────┘
本范式的代表(本章 §7):LLM+P(生成 PDDL problem)、Guan 等人的世界模型(生成 PDDL domain + 验证器闭环)、Xie 等人的目标翻译(自然语言 → PDDL goal)、Silver 等人的泛化规划。它们的共同点:LLM 不直接给计划,只给模型;计划由经典规划器搜出,因此天然继承了经典规划器的完备性与最优性保证。
3.3 两范式对比:一张决定性的表¶
| 维度 | LLM-as-Planner | LLM-as-Modeler |
|---|---|---|
| LLM 输出什么 | 计划本身(动作序列/下一动作/代码) | 规划问题的模型(PDDL domain/goal/状态) |
| 谁来搜索/求解 | LLM(事后接地/执行校验) | 经典规划器(FF/Fast Downward) |
| 可行性保证 | 弱——靠 affordance、反馈、API 兜底 | 强——经典规划器保证解满足 PDDL 约束 |
| 最优性 | 一般无 | 可配置(取决于规划器) |
| 对领域形式化的依赖 | 低——可零样本,不必有 PDDL domain | 高——需要(或需 LLM 生成)PDDL domain |
| 长程任务表现 | 易在长链上累积错误、漂移 | 经典搜索处理长程更稳健 |
| 开放/常识任务 | 强——直接用 LLM 的语言与常识 | 中——常识需先编码进 domain/goal |
| 可解释/可调试 | 弱——计划是黑箱生成 | 强——PDDL 可读、可被验证器逐条查 |
| 典型代表 | SayCan, ReAct, Code-as-Policies, VoxPoser | LLM+P, Guan(世界模型), Xie(目标翻译), Silver |
| 本章对应 | §4, §5, §6, §8 | §7 |
怎么读这张表?一句话:as-Planner 灵活但不严谨,as-Modeler 严谨但要形式化。 前者适合"领域开放、没有现成 PDDL、容忍偶尔出错并靠闭环纠正"的场景(家庭服务、探索性任务);后者适合"领域相对固定、要可验证保证、长程组合复杂"的场景(仓库调度、需要完备性的任务)。
本质洞察:两大范式的分野,本质是"把 LLM 的不可靠性堵在哪一层"。as-Planner 把 LLM 放在计划生成的位置,于是不可靠性会渗到计划里,必须靠下游的 affordance 加权、执行反馈、API 约束层层兜底——这是"事后纠错"的哲学。as-Modeler 把 LLM 退后一步、只让它写模型,于是不可靠性被堵在"模型对不对"这一层,一旦模型经验证器确认无误,后面的搜索就完全由可信的经典规划器接管、计划必然合法——这是"前端设防"的哲学。记住这个对照:as-Planner 信任执行闭环来纠错,as-Modeler 信任经典规划器来保证。 这也解释了为什么 as-Modeler 在"需要严谨保证"的任务上更受学术界青睐(它把可验证性钟摆拉得最回),而 as-Planner 在"开放灵活"的任务上更流行(它最大化利用了 LLM 的常识与零样本能力)。
3.4 把钟摆拉回来:本章在历史脉络中的位置¶
总论 §5 那条历史钟摆——"扩大问题范围 vs 保持可验证性"——在本章有了最具体的着陆点。把它和两范式对上:
符号规划(1971-) 可验证性满, 范围窄(纯离散, 要手写模型)
│ 钟摆向"范围"摆
▼
TAMP 集成(2010s) 扩到几何, 但仍要手写模型 + 采样器, 不懂语言
│ 钟摆继续向"范围"摆
▼
纯 LLM 规划(2022 早期) 扩到开放语言/常识, 但牺牲可验证性(~3%) ← 钟摆摆到最右(范围最大、验证最弱)
│ 研究界意识到摆过头了, 开始往回拉
▼
LLM + 经典混合(2023-) 既要 LLM 开放性, 又要经典可验证性 ← 钟摆回拉
├─ LLM-as-Modeler: 拉得最回(经典规划器全权求解, §7)
└─ LLM-as-Planner + 校验闭环: 拉回一部分(affordance/反馈/验证, §4-§6,§10)
本章讲的所有方法,都处在"钟摆回拉"这个阶段。SayCan(§4)用 affordance 把"物理可行"拉回来;ReAct(§5)用执行反馈把"现实一致"拉回来;LLM-as-Modeler(§7)把"完备可验证"拉到最回;可行性校验(§10)是回拉的总抓手。理解了这一点,你就不会问"LLM 会不会取代经典规划"这种被钟摆证伪的问题,而会问"对我的任务,钟摆该回拉到哪个位置"——这才是工程师该问的问题。
3.5 两范式不是单选:一个混合的真实系统¶
§3.3 反复强调两范式"不互斥、常叠加",但抽象的话不如一个具体例子。这里给一个同时用上两范式的真实风格系统,让你看清它们如何在一个系统里各司其职、而非二选一。
设想一个家用机器人,要处理"帮我把厨房收拾一下,顺便看看冰箱里有没有过期的东西扔掉"这样的复合指令。一个成熟系统会这样组合两范式:
指令: "把厨房收拾一下, 顺便扔掉冰箱里过期的东西"
│
▼ [as-Modeler 那一半] 领域(厨房整理)相对固定、可形式化
│ LLM 翻译出 PDDL goal: (and (clean counter) (forall ?x (stored ?x)))
│ → 交经典规划器搜出"收拾厨房"的合法、有序计划(§7, 可验证)
│
▼ [as-Planner 那一半] "看看有没有过期的"是开放、依赖逐个判断的子任务
│ 这部分难以预先形式化(哪些过期? 要逐个看保质期)
│ → 用 Code-as-Policies 写程序: for item in fridge: if expired(item): discard(item)
│ (§6, 含循环+条件+逐个感知判断, 靠 API 白名单兜底)
│
▼ [两半都接同一套校验与执行]
三层校验(§10) + 执行层闭环 ReAct/行为树(§5/§11) 统一兜底
看清这个组合的逻辑:"收拾厨房"这部分领域可形式化、要可验证保证,走 as-Modeler;"挑过期食物"这部分开放、要逐个感知判断、难形式化,走 as-Planner。 同一个指令的两个子任务,因为性质不同,落到了不同范式——而它们共享同一套下游校验和执行。
本质洞察:这个混合例子点破了一个新手常有的误解——范式是按"子任务的性质"选的,不是按"整个系统"选的。一个真实系统里,不同子任务可以、也常常走不同范式:能形式化、要保证的走 as-Modeler,开放灵活、靠闭环兜的走 as-Planner。§3.3 那张对比表不是让你给系统贴一个"门派标签",而是给你一把尺子,去逐个子任务地量"这一块该走哪条路"。这与总论 §6.3 须知一"板块是叠加的,不是互斥的"完全一致。理解了这一点,你就摆脱了"非此即彼"的思维,能像搭积木一样按每块任务的性质灵活组合两范式——这才是工程师面对复合任务时的真实工作方式。
⚠️ 常见陷阱
- 陷阱 3-1:把两范式当成互斥的二选一。 它们不互斥,常常叠加:一个系统可以用 as-Modeler 让 LLM 写 PDDL goal(§7),同时用 as-Planner 的闭环(ReAct,§5)在执行中纠错。范式是"思路"不是"门派",按需混用。
- 陷阱 3-2:以为 as-Modeler 就没有 LLM 风险了。 as-Modeler 把风险堵在"模型对不对"这一层,但 LLM 写的 PDDL 同样可能有错(语法错、语义错、漏前提)。它的优势不是"没风险",而是"风险被堵在一个可被验证器逐条检查的位置"(§10)——风险可控,不是风险消失。
- 陷阱 3-3:以为"前端"就是无关紧要的外壳。 前端恰恰是决定系统"能不能用"的关键——再强的经典规划器,没有前端就听不懂用户的话。"前端"指它在数据流里的位置(最前),不指它的重要性(次要)。位置靠前、责任重大、但能力有界,这才是 LLM 前端的准确画像。
练习
- 用 §3.3 的对比表,判断下面三个任务该走 as-Planner 还是 as-Modeler,并说明理由:(a) 家用机器人执行"帮我准备一下喝咖啡的东西"(开放、容忍纠错);(b) 自动化仓库每天调度数百个补货任务(领域固定、要可验证、长程);(c) 一次性的探索任务"看看这个陌生房间里有什么能整理的"。
- "as-Planner 信任执行闭环来纠错,as-Modeler 信任经典规划器来保证"——分别说明:如果去掉各自信任的那个组件(as-Planner 去掉执行闭环、as-Modeler 去掉经典规划器),会退化成什么?为什么会很危险?
- 把总论 §5 的历史钟摆图和本章 §3.4 的图对照,用一句话回答:"LLM 会取代经典规划吗"为什么是个被钟摆证伪的问题?正确的提问应该是什么?
4. SayCan:语言可行性加权的开山之作 ⭐⭐⭐¶
§3 给了定位与两范式,从这里开始进入 LLM-as-Planner 范式的具体方法。第一站是 SayCan(Ahn et al., CoRL 2022)——它是把 LLM 接进真实机器人的里程碑,也是"增强而非取代"这条边界第一次被写成数学公式的工作。理解了 SayCan 的那一个乘法,你就理解了 LLM-as-Planner 全部方法的灵魂。
4.1 问题:LLM 说得对,机器人做不到¶
回到 §2.3 的幻觉问题,SayCan 关注其中最尖锐的一种:LLM 提议的动作,机器人当前根本执行不了。
举个论文里的经典例子。用户说"我把饮料洒了,能帮我吗?"("I spilled my drink, can you help?")。一个纯 LLM 被问"下一步该做什么",可能给出非常合理的常识回答:"用吸尘器把它吸干"("use a vacuum cleaner")。这句话作为常识完全正确——可这台机器人没有吸尘器技能,它只会"拿海绵""找抹布""把饮料扔掉"等有限几个动作。LLM 不知道机器人会什么、不会什么,于是它给出的"最合理候选"可能落在机器人能力之外。
这正是 §2.1 语言缺口与 §2.3 幻觉的合流:LLM 有语言和常识(知道洒了要清理),但不知道"这具身体"能做什么(embodiment grounding 缺失)。SayCan 的原标题精辟地概括了解法——"Do As I Can, Not As I Say"(按我能做的做,而非按我嘴上说的做)。
4.2 核心思想:语言可能性乘以物理可行性¶
SayCan 的解法优雅得近乎简单。机器人有一个预定义的技能库 \(\{\ell_1, \ell_2, \dots, \ell_K\}\)(每个 \(\ell\) 是一个用自然语言描述的、已经训练好的低层技能,如"拿起海绵""走到桌子旁")。在每一步,要从库里选一个最该执行的技能。SayCan 用两个分数的乘积来选:
逐项拆解:
- \(i\) 是用户指令("我把饮料洒了,能帮我吗"),\(h\) 是已执行的动作历史(提供上下文)。
- \(p_{\text{LLM}}(\ell \mid i, h)\) 是 "Say" 分数:语言模型认为"在指令 \(i\) 和历史 \(h\) 下,技能 \(\ell\) 是个合理的下一步"的可能性。技术上,这通过让 LLM 给每个候选技能的自然语言描述打分(scoring,即计算该描述在 LLM 下的对数似然)得到。它编码"语言上该做什么"——是常识与任务理解。
- \(p_{\text{afford}}(c_{\ell} \mid s)\) 是 "Can" 分数:在当前世界状态 \(s\) 下,技能 \(\ell\) 当前能成功执行的概率。\(c_\ell\) 表示"\(\ell\) 执行成功"这一事件。这个分数由一个可供性函数(affordance function) 给出——通常是该技能对应的强化学习价值函数 \(V_\ell(s)\)(在 SayCan 里用 TD 训练的 value function),它天然估计"从状态 \(s\) 出发执行 \(\ell\) 的预期成功率"。它编码"物理上能做什么"——是具身可行性。
两者相乘,含义直观得不能再直观:
一个技能只有"语言上该做"且"物理上能做",乘积才高、才会被选中。 "用吸尘器"的 Say 分很高(常识合理)但 Can 分趋零(没这技能,价值函数估成功率 \(\approx 0\)),乘积被压垮;"拿海绵"的 Say 分不错、Can 分也高(够得到、会拿),乘积胜出。
4.3 为什么必须是"乘法",而不是"加法"或"只用一个"¶
这是 SayCan 最值得玩味、也最容易被轻视的设计。为什么用乘积 \(p_{\text{LLM}}\cdot p_{\text{afford}}\),而不是加权和 \(\alpha\, p_{\text{LLM}} + \beta\, p_{\text{afford}}\),更不是只用其中一个?用反事实逐一排除:
反事实一:只用 Say(纯 LLM)。 退化成 §4.1 的灾难——LLM 提议"用吸尘器",机器人傻眼。忽略了物理可行性。
反事实二:只用 Can(纯价值函数)。 机器人会选"当前最容易成功的技能",但完全不管它该不该做。它可能反复执行"原地待命"(成功率 100%)或随便拿个够得到的东西,因为没有任务语义指引。忽略了任务意图。
反事实三:用加法 \(\alpha\, p_{\text{LLM}} + \beta\, p_{\text{afford}}\)。 加法的毛病是一个高分能补偿另一个的低分。"用吸尘器"Say 分极高,即便 Can 分 \(\approx 0\),加权和仍可能超过"拿海绵"——于是机器人还是会去够那个不存在的吸尘器。加法允许"语言一厢情愿地压倒物理现实",这正是要避免的。
反事实四(正解):用乘法。 乘法的关键性质是 "一票否决"——任一因子接近 0,乘积就接近 0,无法被另一因子补偿。Can 分 \(\approx 0\)(做不到)时,无论 Say 分多高(多想做),乘积都 \(\approx 0\),该技能出局。这恰好编码了我们想要的语义:"做不到"是硬约束,不能被"很想做"覆盖。
本质洞察:SayCan 的乘法,是"增强而非取代"在数学上最干净的一次表达。把它和 §3.1 的定位对上——\(p_{\text{LLM}}\) 是 LLM 出的"该做什么"的候选打分(生成/增强那一半),\(p_{\text{afford}}\) 是经典/学习方法守的"能不能做"的可行性闸门(把关那一半)。乘法让"把关"对"生成"拥有一票否决权:LLM 再想做的事,物理上做不到就一律出局。这与加法的"互相补偿"形成鲜明对比——加法里语言能压过物理,乘法里物理能否决语言。一个乘号,就把"LLM 提议、可行性把关、把关说了算"这套哲学钉死了。后面所有 LLM-as-Planner 方法(Grounded Decoding 的 token 级、SayCanPay 的三因子)都是这个乘法的变奏,但灵魂没变:让可行性对语言有否决权。
4.4 SayCan 的完整循环¶
把单步选择串成完整任务,SayCan 是一个贪心的、逐技能的闭环:
用户指令 i: "我把饮料洒了, 能帮我吗?"
│
▼
┌──────────────────────────── 循环每一步 ────────────────────────────┐
│ 1. 对技能库每个 ℓ: │
│ Say 分 = LLM 给 "ℓ的语言描述" 打分(在 i + 历史 h 下) │
│ Can 分 = 价值函数 V_ℓ(s) 估当前状态下 ℓ 的成功率 │
│ 2. 选 ℓ* = argmax (Say × Can) │
│ 3. 执行 ℓ*(低层策略真正动机器人), 观察新状态 s' │
│ 4. 把 ℓ* 追加进历史 h; 若 ℓ* = "done" 或目标达成则退出 │
└─────────────────────────────────────────────────────────────────────┘
│
▼
完整技能序列: 找海绵 → 走到饮料旁 → 擦拭 → ... → done
注意三个要点:
- 它是 LLM-as-Planner(§3.2):计划(技能序列)是 LLM 一步步选出来的,不是经典规划器搜出来的。可行性靠 Can 分(affordance)兜,不靠 PDDL 验证。
- 它是贪心的:每步只选当前最优,不做前瞻搜索。这简单高效,但也是它的软肋——长程任务上贪心容易走进死胡同(SayCanPay 就是来补这个的,§4.6)。
- 技能库是预定义的:SayCan 不发明新动作,只在已有技能里选。这其实是个安全特性——它把 LLM 的输出空间限制在机器人确实会做的动作上,从源头消除了"幻觉出不存在的动作"(呼应 §10 的可行性校验思路:限制输出空间是防幻觉的根本手段之一)。
4.5 SayCan 是怎么"接地"的:affordance 从哪来¶
"Can" 分数的来源——可供性函数——值得单独说,因为它是 SayCan 把语言接到物理世界的接口。
在原始 SayCan 里,每个技能 \(\ell\) 配一个用强化学习(具体是 TD-backup 的 actor-critic)训练出来的价值函数 \(V_\ell(s)\)。这个 \(V_\ell(s)\) 在训练中学会了"从状态 \(s\) 出发,执行技能 \(\ell\) 最终成功的预期回报"——当 \(s\) 下 \(\ell\) 容易成功(如"拿海绵"且海绵就在手边),\(V_\ell\) 高;当 \(\ell\) 难以成功(如"拿海绵"但海绵在看不见的柜子里),\(V_\ell\) 低。把 \(V_\ell(s)\) 归一化当作 \(p_{\text{afford}}(c_\ell\mid s)\),就得到了 Can 分。
这里有个深刻的对称性:Say 来自语言模型(语言世界),Can 来自价值函数(物理世界),SayCan 在它们的乘积处缝合了两个世界。这与总论 §1.3"符号 vs 几何鸿沟"、与 T3 PDDLStream"让采样器把可行性流回符号层"是同一母题的不同变奏——都是让物理可行性的信息,流回到高层决策。只不过 PDDLStream 用的是几何采样器,SayCan 用的是 RL 价值函数;PDDLStream 服务的是符号搜索,SayCan 服务的是 LLM 打分。母题相同:高层不能瞎决策,必须让底层的可行性说话。
4.6 SayCan 的谱系:Grounded Decoding 与 SayCanPay¶
SayCan 之后,"语言乘以可行性"(即 \(p_{\text{LLM}}\cdot p_{\text{afford}}\))这条思路被沿两个方向推进,构成一个清晰的谱系。
纵向加细——Grounded Decoding(Huang et al., NeurIPS 2023):从"技能级"到"token 级"。 SayCan 在整条技能描述的粒度上打分(先有一个固定技能库,给每个库成员算 Say \(\times\) Can)。这要求技能库预先枚举好。Grounded Decoding 把同样的乘法思想下沉到 token 级:在 LLM 逐 token 生成动作描述时,每个 token 的选择都同时考虑"LLM 下该 token 的概率"和"grounded 模型(可供性、安全、用户偏好)下该 token 的可行性",两者相乘来引导解码。Grounded Decoding 通过把 LLM 的 token 似然与可供性函数、安全函数等多种 grounded 模型给出的可行性相乘来引导文本生成,从而在机器人设置下解决复杂的长时域具身任务。好处是不必预先枚举技能库——它能生成库外的、组合性的动作描述,同时仍受可行性约束。一句话:SayCan 是"在给定选项里挑可行的",Grounded Decoding 是"在生成时就只生成可行的"。
横向加项——SayCanPay(Hazra et al., AAAI 2024):从"两因子"到"三因子 + 搜索"。 SayCan 是贪心的(§4.4 要点 2),长程任务上容易选出"每步都可行、但整体绕远或走死"的序列。SayCanPay 加了第三个因子 "Pay"(payoff,长期收益/计划代价的估计),并把贪心选择换成启发式搜索:
其中 \(\hat{R}(\ell)\) 是一个可学习的、估计"选 \(\ell\) 对达成最终目标的长期价值/代价有效性"的模型,被当作启发式搜索(类似 A* 的 \(h\))的指引。SayCanPay 用 LLM 生成动作(Say)、用可学习的领域知识评估动作可行性(Can)与长期收益(Pay),再用启发式搜索选出最佳动作序列,从而得到既可行又低代价的计划。把它放回 §3.4 的钟摆:SayCan 用 Can 把"物理可行"拉回来,SayCanPay 再用 Pay + 搜索把"全局最优性"也往回拉了一些——它在 LLM-as-Planner 范式内,朝经典规划的"最优搜索"靠近了一步。
把谱系画成一张表:
| 方法 | 打分粒度 | 因子 | 选择方式 | 补了什么 |
|---|---|---|---|---|
| SayCan (CoRL 2022) | 技能级 | Say \(\times\) Can | 贪心 | 物理可行性(embodiment grounding) |
| Grounded Decoding (NeurIPS 2023) | token 级 | LLM token \(\times\) grounded | 引导解码 | 摆脱技能库枚举、可生成组合动作 |
| SayCanPay (AAAI 2024) | 技能级 | Say \(\times\) Can \(\times\) Pay | 启发式搜索 | 长期收益 + 全局性(治贪心短视) |
本质洞察:这个谱系揭示了 LLM-as-Planner 的演进逻辑——不断给"纯 LLM 生成"加约束、加把关,把钟摆一点点往"可验证/最优"拉。SayCan 加可行性闸门,Grounded Decoding 把闸门下沉到生成过程,SayCanPay 加最优性搜索。每一步都在回答同一个问题:"光让 LLM 生成不够,还缺哪一道把关?"——这恰是 §3 "增强而非取代" 在方法演进上的展开。看懂这条逻辑,你就能预判这个方向的下一步:继续往里加经典规划的要素(前瞻、回溯、约束传播),直到它在某些维度上逼近 LLM-as-Modeler——而后者干脆把搜索完全交还给经典规划器(§7)。两条范式,殊途同归地在"拉回可验证性"。
⚠️ 常见陷阱
- 陷阱 4-1:把 Say 分当成"LLM 生成一句话"。 Say 分不是让 LLM 自由生成,而是让 LLM 给每个候选技能描述打分(算对数似然)。这个区别很重要:打分把输出空间限制在技能库内,从根上避免幻觉出库外动作。SayCan 用 LLM 的"评分能力"而非"生成能力"。
- 陷阱 4-2:以为乘法只是"加权的一种"。 加法(加权和)允许补偿,乘法实现一票否决——这是质的区别(§4.3 反事实三 vs 四)。把乘法误当加权和,就丢掉了"可行性否决语言"这个 SayCan 的灵魂。
- 陷阱 4-3:以为 affordance 一定要用 RL 价值函数。 \(p_{\text{afford}}\) 是个接口,价值函数只是 SayCan 的一种实现。它也可以来自几何可达性检查、碰撞检测、成功率统计、甚至 VLM 的判断(§8)。关键是"它估计当前状态下技能能否成功",实现可换。
- 陷阱 4-4:以为 SayCan 解决了长程规划。 SayCan 是贪心的,长程任务上会短视走死。这正是 SayCanPay 加 Pay + 搜索要补的。别把"能跑通短任务"误读成"能可靠地做长程规划"。
练习
- 写出 SayCan 的选择公式,并用"我把饮料洒了"的例子,给"用吸尘器""拿海绵""原地待命"三个候选分别估一个定性的 Say 分(高/中/低)和 Can 分(高/中/低),算出乘积排序,说明为什么"拿海绵"胜出。
- 用反事实论证"为什么必须乘法不能加法":构造一组具体的 Say/Can 分数,使得加权和会选出一个物理上做不到的动作,而乘法不会。
- SayCan、Grounded Decoding、SayCanPay 三者,哪个最适合"技能可以自由组合、无法预先枚举"的场景?哪个最适合"长程、要避免走死胡同"的场景?分别说明理由。
- (联系 T3)SayCan 的"让价值函数把可行性流回 LLM 打分",与 PDDLStream"让采样器把可行性流回符号搜索",在思想上有什么共性?两者各自缝合的是哪两个世界?
5. 闭环推理:ReAct 与 Inner Monologue ⭐⭐⭐¶
SayCan 用 affordance 在决策时把可行性拉回来,但它对一个问题无能为力:执行出意外了怎么办? 机器人去拿海绵,结果海绵滑掉了;规划好的动作执行失败了;环境里突然出现没料到的东西。SayCan 的贪心循环会继续往下走,浑然不觉刚才那步根本没成。这一节讲 LLM-as-Planner 的另一条主线——闭环(closed-loop):让执行反馈回流到 LLM,使它能边做边纠错。
5.1 开环 vs 闭环:一次性规划的脆弱¶
先厘清两个概念,它们是理解本节的钥匙,也直接对应总论 §4.3"怎么稳地做下去"。
- 开环规划(open-loop):LLM 一次性把整个计划生成出来,然后不管不顾地逐条执行,执行过程中不接收任何反馈。像闭着眼睛背完一套动作再做。
- 闭环规划(closed-loop):执行每一步后,把环境反馈(成功了吗?看到了什么?)喂回 LLM,让它据此决定下一步——必要时重新规划、纠正、重试。像睁着眼睛边看边做。
开环为什么脆弱?因为它默认了一个在真实世界几乎必然破裂的假设:计划生成时的世界状态,会一直保持到执行完成、且每步都成功。可现实里(总论 §2.1"一个会犯错的世界"):抓取会滑脱、柜门会卡住、物体位置和预想不符、还可能有人动了东西。开环计划的第 3 步一旦失败,后面第 4、5、6 步全部建立在一个错误的世界假设上,越走越偏,无人察觉。
本质洞察:开环与闭环的差距,本质是"是否承认世界会偏离计划"。开环假设世界顺从计划,闭环假设世界会捣乱、于是持续校对。这与总论 §4.3 的洞察完全一致——"一个只会规划不会执行监控的机器人,在实验室能跑、一到真实环境就因为世界不按计划走而频繁卡死"。对 LLM 规划而言,闭环尤其关键,因为 LLM 本就容易幻觉(§2.3)——开环让幻觉无法被纠正、一错到底;闭环则给了"现实反过来纠正幻觉"的机会。闭环是 LLM 规划从"实验室玩具"走向"真实可用"的必经之路。 这也是为什么本章把它单列一节、并在 §11 把它接到 T5 行为树(执行层的工业级实现)。
5.2 ReAct:推理与行动交替¶
ReAct(Yao et al., ICLR 2023)给闭环提供了一个极简而通用的范式。它的名字是 Reasoning + Acting 的合写,核心是让 LLM 在生成时交替产出两种东西:
- Thought(推理):一段自然语言的思考——分析现状、回顾目标、决定下一步策略、处理异常。
- Action(行动):一个具体动作——调用某个技能、查询某个信息、与环境交互。
- 执行 Action 后,环境返回 Observation(观察),再喂回 LLM,进入下一轮 Thought。
于是生成轨迹长这样:
Thought 1: 用户要我整理桌子。先看看桌上有什么。
Action 1: observe(table)
Observation 1: 桌上有一个杯子、一本书,杯子在书的右边。
Thought 2: 杯子和书都要归位。杯子先放到架子。先抓杯子。
Action 2: pick(cup)
Observation 2: 抓取失败——杯子太滑,没夹住。 ← 执行反馈回流
Thought 3: 抓取失败了。可能夹得太松。换更大的夹持力再试一次。 ← LLM 据反馈纠错
Action 3: pick(cup, force=high)
Observation 3: 抓取成功,现在握着杯子。
Thought 4: 成功了。现在放到架子上。
Action 4: place(cup, shelf)
...
关键在 Thought 3:Observation 2 报告了失败,LLM 在 Thought 3 里"想"了一下原因并调整策略。这就是闭环纠错——反馈进来,推理消化,行动调整。ReAct 论文证明了这种"推理-行动"交替的威力:通过让 LLM 交替生成推理轨迹和任务相关动作,推理轨迹帮助模型归纳、追踪和更新行动计划并处理异常,动作则让它从外部环境获取额外信息;在 ALFWorld 和 WebShop 两个交互式决策基准上,ReAct 仅用一两个示例就显著超过模仿学习与强化学习方法。
为什么 Thought 这一步有用?因为它给 LLM 一个显式的"想"的空间(呼应 §9 会讲的 Chain-of-Thought)。没有 Thought,LLM 看到"抓取失败"只能直接蹦下一个 Action,容易重复同样的错;有了 Thought,它先用语言把"为什么失败、该怎么改"推演一遍,再行动——推理为行动提供了纠错的依据。Reasoning 让 Acting 变得可纠错。
5.3 Inner Monologue:把反馈分成三类¶
ReAct 给了"交替"的框架,但没细分"反馈具体有哪些种"。Inner Monologue(Huang et al., CoRL 2022)把环境反馈系统地拆成三类,让闭环的信息来源更完整。它的核心主张是:通过利用环境反馈,LLM 能够在机器人控制场景中形成一种"内心独白"(inner monologue),从而更丰富地处理信息并做出规划,而无需额外训练。三类反馈是:
| 反馈类型 | 回答什么问题 | 来源 | 例子 |
|---|---|---|---|
| 成功检测(success detection) | 上一个动作做成了吗? | 技能自带的成功分类器 / 力觉 | "抓取成功" / "抓取失败" |
| 被动场景描述(passive scene description) | 现在环境是什么样? | 物体检测器 / VLM,持续报告 | "桌上有杯子、书;杯子在书右边" |
| 主动场景查询(active scene query) | 针对某疑问,环境的回答是? | LLM 主动提问、感知/人回答 | LLM 问"杯子是什么颜色?"→"蓝色" |
这三类构成了一个"内心独白":机器人一边行动,一边在"脑子里"自言自语——"我刚才抓成功了吗(成功检测)?现在桌上还有什么(被动描述)?这个我不确定的,我得问一下(主动查询)?"——用这些反馈不断更新自己对世界的认识和下一步计划。
把三类反馈对应回 §5.2 的 ReAct 轨迹:Observation 2"抓取失败"是成功检测;Observation 1"桌上有杯子、书"是被动场景描述;如果 Thought 里冒出"我不确定杯子在不在书后面,先看一眼"然后 Action: observe(behind book),那就是主动场景查询。ReAct 提供"交替"的骨架,Inner Monologue 填充"反馈有哪三类"的血肉——两者高度互补,常被一起使用。
本质洞察:Inner Monologue 的三类反馈,本质是给 LLM 补上感知-行动闭环里"感知"那一环的语言化接口。LLM 活在纯文本世界里,它本身既看不见也摸不着——必须有人把"成功了吗""现在啥样""那个东西是什么"翻译成文字喂给它。三类反馈正是这套翻译的分类:一类报动作结果、一类报环境全貌、一类应主动询问。把它和总论 §3.8 的数据流对照——这正是"④执行层把失败实时反馈回上游"在 LLM 语境下的具体形态。没有这套语言化的反馈接口,LLM 就是个"闭着眼睛下指令"的开环系统;有了它,LLM 才睁开了眼睛。 而"睁眼"恰恰是治幻觉的良药——现实的反馈会不断把 LLM 一厢情愿的想象拉回地面。
5.4 闭环纠错的边界:它能纠什么,不能纠什么¶
闭环很强大,但要避免把它神化。它能纠正的,是"执行层面、能被反馈观测到"的偏差:抓取滑脱(成功检测能发现)、物体不在预想位置(场景描述能发现)、需要补充信息(主动查询能获取)。
它纠不了的,是几类更深的问题:
- 反馈本身错了:如果成功检测器误报(明明失败却报成功),闭环会基于错误反馈继续,甚至越纠越错。闭环的可靠性受限于反馈的可靠性。
- 根本不可行的目标:用户让机器人"把月亮摘下来",再多闭环也纠不出可行计划。可行性的根本判断(§10)不是闭环能替代的。
- 需要全局重排的失败:闭环擅长局部纠错(这一步重试、换个力度),但如果失败意味着整个计划方向错了(比如发现门锁了、整条路线作废),需要的是重新规划而非局部重试。这时该触发上游的符号规划器(T1)重新搜索——这正是 §11 要讲的"闭环纠错 + 重规划"的分工,也是 T5 行为树的核心机制。
5.5 闭环的代价:反馈频率与延迟的权衡¶
闭环不是免费的。每"闭"一次环——把环境反馈喂回 LLM、等它生成下一步——都要付出一次 LLM 推理的延迟(当代大模型一次推理动辄几百毫秒到数秒)。这引出一个被新手忽略、却在真实系统里举足轻重的工程权衡:闭多紧的环?
把"闭环频率"放到一条谱上看:
| 闭环粒度 | 每隔多久回 LLM 一次 | 优点 | 代价 | 适合 |
|---|---|---|---|---|
| 每个低层控制步 | 极频繁(毫秒级) | 反应最快 | LLM 延迟根本跟不上控制频率(1kHz) | 几乎不可行——LLM 太慢 |
| 每个技能/动作后 | 中等(秒级) | 能及时发现动作失败 | 每步一次 LLM 推理,长任务累积延迟 | ReAct/Inner Monologue 的典型粒度 |
| 仅在异常时 | 稀疏(按需) | 省推理、正常时全速跑 | 异常检测器若漏报,错误会持续 | 成熟系统的常见折中 |
| 完全开环 | 从不 | 零额外延迟 | 一错到底(§5.1) | 仅受控 demo |
本质洞察:闭环频率的选择,本质是"反应性"与"实时性/成本"之间的权衡——闭得越紧,越能及时纠错(反应性高),但每次闭环的 LLM 延迟越是拖累整体节奏、烧越多推理成本。这解释了一个真实系统的常见架构:不是让 LLM 参与每一个控制步(它太慢),而是把"快速反应"交给底层(行为树/控制器以高频运行、自己处理可预期的局部失败如重试),只在"底层兜不住的异常"时才上升到 LLM 这一层重新决策。这是一种分层闭环——底层闭紧环(高频、便宜、处理常规),LLM 层闭松环(低频、昂贵、处理意外)。它和总论 §6.1"设计时决策 vs 运行时决策"的两时间尺度、与 T5 行为树"高频 tick + 偶发重规划"的设计完全同构。记住:LLM 适合做"慢思考"的纠错决策,不适合做"快反应"的实时控制——把它放在正确的频率层级上,是用好闭环的关键。
这也精确化了 §5.4 的"局部纠错 vs 重新规划"分工:局部纠错应尽量下放到底层高频处理(重试、微调力度,不必惊动 LLM),只有需要重新决策方向的失败才上升到 LLM/符号规划层。把什么都丢给 LLM 闭环,系统会被 LLM 的延迟拖垮;什么都不丢给 LLM,又退回开环的脆弱。找准这条分界,正是工程功力所在。
⚠️ 常见陷阱
- 陷阱 5-1:以为闭环 = 不会失败。 闭环只是给了纠错的机会,不保证纠错成功。反馈错、目标不可行、需要全局重排时,闭环都可能无能为力。闭环降低失败率,不消除失败。
- 陷阱 5-2:把 ReAct 的 Thought 当成可有可无的注释。 Thought 不是装饰——它是 LLM"消化反馈、决定纠错策略"的工作空间。去掉 Thought 直接生成 Action,纠错能力会显著下降(这与 §9 的 CoT"想一步再答"同源)。
- 陷阱 5-3:混淆"局部纠错"与"重新规划"。 闭环(ReAct/Inner Monologue)擅长局部纠错(重试、微调);遇到方向性失败需要的是重新规划(回到符号规划器搜一条新计划)。把两者混为一谈,会让系统在"该重规划时还在原地反复重试"上死循环。
- 陷阱 5-4:以为有了闭环就不需要执行层(T5)。 ReAct/Inner Monologue 给的是闭环的思路,工业级的执行监控、异常恢复、实时响应要靠行为树(T5)落地。LLM 的闭环是"大脑层面的纠错决策",行为树是"执行层面的稳健机制",两者分工不同(§11 详述)。
练习
- 用一个具体任务(如"把洒在地上的牛奶清理掉")写一段 ReAct 风格的 Thought/Action/Observation 轨迹,其中至少包含一次"执行失败 → LLM 据反馈纠错重试"。
- Inner Monologue 的三类反馈各举一个新例子(不要用正文的),并说明若缺失该类反馈,机器人会在什么情况下犯错。
- 给出一个闭环纠不了的失败例子(属于 §5.4 三类之一),说明为什么它需要的不是闭环重试,而是别的机制(哪个?)。
- (联系 T5)"局部纠错"与"重新规划"的分工,在行为树里分别对应什么节点/机制?(提示:回想总论 §3.5 行为树的 Fallback、重规划触发。)
6. Code-as-Policies:把计划写成程序 ⭐⭐⭐¶
SayCan 让计划是"技能序列",ReAct 让计划是"Thought/Action 交替"。Code-as-Policies(Liang et al., ICRA 2023)给出第三种、也是别具一格的一种输出形态:让 LLM 把计划直接写成可执行的程序代码。这一节讲清"计划即程序"为什么是个强大的形态、它如何接地、又有什么代价。
6.1 核心思想:计划即程序¶
观察一个事实:当代 LLM 不仅会写自然语言,还很会写代码(它们在 GitHub 级代码上训练过)。Code-as-Policies 抓住这一点:与其让 LLM 输出一串动作描述,不如让它输出一段调用机器人 API 的 Python 程序——这段程序本身就是策略(policy)。
举例。用户说"把所有的积木按颜色分别堆起来"。Code-as-Policies 让 LLM 生成的不是"拿红积木1、放到红堆、拿红积木2……"这样的序列,而是一段程序:
# 用户指令: "把所有积木按颜色分别堆起来"
blocks = detect_objects("blocks") # 调用感知 API
colors = set(get_color(b) for b in blocks) # 提取所有颜色
for color in colors: # 对每种颜色
same_color = [b for b in blocks if get_color(b) == color]
base = same_color[0]
for b in same_color[1:]: # 把同色积木依次堆上去
pick_and_place(b, on_top_of(base))
base = b
这段程序里藏着自然语言计划表达不了、或表达起来极笨拙的东西:
- 循环:
for color、for b——"对每一个/每一种"这种量化逻辑,程序用循环天然表达;动作序列则要把循环展开成具体步数(可物体数量运行时才知道,没法预先展开)。 - 条件:
if get_color(b) == color——按条件分支,程序原生支持。 - 组合与抽象:
on_top_of(base)、pick_and_place(...)——可以调用/复用函数,把复杂行为封装。 - 感知-动作交织:
detect_objects的结果直接喂给后续逻辑——感知与决策在同一段代码里流动。
6.2 LMP 与层级分解¶
Code-as-Policies 把这类"LLM 生成的、调用 API 的程序"称作 LMP(Language Model Programs,语言模型程序)。论文的一个关键贡献是层级化的 LMP 生成:Code as Policies 提出一种以机器人为中心的语言模型生成程序(LMP)的范式,能表达反应式策略(如阻抗控制器)以及基于路点的策略(如视觉伺服的抓放、基于轨迹的控制),并在多个真实机器人平台上验证。
"层级"指:当 LLM 写主程序时遇到一个尚未定义的函数(比如它写了 on_top_of(base) 但这个辅助函数还不存在),它可以递归地再生成那个函数的代码。也就是 LLM 写程序时可以"现编现用"地定义辅助函数,一层套一层。这种递归定义让 LMP 能处理相当复杂的任务,而不必把所有逻辑塞进一个扁平的主程序。
把 Code-as-Policies 放回 §3.2 的范式:它属于 LLM-as-Planner(计划是 LLM 直接生成的,只不过形态是代码)。它的可行性怎么兜?靠两点——一是API 的设计(机器人只暴露它确实会做的 API,LLM 只能调这些,类似 SayCan 限制技能库),二是程序里可以写反馈循环和条件检查(比如 while not is_grasped(): retry()),把 §5 的闭环思想直接编码进代码。
6.3 程序形态 vs 符号序列:一张对比表¶
把 Code-as-Policies 的"计划即程序"和经典符号规划的"计划即动作序列"并置,差异一目了然:
| 维度 | 符号动作序列(PDDL 计划) | 程序(LMP, Code-as-Policies) |
|---|---|---|
| 计划长什么样 | [pick(c1), place(c1,r), pick(c2), ...] 扁平序列 |
含循环/条件/函数调用的代码 |
| 表达"对每个物体" | 必须展开成具体步(需预知数量) | for x in objects 一行搞定 |
| 表达条件分支 | 规划时就要枚举所有分支 | if/else 运行时分支 |
| 表达反馈循环 | 本身不含(要靠外层执行器) | while not done: ... 内建 |
| 可行性保证 | 经典规划器保证满足前提(强) | 靠 API 设计 + 运行时检查(弱) |
| 可验证性 | 高(PDDL 可被验证器逐条查) | 低(要靠运行/测试,难静态验证) |
| 适合的任务 | 离散、组合、要可验证保证 | 反应式、含循环条件、感知交织 |
| 范式归属 | 经典①(或 §7 as-Modeler 的产物) | LLM-as-Planner(§3.2) |
本质洞察:程序形态的真正威力,在于它把控制流(control flow) 这个维度还给了计划。符号动作序列是"线性的、展开的、静态的"——它无法表达"重复直到某条件""按情况分支""失败就重试"这类控制结构,只能把一切预先展开成一条直线。而程序天生就是控制流的语言:循环、条件、递归、异常处理。这让 Code-as-Policies 特别擅长反应式、参数化、含运行时不确定性的任务("把所有 X 都怎样""重复到成功为止")。代价是可验证性的丧失——一段含循环和条件的程序,远比一条扁平的动作序列难以静态验证其正确性与安全性(停机问题在那儿摆着)。这正是 §3.3 那张表的又一次印证:表达力与可验证性此消彼长。 程序形态把表达力推到很高,于是把可验证性压到很低——用它时,安全保障就更依赖 API 的精心设计和运行时的检查,而非事前的形式化验证。
6.4 什么时候适合用 Code-as-Policies¶
综合上面的分析,Code-as-Policies 的甜区(sweet spot)很清楚:
- 适合:任务含明显的循环/条件/参数化逻辑("把所有积木分类""重复擦直到干净""如果是红的就放左边");需要反应式控制(阻抗、伺服);机器人有一套设计良好的 API可供调用;容忍用运行时检查代替事前验证。
- 不适合:任务需要强可验证保证(安全攸关、要证明计划合法);需要全局最优(程序不做最优搜索);领域已有完整 PDDL、用经典规划器更稳妥;任务是纯离散组合搜索(符号规划或 as-Modeler 更合适)。
一句话选型:要控制流灵活、容忍弱验证,用 Code-as-Policies;要严谨保证、可验证最优,回到符号规划或 LLM-as-Modeler(§7)。
6.5 安全执行:沙箱与 API 白名单 ⭐⭐⭐¶
"让 LLM 写代码、然后执行它"这件事,比"让 LLM 写动作序列"多了一重风险——执行的是 LLM 生成的、未经验证的代码。这段代码可能调用不存在的函数(H1 幻觉的代码版)、写出死循环、甚至(在最坏情况下)执行危险操作。所以 Code-as-Policies 落地时,"怎么安全地执行 LLM 写的程序"是绕不开的工程问题。
为什么不能直接 exec() LLM 写的代码? 设想最天真的实现:
这段代码的问题,和 §2.3 的本质一脉相承——LLM 是续写引擎,它生成的代码"看起来对"不等于"安全可执行"。exec 把整个 Python 运行时(文件系统、网络、任意库)都暴露给了 LLM 的输出。一个幻觉出的 import os; os.system(...)、一个 while True 死循环,都能让系统失控。这正是 §6.3 那句"可验证性的丧失"在执行层的具体危害。
正确做法:用 API 白名单 + 受限沙箱把执行空间圈起来。 核心思想和 SayCan 限制技能库(§4.4)、提示给能力边界(§9.5)一脉相承——把 LLM 能调用的东西,严格限制在一组安全、受参数约束的机器人 API 上:
# ✅ 正确:只暴露白名单 API, 在受限命名空间里执行, 带超时
SAFE_API = { # 白名单: 只有这些函数 LLM 能调
"detect_objects": detect_objects, # 每个都是经过安全审查的机器人原语
"pick_and_place": pick_and_place, # 参数受约束(如目标必须可达, 内部再校验)
"get_color": get_color,
# 注意: 没有 open/exec/import/os —— LLM 调不到危险操作
}
def run_lmp(code: str, timeout_s: float = 5.0):
# 在只含白名单的受限命名空间里执行(LLM 代码看不到其他任何东西)
restricted_globals = {"__builtins__": SAFE_BUILTINS, **SAFE_API}
try:
run_with_timeout(code, restricted_globals, timeout_s) # 超时杀掉, 防死循环
except NameError as e: # LLM 调了白名单外的函数 → 当场拦下(H1 代码版)
raise UnsafeCodeError(f"调用了未授权的 API: {e}")
这里每一道防线都对应本章的一条原则:白名单 = 限制输出空间防幻觉(§4.4、§9.5);受限命名空间 = 不让 LLM 碰危险操作;超时 = 防 §6.2 提过的死循环;NameError 拦截 = §10 第一层语法/白名单校验在代码形态下的体现。
本质洞察:Code-as-Policies 的安全性,不来自"相信 LLM 写得对",而来自"把 LLM 能做的事先圈死在一个安全集合里"——这与全章"生成不可信、把关靠确定性机制"的主线完全一致。API 白名单本质上是一道编译期/加载期的关卡:LLM 的代码无论怎么写,它能触达的操作集合是被你(而非 LLM)预先决定的。这把"程序形态丢失了可验证性"(§6.3)的风险,从"事后验证整段程序"(难,停机问题)转化为"事前限制可用操作"(易,白名单是有限集)。好的 API 设计因此成了 Code-as-Policies 安全的命门——API 的粒度(暴露多底层的操作)、参数约束(每个操作内部再校验可行性)、副作用边界(能不能碰文件/网络),直接决定了"再坏的 LLM 代码最多能造成多大破坏"。这也呼应陷阱 6-3:API 设计不是小事,它是安全的第一道、也是最根本的一道防线。
⚠️ 常见陷阱
- 陷阱 6-1:以为程序形态比符号序列"更高级、总该用"。 不是。程序换来表达力、赔上可验证性。安全攸关或要可验证保证的任务,扁平的、可被验证器逐条检查的符号计划反而更可取。形态选择取决于任务对"表达力 vs 可验证性"的需求,没有绝对高下。
- 陷阱 6-2:以为 LLM 写的代码一定能跑。 LLM 写的程序同样会有 bug——调用不存在的 API、逻辑错、死循环。它和 §2.3 的幻觉是同一回事,只是换了载体(代码而非动作描述)。必须有沙箱执行、异常捕获、API 白名单来兜(呼应 §10)。
- 陷阱 6-3:把 API 设计当成小事。 恰恰相反——Code-as-Policies 的可行性兜底主要靠 API。API 只暴露机器人确实会做的、且参数受约束的操作,就能把 LLM 的输出空间限制在安全区内(类似 SayCan 限制技能库)。API 设计得好不好,直接决定系统安全不安全。
- 陷阱 6-4:以为它能取代符号规划的搜索。 程序里的循环/条件是预先写死的控制流,不是搜索。需要"在巨大组合空间里找一条满足约束的序列"时,那是经典规划器的搜索能力,程序的控制流替代不了。
练习
- 用 Code-as-Policies 风格,为"把桌上比手机大的物体都放进抽屉"写一段 LMP 伪代码,标出其中的循环、条件、API 调用各在哪。
- 同一个任务(第 1 题),如果用 PDDL 动作序列表达会遇到什么困难?(提示:物体数量、"比手机大"这个条件何时能判断。)
- 举一个不该用 Code-as-Policies、而该用符号规划/as-Modeler 的任务,说明理由(从"可验证性"或"最优性"角度)。
- Code-as-Policies 怎么把 §5 的闭环思想编进代码?写一小段含"抓取失败就重试"的 LMP 片段。
7. LLM-as-Modeler:让大模型生成 PDDL ⭐⭐⭐⭐¶
§4-§6 都是 LLM-as-Planner——让 LLM 直接出计划,可行性靠 affordance、反馈、API 层层兜。这一节转向另一大范式 LLM-as-Modeler,它走了一条哲学上截然不同的路:让 LLM 退后一步,不出计划,只出"规划问题的形式化模型"(PDDL),然后把模型交给经典规划器去完备地搜索求解。 这是本章的硬核(⭐⭐⭐⭐),也是"增强而非取代"这条边界贯彻得最彻底的范式——因为计划完全由可信的经典规划器产出,LLM 的不可靠性被严格地堵在了"模型对不对"这一道可验证的关卡前。
7.1 核心思想:LLM 写模型,规划器来求解¶
回顾 §3.2 的数据流。LLM-as-Modeler 把规划拆成"建模"和"求解"两步,让 LLM 只干第一步:
自然语言指令 + 领域背景
│
▼ LLM 生成形式化模型(它擅长的"翻译")
┌──────────────────────────────────────────┐
│ PDDL domain (动作模型) 和/或 problem │
│ (:action pick :precondition (handempty) │
│ :effect (holding ?x) ...) │
└──────────────────────────────────────────┘
│
▼ 经典规划器求解(它擅长的"完备搜索")
┌──────────────────────────────────────────┐
│ Fast Downward / FF: 在合法 PDDL 上搜索 │
│ → 计划保证满足所有前提、可配置最优 │
└──────────────────────────────────────────┘
│
▼
形式化保证的动作序列
这条路的巨大好处,源自 §0 的 Q3:经典规划器在合法 PDDL 上是完备、可验证、可最优的。 一旦 LLM 写出的 PDDL 经检验确认无误,剩下的搜索就由可信的经典规划器全权接管——它找到的计划必然合法(满足所有前提)、可配置最优,绝不会幻觉出不存在的动作。LLM 的"不严谨"被彻底隔离在"建模"这一步之外,碰不到最终计划。
LLM+P(Liu et al., 2023)是这条路的开创性框架。它的做法是:LLM+P 接收一个规划问题的自然语言描述,先把它转成 PDDL,再用经典规划器快速求解,最后把解翻译回自然语言;实验显示 LLM+P 能为大多数问题给出最优解,而 LLM 自己对多数问题连可行解都给不出。注意最后半句——这正是 §2.3 那个 3% 的另一面:同一个 LLM,让它直接规划近乎失败,让它只翻译成 PDDL 再交规划器,却能给出最优解。 一念之差,天壤之别。
本质洞察:LLM+P 的实验结果,是对本章核心边界最有力的一次量化背书。同一个 LLM、同一批问题,区别只在于让它干哪一步——直接规划(它的弱项,~3%)还是翻译建模(它的强项,接近最优)。这把"增强而非取代"从一句口号变成了可复现的实验事实:LLM 的价值不在于替规划器做搜索,而在于替人做那件繁琐的"把自然语言翻译成形式化模型"的活儿。 它把人类规划专家从"手写 PDDL"里解放出来,同时一丝不让地保住了经典规划器的所有理论保证。这就是钟摆被拉回的极致——范围扩大到了开放自然语言(LLM 翻译),可验证性却一点没丢(规划器求解)。理解了这一点,你就抓住了 LLM-as-Modeler 全部方法的精髓。
7.2 三个层次:翻译 goal、生成 domain、泛化 program¶
"让 LLM 写模型"具体写什么?按 LLM 承担的形式化任务由轻到重,分三个层次,对应三组代表性工作。
层次一:只翻译目标(LLM 写 :goal)。 最轻量——domain 由人预先写好(领域动作模型相对稳定),LLM 只把用户的自然语言指令翻译成 PDDL 的 :goal。Xie 等人(2023)系统研究了这一层:他们实证研究了 LLM(尤其 GPT-3.5)把自然语言目标翻译成 PDDL 的效果,发现 LLM 在翻译任务上远比在规划任务上在行,能生成与自然语言指令一致、且符合给定 PDDL domain/problem 规范的可达成目标。这一层风险最小(domain 是人写的、可信),LLM 只碰目标这一小块,特别适合"领域固定、只是指令多变"的场景(如固定的家庭领域 + 千变万化的用户指令)。
层次二:生成领域模型(LLM 写 :action 的前提与效果)。 更重——让 LLM 生成整个 domain:有哪些动作、每个动作的前提和效果。这难得多,因为 domain 是"物理规律",写错一条前提/效果,后面所有计划都会出问题。Guan 等人(NeurIPS 2023)的工作是这一层的代表,关键在于它不指望 LLM 一次写对:他们构建一个用 PDDL 表达的显式世界(领域)模型,再用可靠的领域无关规划器求解;由于 LLM 未必一次生成完全可用的 PDDL,他们让 LLM 充当 PDDL 与纠正性反馈源(PDDL 校验器、人类)之间的接口,用 GPT-4 为 40 多个动作产出高质量 PDDL 模型,修正后的模型成功解决了 48 个有挑战的规划任务。这里的"校验器 + 反馈"闭环是这一层的灵魂(§7.3 详述)——它正是"把好严谨这道关"的具体机制。
层次三:生成泛化规划程序(LLM 写一个能解整类问题的 program)。 最重——不只解一个问题,而是为整个 PDDL 领域生成一段"通用解题程序"(给定该领域的任意新问题,这段程序都能高效产出计划)。Silver 等人(AAAI 2024)研究了这一层:他们考察 LLM 能否作为泛化规划器——给定一个 domain 和若干训练任务,生成一个能为该领域其他任务高效产出计划的程序;用 GPT-4 合成 Python 程序,配合"自动调试"(程序在训练任务上验证、出错则带四类反馈重新提示)与 CoT 摘要,发现 GPT-4 是出人意料地强大的泛化规划器,而自动调试至关重要。这一层把 LLM 的代码能力(§6)和经典规划的泛化思想结合,是 as-Modeler 里最前沿、也最接近"自动化规划工程"的方向。
把三个层次列成表:
| 层次 | LLM 写什么 | 难度 | 风险 | 代表 | 适合场景 |
|---|---|---|---|---|---|
| 一:翻译目标 | PDDL :goal |
低 | 低(domain 人写、可信) | Xie et al. 2023 | 领域固定、指令多变 |
| 二:生成 domain | :action 前提/效果 |
高 | 高(写错规律全盘错) | Guan et al. 2023 | 领域需快速建模、有校验闭环 |
| 三:泛化程序 | 解整类问题的 program | 最高 | 中(程序可在训练集验证) | Silver et al. 2024 | 自动化规划工程、需泛化 |
本质洞察:这三个层次,是按"把多少形式化负担转给 LLM"递增排列的——层次一只让它碰目标(最小负担、最小风险),层次三让它写整个解题器(最大负担、最大收益)。这里有一条清晰的工程权衡:LLM 承担的形式化越多,省的人力越多,但出错的影响面也越大、越需要强力的校验闭环兜底。层次一几乎不需要校验(domain 可信),层次二必须有校验器闭环(Guan 的灵魂),层次三靠在训练集上自动调试(Silver 的灵魂)。选哪一层,本质是回答"我愿意让 LLM 碰多少形式化、又配得起多强的校验"——这又一次印证了全章主线:LLM 出力的边界,由"配套的把关能力"决定。
7.3 灵魂所在:校验器反馈闭环(generate-validate-repair)¶
层次二、三的成功,都不靠"LLM 一次写对",而靠一个自纠错闭环。这是 LLM-as-Modeler 区别于"天真地让 LLM 写 PDDL"的关键,值得单独讲透。它的结构是 生成-校验-修复(generate → validate → repair):
┌─────────────────────────────────────────────────────────────┐
│ 1. 生成: LLM 根据自然语言 + 领域背景, 写出 PDDL(domain/goal) │
│ │ │
│ ▼ │
│ 2. 校验: 把 PDDL 交给【确定性的、可信的校验器】检查 │
│ ├─ 语法校验: PDDL 解析器(语法对不对、谓词/类型声明了吗) │
│ ├─ 语义校验: VAL 等计划验证器(动作前提/效果自洽吗、 │
│ │ 目标可达吗、有无孤立谓词/类型错误) │
│ └─ (可选)在训练任务上试解, 看能否产出正确计划 │
│ │ │
│ ┌───────────────┴───────────────┐ │
│ 校验通过 校验失败 │
│ │ │ │
│ ▼ ▼ │
│ 3a. 交经典规划器求解(完备) 3b. 把【具体报错信息】喂回 LLM │
│ → 合法可行计划 "第N行谓词未定义""动作X │
│ 前提引用了不存在的类型" │
│ → 回到步骤 1 重写 │
└─────────────────────────────────────────────────────────────┘
这个闭环的精髓在两点:
- 校验器是确定性的、可信的——不是另一个 LLM。 PDDL 解析器、VAL 计划验证器都是经典的、形式化的工具,它们的判断确定无误。用它们来检查 LLM 的输出,等于用"可信的尺子"量"不可信的产物"。这与§10要强调的原则一致:别让 LLM 给自己把关,要让确定性工具把关。
- 反馈是具体的、可定位的。 步骤 3b 喂回去的不是泛泛的"你错了",而是校验器吐出的精确报错("第 N 行谓词
on未声明""动作pick的前提引用了未定义的类型?z")。LLM 拿到精确报错,修复的命中率远高于盲目重写。这正是 Guan 工作里"LLM 作为 PDDL 与纠正反馈之间的接口"的含义——LLM 既是写手,又是"读懂报错并据此修订"的修订者。
把它和 §5 的闭环对照:§5 ReAct/Inner Monologue 是执行层的闭环(用环境反馈纠执行偏差),这里是建模层的闭环(用校验器反馈纠模型错误)。两者同构——都是"产出 → 反馈 → 纠错",只是反馈源不同(一个是物理环境,一个是形式化校验器)。自纠错闭环是贯穿本章的核心模式,在执行层、建模层都出现。
7.4 为什么 as-Modeler 把可验证性钟摆拉得最回¶
回到 §3.4 的钟摆。LLM-as-Modeler 之所以被称为"把钟摆拉得最回"的范式,因为它在数据流的设计上,把 LLM 的不可靠性完全挡在了最终计划之外:
- LLM 只碰模型(PDDL),碰不到计划——计划是经典规划器搜出来的。
- 模型在交给规划器前,要过确定性校验器——语法、语义、可解性逐层把关。
- 校验通过的模型,规划器对它的求解是完备、可验证、可最优的。
于是最终计划继承了经典规划的全部理论保证,而 LLM 的贡献被限定在"把自然语言翻译成(待校验的)形式化模型"——它的不严谨即便发作(写错 PDDL),也会被校验器拦下、退回重写,不会漏到最终计划里。对照 §3.3 那张表:as-Modeler 在"可行性保证""最优性""可解释/可调试"三列上全面优于 as-Planner,代价是"对领域形式化的依赖"更高、"开放/常识任务"上稍弱(常识要先编码进 domain/goal)。
本质洞察:as-Modeler 和 as-Planner 的终极区别,是"信任谁来产出最终计划"。as-Planner 信任 LLM 产出计划、再用一堆下游机制(affordance、反馈、API)去补救它的不可靠;as-Modeler 干脆不信任 LLM 产出计划,只信任它做翻译,把产出计划这件大事完全交给可信的经典规划器。前者是"用了不可靠的东西、努力补救",后者是"把不可靠的东西挡在关键路径外"。从可验证性角度,后者显然更稳——这就是为什么需要严谨保证的任务(仓库调度、安全攸关)几乎都倾向 as-Modeler。但它有个前提:得有 PDDL domain(人写或 LLM 生成 + 校验)。当领域开放到连 domain 都难以形式化时("看看这个陌生环境有什么好玩的"),as-Modeler 就力不从心,那时才轮到 as-Planner 的开放性登场。两范式的适用边界,最终由"领域能否被形式化"划定。
7.5 一个端到端的例子:从"收拾桌子"到合法计划¶
把 §7.1-§7.4 串成一个贯穿场景(总论的"收拾厨房"的桌面版)的 as-Modeler 全流程,让抽象落地:
用户: "帮我把桌子收拾干净, 杯子放架子, 书放书柜"
│
▼ [层次一: LLM 翻译 goal] domain 已由人写好(pick/place/move 等动作模型)
LLM 输出 :goal →
(:goal (and (on cup shelf) (on book bookshelf)
(forall (?x - clutter) (stored ?x))))
│
▼ [校验] PDDL 解析器: 谓词 on/stored 声明了吗? 类型 clutter 存在吗?
├─ 失败示例: LLM 写成 (on cup shelve) —— "shelve" 拼错, 解析器报"未定义对象 shelve"
│ → 报错喂回 LLM → LLM 改成 shelf → 重新校验通过
▼ [校验通过]
│
▼ [经典规划器 Fast Downward 求解] 在合法 domain+goal 上完备搜索
计划(保证满足所有前提, 如"放架子前手得先抓着杯子"):
move(table) → pick(cup) → move(shelf) → place(cup,shelf)
→ move(table) → pick(book) → move(bookshelf) → place(book,bookshelf) → ...
│
▼ [交下游] 每个动作的几何可行性(够不够得到)交 T3/T4; 执行监控交 T5
注意整条流程里 LLM 只出现在第一步(翻译 goal)和校验失败时的修复(拼写纠错),计划本身完全是经典规划器搜出来的——它保证了"放架子前必须先抓着杯子"这类前提约束(LLM 直接规划时常忘)。这就是 as-Modeler 的价值:用 LLM 的语言能力解决"听懂指令",用经典规划器的搜索能力保证"计划合法"。
⚠️ 常见陷阱
- 陷阱 7-1:让 LLM 既写 PDDL 又自己求解。 这就把 as-Modeler 退化回 as-Planner 了,丢掉了交经典规划器求解的全部保证。as-Modeler 的关键是求解必须交给经典规划器,LLM 只负责到"写出合法 PDDL"为止。
- 陷阱 7-2:用另一个 LLM 当校验器。 校验必须用确定性的形式化工具(PDDL 解析器、VAL)。用 LLM 校验 LLM,等于让续写者审续写——它可能"幻觉"地认为错误的 PDDL 是对的(§10 详述)。可信的校验器是 as-Modeler 闭环的基石。
- 陷阱 7-3:以为 LLM 一次就能写对 domain。 层次二、三几乎不可能一次写对。Guan 和 Silver 的成功关键都在自纠错闭环(校验器/自动调试反馈),不在"模型够强一次到位"。没有闭环的 as-Modeler 极脆弱。
- 陷阱 7-4:选错层次。 领域固定就别让 LLM 去生成 domain(层次二,高风险),只让它翻译 goal(层次一,低风险)就够。让 LLM 承担超出必要的形式化负担,是在白白引入风险。先问"哪些部分人写更可靠、哪些非 LLM 不可",再定层次。
- 陷阱 7-5:以为有了 as-Modeler 就不需要懂 PDDL。 恰恰相反——你必须懂 PDDL 才能判断 LLM 写的对不对、才能设计校验、才能看懂报错来修。这正是总论 §5.3"不懂 PDDL,连 LLM 生成的 PDDL 对不对都判断不了"的含义。as-Modeler 不是"PDDL 的替代品",是"PDDL 的自动写手 + 人工/工具审核"。
练习
- 用自己的话解释 LLM+P 的实验"同一个 LLM 直接规划近乎失败、翻译成 PDDL 再交规划器却接近最优",并说明它为什么是"增强而非取代"的有力证据。
- 画出 generate-validate-repair 闭环,标出"校验"这一步具体查哪三类问题(语法/语义/可解性),并说明为什么校验器绝不能用另一个 LLM。
- 给定三个任务,判断各该用 as-Modeler 的哪个层次(翻译 goal / 生成 domain / 泛化程序):(a) 一个领域已有成熟 PDDL domain、只是用户指令多变;(b) 一个全新领域、还没有任何 PDDL、要快速建模;(c) 一个领域要反复解大量同类新问题、希望一次生成通用解题器。
- (联系 §5)建模层的 generate-validate-repair 闭环,与执行层的 ReAct/Inner Monologue 闭环,结构上有什么共性?反馈源各是什么?
- 续写 §7.5 的例子:假设 LLM 把
:goal里漏写了(stored ?x)那一条(忘了"杂物要收纳"),校验器能发现吗?为什么这类"语义不完整"比"拼写错误"更难被自动校验抓住?(提示:思考校验器能验证"语法/可解",但能不能验证"目标是否完整表达了用户意图"。)
8. VLM 接地:把语言连到像素与三维 ⭐⭐⭐¶
到这里有个一直被绕过的问题该正面回答了。LLM 活在纯文本世界——可机器人面对的是像素、点云、三维空间。LLM 写出 pick(cup),但"哪个像素团是 cup""它的三维位姿是什么",LLM 自己根本不知道。怎么把语言里的符号,连到物理世界的感知? 这就是符号接地问题(symbol grounding problem),本节讲它在 LLM 任务规划里的解法——视觉语言模型(VLM)接地。
8.1 符号接地问题:language gap 的几何版¶
回顾 §2 的两道缝。语言缺口(听不懂指令)由 LLM 的语言能力补;但还有一道更底层的缝:LLM 输出的符号(cup、shelf、on)和物理世界的感知(像素、坐标)之间,没有天然的对应。
具体地,一个 LLM 生成的计划 pick(cup) 要真正执行,需要回答:
- 指代接地(referential grounding):场景里哪个物体是 "cup"?(要把符号
cup连到具体的视觉实例) - 空间接地(spatial grounding):这个 cup 在哪?它的三维位姿、抓取点是什么?(要把符号连到几何坐标)
- 关系接地(relational grounding):
(on cup table)这个关系,在当前感知里成立吗?(要把符号关系连到感知判断)
这三件事,纯 LLM 都做不到——它没有眼睛。这正是总论 §1.3"符号 vs 几何鸿沟"在 LLM 语境下的再现:符号(语言)和几何(感知)说着两种语言,需要一座桥。而 VLM(视觉语言模型,能同时处理图像和文本的模型,如 CLIP、开放词汇检测器、多模态大模型)恰好是这座桥——它把"语言描述"和"视觉内容"对齐在同一个表示空间里。
本质洞察:符号接地问题是 §2"两道缝"故事的第三道、也是最底层的一道缝。语言缺口是"听不懂人话",常识缺口是"不懂隐含规则",接地缺口是"不知道话里的词指物理世界的哪个东西"。前两道缝 LLM 自己能补,第三道缝 LLM 补不了——因为它没有感知。必须引入一个"看得见"的模型(VLM)来把符号连到像素与坐标。 这也再次印证全章主线:LLM 不是万能的,它有明确的能力边界(纯语言),越过边界的事(看、量、接地)要交给专门的模型。把 VLM 接地理解为"给 LLM 装上眼睛",就抓住了本节的全部。
8.2 接地的三种粒度¶
VLM 接地在实践中有三种由粗到细的粒度,对应不同的下游需求:
| 粒度 | 接地到什么 | 典型工具 | 服务于 |
|---|---|---|---|
| 物体级 | 符号 → 图像里的物体框/掩码 | 开放词汇检测(如 OWL-ViT、Grounding DINO)、分割(SAM) | "cup 是哪个" → 给抓取一个目标 |
| 关系级 | 符号关系 → 感知判断(真/假) | VLM 问答("cup 在 table 上吗?") | 验证前提、闭环成功检测(§5) |
| 稠密空间级 | 语言 → 三维空间的稠密值场 | VoxPoser 式的 3D value map | 直接指引运动规划/轨迹合成 |
物体级最常用——开放词汇检测器接收一个文本词("cup",哪怕训练时没见过这个类别),在图像里框出对应物体。这给 pick(cup) 提供了"抓哪儿"的目标。"开放词汇"是关键:传统检测器只认固定类别,开放词汇检测器认任意文本描述,正好配 LLM 输出的任意符号。
关系级服务于 §5 的闭环——要判断"抓取成功了吗""cup 还在 table 上吗",可以让 VLM 看着图像回答。这把 Inner Monologue 的"成功检测""场景描述"用 VLM 实现了。
稠密空间级最精细,下面单讲。
8.3 VoxPoser:把语言变成三维值图¶
VoxPoser(Huang et al., CoRL 2023)是稠密空间接地的代表,它的做法很有想象力:让 LLM 写代码去调用 VLM,合成一个覆盖三维工作空间的"值图",直接指引机器人运动。
具体地:VoxPoser 观察到 LLM 擅长从自由形式语言指令推断可供性(affordance)与约束(constraint),于是利用其写代码的能力去与视觉语言模型交互,组合出 3D value map,把知识接地到智能体的观测空间;这些值图被用在一个基于模型的规划框架里,零样本地合成对动态扰动鲁棒的闭环机器人轨迹。
拆解这个机制(它把本章好几条线索缝在了一起):
指令: "打开最上面的抽屉, 小心那个花瓶"
│
▼ LLM(Code-as-Policies 式, §6) 写代码, 把指令拆成"可供性"和"约束"
├─ 可供性图(affordance map): 在"最上抽屉把手"处赋高值(要去那里)
└─ 约束图(constraint map): 在"花瓶"周围赋高代价(要避开)
│ 代码里调用 VLM/检测器定位"抽屉把手""花瓶"的三维位置
▼ 两张图合成一个 3D value map(每个体素一个分数: 想去/想避)
▼ 基于模型的运动规划在值图上做轨迹优化 → 闭环轨迹(对扰动鲁棒)
VoxPoser 的精妙在于它同时调动了本章三条线索:用 LLM 的语言理解拆解指令(§2 常识)、用 Code-as-Policies 的代码生成组织流程(§6)、用 VLM 把符号接地到三维(本节)。而且它产出的不是离散符号计划,而是稠密的、可直接喂给运动规划的值场——这把"接地"做到了最细的粒度:不只告诉机器人"cup 在哪",而是告诉它"空间每一处有多想去/多想避"。
把 VoxPoser 放回范式(§3.2):它是 LLM-as-Planner(LLM 直接驱动生成值图与轨迹),但它的"计划"形态既不是符号序列、也不是纯程序,而是三维值场 + 优化轨迹——可以看作 Code-as-Policies 在"连续空间接地"方向的延伸。
本质洞察:VoxPoser 揭示了 LLM 任务规划的一种深刻可能——LLM 不必直接输出动作,它可以输出"塑造下游优化问题的东西"。SayCan 让 LLM 选技能、LLM+P 让 LLM 写 PDDL、VoxPoser 让 LLM 塑造一个值场再交给运动优化。它们的共性是:LLM 在最擅长的"高层语义"层面发力(这里该高值、那里该避开),把"在连续空间里求一条最优轨迹"这件 LLM 干不了的事,交给经典的运动规划/优化。 这又是"增强而非取代"——只不过这次 LLM 增强的不是符号规划器(如 §7),而是运动层的优化器。看懂这点,你就理解了 LLM 接入机器人的一条通用配方:让 LLM 定义/塑造问题(它懂语义),让经典数值方法求解问题(它保证质量)。 这条配方贯穿 SayCan(塑造选择)、LLM+P(塑造符号问题)、VoxPoser(塑造优化问题)。
8.4 接地的可靠性:又一个不能让 LLM 独裁的环节¶
接地很关键,但它也是新的出错点,且这个错 LLM 自己发现不了:
- 检测错:开放词汇检测器把"杯子"框成了旁边的碗——后续抓取抓错对象。
- 指代歧义:场景里有三个杯子,LLM 说
pick(cup),到底哪个?需要消歧(问用户、或选最近的)。 - 关系误判:VLM 误判"cup 在 table 上"(其实悬空/被遮挡)——前提验证给出假信号。
这些都说明:接地结果同样要校验、要兜底,不能盲信。实践中的对策——多视角确认、置信度阈值、歧义时主动询问(Inner Monologue 的主动查询,§5.3)、关键操作前用力觉/碰撞二次确认——本质都是"别让接地结果一锤定音"。这与 §4(affordance 把关)、§7(校验器把关)、§10(可行性校验)是同一原则的延续:任何 LLM/感知给出的结果,在进入不可逆的物理执行前,都要有一道独立的把关。
8.5 两种接地的信息流向:感知喂给 LLM vs LLM 驱动感知¶
接地在系统里有两种截然不同的接法,区别在于谁主动、信息往哪流。分清它们,能帮你理解本章不同方法在"接地"这件事上的不同架构。
方式一:感知 → 文字 → 喂给 LLM(perception-to-text,被动接地)。 感知系统先行把场景翻译成文字描述,再塞进 LLM 的提示里。LLM 拿到的是已经文字化的世界("桌上有杯子在(0.3,0.2)、书在(0.5,0.1)")。这是 SayCan、Inner Monologue 的被动场景描述(§5.3)、§9.5 提示里的"当前世界状态"采用的方式。
方式二:LLM → 代码 → 驱动感知(LLM-drives-perception,主动接地)。 LLM 先行生成代码,代码里主动调用感知 API 去查询它需要的信息。是 LLM 决定"现在该看什么、问什么"。这是 Code-as-Policies(§6)、VoxPoser(§8.3)采用的方式——LLM 写的程序里有 detect_objects("cup")、get_color(b),运行时才去调感知。
把两者并置:
| 方式一 被动接地 | 方式二 主动接地 | |
|---|---|---|
| 谁主动 | 感知先行,LLM 被动收 | LLM 先行,主动调感知 |
| LLM 看到的 | 预先文字化的场景全貌 | 自己按需查询的结果 |
| 优点 | 简单、LLM 不必"会调感知" | 灵活、只查需要的、省感知开销 |
| 缺点 | 可能喂了一堆无关信息(§9.5 陷阱) | LLM 要会写正确的感知调用 |
| 代表 | SayCan、Inner Monologue 被动描述 | Code-as-Policies、VoxPoser |
本质洞察(对比性思维):这两种接地方式,对应 §3.2 两范式的一个微妙投影——被动接地更像"把世界端给 LLM",主动接地更像"让 LLM 自己去探世界"。被动接地把"看什么"的决定权交给系统设计者(预先决定喂哪些场景信息),主动接地把这个决定权交给 LLM(它写代码决定查什么)。前者可控但可能信息冗余或遗漏,后者灵活但依赖 LLM 正确地"知道该查什么"。真实系统常两者混用:用被动接地喂一个粗粒度的场景概览(让 LLM 有全局感),再让 LLM 在需要细节时用主动接地去查(如"我得确认杯子是不是空的,查一下")。理解这条信息流向的区别,你在设计系统时就能想清楚:哪些感知信息该预先喂、哪些该让 LLM 按需取——喂太多则冗余、喂太少则 LLM 瞎猜,这条平衡正是接地工程的核心拿捏。
⚠️ 常见陷阱
- 陷阱 8-1:以为 LLM 自己能"看到"场景。 LLM 是纯文本模型,没有视觉。所有"看"的能力来自外接的 VLM/检测器。把场景信息喂给 LLM 前,必须先由感知模型把像素翻译成文字/坐标——这一步缺了,LLM 就是瞎子在下指令。
- 陷阱 8-2:把开放词汇检测当成万能。 开放词汇检测能认任意文本类别,但仍会错(小物体、遮挡、罕见物、歧义描述)。接地结果要带置信度、要能消歧、要可兜底,不能当成 ground truth。
- 陷阱 8-3:混淆三种接地粒度的用途。 物体级给抓取目标、关系级做前提/成功验证、稠密空间级指引运动优化——用途不同。要做"验证 cup 在不在 table 上"却去做稠密值图,或要指引轨迹却只做物体框,都是用错粒度。
- 陷阱 8-4:以为 VoxPoser 取代了运动规划。 VoxPoser 用 LLM 塑造值图,但求轨迹仍靠基于模型的运动规划/优化。它是"LLM 定义问题 + 经典方法求解",不是"LLM 取代运动规划"(呼应 §8.3 洞察)。
练习
- 给
place(cup, on=plate)这个动作,列出它执行前需要的三种接地(指代/空间/关系)各要回答什么问题、分别用什么工具。 - "开放词汇检测"为什么特别适合给 LLM 任务规划做接地?(提示:对比传统固定类别检测器,考虑 LLM 输出符号的开放性。)
- VoxPoser 同时用到了本章哪三条线索(§2/§6/§8)?用一句话说明它把"接地"做到了什么粒度、产出什么形态的"计划"。
- 接地结果为什么也要"校验、兜底、不能让 LLM 独裁"?举一个"接地错了但 LLM 浑然不觉"的例子,说明该用什么对策。
9. 提示工程与结构化输出 ⭐⭐⭐¶
前面几节讲了"用 LLM 做什么",这一节讲一个贯穿所有方法的工程基础:怎么问,LLM 才答得好、答得能用? 这就是提示工程(prompt engineering)与结构化输出(structured output)。它不深奥,但极其实用——前面所有方法(SayCan 打分、生成 PDDL、写程序)能不能落地,很大程度上取决于提示设计得好不好。
9.1 为什么提示如此关键:LLM 的输出由上下文塑造¶
回到 §2.3 的本质——LLM 是条件概率下的续写:\(p_\theta(\text{输出}\mid \text{上下文})\)。输出完全由上下文(提示)塑造。同一个 LLM,提示设计的好坏,能让"生成合法 PDDL"的成功率从几乎为零到相当高。这不是玄学,是机制使然:你给的上下文,决定了它续写时落在哪片概率分布上。
所以提示工程的核心目标只有一个:把上下文构造得让"我想要的那种输出"成为高概率续写。具体到任务规划,有四类关键技术。
9.2 技术一:少样本示例(few-shot)¶
最有效的手段——在提示里给几个"输入→输出"的范例,LLM 据此模仿格式与风格。这利用了 LLM 的上下文学习(in-context learning) 能力:不改参数,仅靠提示里的例子就学会任务模式。
[提示模板]
你是机器人任务规划器。把指令翻译成 PDDL goal。可用谓词: on, holding, clean, stored。
示例1:
指令: "把杯子放到桌上"
goal: (:goal (on cup table))
示例2:
指令: "清理桌面并把书收好"
goal: (:goal (and (clean table) (stored book)))
现在:
指令: "把杯子放架子, 桌子擦干净"
goal: ← LLM 在此续写, 模仿上面格式
为什么有效?因为示例把"输出该长什么样"(PDDL 语法、用哪些谓词、什么风格)锚定在了上下文里,让符合该格式的续写概率飙升。这是 §4 SayCan、§6 Code-as-Policies、§7 生成 PDDL 全都依赖的基础技术——它们的提示里都有精心挑选的示例。
9.3 技术二:思维链(Chain-of-Thought, CoT)¶
让 LLM "先想再答"——在给出最终答案前,先用自然语言把推理过程写出来。这就是思维链(Wei et al., NeurIPS 2022):通过在提示里提供少量"思维链"示范(把推理过程一步步写出来),能在算术、常识与符号推理等一系列任务上显著提升大模型的表现,且这种推理能力随模型规模增大而自然涌现。
在任务规划里,CoT 让 LLM 先分析"任务要分几步、有什么依赖、要注意什么前提",再输出计划:
指令: "把被书挡住的杯子放到架子上"
[不用 CoT] 直接输出: pick(cup) → place(cup, shelf) ← 漏了"先移书"!
[用 CoT] 先想:
- 杯子被书挡住, 直接抓会碰到书 → 得先移开书
- 移书后才能抓杯子 → 再抓杯子
- 然后放到架子
计划: move_aside(book) → pick(cup) → place(cup, shelf) ← 正确, 补上了隐含步骤
CoT 为什么有用?因为它给了 LLM 一段显式的"推演空间"——把多步推理摊开在上下文里,每一步都成为后续步骤的条件,降低了"一步跳到错误结论"的概率。这与 §5.2 ReAct 的 Thought 同源(Thought 就是 CoT 在闭环里的形态)。CoT 是把 LLM 的"续写"往"像推理"那一侧推的最简单有效的手段——虽然它仍不是真推理(§2.3),但能显著改善多步任务的输出质量。
9.4 技术三:结构化输出与约束解码¶
LLM 默认输出自由文本,但下游(规划器、API、执行器)要的是严格结构化的东西——合法的 PDDL、可解析的 JSON、白名单内的 API 调用。怎么让 LLM 的输出保证符合结构?三个层次的手段,强制力递增:
| 手段 | 怎么做 | 强制力 | 代价 |
|---|---|---|---|
| 格式指令 + 示例 | 提示里要求"只输出 JSON"并给 JSON 示例 | 弱(靠模仿,可能跑偏) | 低 |
| 输出后解析校验 | 拿到输出后用解析器检查,不合格就重试/纠错(§7.3 闭环) | 中(事后兜底) | 中(要重试) |
| 约束解码(constrained decoding) | 在生成时限制每步只能选符合语法的 token(如按 PDDL/JSON 的文法约束采样) | 强(生成时即保证合法) | 高(要改解码、接文法) |
约束解码最彻底——它把"输出必须合法"这个要求编码进采样过程,从源头杜绝不合法输出(类比 §4 Grounded Decoding 把可行性编进 token 选择,§6 用 API 白名单限制可调用动作)。它和 §10 的可行性校验是"防"与"治"的两手:约束解码在生成时防住非法输出,校验闭环在生成后治住漏网的错误。
本质洞察:结构化输出的三个层次,本质是"把约束施加在生成流程的哪个位置"——提示在输入端软性引导(最弱)、解析校验在输出端事后把关(中等)、约束解码在生成中硬性限制(最强)。这条"输入引导 → 生成约束 → 输出校验"的谱系,和本章反复出现的防幻觉手段一脉相承:SayCan 用技能库限输出空间、Code-as-Policies 用 API 白名单、Grounded Decoding 用可行性约束解码、as-Modeler 用校验器闭环——它们都是在"LLM 自由生成"和"系统需要的严格结构"之间,选一个位置施加约束。位置越靠前(生成中、输入端)越能防患于未然,但实现越难;越靠后(输出端)越易实现,但只能事后补救。工程上常组合使用:示例引导 + 约束解码防住大头 + 校验闭环兜住残余。这套"多道设防"的思路,正是把不可靠的 LLM 用进可靠系统的工程精髓。
9.5 技术四:上下文构造——喂什么进去¶
最后一类技术关乎"提示里该放哪些信息"。一个任务规划的提示,通常要拼装:
- 角色与任务说明:"你是机器人任务规划器,把指令翻译成 PDDL goal"。
- 能力边界:可用的谓词、技能库、API 列表——显式告诉 LLM 它能用什么(这从源头防幻觉,呼应 SayCan 限技能库)。
- 当前世界状态:由感知/VLM 接地(§8)翻译成文字的场景描述("桌上有杯子、书;杯子在书右边")。
- 少样本示例 + CoT 示范(§9.2、§9.3)。
- 输出格式要求(§9.4)。
其中"能力边界"和"世界状态"最容易被忽视却最关键:不告诉 LLM 机器人有哪些技能,它就会幻觉出没有的动作(§2.3 的"用吸尘器");不告诉它当前世界状态,它就会基于想象规划。 把这两样喂准、喂全,能消除一大半幻觉。
9.6 把四类技术拼起来:一个完整提示的对照¶
前面四类技术(few-shot / CoT / 结构化输出 / 上下文构造)单独讲清了,但工程上它们总是一起用。这里给一个把四类技术拼全的完整提示,再给一个"什么都没做"的坏提示对照,让你直观看到差距来自哪。
坏提示(新手常写,缺所有技术):
这个提示几乎必然出问题:没给能力边界(LLM 会幻觉动作 H1)、没给世界状态(LLM 基于想象)、没给格式(输出五花八门难解析)、没给示例(LLM 不知道你要 PDDL 还是别的)、没让它思考(漏隐含步骤 H4)。
好提示(四类技术拼全):
你是机器人任务规划器, 把自然语言指令翻译成 PDDL :goal。 ← 角色(§9.5)
【可用谓词】(只能用这些, 不得发明) ← 能力边界, 防 H1(§9.5)
(on ?x ?y) (holding ?x) (handempty) (clean ?surf) (stored ?x)
【可用对象】 cup book shelf table bookshelf sink
【当前世界状态】 ← 防"想象规划"(§9.5)
(on cup table) (on book table) (handempty)
【示例】 ← few-shot 锚定格式(§9.2)
指令: "把书放到书柜" ->
思考: 目标是 book 在 bookshelf 上。 ->
(:goal (on book bookshelf))
【请先思考再输出】先列出指令隐含的全部子目标, 再写 goal。 ← CoT(§9.3), 暴露 H4 遗漏
【输出格式】严格只输出一个 (:goal ...) S-表达式, 无其他文字。 ← 结构化(§9.4)
指令: "把杯子放到架子上"
把好提示的每一块标注对应的技术,你会发现它不是在堆话术,而是在系统性地堵每一类幻觉:能力边界堵 H1、世界状态堵"凭空想象"、CoT 让它列全子目标从而减少 H4、格式要求让输出可被语法层校验(§10)直接吃。
本质洞察:好提示和坏提示的差距,本质是"你替 LLM 把多少不确定性消除掉了"——坏提示把"用什么动作、世界什么样、要什么格式、要不要想"全部留给 LLM 去猜,猜错就是幻觉;好提示把这些能确定的都先确定下来(白名单、状态、格式都是你已知的),只把"翻译"这一件 LLM 真正擅长的事留给它。这呼应 §9.1 的机制:输出由上下文塑造,你把上下文约束得越紧、越贴近"我要的那种输出",LLM 落在正确概率区的机会就越大。提示工程的真谛不是'怎么哄 LLM',而是'怎么把任务中确定的部分替它定死,只留它擅长的那一点让它发挥'——这与全章"给 LLM 划清边界、把能交给确定性机制的都交出去"的主线完全一致。
⚠️ 常见陷阱
- 陷阱 9-1:以为提示工程是"调话术的玄学"。 它有明确机制(输出由上下文的条件概率塑造)。少样本锚定格式、CoT 提供推演空间、约束解码限制输出——每一招都对应可解释的原理,不是碰运气。
- 陷阱 9-2:不告诉 LLM 能力边界就让它规划。 不给技能库/API/谓词列表,LLM 必然幻觉出机器人没有的动作。能力边界是提示里最该显式写清的部分,它是防幻觉的第一道闸。
- 陷阱 9-3:把 CoT 的"想"当成可靠推理。 CoT 改善多步任务,但 LLM 仍是续写(§2.3),CoT 里的推理也可能错。它降低出错率,不保证正确——最终仍要校验(§10)。别因为"它想得头头是道"就跳过验证。
- 陷阱 9-4:用格式指令代替约束解码却指望强保证。 "请只输出 JSON"是软约束,LLM 可能跑偏。要保证结构合法,得靠约束解码(生成时限制)或解析校验闭环(事后兜底),不能只靠一句格式要求。
- 陷阱 9-5:上下文塞太多无关信息。 上下文窗口有限且信噪比影响输出——把无关的领域细节、冗长历史全塞进去,会稀释关键信息(能力边界、当前状态),反而降低输出质量。要喂准、喂精,不是喂多。
练习
- 为"把指令翻译成机器人 API 调用序列"设计一个 few-shot 提示模板,包含:角色说明、API 白名单、两个示例、当前状态占位、输出格式要求。标出哪部分在防幻觉。
- 给一个"不用 CoT 会漏掉隐含步骤"的任务例子(不要用正文的"移书"),分别写出不用 CoT 的错误输出和用 CoT 的正确推演。
- 解释结构化输出三层手段(格式指令/解析校验/约束解码)"把约束施加在生成流程哪个位置",并说明各自的强制力与代价。
- 提示里"能力边界"和"当前世界状态"分别防住哪一类幻觉?把它们和 §2.3 的幻觉分类(幻觉动作/违反前提/忽略几何)对应起来。
10. 幻觉与可行性校验:把好严谨这道关 ⭐⭐⭐⭐¶
前面每一节都在不同地方提到"要校验、要兜底、不能让 LLM 独裁"。这一节把这条贯穿全章的原则收拢成一个系统的方法论:LLM 会犯哪些错(幻觉的分类),以及怎么用分层校验把它们逐一拦住。这是本章的第二个硬核(⭐⭐⭐⭐),也是"增强而非取代"从理念落到工程的总抓手——所谓"经典守严谨",落到实处就是这套校验。
10.1 幻觉的四种形态¶
"幻觉(hallucination)"在 LLM 通用语境里指"生成看似合理但实则错误/虚构的内容"。在任务规划里,它有四种具体形态,各自的危害和拦截方式都不同:
| 幻觉形态 | 表现 | 根源 | 例子 |
|---|---|---|---|
| 幻觉动作 | 用了机器人不存在的技能/API | LLM 不知道能力边界 | "用微波炉解冻"——没这技能 |
| 违反前提 | 动作的前提不满足却照用 | LLM 不做前提检查 | 手里拿着书又去 pick(cup)——handempty 不满足 |
| 忽略几何 | 物理上不可行却当可行 | LLM 看不到几何 | 让臂展 0.8m 去够 1.2m 高的架子 |
| 目标走样 | 翻译的目标偏离用户意图 | 语言歧义/LLM 理解偏差 | "收拾干净"漏译了"杂物要收纳" |
这四种形态恰好对应本章前面埋的伏笔:幻觉动作(§2.3、§4 用技能库防)、违反前提(§7 用经典规划器/校验器防)、忽略几何(§2.2、§8 用 VLM/几何检查防)、目标走样(§7.5 练习 5 的"语义不完整"难题)。把它们分清,是因为不同形态要用不同的关卡拦——一刀切的"校验"是抓不全的。
本质洞察:四种幻觉形态,本质对应 LLM 的四个"盲区"——不知道自己(机器人)能做什么(幻觉动作)、不检查逻辑前提(违反前提)、看不见物理几何(忽略几何)、可能误解人的意图(目标走样)。这四个盲区,恰恰是经典方法(符号规划、几何采样、形式验证)的四个强项区。于是"校验"的本质,就是用经典方法的强项,去补 LLM 的盲区——一个盲区配一道关卡。 这是"增强而非取代"最具体的操作图景:不是笼统地"让经典方法把关",而是针对 LLM 每一类具体的不可靠,配一道专门的、来自经典方法的关卡。看清这个"盲区-关卡"的一一对应,你就知道一个 LLM 规划系统该设哪几道关、每道关拦什么。
10.2 三层可行性校验¶
把上面的"盲区-关卡"对应,组织成一套分层校验——从浅到深三层,每层拦不同的错。这是本节的核心方法论。
LLM 生成的候选(计划 / PDDL / 代码)
│
▼ ┌──────────────────────────────────────────────┐
第一层 │ 语法校验 (Syntactic) │
│ │ 查: 格式合法吗? 谓词/类型/API 声明了吗? │
│ │ 工具: PDDL 解析器 / JSON schema / API 白名单 │
│ │ 拦住: 幻觉动作(调了不存在的 API)、格式错 │
│ └──────────────────────────────────────────────┘
│ │通过
▼ ┌──────────────────────────────────────────────┐
第二层 │ 语义校验 (Semantic) │
│ │ 查: 逻辑自洽吗? 前提满足吗? 目标可达吗? │
│ │ 工具: VAL 计划验证器 / 经典规划器试解 / 状态机 │
│ │ 拦住: 违反前提、逻辑矛盾、目标不可达 │
│ └──────────────────────────────────────────────┘
│ │通过
▼ ┌──────────────────────────────────────────────┐
第三层 │ 几何/物理校验 (Geometric/Physical) │
│ │ 查: 够得到吗? 无碰撞吗? IK 有解吗? 抓得稳吗? │
│ │ 工具: IK 求解器/碰撞检测/运动规划(T3)/优化(T4) │
│ │ 拦住: 忽略几何(够不到、要碰撞、抓不稳) │
│ └──────────────────────────────────────────────┘
│ │通过
▼
可执行的、三层都验过的计划 → 交执行层(T5)
逐层说明它们的分工与不可替代性:
- 第一层 语法校验:最浅、最快、最便宜。用解析器/白名单查"格式对不对、用的东西存不存在"。它专拦幻觉动作和格式错——LLM 调了
vacuum()但 API 白名单里没有,这层直接拦下。这层拦不住"语法对但逻辑错"(比如pick(cup)语法没问题,但此刻手不空),那是第二层的事。 - 第二层 语义校验:中等深度。用 VAL(PDDL 计划验证器)或让经典规划器试解,查"前提满不满足、目标可不可达、逻辑自不自洽"。它专拦违反前提和逻辑矛盾——这正是经典符号方法(§7)的主场。这层拦不住"逻辑对但几何不可行"(符号上
place(cup, shelf)前提都满足,但架子物理上够不到),那是第三层的事。 - 第三层 几何/物理校验:最深、最贵。用 IK 求解、碰撞检测、运动规划(T3)或轨迹优化(T4),查"够不够得到、会不会碰、抓不抓得稳"。它专拦忽略几何——这是 LLM 和符号规划器共同的盲区,必须靠运动层补。
注意三层的顺序与早停:从便宜到昂贵排列,前层不过就不必做后层(语法都错了,不必费力做几何检查)。这是工程效率的考量——把最贵的几何校验留到最后,只对"语法语义都过关"的候选才做。
本质洞察:三层校验为什么必须分层、而不能合成一个"大校验"?因为三层对应三种不同的"可行"——语法可行(格式合法)、语义可行(逻辑自洽、前提满足)、几何可行(物理够得到、走得通)。这三种"可行"用完全不同的工具判定(解析器 vs 逻辑验证器 vs 几何引擎),且有严格的依赖顺序(语法不对谈不上语义,语义不通谈不上几何)。这恰好重现了总论 §1.3 的"符号 vs 几何鸿沟"——第一、二层在符号侧(离散、逻辑),第三层在几何侧(连续、物理)。所以这套三层校验,本质是把 TAMP 全线的能力(符号规划验证 + 几何可行性检查)组织成一道针对 LLM 输出的"质检流水线"。 它把本章(LLM 前端)和前几章(T1 符号、T3/T4 几何)严丝合缝地接了起来——LLM 在最前面生成,三层校验逐层把关,每一层都调用对应章节的经典方法。这就是为什么说"不学经典就用不好 LLM":三层校验里有两层(语义、几何)直接就是前几章的内容。
10.3 自纠错闭环:校验失败之后¶
校验拦下一个错误,不是终点——好的系统会把错误反馈给 LLM 让它自己改,形成自纠错闭环。这就是 §7.3 generate-validate-repair 闭环的一般化,适用于全章所有 LLM 输出(计划/PDDL/代码):
LLM 生成候选 ──► 三层校验 ──┬─ 全通过 ─► 交执行
▲ │
│ └─ 某层失败
│ │
│ 把【具体、可定位的报错】喂回 LLM:
└─── "第3步 pick(cup) 前提 handempty 不满足(手里有 book)"
"place(cup,shelf): IK 无解, 架子高度 1.2m 超出臂展"
→ LLM 据此修订 → 重新生成 → 再校验 (限定最多 N 轮)
两个工程要点(和 §7.3 一致,这里强调其普适性):
- 反馈要具体可定位:喂回"第 3 步
pick(cup)前提handempty不满足,因为手里有book",远胜于"计划有错"。具体报错让 LLM 的修复有的放矢,命中率高得多。校验器(VAL、IK 求解器)天然能产出这种精确诊断——这是它们比"另一个 LLM 当裁判"更可靠的又一原因。 - 要有重试上限:LLM 可能反复改不对(陷在同一个错误上)。必须设最多 N 轮,超了就降级——回退到更保守的策略、或求助人类、或报告无解。无上限的自纠错会死循环。
把它和 §5 执行层闭环、§7.3 建模层闭环并列——本章出现了三个层次的自纠错闭环,结构同构(生成 → 反馈 → 纠错),反馈源不同:
| 闭环 | 在哪一层 | 反馈源 | 纠什么 | 对应节 |
|---|---|---|---|---|
| 执行闭环 | 执行时 | 物理环境(成功检测/场景) | 执行偏差(滑脱、位置不符) | §5 |
| 建模闭环 | 建模时 | 形式化校验器(VAL/解析器) | 模型错误(PDDL 写错) | §7.3 |
| 校验闭环 | 计划生成后 | 三层校验器 | 计划的幻觉(动作/前提/几何) | §10.3 |
本质洞察:三个自纠错闭环结构同构,绝非巧合——它们都是同一个深层原则的实例:LLM 的不可靠不靠"让它更聪明"来根治,而靠"给它配一个可信的反馈源 + 让它据反馈迭代"来驯服。 反馈源必须是确定性、可信、能给精确诊断的(环境的物理真相、校验器的形式化判断),绝不能是另一个同样不可靠的 LLM。这就引出了下一小节那条最重要的红线。
10.4 红线:别让 LLM 给自己把关¶
本章反复出现一句话,这里把它立成一条不可逾越的红线:可行性的最终把关,必须由确定性的、可信的工具完成,不能由 LLM(哪怕是另一个 LLM)完成。
为什么这条红线不能破?因为 LLM 的不可靠是系统性的(§2.3 续写而非推理)。用一个不可靠的东西去校验另一个不可靠的东西,错误不会被消除,只会被叠加或掩盖:
- 让同一个 LLM"检查自己的计划对不对"——它可能用同样的盲区"确认"自己的错误(它当初为什么生成这个错,就为什么会觉得这个错是对的)。
- 让另一个 LLM 当裁判——它有自己的幻觉,可能"幻觉地"通过一个错误计划,或"幻觉地"否决一个正确计划。
这不是说 LLM 在校验里一点用没有——它可以做初筛、辅助、生成测试用例。但最终的、决定"能不能执行"的那道关,必须是确定性工具:PDDL 解析器(语法)、VAL(语义)、IK/碰撞检测(几何)。这些工具的判断确定、可复现、可信。
这条红线还能用最近的实证支撑。Mendez-Mendez(2025)系统研究了"用 LLM 替代 TAMP 求解器组件"的效果(针对 PDDLStream,本线 T3 详述):他们用 4950 个问题系统评测了 LLM 替代 PDDLStream 各组件的能力,结论是目前 LLM 替代仍明显更差,印证了"LLM 辅助而非替代"经典求解器内核。把它推广到校验:LLM 替代经典求解器的内核尚且更差,让它替代校验器、给自己的输出最终把关,同样不可靠。 把关这件事,目前没有捷径——必须用经典的确定性工具。
本质洞察:这条红线,是"增强而非取代"边界的最后一道、也最不可让步的防线。前面所有方法(SayCan、Code-as-Policies、as-Modeler)都在不同程度上让 LLM 出力,但它们无一例外地把最终可行性判断留给了确定性机制(affordance 价值函数、API 执行、经典规划器、形式校验器)。一旦突破这条红线——让 LLM 给自己的输出做最终把关——整个系统就失去了可信的锚点,LLM 的幻觉将畅通无阻地漏到物理执行,后果在真实机器人上可能是不可逆的(撞坏东西、伤到人)。所以记住:LLM 可以提议、可以生成、可以辅助、可以初筛,但"这个计划到底能不能执行"的最终裁决权,永远握在确定性工具手里。 这是把 LLM 安全地用进物理系统的根本前提,没有例外。
10.5 一张总图:防与治的全套设防¶
把全章的防幻觉手段汇成一张图,它也是本章工程层面的总纲——多道设防,层层把关:
┌─────────────── 防(生成时就限制, 减少错误产生) ───────────────┐
│ • 技能库/API 白名单限输出空间(§4 SayCan, §6 Code-as-Policies)│
│ • 能力边界写进提示(§9.5) │
│ • 约束解码: 按文法限制 token(§9.4, §4 Grounded Decoding) │
│ • LLM 只写模型不写计划, 退后一步(§7 as-Modeler) │
└──────────────────────────────────────────────────────────────┘
│ 残余错误漏过来
▼
┌─────────────── 治(生成后校验, 拦住漏网错误) ─────────────────┐
│ • 三层校验: 语法→语义→几何(§10.2) │
│ • 自纠错闭环: 精确报错喂回 LLM 迭代修复(§10.3) │
│ • 红线: 最终把关用确定性工具, 不用 LLM(§10.4) │
└──────────────────────────────────────────────────────────────┘
│ 三层都过
▼
┌─────────────── 兜(执行时再闭环, 应对动态意外) ───────────────┐
│ • 执行监控 + 成功检测(§5 Inner Monologue) │
│ • 失败局部重试 / 全局重规划(§5.4, 交 T5 行为树) │
└──────────────────────────────────────────────────────────────┘
"防-治-兜"三道,对应"生成时-生成后-执行时"三个时机。一个工业级 LLM 规划系统,这三道通常都要有——防得越早越省力,但防不住的要治,治不住的(动态环境的运行时意外)还要靠执行层兜。这套三道设防,就是"增强而非取代"在系统工程上的完整落地。
⚠️ 常见陷阱
- 陷阱 10-1:用一道"大校验"代替分层。 三层(语法/语义/几何)用不同工具、有依赖顺序,必须分层。合成一道会导致"该用解析器的地方用了几何引擎""语法没过就去做昂贵几何检查"等错配与浪费。
- 陷阱 10-2:让 LLM 给自己把关(破红线)。 最危险的错误。最终可行性判断必须用确定性工具。LLM 自检/LLM 当裁判都不可靠(错误叠加/掩盖),Mendez-Mendez 2025 已实证 LLM 替代求解器更差。这条红线没有例外。
- 陷阱 10-3:反馈太笼统,自纠错低效。 喂回"有错"远不如喂回"第 3 步前提
handempty不满足"。具体可定位的报错(校验器天然能产出)让修复有的放矢,这是自纠错闭环高效的前提。 - 陷阱 10-4:自纠错不设上限。 LLM 可能反复改不对,无上限会死循环。必须设最多 N 轮,超了就降级(回退保守策略/求助人类/报告无解)。
- 陷阱 10-5:以为"防"做好了就不用"治"和"兜"。 防(限输出空间、约束解码)减少错误产生但堵不住全部;治(校验)拦生成后的残余;兜(执行闭环)应对运行时的动态意外。三道时机不同、缺一不可,尤其执行时的意外是任何事前手段都防不住的。
- 陷阱 10-6:把"目标走样"当成校验能全拦的。 语法/语义校验能查"目标是否合法、可达",但查不出"目标是否完整、正确地表达了用户意图"(§7.5 练习 5)。目标走样部分要靠与用户确认(主动查询,§5.3)、而非纯自动校验——这是 LLM 规划里一个尚未被工具完全解决的软肋。
练习
- 把四种幻觉形态(幻觉动作/违反前提/忽略几何/目标走样)各对应到三层校验的哪一层能拦(或拦不住),制成一张"幻觉-关卡"对应表。哪一种幻觉三层校验都难完全拦住?为什么?
- 解释三层校验为什么必须"从便宜到昂贵、前层不过不做后层"。给一个"语法就错了却先做了几何检查"的反例,说明它浪费在哪。
- 用自己的话陈述 §10.4 的红线,并解释为什么"让另一个 LLM 当裁判"也违反这条红线(提示:另一个 LLM 也有幻觉)。
- 把本章三个自纠错闭环(执行/建模/校验)列出来,指出它们的共同结构和各自的反馈源。为什么反馈源必须是确定性的?
- 为一个"LLM 驱动的家庭整理机器人"设计"防-治-兜"三道设防各包含哪些具体措施(至少各两条),说明每道措施拦/兜哪类错误。
11. 与符号规划的前端关系:完整数据流 ⭐⭐⭐¶
前面十节,每一节都在反复说同一句话的不同侧面——"LLM 补语言常识,经典方法守可行最优"。这一节把这句话收口:画出一条从"一句人话"到"机器人动起来"的完整数据流,让你看清 LLM 前端到底接在 T1-T5 这套经典系统的哪个位置、和每一块怎么交接、反馈怎么回流。这是把全章、乃至整条 TAMP 线串成一个系统的一节。
11.1 一张总图:LLM 前端如何接入 T1-T5¶
总论 §3.8 给过一张六板块数据流图。现在把 LLM(板块⑤)的内部展开,和 T1-T5 接起来,得到本章的总集成图:
人: "帮我把厨房收拾干净"
│
╔════▼═══════════════════════════════════════════════════════════════╗
║ 【LLM 前端】(本章, 板块⑤) —— 补语言与常识, 产出"待验证的候选" ║
║ ║
║ ① 意图理解 + 常识补全(§2): "干净" → 杯子归位/书上架/台面擦净 ║
║ ② 感知接地(§8 VLM): 哪个是杯子? 在哪? → 把场景翻译成符号/坐标 ║
║ ③ 二选一范式产出候选: ║
║ ├─ as-Planner(§4-§6): 直接出动作序列/程序(SayCan/ReAct/Code) ║
║ └─ as-Modeler(§7): 出 PDDL domain/goal ║
║ ④ 三层校验(§10): 语法→语义→几何, 失败则自纠错闭环回 ①③ ║
╚════╤═══════════════════════════════════════════════════════════════╝
│ 交付"已过语法+语义校验"的候选(PDDL goal / 动作序列)
▼
┌────────────────────────────────────────────────────────────────────┐
│ 【经典符号规划】T1/T2 (板块①) —— 守逻辑可行与最优 │
│ as-Modeler 路: 在 LLM 写的合法 PDDL 上完备搜索 → 保证合法/最优计划 │
│ as-Planner 路: 验证 LLM 给的序列逻辑可行(VAL), 不行则重排/重搜 │
└────────────────────────────────┬───────────────────────────────────┘
│ 带先后关系的符号动作序列(每个动作待定几何参数)
▼
┌────────────────────────────────────────────────────────────────────┐
│ 【TAMP 集成】T3 PDDLStream / T4 LGP (板块②③) —— 跨符号-几何鸿沟 │
│ 为每个动作求几何可行的参数与轨迹(抓取位姿/放置点/无碰撞路径) │
│ 这正是 §10 第三层"几何校验"的承担者; 够不到 → 可行性回流上面重排 │
└────────────────────────────────┬───────────────────────────────────┘
│ 几何可行的参数化计划(动作 + 轨迹)
▼
┌────────────────────────────────────────────────────────────────────┐
│ 【执行层】T5 行为树 (板块④) —— 守运行时稳健 │
│ 把计划编译成 BT 稳健执行; 监控异常; 抓滑了重试; 方向性失败→重规划 │
│ 这是 §5 闭环思想的工业级落地; 局部纠错在此, 重规划信号回流上游 │
└────────────────────────────────┬───────────────────────────────────┘
▼
运动层(RRT/MPC/MPPI) → 控制层 → 硬件
这张图把本章每一节都安放到了系统里的精确位置:§2 在"意图理解"、§8 在"感知接地"、§4-§7 在"产出候选"、§10 在"校验"与"几何承担者"、§5 在"执行层闭环"。全章不是十三个孤立的话题,而是这一条数据流上的不同工位。
11.2 三个关键交接面:LLM 前端和经典系统怎么对接¶
数据流里最容易出问题的是交接面(interface)。LLM 前端和经典系统之间有三个关键交接,逐一讲清"交什么、谁验、出错怎么回流"。
交接面 A:LLM 前端 → 符号规划(§7 + §10 的落点)。 - 交什么:as-Modeler 交 PDDL(domain/goal);as-Planner 交动作序列。 - 谁验:语法层(PDDL 解析器)+ 语义层(VAL)——在交接面上设关。 - 出错回流:校验失败 → 报错喂回 LLM 自纠错(§10.4)。这是 LLM 不可靠性被堵住的第一道关键交接。
交接面 B:符号规划 → TAMP 几何(§10 第三层的落点)。 - 交什么:带先后的符号动作序列,每个动作的几何参数(抓取位姿、放置点)待定。 - 谁验:几何层——T3 PDDLStream 的采样器 / T4 LGP 的优化,确定"够不够得到、无碰撞否"。 - 出错回流:几何不可行 → 可行性信息流回符号层触发重排(这正是 T3 的核心机制"让采样器把可行性流回符号搜索")。这是符号-几何鸿沟的搭桥处。
交接面 C:几何计划 → 执行层(§5 闭环的落点)。 - 交什么:几何可行的参数化计划(动作 + 轨迹)。 - 谁验:执行期监控——T5 行为树持续 tick,检查每步是否如预期。 - 出错回流:抓滑/卡住等局部失败 → 行为树 Fallback 局部纠错(重试、换力度);门锁了/路线作废等方向性失败 → 触发重规划信号,回流到符号规划层(甚至 LLM 前端)重来。这是 §5.4"局部纠错 vs 重新规划"分工的系统落地。
本质洞察:这三个交接面,本质是把 §10 的"三层校验"展开到了系统的三个不同层级——交接面 A 承担语法+语义校验(符号层把关)、交接面 B 承担几何校验(几何层把关)、交接面 C 承担执行期校验(运行时把关)。校验不是集中在一个地方做完的,而是沿着数据流分布在每一个交接面上——每往下走一层、信息变得更"实"一分,就用一道相应的关把住一类此前拦不住的错。这种"分布式、分层把关"的设计,正是一个鲁棒机器人系统的骨架:它确保 LLM 的不可靠性,无论以哪类幻觉的形式发作,都会在某个交接面上被对应的经典/确定性组件拦下,而不会一路漏到不可逆的物理执行。理解了这三个交接面,你就理解了"增强而非取代"不是一句态度,而是一套贯穿整个系统、层层设防的工程架构。
11.3 一个贯穿场景的端到端走查:"收拾厨房"全流程¶
把总论那个贯穿场景"帮我把厨房收拾干净"走一遍完整数据流,让前面的抽象彻底落地。
[输入] 人: "帮我把厨房收拾干净"
[LLM 前端]
① 意图+常识(§2): "干净" → {脏杯子→水槽, 书→书架, 面包屑→垃圾桶, 擦台面}
(常识: 脏的去水槽不是书架; 屑要扫不是抓——LLM 的常识在此发力)
② 接地(§8): VLM 检测 → cup@(0.3,0.2,0.8), book@(0.5,0.1,0.8), crumbs@台面
(开放词汇检测把符号 cup/book 连到三维坐标)
③ 产出候选(as-Modeler, §7): LLM 写 :goal
(:goal (and (in cup sink) (on book shelf) (clean table)))
④ 校验(§10):
语法✓(谓词都声明) 语义✓(VAL: 可达) → 过, 交下游
[若 LLM 把 sink 拼成 sinc → 语法层拦 → 报错喂回 → 改对]
[符号规划 T1] 在合法 domain+goal 上 Fast Downward 搜索 →
计划: move→pick(cup)→move(sink)→place(cup,sink)→move→pick(book)
→move(shelf)→place(book,shelf)→wipe(table)→...
(保证前提: "放杯子前手得抓着杯子"——LLM 直接规划常忘, 规划器不会忘)
[TAMP 几何 T3/T4] 为每个动作求几何参数:
pick(cup): IK 求抓取位姿 ✓
place(book,shelf): 书架上层够不到! ✗
→ 几何不可行信息回流符号层(交接面B)
→ 符号层重排: 改放下层, 或先 move_base 靠近 → 重新求解 ✓
[执行层 T5] 编译成行为树, 逐步执行:
pick(cup) 时杯子滑落 → BT Fallback: 重试(局部纠错, §5/§11.2-C) ✓
发现垃圾桶满了(方向性意外) → 触发重规划信号回流上游
[输出] 厨房收拾干净; 全程 LLM 补常识/翻译, 经典方法守每一道可行性关
这一条走查浓缩了全章:LLM 在最前面补常识、做翻译、接地(它的强项),随后每往下一层都有一道经典/确定性的关在把守——符号规划守逻辑前提、TAMP 几何守够不够得到、行为树守执行稳健。任何一类幻觉(拼错、漏前提、够不到)都被对应的关拦下并触发回流纠正。这就是"听得懂话又跑得稳"的系统该有的样子。
⚠️ 常见陷阱(§11)
- 陷阱 11-1:把 LLM 前端和经典系统拼成"接缝漏风"的管道。 若交接面上不设校验,LLM 的幻觉会直接漏到下游——拼错的 PDDL 让规划器崩、够不到的计划让执行出事。每个交接面必须有对应的关(A 语法语义、B 几何、C 执行监控),这是 §11.2 的核心。
- 陷阱 11-2:以为反馈是单向下行的。 数据流的箭头不全向下——几何不可行要回流符号层重排、执行方向性失败要回流触发重规划。反馈回路才是系统鲁棒的关键(总论 §1.4 反复强调的"耦合")。只下行不回流的系统,一遇意外就一路错到底。
- 陷阱 11-3:把"几何校验"留在 LLM 前端做。 LLM 看不到几何(§2.3),几何校验必须交给 T3/T4 的几何引擎(交接面 B)。试图让 LLM 自己判断"够不够得到",等于让瞎子量距离——这是 H3 幻觉的温床。
- 陷阱 11-4:以为有了 LLM 前端就不需要 T1-T5 了。 恰恰相反——LLM 前端的价值正建立在 T1-T5 这套可信后端之上。没有符号规划守逻辑、没有 TAMP 守几何、没有行为树守执行,LLM 的候选就无人验证、直接漏到物理世界。前端越强,越需要可靠的后端兜底。
练习(§11)
- 默画 §11.1 的总数据流图(LLM 前端 → T1 → T3/T4 → T5),标出本章每一节(§2/§4-§7/§8/§10/§5)各落在图的哪个工位。
- 三个交接面(A/B/C)各"交什么、谁验、出错怎么回流"?说明它们如何把 §10 的三层校验展开到系统的三个层级。
- 续走 §11.3 的场景:假设执行到
wipe(table)时发现抹布不在预想位置。判断这是"局部失败"还是"方向性失败",该走交接面 C 的哪条回流(局部纠错 or 重规划)?为什么? - (跨章综合,联系 T1+T3+T5)用本章 LLM 前端 + T1 符号规划 + T3 PDDLStream + T5 行为树,描述"把一句自然语言指令变成机器人稳健执行"的完整链路,并指出每段链路守的是哪一类可行性(逻辑/几何/运行时)。
12. 一个最小可运行原型:80 行串起 LLM→PDDL→规划器 ⭐⭐⭐¶
讲了这么多原理,这一节动手把它们落成代码。我们实现一个最小的 LLM-as-Modeler 闭环:输入一句自然语言指令,输出一个经典规划器搜出的、保证合法的计划。它把 §7(LLM 写 PDDL)、§9(提示工程)、§10(三层校验 + 自纠错)这三节的核心,浓缩成约 80 行可读的 Python。读懂这段代码,你就把全章的"as-Modeler 路线"从概念变成了能跑的东西。
12.1 先想清楚:这段代码要串起哪几个组件¶
按 §11 的数据流,一个 as-Modeler 最小闭环需要五个组件,缺一不可。先列清楚"为什么要它、它对应哪一节",再写代码——这是 R8"先讲为什么"的纪律:
| 组件 | 职责 | 为什么需要 | 对应节 |
|---|---|---|---|
build_prompt |
拼装提示(角色+谓词白名单+状态+示例+格式) | 输出由上下文塑造;喂准能力边界防幻觉 | §9.5 |
llm_generate |
调 LLM 把指令翻译成 PDDL goal | LLM 的强项是翻译,不是规划(§7.1) | §7.1 |
syntactic_check |
语法校验:谓词在白名单里吗、格式对吗 | 拦 H1 幻觉动作,最便宜的关先做 | §10.2 第一层 |
semantic_check |
语义校验:交规划器试解,可达吗、前提自洽吗 | 拦 H2 违反前提;这里顺带就把计划搜出来了 | §10.2 第二层 |
repair_loop |
自纠错:校验失败把精确报错喂回 LLM 重写 | LLM 不一次写对,但擅长按反馈改(§10.4) | §10.4 |
注意一个巧妙处:as-Modeler 里语义校验和求解是同一步——把 LLM 写的 goal 交给经典规划器,规划器若能搜出计划,就同时证明了"goal 可达、逻辑自洽"(语义通过)并产出了那个合法计划。所以下面代码里 planner.solve 一身二职。几何校验(第三层)在最小原型里用一个桩函数 geometric_check 占位,真实系统接 T3/T4(§11 交接面 B)。
12.2 正确实现:约 80 行的闭环¶
# llm_modeler_min.py —— LLM-as-Modeler 最小闭环(教学简化版)
# 依赖: 一个 LLM 接口、一个 PDDL 解析器、一个经典规划器(如 Fast Downward)
# 本代码聚焦"如何把组件接成闭环", LLM/解析器/规划器均以接口形式给出
from dataclasses import dataclass
# ---- 领域配置: 由人预先写好的可信部分(domain + 白名单 + 当前状态) ----
DOMAIN_PDDL = open("kitchen_domain.pddl").read() # 人写的动作模型(可信, §7.2 层次一)
PREDICATE_WHITELIST = {"on", "in", "clean", "holding", "handempty", "stored"} # 防 H1
INIT_STATE = "(on cup table) (on book table) (handempty)" # 由感知/VLM 接地得到(§8)
FEWSHOT = '指令: "把杯子放到架子上" -> (:goal (on cup shelf))' # few-shot 锚定(§9.2)
def build_prompt(instruction: str, error_feedback: str = "") -> str:
"""拼装提示。喂准能力边界(谓词白名单)与当前状态, 是防幻觉第一闸(§9.5)。"""
prompt = (
"你是机器人任务规划器, 把指令翻译成 PDDL :goal。\n"
f"【只能用这些谓词】{sorted(PREDICATE_WHITELIST)}\n" # 能力边界, 防 H1
f"【当前世界状态】{INIT_STATE}\n" # 防"基于想象规划"
f"【示例】{FEWSHOT}\n"
"【先思考】列出指令隐含的所有子目标, 再写 goal。\n" # CoT, 也利于暴露 H4
"【输出】只输出一个合法的 (:goal ...), 不要解释。\n"
)
if error_feedback: # 自纠错: 把上一轮的精确报错喂回(§10.4 反馈要具体)
prompt += f"\n【上次的错误, 请修正】{error_feedback}\n"
prompt += f'\n指令: "{instruction}"'
return prompt
def syntactic_check(goal_pddl: str) -> tuple[bool, str]:
"""第一层 语法校验: 谓词都在白名单里吗? 拦 H1 幻觉动作(§10.2)。用确定性解析, 非 LLM。"""
try:
used = parse_predicates(goal_pddl) # 解析出 goal 里用到的谓词(AST 层面)
except ParseError as e:
return False, f"PDDL 语法错误: {e}" # 格式就不对
illegal = used - PREDICATE_WHITELIST
if illegal:
return False, f"用了未声明的谓词 {illegal}(不在白名单)" # H1 被拦
return True, ""
def semantic_check_and_solve(goal_pddl: str) -> tuple[bool, str, list]:
"""第二层 语义校验 + 求解: 交经典规划器。能搜出计划=goal 可达且逻辑自洽(拦 H2)。"""
problem = make_problem(INIT_STATE, goal_pddl) # 拼成完整 PDDL problem
result = planner.solve(DOMAIN_PDDL, problem) # 经典规划器(完备搜索, §7.1)
if result.unsolvable:
return False, "目标在逻辑上不可达(前提无法满足或目标矛盾)", [] # H2/不可达被拦
return True, "", result.plan # 计划保证满足所有前提(soundness)
def geometric_check(plan: list) -> tuple[bool, str]:
"""第三层 几何校验(桩): 真实系统接 T3 PDDLStream/T4 LGP(§11 交接面 B)。拦 H3。"""
for action in plan:
if not feasible_stub(action): # 占位: IK 有解? 无碰撞? 够得到?
return False, f"动作 {action} 几何不可行(够不到/碰撞)" # H3 被拦
return True, ""
def plan_from_instruction(instruction: str, max_retries: int = 4) -> list:
"""主闭环: 生成 -> 三层校验 -> 失败把报错喂回自纠错(§10.4)。重试有上限(防死循环)。"""
feedback = ""
for attempt in range(max_retries): # 重试上限, 超限升级(§10.4 陷阱)
prompt = build_prompt(instruction, feedback)
goal_pddl = llm_generate(prompt) # LLM 只做翻译(§7.1)
ok, err = syntactic_check(goal_pddl) # 第一层(最便宜, 先做)
if not ok:
feedback = err; continue # 失败 -> 精确报错喂回重写
ok, err, plan = semantic_check_and_solve(goal_pddl) # 第二层(顺带求解)
if not ok:
feedback = err; continue
ok, err = geometric_check(plan) # 第三层(最贵, 最后做)
if not ok:
feedback = err; continue # 几何不可行也喂回(或回流符号层重排)
return plan # 三层全过, 交付(再由 T5 执行监控)
raise RuntimeError(f"{max_retries} 次自纠错仍失败, 升级处理(上报人/换预案)") # 超限
把这段代码对照 §11.1 的数据流图:build_prompt+llm_generate 是 LLM 前端的"产出候选",三个 *_check 是三层校验(且第二层兼任经典规划器求解),repair_loop 是自纠错闭环。80 行,把 as-Modeler 路线完整跑通了。
12.3 错误实现:四个一眼就错的反例¶
教学的一半价值在"看清错在哪"。下面四段是新手最容易写出的错误版本,每段都违反了本章的一条核心原则:
# ❌ 错误 1: 让 LLM 既写 goal 又自己"规划"出计划, 跳过经典规划器
def plan_wrong_1(instruction):
return llm_generate(f"把'{instruction}'直接输出成动作序列") # 退化成 as-Planner!
# 问题: 丢掉了经典规划器的完备/最优/soundness 保证(§7 陷阱 7-1)。
# 计划可能违反前提(H2)、不可行, 无人验证。as-Modeler 的求解必须交规划器。
# ❌ 错误 2: 用另一个 LLM 当校验器
def semantic_check_wrong(goal_pddl):
ans = llm_generate(f"这个 PDDL goal 对吗? {goal_pddl}") # 让续写者审续写!
return "对" in ans
# 问题: 违反 §10.3 铁律。第二个 LLM 共享同样盲区、会自信确认错误、不可复现。
# 必须用确定性工具(规划器/VAL/解析器)。
# ❌ 错误 3: 不设重试上限
def repair_wrong(instruction):
feedback = ""
while True: # 无上限!
goal = llm_generate(build_prompt(instruction, feedback))
ok, err = syntactic_check(goal)
if ok: return goal
feedback = err # 改了又错就死循环
# 问题: LLM 不保证能修好(§10.4)。无上限闭环会卡死。必须设 N 次上限 + 超限升级。
# ❌ 错误 4: 校验顺序颠倒, 先做最贵的几何
def plan_wrong_4(instruction):
goal = llm_generate(build_prompt(instruction))
geometric_check(parse(goal)) # 先做最贵的几何, 可此时连谓词都是幻觉的!
syntactic_check(goal) # 语法校验反而最后做
# 问题: 违反 §10.2"廉价在前"的级联原则。对一个语法就错(H1)的 goal 做昂贵的
# 几何检查, 纯属浪费; 甚至会因为 goal 根本解析不了而崩在几何步。
12.4 三种"求解后端"的对比¶
最小原型的 planner.solve 可以换成不同后端,对应本章不同范式。把它们并置,能看清"换一个后端 = 换一条技术路线":
# === 同一个 LLM 翻译出的 goal, 喂给三种不同后端 ===
# 后端 A: 经典规划器(本节, as-Modeler) —— 完备/最优/可验证(§7)
plan = planner.solve(DOMAIN_PDDL, make_problem(INIT_STATE, goal_pddl))
# 适用: 领域可形式化、要可验证保证。推荐初学者首选。
# 后端 B: SayCan 式贪心选技能(as-Planner) —— 无需 PDDL domain(§4)
plan = [saycan_step(instruction, hist, state, SKILLS) for _ in range(MAX_STEPS)]
# 适用: 领域开放、有技能库但难写 domain。可行性靠 affordance 兜, 不保证最优。
# 后端 C: Code-as-Policies 程序(as-Planner) —— 计划即程序(§6)
program = llm_generate(code_prompt(instruction, API_LIST)) # 生成调 API 的程序
plan = sandboxed_execute(program) # 沙箱执行(防 H1/死循环, §6 陷阱 6-2)
# 适用: 含循环/条件/参数化逻辑。表达力强, 可验证性弱。
# 对比:
# | 后端 | 范式 | 需 PDDL domain? | 可行性保证 | 最优 | 适合 |
# |------|------|----------------|-----------|------|------|
# | A 经典规划器 | as-Modeler | 需要 | 强(soundness) | 可 | 领域固定、要可验证 |
# | B SayCan 贪心 | as-Planner | 不需要 | 弱(affordance 兜) | 否 | 开放、有技能库 |
# | C 程序执行 | as-Planner | 不需要 | 弱(沙箱+检查) | 否 | 含控制流逻辑 |
本质洞察:这段"换后端"的对比,把 §3 两范式、§13 象限图落成了可执行的代码差异——同一个 LLM 翻译出的东西,喂给后端 A(经典规划器)就是 as-Modeler(可验证),喂给 B/C 就是 as-Planner(灵活)。"用哪种 LLM 规划方法"在代码层面,本质就是"LLM 的输出交给哪个后端去落地"这一个选择。 这也再次印证全章主线:LLM 那一步(翻译/生成)在三种后端里几乎一样,真正决定系统"严谨还是灵活"的,是后端是不是经典求解器。把这一点想透,你读任何 LLM 规划系统的代码,第一眼就该去找"LLM 的输出最后交给谁"——那个"谁"决定了它的一切性质。
⚠️ 常见陷阱(§12)
- 陷阱 12-1:把桩函数当成真实现。
geometric_check用了桩feasible_stub——真实系统必须接 T3/T4 的几何引擎(§11 交接面 B)。把桩当真实现,等于跳过了第三层校验,H3 会漏到执行。 - 陷阱 12-2:以为
llm_generate一次就对、删掉 repair_loop。 删掉自纠错闭环,系统极脆弱——LLM 一次写错(很常见)就直接失败。闭环是 as-Modeler 的灵魂(§10.4),不是可选优化。 - 陷阱 12-3:把 DOMAIN_PDDL 也让 LLM 生成却不校验。 最小原型里 domain 是人写的可信部分(层次一)。若要让 LLM 生成 domain(层次二),必须加 domain 级校验闭环(§7.2 Guan),不能直接信任。
- 陷阱 12-4:feedback 喂回泛泛的"你错了"。 代码里
feedback是校验器吐出的精确报错(哪个谓词、哪步前提)。喂回泛泛信息,LLM 修复命中率骤降(§10.4 反馈要具体)。
练习(§12)
- 把 §12.2 的代码读一遍,画出它的控制流(哪步成功去哪、失败去哪),并标出三层校验、自纠错闭环、经典求解各在哪几行。
- §12.3 四个错误实现各违反了本章哪条核心原则?把它们和 §7/§10 的陷阱编号对应起来。
- 给
plan_from_instruction加一个功能:当几何校验(第三层)失败时,不是简单喂回重写,而是把"哪个动作够不到"的信息回流,提示 LLM 换一个放置位置(如把shelf改成low_shelf)。写出这段修改,并说明它如何对应 §11.2 交接面 B 的"可行性回流"。 - (跨章综合,联系 T1 + §7)把 §12.2 改造成"让 LLM 生成 domain"(层次二)的版本:需要新增什么校验?为什么 domain 级校验比 goal 级校验更关键、更难?(提示:domain 是"物理规律",错一条前提全盘错,§7.2。)
13. 近五年研究地图与选型 ⭐⭐⭐¶
学完十二节方法,最后这一节给你一张"地图 + 指南针":把 2022-2025 的关键工作按时间线和方法象限排好(看清谁在哪、谁继承谁),给一棵落地选型决策树(面对真实任务该用哪条路),再点出前沿与边界(往哪走、哪里别去)。这一节不引入新方法,只帮你把全章建立的认知结构化、可检索化。
13.1 时间线:2022-2025 的关键脉络¶
2022 │ SayCan (CoRL) —— 语言×可行性, LLM 接真实机器人的里程碑(§4)
│ Inner Monologue (CoRL) —— 环境反馈闭环, 三类反馈(§5.3)
│ Socratic Models —— 多模态模型零样本组合(VLM 接地的早期思路, §8)
─────┼──────────────────────────────────────────────────────────────────────
2023 │ ReAct (ICLR) —— 推理-行动交替, 影响整个 agent 领域(§5.2)
│ Code as Policies(ICRA) —— 计划即程序(§6); ProgPrompt(ICRA) 并列
│ LLM+P —— 翻译成 PDDL 交规划器, as-Modeler 开创(§7.1)
│ Guan et al. (NeurIPS) —— LLM 生成 PDDL domain + 校验闭环(§7.2)
│ Valmeekam PlanBench(NeurIPS) —— 批判: LLM 自主规划~3%, 戳破乐观(§3.3)
│ VoxPoser (CoRL) —— LLM 塑造 3D 值图, 稠密接地(§8.3)
│ Grounded Decoding(NeurIPS) —— 把"语言×可行性"下沉到 token 级(§4.6)
│ Xie et al. —— 系统研究 LLM 翻译自然语言 goal → PDDL(§7.2)
─────┼──────────────────────────────────────────────────────────────────────
2024 │ Silver et al. (AAAI) —— LLM 作泛化规划器 + 自动调试(§7.2 层次三)
│ SayCanPay (AAAI) —— 加 Pay 因子 + 启发式搜索, 治贪心短视(§4.6)
│ (多篇综述) —— "两范式 + 钟摆回拉"成为领域共识(§3.4)
─────┼──────────────────────────────────────────────────────────────────────
2025 │ 趋势: LLM 前端与经典后端的接口标准化; as-Modeler 工程化;
│ 意图对齐(H4)、长程可靠性、与底层策略联合 成为新焦点(§13.4)
时间线读出三个阶段:2022 是"接进来"(SayCan/Inner Monologue 证明 LLM 能驱动真实机器人);2023 是"分两路 + 被证伪"(as-Planner 与 as-Modeler 各自成形,PlanBench 戳破"纯 LLM 会规划"的乐观,逼大家走混合路线);2024-2025 是"拉回可验证性 + 工程化"(加搜索、加校验、标准化接口,钟摆往回拉)。这正是总论 §5 历史钟摆在五年尺度上的微观重演。
13.2 方法象限:用两个轴给全章方法定位¶
把本章所有方法放进一个二维象限——横轴"LLM 输出什么"(计划 ↔ 模型),纵轴"可行性怎么保证"(事后兜底 ↔ 经典求解保证):
经典求解保证可行性 ▲
│ LLM+P, Guan, Silver, Xie
│ (LLM-as-Modeler §7)
│ ·写 PDDL, 交规划器, 继承完备/最优
│ ·可验证性最强, 但需领域可形式化
│
──────────────────┼──────────────────────────────►
LLM 输出"模型" │ LLM 输出"计划"
│
│ SayCan, ReAct, Inner Monologue,
│ Code-as-Policies, VoxPoser
│ (LLM-as-Planner §4-6,8)
│ ·直接出计划, 靠 affordance/反馈/API 兜
│ ·开放灵活, 但可验证性弱
事后兜底保证可行性 ▼
这张象限图把 §3.3 那张对比表可视化了:右下角(as-Planner)开放灵活、可验证性弱;左上角(as-Modeler)可验证性强、需领域可形式化。没有方法在右上角——"LLM 直接出计划"且"经典求解保证"是矛盾的(计划已由 LLM 出了,经典规划器没东西可搜)。这个"右上角的空缺"恰恰说明了两范式的本质张力:要经典求解的保证,就得让 LLM 退到"写模型";要 LLM 直接出计划的灵活,就得放弃经典求解的保证、改用事后兜底。
本质洞察:这张象限图的"对角线结构"——方法要么落在左上、要么落在右下,左上右下不可兼得——揭示了 LLM 任务规划最深的一条权衡:LLM 越往"直接出计划"走(右),就越远离"经典求解的可验证保证"(下);越想要可验证保证(上),就越得让 LLM 退回"只写模型"(左)。 这不是工程没做好,而是原理性的——因为可验证保证来自"经典规划器在合法模型上的搜索",而一旦让 LLM 把计划直接出了,就没有"在模型上搜索"这一步可供保证了。理解这条对角线,你做选型时就有了根本依据:先问"我能不能把领域形式化成 PDDL"——能,就往左上走(as-Modeler,要可验证);不能,就往右下走(as-Planner,靠闭环兜底)。 这比记住任何具体方法都重要。
13.3 落地选型决策树¶
把象限的洞察做成一棵可操作的决策树,供工程师面对真实任务时走一遍(它是总论 §6 选型树在"已决定用 LLM"之后的细化):
我有个任务, 已确定需要 LLM 前端(指令是自然语言/需开放常识), 怎么落地?
│
├─ Q1: 这个领域能形式化成 PDDL 吗? (动作/前提/效果写得清楚吗?)
│ ├─ 能, 且领域相对固定 → 走 LLM-as-Modeler (§7) ★可验证性最强
│ │ ├─ domain 已有/好写 → LLM 只翻译 goal (层次一, 低风险)
│ │ ├─ domain 要新建 → LLM 生成 domain + 校验闭环 (层次二)
│ │ └─ 要反复解同类问题 → LLM 生成泛化程序 (层次三)
│ │ ↓ 无论哪层, 求解都交经典规划器, 几何交 T3/T4
│ └─ 不能(领域太开放/难形式化) → 走 LLM-as-Planner, 进 Q2
│
├─ Q2: 任务的"计划"主要是什么形态?
│ ├─ 离散技能序列(在固定技能库里选) → SayCan 式 (§4)
│ │ + 长程/怕走死 → 加 SayCanPay 的搜索 (§4.6)
│ ├─ 含循环/条件/参数化("把所有X都...") → Code-as-Policies (§6)
│ └─ 需稠密空间指引(避开/靠近某处) → VoxPoser 式值图 (§8.3)
│
├─ Q3: (无论上面选哪条) 执行中世界会变吗? 会出意外吗?
│ ├─ 会(几乎所有真实任务) → 必加闭环 (ReAct/Inner Monologue §5)
│ │ + 工业级执行监控 (T5 行为树)
│ └─ 不会(受控 demo) → 可省闭环(但不建议)
│
└─ Q4: (贯穿) 以下必做, 无论选了什么:
├─ 接地: 符号 → 感知 (VLM, §8) —— 否则 LLM 是瞎子
├─ 三层校验: 语法/语义/几何 (§10) —— 否则幻觉漏到执行
├─ 几何校验接 T3/T4 (§11 交接面 B) —— LLM 看不到几何
└─ 意图攸关时留人确认 (§10.5 H4) —— 校验拦不住翻译走样
三条使用须知(呼应总论 §6.3):
- 须知一:先问"能否形式化"(Q1),它是分水岭。 这是 §13.2 象限对角线的实践化——能形式化就往 as-Modeler 走(可验证性强),不能才退到 as-Planner。别一上来就选具体方法。
- 须知二:Q4 那四条是"无论如何都要做"的。 接地、三层校验、几何后端、意图确认——它们不是某条路线专属,是所有 LLM 规划系统的公共底座。漏掉任何一条,系统就会在对应的地方栽(§11 陷阱)。
- 须知三:范式可叠加。 一个系统完全可以 as-Modeler(Q1)+ 闭环纠错(Q3)+ VLM 接地(Q4)同时用。决策树帮你判断"需要哪几块",不是"只能选一块"。
13.4 研究前沿与边界¶
前沿(值得投入的方向):
- 意图对齐(H4 / validation):让 LLM 翻译的形式化目标忠实于用户真实意图,是三层校验解决不了的开放难题(§10.5)。反向翻译、隐含假设显式化、交互式澄清都还很初步。
- 长程可靠性:LLM 在长链任务上误差累积(§3.3)。如何让 as-Planner 在几十上百步的任务上保持可靠(更强的闭环?更深的搜索?与 as-Modeler 融合?)是核心挑战。
- 接口标准化与自动化规划工程:让"LLM 写 PDDL + 校验 + 求解"这条链路工程化、自动化(Silver 的泛化程序是雏形),逼近"自动化的规划工程师"。
- 与底层策略的联合:本章的边界(LLM 作任务规划器 vs 端到端 VLA)正在移动——把 LLM 的高层规划与底层学习策略联合训练/推理,是最有潜力也最模糊的前沿。
边界(容易踩坑、要清醒的地方):
- 别信"纯 LLM 端到端、无任何校验"的方案——它在安全攸关部署里必然出事(§2.4 陷阱)。PlanBench 的 ~3% 是警钟。
- 别把本章方法和端到端 VLA 混为一谈——本章是符号/语言层的任务规划,VLA 是端到端动作生成,归 06 具身智能线(§3.1)。
- 别迷信 benchmark——很多"LLM 会规划"的乐观结论来自评测宽松或任务泄漏。用 PlanBench 这类严格基准(§13.1)。
- 别忘了地基——这个方向跑得越快,越要 T1-T4 的经典功底兜底。不懂 PDDL,追前沿只会越追越虚(总论 §5.3)。
⚠️ 常见陷阱(§13)
- 陷阱 13-1:用"最新 = 最好"选方法。 SayCan(2022) 在"固定技能库选技能"上仍是最合适的,未必比 2024 的方法差。选方法按任务结构(§13.3 决策树),不按发表年份(呼应总论 §6.3 须知)。
- 陷阱 13-2:以为象限有"右上角"的银弹方法。 "LLM 直接出计划"且"经典求解保证"是矛盾的(§13.2)。追求"既灵活又可验证的单一方法"是缘木求鱼——要么选边,要么靠两范式叠加。
- 陷阱 13-3:被"LLM 取代经典规划"的叙事带偏。 全章和总论 §5 反复证伪了它。前沿是"如何更好结合",不是"取代"。被这个叙事带偏,会让你忽视地基、错判方向。
练习(§13)
- 把本章八个代表方法(SayCan/Inner Monologue/ReAct/Code-as-Policies/VoxPoser/LLM+P/Guan/Silver)各自填进 §13.2 的象限图,并解释为什么没有方法落在右上角。
- 走一遍 §13.3 的决策树,为下面三个任务各选一条落地路线并说明 Q1-Q4 怎么答的:(a) 固定家庭场景、用户指令多变的整理机器人;(b) 全新实验室环境、要快速搭一个"听指令做操作"的 demo;(c) 仓库每天调度数百个补货任务、要可验证最优。
- 用 §13.1 的时间线,论证"2023 年 PlanBench 的批判如何把整个领域从 as-Planner 独大推向 LLM+经典混合"。这体现了总论 §5 的什么规律?
- (开放)选一篇 2024-2025 的 LLM 机器人规划新论文,用本章的框架分析它:它属于哪个范式(§3.2)?落在象限哪个位置(§13.2)?它的可行性怎么保证、校验在哪几个交接面(§11)?它补了本章哪个前沿空白或踩了哪个边界(§13.4)?
本章常见误解汇总¶
| 误解 | 正确理解 | 出处 |
|---|---|---|
| "LLM 这么强,迟早取代经典规划器" | 不会。LLM 不可验证是其概率续写本质决定的结构性属性,不是"还不够强"。可验证性来自显式搜索,不能靠"更聪明"获得。两者互补、缺一不可。 | §2.3, §2.4 |
| "LLM 会幻觉,但提示词调好就能消除" | 提示工程能降低幻觉频率,但不能从原理上消除——幻觉和正常输出来自同一机制。必须靠外部确定性校验拦截(§10),不能靠内部调教根除。 | §2.3, §9, §10 |
| "经典规划器过时了,学它只为应付本章" | 恰相反,经典规划器是 LLM 规划的安全网与验证后端。LLM-as-Modeler 下游就是它;不懂 PDDL 连 LLM 写的对不对都判断不了。 | §2.4, §7 |
| "LLM-as-Planner 和 as-Modeler 是二选一的门派" | 不互斥,常叠加。可以 as-Modeler 让 LLM 写 PDDL goal,同时 as-Planner 的闭环在执行中纠错。范式是思路不是门派。 | §3.4 |
| "as-Modeler 用了 LLM 写 PDDL,就没 LLM 风险了" | 风险没消失,只是被堵在"模型对不对"这一可被校验器逐条检查的位置。LLM 写的 PDDL 同样可能错,靠校验器拦下。 | §3.4, §7.3 |
| "SayCan 的乘法只是加权的一种" | 乘法实现一票否决(任一因子 \(\approx 0\) 则乘积 \(\approx 0\)),加法允许互相补偿(语言能压过物理)。这是质的区别,乘法才编码了"做不到否决很想做"。 | §4.3 |
| "有了闭环(ReAct)就不会失败了" | 闭环只给纠错机会,不保证成功。反馈错、目标不可行、需全局重排时,闭环也无能为力。它降低失败率,不消除失败。 | §5.4 |
| "程序形态(Code-as-Policies)比符号序列更高级,总该用" | 程序换来表达力(循环/条件)、赔上可验证性。安全攸关、要可验证保证的任务,扁平可验证的符号计划反而更可取。 | §6.3 |
| "LLM 自己能看到场景" | LLM 是纯文本模型,没有视觉。所有"看"的能力来自外接 VLM/检测器。场景必须先由感知翻译成文字/坐标才能喂给 LLM。 | §8.1 |
| "三层校验全过就万无一失" | H4(目标翻译走样)能骗过全部三层——它语法语义几何都合法,唯独偏离用户意图。校验做的是 verification,意图对齐需要 validation(人确认)。 | §10.5 |
| "校验可以让另一个 LLM 来做" | 绝对不行。校验器和被校验者机制相同就共享盲区、会自信地确认错误、不可复现。必须用确定性工具(解析器/VAL/几何引擎)。 | §10.3 |
| "几何校验在本章可以省掉,逻辑对就差不多" | H3(够不到、碰撞)正是 TAMP 的核心难题。逻辑对而几何错的计划一执行就出事。几何校验(接 T3/T4)不可省。 | §10, §11 |
| "LLM 很强大,所有机器人任务都该用它" | 不是。LLM 只补"语言/常识缺口"。目标已形式化、领域固定的任务不缺这两样,硬塞 LLM 只增风险与延迟。看任务缺不缺,而非看 LLM 强不强。 | §2.5 |
| "闭环就该闭得越紧越好、每步都回 LLM" | 不对。每次闭环都付出 LLM 推理延迟。真实系统是分层闭环——底层高频处理常规失败,只在异常时才上升到慢而贵的 LLM 层。 | §5.5 |
| "让 LLM 写代码(Code-as-Policies),直接 exec 就行" | 危险。直接 exec 把整个运行时暴露给 LLM 的幻觉(死循环、危险调用)。必须 API 白名单 + 受限沙箱 + 超时,把可执行空间事前圈死。 | §6.5 |
| "感知信息当然要全部喂给 LLM 越多越好" | 不是。喂太多无关信息会稀释关键信息、降低输出质量。被动接地喂粗概览、主动接地按需查细节,平衡才是关键。 | §8.5, §9.5 |
本章小结¶
本章只回答一个问题,但回答得很完整:怎么让大语言模型在机器人任务规划里既出得上力、又不闯祸? 回顾全章的答案链:
- §2 为什么需要 LLM:经典规划器有两个软肋——听不懂自然语言、缺常识;这正是 LLM 的两个强项。但 LLM 的本质是续写引擎而非推理引擎——它生成"统计上最像好计划的文字",不保证可行、合法、最优。这道"像 vs 是"的鸿沟,是全章一切设计的起点。
- §3 定位与两范式:LLM 是"有常识但不严谨的前端"——负责生成,不负责把关。两大范式:LLM-as-Planner(直接出计划,靠 affordance/反馈/API 兜底)与 LLM-as-Modeler(出 PDDL,交经典规划器求解,继承其完备/最优保证)。区别本质是"把 LLM 的不可靠性堵在哪一层"。
- §4 SayCan:把"增强而非取代"第一次写成公式——\(\ell^*=\arg\max_\ell\, p_{\text{LLM}}(\ell\mid i,h)\cdot p_{\text{afford}}(c_\ell\mid s)\)。乘法让物理可行性对语言拥有一票否决权。谱系:Grounded Decoding(token 级)、SayCanPay(加 Pay + 搜索)。
- §5 闭环:开环假设世界顺从计划、脆弱;闭环承认世界会捣乱、持续校对。ReAct(推理-行动交替)让 Reasoning 使 Acting 可纠错;Inner Monologue 把环境反馈分成成功检测/被动描述/主动查询三类。
- §6 Code-as-Policies:计划即程序,把控制流(循环/条件/反馈)还给计划——表达力强,但可验证性弱(表达力与可验证性此消彼长)。
- §7 LLM-as-Modeler:让 LLM 退后一步只写模型、交经典规划器求解,把可验证性钟摆拉得最回。三层次(翻译 goal / 生成 domain / 泛化程序)按形式化负担递增。灵魂是 generate-validate-repair 自纠错闭环,校验器必须是确定性工具。
- §8 VLM 接地:补符号接地这第三道缝——LLM 没有眼睛,靠 VLM 把符号连到像素与三维。三种粒度(物体/关系/稠密空间)。VoxPoser 揭示通用配方:"LLM 定义/塑造问题,经典数值方法求解问题"。
- §9 提示工程:输出由上下文塑造。few-shot 锚定格式、CoT 提供推演空间、结构化输出/约束解码保证合法、上下文要喂准能力边界与世界状态(防幻觉第一闸)。
- §10 幻觉与三层校验(硬核):幻觉分四类(幻觉动作/违反前提/忽略几何/目标走样),对应 LLM 四个盲区。三层校验(语法/语义/几何)沿"形式→逻辑→物理"抽象阶梯层层过滤,廉价的关在前。铁律:校验必须用确定性工具,绝不让 LLM 自查。H4(意图走样)拦不住,需人确认(validation 不等于 verification)。
- §11 完整数据流:LLM 前端接在 T1-T5 之上,三个交接面(符号/几何/执行)把三层校验展开到系统三个层级。反馈回路(几何回流重排、执行失败重规划)是鲁棒的关键。
- §12 最小原型:80 行串起"指令→PDDL→校验→规划器→自纠错",把 as-Modeler + 三层校验落成可运行代码。
- §13 研究地图:2022-2025 时间线、两范式象限、选型决策、前沿与边界。
全章一句话:LLM 补语言与常识(前端、生成),经典方法守可行与最优(后端、把关),用三层校验 + 自纠错闭环把两者焊在一起——这就是"增强而非取代"从理念到工程的完整落地。 它呼应了总论 §1.1 那个反差的解法:LLM 给机器人补常识、经典方法给机器人保严谨,两者合起来才是完整的大脑。
全章一图速览(把这张图记住,就记住了本章的骨架):
人话: "把厨房收拾干净"
│
┌────────────────────┴────────────────────┐
│ LLM 前端 = 生成(强) │ ← §2 补语言/常识; §2.3 续写非推理
│ ├ 范式 as-Planner(§4-6,8) │ as-Modeler(§7)│ ← §3 两范式; §13.2 象限对角线
│ └ 接地(§8) + 提示工程(§9) │
└────────────────────┬────────────────────┘
│ 候选(动作序列 / PDDL / 程序)
┌────────────────────┴────────────────────┐
│ 三层校验 = 把关(确定性, 非 LLM) §10 │ ← 铁律: 校验绝不让 LLM 自查(§10.3)
│ 语法(拦H1) → 语义(拦H2) → 几何(拦H3) │ ← 廉价在前; H4 拦不住, 需人确认
│ 失败 → 自纠错闭环把精确报错喂回(§10.4) │
└────────────────────┬────────────────────┘
│ 合法/可行的计划
┌────────────────────┴────────────────────┐
│ 经典后端 = 守严谨 T1符号→T3/T4几何→T5执行│ ← §11 三交接面分层把关 + 反馈回流
└────────────────────┬────────────────────┘
▼
机器人稳健执行
主线: LLM 增强而非取代; 前端用 LLM, 把关用经典
核心术语速查¶
见下方"术语速查表"。
知识点总表¶
见下方"知识点总表"。
术语速查表¶
| 术语 | 英文 | 一句话定义 | 出处 |
|---|---|---|---|
| 自回归语言模型 | autoregressive LM | 给定上文、逐 token 续写下一个最可能词的模型;LLM 的本质 | §2.3 |
| 幻觉 | hallucination | LLM 生成看似合理但实则错误/虚构的内容;任务规划里分四类 | §2.3, §10.1 |
| LLM-as-Planner | — | 让 LLM 直接输出计划(序列/程序),可行性靠下游兜底的范式 | §3.2 |
| LLM-as-Modeler | — | 让 LLM 只输出 PDDL 模型、交经典规划器求解的范式 | §3.2 |
| 可供性 | affordance | "当前状态下某技能能成功执行"的概率;SayCan 的 Can 分 | §4.2 |
| SayCan 乘法 | — | \(p_{\text{LLM}}\cdot p_{\text{afford}}\),让物理可行性对语言一票否决 | §4.2-4.3 |
| 开环 / 闭环 | open/closed-loop | 一次性规划不接反馈 / 每步接环境反馈并纠错 | §5.1 |
| 推理-行动交替 | ReAct | LLM 交替生成 Thought(推理)与 Action(行动)的范式 | §5.2 |
| 内心独白 | Inner Monologue | 用三类环境反馈(成功检测/被动描述/主动查询)支撑闭环 | §5.3 |
| 语言模型程序 | LMP | LLM 生成的、调用机器人 API 的程序,即策略本身 | §6.2 |
| 符号接地问题 | symbol grounding | 语言符号与物理感知(像素/坐标)之间无天然对应的问题 | §8.1 |
| 开放词汇检测 | open-vocab detection | 能按任意文本描述(含未训练类别)检测物体 | §8.2 |
| 三维值图 | 3D value map | VoxPoser 中 LLM 塑造的、指引运动优化的稠密值场 | §8.3 |
| 少样本 / 思维链 | few-shot / CoT | 提示里给示例锚定格式 / 让 LLM"想一步再答" | §9.2-9.3 |
| 约束解码 | constrained decoding | 生成时限制 token 选择,保证输出结构合法 | §9.4 |
| 三层可行性校验 | 3-layer feasibility check | 语法/语义/几何,沿"形式→逻辑→物理"层层过滤 | §10.2 |
| 计划验证器 | plan validator (VAL) | 确定性地逐步推演、检查计划是否满足前提的工具 | §10.2 |
| 自纠错闭环 | generate-validate-repair | 生成→校验→把精确报错喂回修复的迭代闭环 | §10.4 |
| 验证 vs 确认 | verification vs validation | 造得对不对(可自动)vs 造的是不是该造的(需人) | §10.5 |
| 交接面 | interface | LLM 前端与经典系统对接处,每处设一道相应校验关 | §11.2 |
知识点总表¶
| # | 知识点 | 核心要点 | 对应节 | 难度 |
|---|---|---|---|---|
| 1 | 语言/常识缺口 | 经典规划器两软肋,LLM 两强项,互补 | §2.1-2.2, §2.4 | ⭐⭐ |
| 2 | 续写非推理 | LLM 是概率续写,"像计划"不等于"是计划",幻觉之源 | §2.3 | ⭐⭐⭐ |
| 3 | LLM 定位 | 有常识不严谨的前端,负责生成不负责把关 | §3.1 | ⭐⭐⭐ |
| 4 | 两大范式 | as-Planner(直接出计划)vs as-Modeler(出 PDDL) | §3.2-3.3 | ⭐⭐⭐ |
| 5 | 钟摆回拉 | 既要 LLM 开放性、又要经典可验证性 | §3.4 | ⭐⭐ |
| 6 | SayCan 乘法 | Say \(\times\) Can,物理可行性一票否决语言 | §4.2-4.3 | ⭐⭐⭐ |
| 7 | SayCan 谱系 | Grounded Decoding(token 级)、SayCanPay(加搜索) | §4.6 | ⭐⭐⭐ |
| 8 | 开环 vs 闭环 | 闭环承认世界会偏离计划、持续校对 | §5.1 | ⭐⭐⭐ |
| 9 | ReAct / Inner Monologue | 推理-行动交替 / 三类环境反馈 | §5.2-5.3 | ⭐⭐⭐ |
| 10 | 计划即程序 | 控制流还给计划,表达力↑可验证性↓ | §6.1-6.3 | ⭐⭐⭐ |
| 11 | LLM 写 PDDL | 三层次(goal/domain/program),交规划器求解 | §7.1-7.2 | ⭐⭐⭐⭐ |
| 12 | 校验器反馈闭环 | generate-validate-repair,校验器须确定性 | §7.3, §10.4 | ⭐⭐⭐⭐ |
| 13 | 符号接地 | LLM 没眼睛,VLM 把符号连到像素/三维 | §8.1-8.3 | ⭐⭐⭐ |
| 14 | 提示工程 | few-shot/CoT/约束解码/喂准能力边界 | §9.1-9.5 | ⭐⭐⭐ |
| 15 | 幻觉四分类 | 幻觉动作/违反前提/忽略几何/目标走样 | §10.1 | ⭐⭐⭐⭐ |
| 16 | 三层可行性校验 | 语法/语义/几何,廉价在前、层层过滤 | §10.2 | ⭐⭐⭐⭐ |
| 17 | 校验铁律 | 必须确定性工具,绝不让 LLM 自查 | §10.3 | ⭐⭐⭐⭐ |
| 18 | verification vs validation | H4 拦不住,意图对齐需人确认 | §10.5 | ⭐⭐⭐ |
| 19 | 完整数据流 | LLM 前端接 T1-T5,三交接面分层把关 | §11.1-11.2 | ⭐⭐⭐ |
| 20 | 最小原型 | 80 行 as-Modeler + 三层校验闭环 | §12 | ⭐⭐⭐ |
本章综合练习与跨章思考题¶
各小节的练习训练单点能力,下面这些题需要把全章、乃至整条 TAMP 线串起来思考——它们没有标准答案,目的是检验你是否真正建立了"LLM 前端 + 经典后端"的系统观。
综合题一(贯穿全章、设计一个完整系统)。 为"家用整理机器人,接收口语指令、在客厅/厨房/书房三类场景工作"设计一个 LLM 任务规划系统。要求画出从"用户说话"到"机器人动起来"的完整数据流(参照 §11.1),并对每个环节回答:(a) 用 as-Planner 还是 as-Modeler(§3.2),为什么?(b) 接地怎么做、用被动还是主动(§8.5)?(c) 三层校验各设在哪个交接面(§10.2、§11.2)?(d) 哪里必须留人确认(§10.5)?(e) 闭环闭在哪个频率层级(§5.5)?
综合题二(对比性、三范式同题异解)。 同一个任务"把桌上所有脏盘子放进洗碗机",分别用 SayCan(§4)、Code-as-Policies(§6)、LLM-as-Modeler(§7)三种方法各写一个高层方案草图。对比:哪个最能表达"所有盘子"这个量化(提示 §6.3)?哪个可验证性最强?哪个最不依赖预先写好的 PDDL?把它们填进 §13.2 的象限图。
综合题三(跨章、联系 T1+T3+T5)。 用本章 LLM 前端 + T1 符号规划 + T3 PDDLStream + T5 行为树,完整描述"用户说'收拾厨房' → 机器人稳健执行完毕"的链路。要求:(a) 标出每段链路守的是哪类可行性(逻辑/几何/运行时);(b) 指出至少两处反馈回流及其触发条件(几何不可行回流、执行失败回流);(c) 说明若抽掉 T3 这一环,系统会在哪类幻觉(H1-H4)上栽,为什么。
综合题四(批判性、边界与陷阱)。 有人提出一个方案:"用最新最强的 LLM,直接从口语指令端到端输出机器人动作序列,不要任何经典规划器或校验,相信模型足够聪明。" 请用本章至少四条原则(建议涉及 §2.3、§2.4 陷阱、§3.3 的 PlanBench、§10.3 校验铁律)系统地批判这个方案,并说明它会在什么样的任务上"看起来能跑"、什么样的任务上"必然出事"。
综合题五(前瞻、钟摆与边界移动)。 总论 §5 的历史钟摆和本章 §3.4、§13.1 都指出"前沿在拉回可验证性"。结合 §13.4 的前沿与边界,预测:未来三年 LLM 任务规划最可能在哪个方向取得突破(意图对齐?长程可靠性?与底层策略融合?),又最不可能在哪个方向突破(提示:可验证性是结构性属性,§2 陷阱)。为你的预测给出基于本章原理的论证。
累积项目:本章新增模块¶
整条 TAMP 线有一个贯穿始终的累积项目 Mini-TAMP——从 T1 的"PDDL + 朴素 Plan-then-Check 协调器"起步,T3 用 PDDLStream 替换了朴素协调器(让符号-几何交织)、T5 给它加上行为树执行层。到本章,Mini-TAMP 要补上它一直缺的那一块——自然语言前端。
本章新增模块:给 Mini-TAMP 装一个"听得懂话"的 LLM 前端。
到目前为止,Mini-TAMP 的输入一直是人手写的 PDDL problem(初始状态 + goal)。本章的任务是让它能直接接收一句自然语言指令。新增模块按 §12 的 as-Modeler 最小闭环实现,分四步集成:
Mini-TAMP 现状(T1→T3→T5): 人写 PDDL problem → 协调器 → 几何 → 行为树执行
▲
│ 本章在这里"接上前端"
本章新增: 自然语言指令 ──► [LLM 前端模块] ──► PDDL goal ──► (接入现有 Mini-TAMP)
| 步骤 | 新增内容 | 复用本章哪节 | 验收标准 |
|---|---|---|---|
| 1 | 提示模板 + LLM 调用:把指令 + 谓词白名单 + 当前状态拼成提示,调 LLM 生成 PDDL goal | §9.5 模板、§7.1 | 对"把杯子放架子"能生成合法 (:goal ...) |
| 2 | 三层校验接入:语法(解析器查白名单)→ 语义(交 Mini-TAMP 的规划器试解)→ 几何(复用 T3 的采样器) | §10.2、§12.2 | 三类幻觉(H1/H2/H3)各能被对应层拦下 |
| 3 | 自纠错闭环:校验失败把精确报错喂回 LLM,重试有上限 | §10.4、§12.2 | 故意让 LLM 拼错谓词,能自动修复 |
| 4 | 接地(可选进阶):用开放词汇检测把"杯子"连到 Mini-TAMP 世界状态里的物体 | §8.2、§8.5 | 指令里的物体名能映射到场景实例 |
集成后的效果:原来要人写 (:goal (on cup shelf)) 才能驱动的 Mini-TAMP,现在对着它说"把杯子放到架子上"就能跑——而且 LLM 写错时三层校验会拦下、自纠错会修复,最终交给经典规划器的仍是合法的 PDDL,Mini-TAMP 下游(协调器、几何、行为树)一行都不用改。
累积项目的设计意图:注意这个新增模块只在 Mini-TAMP 最前面加了一层,下游完全不动——这正是本章"LLM 作前端"定位(§3.1)和"完整数据流"(§11)在累积项目里的亲手验证。它让你切身体会到:LLM 前端是"接上去"的,不是"换进去"的;经典的 T1-T5 后端是稳固的地基,LLM 只是给它配了一个自然语言入口。做完这个模块,你就拥有了一个"听得懂话、又跑得稳"的完整 Mini-TAMP——这正是总论路径丁(工业落地/快速可用)的目标系统。
下一步(T8):Mini-TAMP 将从单机扩展到多机——LLM 前端理解"三台机器人收拾仓库",再交给 T8 的任务分配层分工。本章的前端模块在多机场景可直接复用。
延伸阅读¶
按"先读哪篇"的顺序与本章脉络组织。难度标注:⭐ 入门、⭐⭐ 核心、⭐⭐⭐ 进阶/研究级。
LLM-as-Planner 范式(§4-§6、§8): - Ahn et al. (2022), "Do As I Can, Not As I Say: Grounding Language in Robotic Affordances," CoRL 2022(SayCan)。⭐⭐ —— 本章 §4 的源头,"语言 \(\times\) 可行性"乘法的开山之作,必读。 - Huang et al. (2022), "Inner Monologue: Embodied Reasoning through Planning with Language Models," CoRL 2022。⭐⭐ —— §5.3 的三类环境反馈,闭环规划的代表。 - Yao et al. (2023), "ReAct: Synergizing Reasoning and Acting in Language Models," ICLR 2023。⭐⭐ —— §5.2 推理-行动交替范式,影响极广,通用 agent 的基石。 - Liang et al. (2023), "Code as Policies: Language Model Programs for Embodied Control," ICRA 2023。⭐⭐ —— §6 计划即程序,把控制流还给计划。 - Singh et al. (2023), "ProgPrompt: Generating Situated Robot Task Plans using Large Language Models," ICRA 2023。⭐⭐ —— 与 Code-as-Policies 并列的"程序式提示"代表,§6 延伸。 - Huang et al. (2023), "VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models," CoRL 2023。⭐⭐⭐ —— §8.3 稠密空间接地,"LLM 塑造优化问题"的范例。
LLM-as-Modeler 范式(§7): - Liu et al. (2023), "LLM+P: Empowering Large Language Models with Optimal Planning Proficiency," arXiv:2304.11477。⭐⭐ —— §7.1 开创性框架,"翻译成 PDDL 再交规划器"的代表,是核心边界最有力的量化背书。 - Guan et al. (2023), "Leveraging Pre-trained Large Language Models to Construct and Utilize World Models for Model-based Task Planning," NeurIPS 2023。⭐⭐⭐ —— §7.2 层次二(生成 domain)+ 校验器反馈闭环的灵魂工作。 - Silver et al. (2024), "Generalized Planning in PDDL Domains with Pretrained Large Language Models," AAAI 2024。⭐⭐⭐ —— §7.2 层次三(泛化程序)+ 自动调试,最前沿的"自动化规划工程"。
批判与边界(§3.3、§10): - Valmeekam et al. (2023), "On the Planning Abilities of Large Language Models - A Critical Investigation," NeurIPS 2023(PlanBench)。⭐⭐⭐ —— 用严格基准戳破"LLM 会规划"的乐观叙事,本章"~3%"数字的来源,理解边界的必读。
SayCan 谱系(§4.6): - Huang et al. (2023), "Grounded Decoding: Guiding Text Generation with Grounded Models for Robot Control," NeurIPS 2023。⭐⭐⭐ —— 把"语言 \(\times\) 可行性"从技能级下沉到 token 级。 - Hazra et al. (2024), "SayCanPay: Heuristic Planning with Large Language Models using Learnable Domain Knowledge," AAAI 2024。⭐⭐⭐ —— 给 SayCan 加"Pay"因子 + 启发式搜索,治贪心短视。
综述(建立全局,§13): - 关于 LLM 用于机器人/任务规划的综述(2024-2025,arXiv 多篇)。⭐⭐ —— 建立"两范式 + 钟摆回拉"全局观,配合本章 §13 研究地图阅读。
前置必读(地基): - 本项目 TAMP_T1《任务与运动规划基础》、T3《PDDLStream》。⭐⭐ —— 本章的硬地基。不懂 PDDL 与符号-几何鸿沟,§7/§10/§11 几乎无法读懂(总论 §5.3)。
本章与后续章节的关系¶
| 章节 | 关系 | 本章为它铺垫 / 它如何延续本章 |
|---|---|---|
| T1 任务与运动规划基础 | 硬前置 | T1 教 PDDL 与经典规划器,是本章 §7(LLM 写 PDDL)、§10(语义校验)、§11(符号规划后端)的地基。不懂 T1 读不懂本章硬核。 |
| T2 任务规划与任务分配 | 前置 | T2 的 HTN、时序规划,是 LLM 前端下游可接的符号规划器的更强形态。本章 §11 的"符号规划"工位可由 T2 的方法承担。 |
| T3 PDDLStream | 协同后端 | 本章 §10 第三层"几何校验"、§11 交接面 B 的承担者。LLM 前端产出符号计划,T3 为每个动作求几何可行参数、把可行性回流。两章在"几何校验"处直接咬合。 |
| T4 LGP | 协同后端 | 与 T3 并列的几何后端(富接触任务)。本章 §8.3 VoxPoser"塑造优化问题"的思想与 LGP 的优化范式相通。 |
| T5 行为树与执行监控 | 协同执行层 | 本章 §5(闭环纠错思想)、§11 交接面 C 的工业级落地。LLM 的"大脑层纠错"由 T5 的行为树在"执行层稳健机制"上实现(局部纠错 vs 重规划的分工)。 |
| T6 不确定性 TAMP | 正交叠加 | T6 给规划加"信念空间"一层。当 LLM 前端的感知接地(§8)本身带不确定性时,下游可叠加 T6 的方法处理。 |
| T8 多机器人 TAMP | 后续延伸 | 下一章。本章 LLM 前端在多机场景同样适用——LLM 理解"三台机器人收拾仓库"的意图,再交 T8 的分配层分工(总论 §3.8 完整数据流)。 |
| T9 长时域移动操作综合实战 | 整合收尾 | 把本章 LLM 前端与 T1-T5 整合成一个"听得懂话又跑得稳"的完整长时域系统,§11 的数据流是其骨架。 |
| 06 具身智能线(VLA) | 边界划清 | 本章只讲 LLM 作任务规划器(符号/语言层);端到端动作模型(VLA)归具身智能线。两者边界在 §3.1、§13 反复澄清,且这条边界正在快速移动。 |
🔧 故障排查手册¶
LLM 任务规划的故障,大多源于"该校验的没校验、该接地的没接地、该回流的没回流"。下表列出五个最常见的故障场景,按"症状 → 可能原因 → 排查步骤 → 相关章节"组织。
| 症状 | 可能原因 | 排查步骤 | 相关节 |
|---|---|---|---|
LLM 生成的计划里有机器人不存在的动作(如 vacuum(floor)) |
提示里没给能力边界;没做语法层白名单校验 | 1. 检查提示是否显式列出了技能/API/谓词白名单(§9.5);2. 在输出后加白名单匹配(语法层校验,§10.2);3. 仍漏则用约束解码限制输出空间(§9.4) | §4, §9, §10 |
| 计划逻辑看着对,执行到某步发现前提不满足(如手没空就去抓) | 没做语义层校验;LLM 不做约束传播(§2.3) | 1. 用 VAL 等计划验证器逐步推演状态(§10.2 第二层);2. 报错喂回 LLM 自纠错(§10.4);3. 根治:改用 as-Modeler,交经典规划器搜索(前提天然满足,§7) | §7, §10 |
| 计划逻辑对、真机一执行就够不到/碰撞 | 缺第三层几何校验;让 LLM 自己判断几何(H3 幻觉) | 1. 确认有没有接 T3/T4 做几何校验(§10.2 第三层、§11 交接面 B);2. 几何不可行要回流符号层重排,而非硬执行(§11.2-B);3. 别让 LLM 判"够不够得到"——它看不到几何(§2.3) | §8, §10, §11 |
| LLM 写的 PDDL 反复语法报错、自纠错改了又错 | 反馈不具体;无重试上限陷入循环;提示缺 PDDL 规范/示例 | 1. 把校验器的精确报错(哪行哪个谓词)喂回,而非"你错了"(§10.4);2. 设重试上限 N,超限升级(§10.4 陷阱 10-3);3. 提示里加 few-shot PDDL 示例锚定格式(§9.2) | §7, §9, §10 |
| 计划全部校验通过,但做出来不是用户想要的(如漏了擦桌子) | 目标翻译走样(H4);三层校验拦不住意图偏差 | 1. 用反向翻译让用户确认理解(§10.5);2. 让 LLM 显式列出隐含假设(§10.5);3. 关键目标人在环确认——这是 validation,非 verification(§10.5 洞察) | §7.5, §10.5 |
| 执行中出意外(抓滑/卡住),系统在原地反复重试、不会换策略或重规划 | 混淆"局部纠错"与"重新规划";执行层闭环缺失 | 1. 区分局部失败(重试,§5/§11.2-C)与方向性失败(重规划信号回流上游);2. 用行为树(T5)的 Fallback + 重规划触发实现这套分工;3. 设重试上限,避免死循环(§5.4) | §5, §11 |
| 系统反应迟钝、节奏被拖垮,每个动作前都卡顿几秒 | 闭环闭得太紧——每个低层步都回 LLM(§5.5) | 1. 检查闭环频率:常规局部失败应下放底层高频处理,别每步惊动 LLM(§5.5);2. 改成分层闭环——底层快、LLM 层慢且只在异常时介入;3. 评估是否真需要每步 LLM 反馈,多数不需要 | §5.5 |
| LLM 输出质量忽好忽坏、同样指令结果不稳定 | 提示信噪比差——塞了太多无关信息稀释关键内容 | 1. 精简上下文,确保能力边界与当前状态突出(§9.5 陷阱 9-5);2. 用 few-shot 锚定输出格式(§9.2);3. 关键输出加约束解码/解析校验,别只靠格式指令(§9.4) | §9 |
排查总则:遇到 LLM 规划出问题,先问三句话——"该校验的校验了吗?"(§10 三层)"该接地的接地了吗?"(§8)"该回流的回流了吗?"(§11 三个交接面)。本章 90% 的故障,都能定位到这三问之一。如果三问都做到位、问题仍在,那大概率是 H4 意图偏差(§10.5)——它需要的不是更强的校验,而是人的确认。
API 与提示模板速查表¶
本章不绑定具体某个 LLM 厂商的 SDK(它们迭代太快),这里给出与厂商无关的接口抽象和提示模板骨架——理解了这些抽象,换任何 SDK 都能对号入座。
核心接口抽象¶
| 接口 | 输入 | 输出 | 用在哪 |
|---|---|---|---|
llm.score(text) |
一段文本 | 该文本的对数似然 | SayCan 的 Say 分(给候选技能打分,§4.2) |
llm.generate(prompt) |
提示字符串 | 续写的文本 | 生成动作序列/PDDL/代码(§4-§7) |
affordance.value(skill, state) |
技能 + 当前状态 | 成功概率 \(\in[0,1]\) | SayCan 的 Can 分(§4.2),可由 RL 价值函数/几何检查实现 |
vlm.detect(text_label, image) |
文本类别 + 图像 | 物体框/掩码 + 置信度 | 物体级接地(§8.2) |
vlm.query(question, image) |
问题 + 图像 | 答案 | 关系级接地、成功检测(§8.2、§5.3) |
pddl.parse(text) |
PDDL 字符串 | AST 或语法错误 | 语法层校验(§10.2 第一层) |
validator.check(domain, init, plan) |
模型 + 计划 | 通过 / 第几步哪个前提不满足 | 语义层校验(VAL,§10.2 第二层) |
planner.solve(domain, problem) |
domain + problem | 计划(或不可解) | 经典规划求解(as-Modeler,§7) |
geom.feasible(action, params) |
动作 + 几何参数 | 可行 / IK 无解 / 碰撞 | 几何层校验(接 T3/T4,§10.2 第三层) |
LLM-as-Modeler 提示模板骨架(§7 + §9)¶
你是机器人任务规划器。把用户指令翻译成 PDDL :goal。
【可用谓词】(只能用这些) ← 能力边界, 防 H1 幻觉(§9.5)
(on ?x ?y) (in ?x ?y) (clean ?surface) (holding ?x) (handempty) ...
【可用类型】 object location robot clutter ...
【当前世界状态】(由感知/VLM 接地, §8) ← 防"基于想象规划"(§9.5)
(on cup table) (on book table) (handempty) ...
【示例】(few-shot 锚定格式, §9.2)
指令: "把杯子放到架子上" → (:goal (on cup shelf))
【输出格式】只输出一个合法的 (:goal ...) 表达式, 不要解释。 ← §9.4
【思考】先列出指令隐含的所有子目标, 再写 goal。 ← CoT, §9.3; 也利于暴露 H4 遗漏
用户指令: "{{把这里替换成实际指令}}"
SayCan 选择伪代码骨架(§4)¶
def saycan_step(instruction, history, state, skills):
best, best_score = None, -1.0
for skill in skills: # 只在技能库内选, 防幻觉(§4.4)
say = llm.score(f"{instruction}\n{history}\nRobot: {skill.desc}") # 语言可能性
can = affordance.value(skill, state) # 物理可行性(§4.2)
score = say * can # 乘法: 一票否决(§4.3), 不是加法!
if score > best_score:
best, best_score = skill, score
return best # argmax (Say × Can)
速查表用法:这些抽象是"接口契约"——任何 LLM 规划系统都由它们组合而成。看一个新方法(论文/开源项目)时,对照这张表问"它用了哪几个接口、怎么连的、校验在哪几个接口上设的",就能快速看穿它的骨架。本章所有方法,本质都是这些接口的不同接法。
研究实践建议¶
本章是前沿专题,方法迭代极快。这里按"动手 / 选型 / 研究"三个层次给出建议,帮你既跟得上前沿、又不被热点带偏。
给动手实践者¶
- 先把经典地基打牢,再上 LLM。 本章反复强调,LLM 是前端、经典方法是后端(§3、§11)。如果 §0 自测的 Q1-Q3(PDDL、符号-几何鸿沟、规划器保证)答不顺,先回 T1-T3——否则你会把 LLM 当成"万能黑盒",部署时栽跟头还找不到病根(§2 跳过场景二)。
- 从 LLM-as-Modeler 起步,而非 as-Planner。 对初学者,as-Modeler(§7,LLM 写 PDDL goal + 经典规划器求解)比 as-Planner 更容易做出"可靠"的系统——因为可行性保证由经典规划器兜底,你不必从头搭 affordance/反馈那套复杂兜底机制。先用 §12 的原型跑通"指令 → PDDL → 规划器 → 计划",再逐步加难度。
- 校验闭环优先于提示调优。 新手容易把时间花在"调提示词"上(§9),但提示工程的收益有上限(它降低幻觉频率却不能消除,§2.3 陷阱)。真正决定系统可靠性的是三层校验 + 自纠错闭环(§10)。先把校验闭环搭起来,再回头优化提示。
- 用现成工具,别重造轮子。 PDDL 解析与验证用 VAL、规划器用 Fast Downward、开放词汇检测用成熟模型(§8)。本章的价值是教你怎么把这些可信组件接起来(§11 的数据流),而不是让你重写它们。
给系统选型者¶
- 先走总论 §6 的选型决策树,再决定要不要 LLM。 LLM 不是默认选项——只有当"任务指令是自然语言/需要开放常识"时才引入它(决策树 Q2)。领域固定、目标已形式化的任务,纯经典方法更稳。
- 按"领域能否形式化"在两范式间选。 领域相对固定、要可验证保证 → as-Modeler(§7);领域开放、连 domain 都难写、容忍闭环纠错 → as-Planner(§4-§6)。这是 §7.4 那条边界的实践化。
- 几何校验和执行监控不可省。 无论用哪种 LLM 方法,几何可行性(接 T3/T4)和执行期监控(接 T5)都是真实部署的刚需(§10 陷阱 10-5、§11 陷阱 11-4)。把它们当默认配置,不是可选加项。
给研究者¶
- 关注"钟摆回拉"的方向,而非"LLM 取代一切"的叙事。 总论 §5 和本章 §3.4 都指出,前沿在于"如何让学习式的开放性与符号式的可验证性更好结合",不在于用 LLM 替掉经典规划。被"纯 LLM 端到端"叙事带偏,是这个领域最常见的研究误区。
- 批判性地看待 benchmark 结果。 Valmeekam 等人(2023)的 PlanBench 提醒我们:LLM 在精心设计的规划基准上可能表现很差(§3.3),而很多"LLM 会规划"的乐观结论来自任务泄漏或评测宽松。做研究要用 PlanBench 这类严格基准,区分"看起来会"和"真的会"。
- 目标对齐(H4)是开放难题。 三层校验拦不住"翻译走样"(§10.5)——验证(verification)解决不了确认(validation)。如何让 LLM 翻译的形式化目标忠实于用户意图,是一个理论与工程都未解决的前沿问题,值得投入。
- 本章方法与端到端 VLA 的边界正在移动。 本章只讲 LLM 作任务规划器(符号/语言层),端到端动作模型(VLA)归 06 具身智能线。但两者的边界在快速变化(如把 LLM 规划与底层策略联合训练)。关注这条边界的演化,是这个方向最有潜力的研究空间之一。
版本信息速查¶
| 项目 | 说明 |
|---|---|
| 本章定位 | TAMP_T7,总论板块⑤(学习式)的纵深展开 |
| 核心边界 | LLM 增强而非取代经典规划(贯穿全章主线) |
| 两大范式 | LLM-as-Planner(§4-§6、§8)/ LLM-as-Modeler(§7) |
| 核心方法论 | 三层可行性校验:语法 / 语义 / 几何(§10) |
| 前置依赖 | T1(PDDL/规划器,硬依赖)、T3/T4(几何校验后端)、T5(执行层) |
| 文档类型 | 算法工程教学(text:code 比例不低于 60:40,公式一律 LaTeX) |
下一章预告: TAMP_T8《多机器人 TAMP》将把视角从"单台机器人怎么想/做"扩展到"多台机器人怎么分工与协同"。它回到总论 §3.7 的板块⑥(任务分配,MRTA),讲清当任务的代价依赖路线(顺路便宜、避让费时)时,"谁来做"(分配)与"怎么做"(规划)为什么必须联合求解,以及匈牙利算法、拍卖/CBBA、分配-规划联合优化各自的适用场景。本章学的 LLM 前端在多机场景同样适用——一句"三台机器人把仓库收拾干净",仍由 LLM 理解意图、再交给分配层分工、各机器人再走本章学的规划-几何-执行链路(总论 §3.8 的完整数据流)。从单机到多机,是 TAMP 线从"个体智能"走向"群体智能"的关键一跃。