跳转至

本文档属于 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. 本章目标

学完本章后,你应当能够:

  1. 解释 LLM 在任务层的正确定位——"有常识但不严谨的任务规划器",并说清总论反复强调的核心边界(增强而非取代经典规划)在技术上具体意味着什么、为什么不能让 LLM 独自把关可行性。
  2. 区分 LLM 任务规划的两大范式——LLM-as-Planner(让 LLM 直接输出动作序列)与 LLM-as-Modeler(让 LLM 生成 PDDL/目标,再交经典规划器求解),说出各自的信息流、强弱项与适用场景。
  3. 推导 SayCan 的语言-可行性联合打分公式 \(p(\text{选某技能}) \propto p_{\text{LLM}}(\ell\mid i)\cdot p_{\text{affordance}}(c\mid s,\ell)\),理解"语言说该做"与"物理能做到"为什么必须相乘,并把它与 Grounded Decoding、SayCanPay 放进同一谱系。
  4. 描述 开环规划与闭环规划的区别,讲清 ReAct(推理-行动交替)和 Inner Monologue(三类环境反馈)如何用执行反馈实现自纠错。
  5. 对比 Code-as-Policies(计划即程序)与符号计划(计划即动作序列)两种输出形态,理解程序形态如何天然表达循环、条件与反馈。
  6. 实现(在伪代码层面)一个 LLM-as-Modeler 的最小闭环:自然语言 → 提示 LLM 生成 PDDL → 语法/语义/几何三层校验 → 经典规划器求解 → 失败时把报错喂回 LLM 自纠错。
  7. 诊断 LLM 任务规划的典型失败——幻觉动作、违反前提、忽略几何、目标翻译走样——并说清三层可行性校验(语法、语义、几何)各拦住哪一类。
  8. 判断一个真实任务该用 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 (and (on cup shelf) (on book bookshelf) (clean table)
            (forall (?x - clutter) (stored ?x))))

这个翻译过去全靠人。每来一个新任务、换一句新指令,工程师就得重写 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)。分清它们,才能选对方法。

练习

  1. 举三个"常识隐含前提"的例子(除了正文的"杯子被书挡住"),说明若不写进 PDDL domain,经典规划器会犯什么错,而 LLM 为什么大概率能补上。
  2. "LLM 自主规划成功率只有约 3%"——这个数字是在什么任务上测的(提示:Valmeekam 2023 用的基准)?它能不能推广到"LLM 在所有规划任务上都只有 3%"?为什么不能(提示:考虑 LLM-as-Modeler 与 as-Planner 的区别,§3 会展开)?
  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 前端的准确画像。

练习

  1. 用 §3.3 的对比表,判断下面三个任务该走 as-Planner 还是 as-Modeler,并说明理由:(a) 家用机器人执行"帮我准备一下喝咖啡的东西"(开放、容忍纠错);(b) 自动化仓库每天调度数百个补货任务(领域固定、要可验证、长程);(c) 一次性的探索任务"看看这个陌生房间里有什么能整理的"。
  2. "as-Planner 信任执行闭环来纠错,as-Modeler 信任经典规划器来保证"——分别说明:如果去掉各自信任的那个组件(as-Planner 去掉执行闭环、as-Modeler 去掉经典规划器),会退化成什么?为什么会很危险?
  3. 把总论 §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 用两个分数的乘积来选:

\[ \ell^{*} \;=\; \arg\max_{\ell \in \{\ell_1,\dots,\ell_K\}} \; \underbrace{p_{\text{LLM}}(\ell \mid i,\, h)}_{\text{语言可能性 (Say)}} \;\cdot\; \underbrace{p_{\text{afford}}(c_{\ell} \mid s)}_{\text{物理可行性 (Can)}} \]

逐项拆解:

  • \(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

注意三个要点:

  1. 它是 LLM-as-Planner(§3.2):计划(技能序列)是 LLM 一步步选出来的,不是经典规划器搜出来的。可行性靠 Can 分(affordance)兜,不靠 PDDL 验证。
  2. 它是贪心的:每步只选当前最优,不做前瞻搜索。这简单高效,但也是它的软肋——长程任务上贪心容易走进死胡同(SayCanPay 就是来补这个的,§4.6)。
  3. 技能库是预定义的: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,长期收益/计划代价的估计),并把贪心选择换成启发式搜索

\[ \text{score}(\ell) \;\propto\; \underbrace{p_{\text{LLM}}(\ell\mid\cdot)}_{\text{Say}}\;\cdot\;\underbrace{p_{\text{afford}}(c_\ell\mid s)}_{\text{Can}}\;\cdot\;\underbrace{\hat{R}(\ell)}_{\text{Pay}} \]

其中 \(\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 + 搜索要补的。别把"能跑通短任务"误读成"能可靠地做长程规划"。

练习

  1. 写出 SayCan 的选择公式,并用"我把饮料洒了"的例子,给"用吸尘器""拿海绵""原地待命"三个候选分别估一个定性的 Say 分(高/中/低)和 Can 分(高/中/低),算出乘积排序,说明为什么"拿海绵"胜出。
  2. 用反事实论证"为什么必须乘法不能加法":构造一组具体的 Say/Can 分数,使得加权和会选出一个物理上做不到的动作,而乘法不会。
  3. SayCan、Grounded Decoding、SayCanPay 三者,哪个最适合"技能可以自由组合、无法预先枚举"的场景?哪个最适合"长程、要避免走死胡同"的场景?分别说明理由。
  4. (联系 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 详述)。

练习

  1. 用一个具体任务(如"把洒在地上的牛奶清理掉")写一段 ReAct 风格的 Thought/Action/Observation 轨迹,其中至少包含一次"执行失败 → LLM 据反馈纠错重试"。
  2. Inner Monologue 的三类反馈各举一个新例子(不要用正文的),并说明若缺失该类反馈,机器人会在什么情况下犯错。
  3. 给出一个闭环纠不了的失败例子(属于 §5.4 三类之一),说明为什么它需要的不是闭环重试,而是别的机制(哪个?)。
  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 colorfor 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 写的代码? 设想最天真的实现:

# ❌ 危险:直接执行 LLM 生成的代码, 不设任何边界
code = llm_generate(f"写代码完成: {instruction}")
exec(code)        # 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:以为它能取代符号规划的搜索。 程序里的循环/条件是预先写死的控制流,不是搜索。需要"在巨大组合空间里找一条满足约束的序列"时,那是经典规划器的搜索能力,程序的控制流替代不了。

练习

  1. 用 Code-as-Policies 风格,为"把桌上比手机大的物体都放进抽屉"写一段 LMP 伪代码,标出其中的循环、条件、API 调用各在哪。
  2. 同一个任务(第 1 题),如果用 PDDL 动作序列表达会遇到什么困难?(提示:物体数量、"比手机大"这个条件何时能判断。)
  3. 举一个不该用 Code-as-Policies、而该用符号规划/as-Modeler 的任务,说明理由(从"可验证性"或"最优性"角度)。
  4. 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 重写     │
   └─────────────────────────────────────────────────────────────┘

这个闭环的精髓在两点:

  1. 校验器是确定性的、可信的——不是另一个 LLM。 PDDL 解析器、VAL 计划验证器都是经典的、形式化的工具,它们的判断确定无误。用它们来检查 LLM 的输出,等于用"可信的尺子"量"不可信的产物"。这与§10要强调的原则一致:别让 LLM 给自己把关,要让确定性工具把关。
  2. 反馈是具体的、可定位的。 步骤 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 的自动写手 + 人工/工具审核"。

练习

  1. 用自己的话解释 LLM+P 的实验"同一个 LLM 直接规划近乎失败、翻译成 PDDL 再交规划器却接近最优",并说明它为什么是"增强而非取代"的有力证据。
  2. 画出 generate-validate-repair 闭环,标出"校验"这一步具体查哪三类问题(语法/语义/可解性),并说明为什么校验器绝不能用另一个 LLM。
  3. 给定三个任务,判断各该用 as-Modeler 的哪个层次(翻译 goal / 生成 domain / 泛化程序):(a) 一个领域已有成熟 PDDL domain、只是用户指令多变;(b) 一个全新领域、还没有任何 PDDL、要快速建模;(c) 一个领域要反复解大量同类新问题、希望一次生成通用解题器。
  4. (联系 §5)建模层的 generate-validate-repair 闭环,与执行层的 ReAct/Inner Monologue 闭环,结构上有什么共性?反馈源各是什么?
  5. 续写 §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 输出的符号(cupshelfon)和物理世界的感知(像素、坐标)之间,没有天然的对应

具体地,一个 LLM 生成的计划 pick(cup) 要真正执行,需要回答:

  1. 指代接地(referential grounding):场景里哪个物体是 "cup"?(要把符号 cup 连到具体的视觉实例)
  2. 空间接地(spatial grounding):这个 cup 在哪?它的三维位姿、抓取点是什么?(要把符号连到几何坐标)
  3. 关系接地(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 提示里的"当前世界状态"采用的方式。

   相机 → VLM/检测器 → "桌上有杯子、书" (文字) → 塞进 LLM 提示 → LLM 规划
         (感知先把世界翻译成文字, LLM 被动接收)

方式二:LLM → 代码 → 驱动感知(LLM-drives-perception,主动接地)。 LLM 先行生成代码,代码里主动调用感知 API 去查询它需要的信息。是 LLM 决定"现在该看什么、问什么"。这是 Code-as-Policies(§6)、VoxPoser(§8.3)采用的方式——LLM 写的程序里有 detect_objects("cup")get_color(b),运行时才去调感知。

   LLM → 写代码(含 detect/query 调用) → 运行时主动查感知 → 拿到结果继续
         (LLM 主动决定查什么, 感知按需被调用)

把两者并置:

方式一 被动接地 方式二 主动接地
谁主动 感知先行,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 洞察)。

练习

  1. place(cup, on=plate) 这个动作,列出它执行前需要的三种接地(指代/空间/关系)各要回答什么问题、分别用什么工具。
  2. "开放词汇检测"为什么特别适合给 LLM 任务规划做接地?(提示:对比传统固定类别检测器,考虑 LLM 输出符号的开放性。)
  3. VoxPoser 同时用到了本章哪三条线索(§2/§6/§8)?用一句话说明它把"接地"做到了什么粒度、产出什么形态的"计划"。
  4. 接地结果为什么也要"校验、兜底、不能让 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:上下文塞太多无关信息。 上下文窗口有限且信噪比影响输出——把无关的领域细节、冗长历史全塞进去,会稀释关键信息(能力边界、当前状态),反而降低输出质量。要喂准、喂精,不是喂多。

练习

  1. 为"把指令翻译成机器人 API 调用序列"设计一个 few-shot 提示模板,包含:角色说明、API 白名单、两个示例、当前状态占位、输出格式要求。标出哪部分在防幻觉。
  2. 给一个"不用 CoT 会漏掉隐含步骤"的任务例子(不要用正文的"移书"),分别写出不用 CoT 的错误输出和用 CoT 的正确推演。
  3. 解释结构化输出三层手段(格式指令/解析校验/约束解码)"把约束施加在生成流程哪个位置",并说明各自的强制力与代价。
  4. 提示里"能力边界"和"当前世界状态"分别防住哪一类幻觉?把它们和 §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 一致,这里强调其普适性):

  1. 反馈要具体可定位:喂回"第 3 步 pick(cup) 前提 handempty 不满足,因为手里有 book",远胜于"计划有错"。具体报错让 LLM 的修复有的放矢,命中率高得多。校验器(VAL、IK 求解器)天然能产出这种精确诊断——这是它们比"另一个 LLM 当裁判"更可靠的又一原因。
  2. 要有重试上限: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 规划里一个尚未被工具完全解决的软肋。

练习

  1. 把四种幻觉形态(幻觉动作/违反前提/忽略几何/目标走样)各对应到三层校验的哪一层能拦(或拦不住),制成一张"幻觉-关卡"对应表。哪一种幻觉三层校验都难完全拦住?为什么?
  2. 解释三层校验为什么必须"从便宜到昂贵、前层不过不做后层"。给一个"语法就错了却先做了几何检查"的反例,说明它浪费在哪。
  3. 用自己的话陈述 §10.4 的红线,并解释为什么"让另一个 LLM 当裁判"也违反这条红线(提示:另一个 LLM 也有幻觉)。
  4. 把本章三个自纠错闭环(执行/建模/校验)列出来,指出它们的共同结构和各自的反馈源。为什么反馈源必须是确定性的?
  5. 为一个"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)

  1. 默画 §11.1 的总数据流图(LLM 前端 → T1 → T3/T4 → T5),标出本章每一节(§2/§4-§7/§8/§10/§5)各落在图的哪个工位。
  2. 三个交接面(A/B/C)各"交什么、谁验、出错怎么回流"?说明它们如何把 §10 的三层校验展开到系统的三个层级。
  3. 续走 §11.3 的场景:假设执行到 wipe(table) 时发现抹布不在预想位置。判断这是"局部失败"还是"方向性失败",该走交接面 C 的哪条回流(局部纠错 or 重规划)?为什么?
  4. (跨章综合,联系 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)

  1. 把 §12.2 的代码读一遍,画出它的控制流(哪步成功去哪、失败去哪),并标出三层校验、自纠错闭环、经典求解各在哪几行。
  2. §12.3 四个错误实现各违反了本章哪条核心原则?把它们和 §7/§10 的陷阱编号对应起来。
  3. plan_from_instruction 加一个功能:当几何校验(第三层)失败时,不是简单喂回重写,而是把"哪个动作够不到"的信息回流,提示 LLM 换一个放置位置(如把 shelf 改成 low_shelf)。写出这段修改,并说明它如何对应 §11.2 交接面 B 的"可行性回流"。
  4. (跨章综合,联系 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 研究前沿与边界

前沿(值得投入的方向)

  1. 意图对齐(H4 / validation):让 LLM 翻译的形式化目标忠实于用户真实意图,是三层校验解决不了的开放难题(§10.5)。反向翻译、隐含假设显式化、交互式澄清都还很初步。
  2. 长程可靠性:LLM 在长链任务上误差累积(§3.3)。如何让 as-Planner 在几十上百步的任务上保持可靠(更强的闭环?更深的搜索?与 as-Modeler 融合?)是核心挑战。
  3. 接口标准化与自动化规划工程:让"LLM 写 PDDL + 校验 + 求解"这条链路工程化、自动化(Silver 的泛化程序是雏形),逼近"自动化的规划工程师"。
  4. 与底层策略的联合:本章的边界(LLM 作任务规划器 vs 端到端 VLA)正在移动——把 LLM 的高层规划与底层学习策略联合训练/推理,是最有潜力也最模糊的前沿。

边界(容易踩坑、要清醒的地方)

  1. 别信"纯 LLM 端到端、无任何校验"的方案——它在安全攸关部署里必然出事(§2.4 陷阱)。PlanBench 的 ~3% 是警钟。
  2. 别把本章方法和端到端 VLA 混为一谈——本章是符号/语言层的任务规划,VLA 是端到端动作生成,归 06 具身智能线(§3.1)。
  3. 别迷信 benchmark——很多"LLM 会规划"的乐观结论来自评测宽松或任务泄漏。用 PlanBench 这类严格基准(§13.1)。
  4. 别忘了地基——这个方向跑得越快,越要 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)

  1. 把本章八个代表方法(SayCan/Inner Monologue/ReAct/Code-as-Policies/VoxPoser/LLM+P/Guan/Silver)各自填进 §13.2 的象限图,并解释为什么没有方法落在右上角。
  2. 走一遍 §13.3 的决策树,为下面三个任务各选一条落地路线并说明 Q1-Q4 怎么答的:(a) 固定家庭场景、用户指令多变的整理机器人;(b) 全新实验室环境、要快速搭一个"听指令做操作"的 demo;(c) 仓库每天调度数百个补货任务、要可验证最优。
  3. 用 §13.1 的时间线,论证"2023 年 PlanBench 的批判如何把整个领域从 as-Planner 独大推向 LLM+经典混合"。这体现了总论 §5 的什么规律?
  4. (开放)选一篇 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 规划系统都由它们组合而成。看一个新方法(论文/开源项目)时,对照这张表问"它用了哪几个接口、怎么连的、校验在哪几个接口上设的",就能快速看穿它的骨架。本章所有方法,本质都是这些接口的不同接法。


研究实践建议

本章是前沿专题,方法迭代极快。这里按"动手 / 选型 / 研究"三个层次给出建议,帮你既跟得上前沿、又不被热点带偏。

给动手实践者

  1. 先把经典地基打牢,再上 LLM。 本章反复强调,LLM 是前端、经典方法是后端(§3、§11)。如果 §0 自测的 Q1-Q3(PDDL、符号-几何鸿沟、规划器保证)答不顺,先回 T1-T3——否则你会把 LLM 当成"万能黑盒",部署时栽跟头还找不到病根(§2 跳过场景二)。
  2. 从 LLM-as-Modeler 起步,而非 as-Planner。 对初学者,as-Modeler(§7,LLM 写 PDDL goal + 经典规划器求解)比 as-Planner 更容易做出"可靠"的系统——因为可行性保证由经典规划器兜底,你不必从头搭 affordance/反馈那套复杂兜底机制。先用 §12 的原型跑通"指令 → PDDL → 规划器 → 计划",再逐步加难度。
  3. 校验闭环优先于提示调优。 新手容易把时间花在"调提示词"上(§9),但提示工程的收益有上限(它降低幻觉频率却不能消除,§2.3 陷阱)。真正决定系统可靠性的是三层校验 + 自纠错闭环(§10)。先把校验闭环搭起来,再回头优化提示。
  4. 用现成工具,别重造轮子。 PDDL 解析与验证用 VAL、规划器用 Fast Downward、开放词汇检测用成熟模型(§8)。本章的价值是教你怎么把这些可信组件接起来(§11 的数据流),而不是让你重写它们。

给系统选型者

  1. 先走总论 §6 的选型决策树,再决定要不要 LLM。 LLM 不是默认选项——只有当"任务指令是自然语言/需要开放常识"时才引入它(决策树 Q2)。领域固定、目标已形式化的任务,纯经典方法更稳。
  2. 按"领域能否形式化"在两范式间选。 领域相对固定、要可验证保证 → as-Modeler(§7);领域开放、连 domain 都难写、容忍闭环纠错 → as-Planner(§4-§6)。这是 §7.4 那条边界的实践化。
  3. 几何校验和执行监控不可省。 无论用哪种 LLM 方法,几何可行性(接 T3/T4)和执行期监控(接 T5)都是真实部署的刚需(§10 陷阱 10-5、§11 陷阱 11-4)。把它们当默认配置,不是可选加项。

给研究者

  1. 关注"钟摆回拉"的方向,而非"LLM 取代一切"的叙事。 总论 §5 和本章 §3.4 都指出,前沿在于"如何让学习式的开放性与符号式的可验证性更好结合",不在于用 LLM 替掉经典规划。被"纯 LLM 端到端"叙事带偏,是这个领域最常见的研究误区。
  2. 批判性地看待 benchmark 结果。 Valmeekam 等人(2023)的 PlanBench 提醒我们:LLM 在精心设计的规划基准上可能表现很差(§3.3),而很多"LLM 会规划"的乐观结论来自任务泄漏或评测宽松。做研究要用 PlanBench 这类严格基准,区分"看起来会"和"真的会"。
  3. 目标对齐(H4)是开放难题。 三层校验拦不住"翻译走样"(§10.5)——验证(verification)解决不了确认(validation)。如何让 LLM 翻译的形式化目标忠实于用户意图,是一个理论与工程都未解决的前沿问题,值得投入。
  4. 本章方法与端到端 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 线从"个体智能"走向"群体智能"的关键一跃。