各位同行,我先把话撂这儿:提示工程不是写几句漂亮话让模型“聊天”,在自动驾驶这个领域,它本质上是在跟一个“从海量视频里学会开车直觉”的多模态大模型签一份极其严格的驾驶行为合同。我作为提示工程架构师,过去一年多主力工作就是把这份“合同”反复打磨,让它输出的每个驾驶决策都可解释、可控制、兜得住底。这篇帖子里没有任何纸上谈兵,全部来自我实际调试车载多模态大模型的经验,直接给到你能抄作业的设计思路、提示词模板、评测方法和踩坑实录。
1. 整体设计思路:为什么自动驾驶比通用助手更需要提示工程
1.1 提示工程在车端扮演的真实角色
很多人对提示工程的理解停留在“润色输出”“引导回答方向”,但在自动驾驶系统里,提示工程承担的是传统软件工程里“意图识别 + 规则引擎 + 状态机”的活。你可以把整个驾驶系统想成一个三层结构:底层是传感器融合与实时控制(车速、转向、制动),中间层是决策规划模块,顶层则是我负责的区域——利用多模态大模型对复杂场景进行“语义理解”与“行为预案生成”。
传统自动驾驶决策模块依赖人工编写的规则和大量路测数据训练出的模型,碰到没见过的场景就容易“死机”。而引入带提示工程的多模态大模型之后,系统就像请了一位随时能听懂复杂交通状况、并快速给出建议的老司机。但这位“老司机”不是白纸一张——它什么都懂,也可能什么都胡说。提示工程就是给它划定一条极其清楚的思考路径,告诉它什么时候该激进、什么时候必须保守、在无法判断时必须输出什么。
1.2 与通用语言提示工程的核心区别
我在最初搭建提示框架时也犯过“拿通用方法论往车上套”的错,后来碰了几次壁才总结出三个本质区别。
**第一个区别:输入不是文字流,而是多模态时空切片。**语言模型的提示词往往是“文本上下文”,而车载模型要同时处理前视摄像头的画面、毫米波雷达的目标列表、高清地图的车道拓扑、自车速度、方向盘转角、导航路径意图。这些数据必须被编码成一种模型能“对齐理解”的结构化上下文,不是简单拼在一起就完事。我实测下来,把视觉特征做成带空间位置的patch embedding、把矢量地图数据写成token序列,再按时间轴拼接,推理稳定性提升非常明显。
**第二个区别:误差容忍度是毫秒级和厘米级。**通用助手的回答错了顶多重新问一次,自动驾驶猜错一个车的朝向就可能引发连锁反应。因此提示工程必须设计出“保守退让”的输出模式,让模型在不确定时给出低置信度信号,而不是强行做一个选择。
**第三个区别:可溯源性与审计要求极高。**每一条模型的决策理由都要能回放,能定位到是提示哪句话、哪段上下文导致了偏差。这意味着我们提示词里不能有模糊的表达,每一个指令都要对应明确的场景触发条件。
1.3 架构选型:为什么是分层提示链而非单次巨型提示
我开始采用的是“单次大提示词 + 全量上下文”,把所有传感器数据、地图信息一次性塞给模型。效果很惨:推理延迟直接超过500ms,而且长上下文的注意力分散,关键障碍物信息经常被“淹没”。后来我参考了传统算法里的“分层规划”思想,把提示词拆成三层链式结构。
- 第一层:场景判断层。负责回答“当前处于什么场景”,比如城市路口、高速巡航、施工区域、拥堵跟车。
- 第二层:意图理解层。负责回答“周围交通参与者的意图是什么”,比如哪辆车在变道、哪个行人准备过街、哪辆摩托车在钻缝。
- 第三层:决策建议层。基于前两层的输出生成“本车驾驶行为预案”,输出结构化动作和参数。
这种分层设计的好处有两点:一方面,每一层模型的任务变简单了,上下文长度可以单独裁剪,延迟更容易控制;另一方面,每一层都有单独的置信度和可观测入口,出了问题能快速定位是“场景误判”还是“意图理解错误”,不用大海捞针。
2. 核心细节解析:自动驾驶提示词的四个关键组成
2.1 系统提示词的设计逻辑:角色、边界、安全公约
系统提示词是整条提示链的总纲,我把它拆成角色定义、边界守则、安全公约三块。
角色定义不能写太虚。例如“你是专业的自动驾驶决策专家”不如写成:
你是某自动驾驶系统的决策规划模块,负责在给定的感知信息和导航意图下,输出安全、合规、高效的自车驾驶行为。你的决策仅对当前时间步有效,必须结合实时输入给出动作原语和参数。
边界守则要回答“哪些事你不能做”。比如明确禁止自车越过实线、禁止在无保护路口强行通过、禁止在没有足够间隙时汇入主路。这些行为不可描述为“尽量”,要写为“当且仅当满足以下条件才可执行”。
安全公约则是所有决策的皇冠条款。我设计了一个三阶梯约束:第一,碰撞风险不可接受;第二,违反基础交通规则不可接受;第三,在以上前提下可追求通行效率。这个顺序永远不能反,否则模型会倾向于激进行驶。
2.2 多模态上下文的组织与编码技巧
多模态输入的组织方式直接决定模型能否“看懂”路况。我总结了三个关键点。
时空语义对齐。视觉特征与矢量地图必须建立在统一坐标系上。我的做法是将自车位置设为原点,前向为x轴,将所有障碍物、车道线、目标物的坐标都转换为自车坐标系,再以文本形式插入上下文。这样模型不需要在“图像坐标 vs 世界坐标”之间做转换,推理负担显著降低。
关键区域的显著性标记。不是所有画面都同等重要。提示词中要突出标注影响当前决策的关键对象,比如:
- 前向200米内正在变道的车辆
- 左侧盲区接近的摩托车
- 路口处意图冲突的行人
我会用“ ”这样的结构把关键目标具象化,让模型优先关注。
历史轨迹摘要而非全量回放。把过去10秒的轨迹数据全量堆进上下文既不经济也干扰注意力。我改为只保留关键帧和语义摘要:某车在3秒内从车道A切入车道B、某行人在路口边缘犹豫了2秒。这种压缩后的时间上下文既能保留运动趋势,又不会造成token浪费。
2.3 输出约束:从自由文本到结构化驾驶指令
早期我们直接让模型输出自然语言决策,结果五花八门,下游规划模块根本没法解析。后来我设计了严格的结构化输出协议,强制模型生成JSON格式,并且挡掉一切“嗯嗯啊啊”。
每一位决策输出必须包含五个字段:
- action:动作原语,取值如keep_lane, lane_change_left, decelerate_to_stop, slow_down_prepare_stop等
- target_speed:目标车速,单位km/h
- reason:决策理由,一句话,限定20字以内
- confidence:置信度,0到1的小数
- fallback_plan:当主决策不可执行时的保守备用动作
输出协议中我用了一个小技巧:在JSON结构前加一句“请只输出一个合法的JSON对象,不要附加解释”,并配合温度参数调低。实测在温度从0.8降到0.2之后,非法输出率从11%降到接近0.5%。采样参数是提示工程最便宜但最有效的开关,很多人会忽略。
2.4 上下文窗口管理:长尾场景的分而治之
对于城市复杂路口这类长尾场景,单条提示链的上下文容易撑爆窗口或者让模型失焦。我的解决方案是设计“场景专属子提示链”。
具体做法是:第一层场景判断层一旦识别到“无保护左转路口”,就动态加载一套专门针对左转场景的子提示模板,里面包含该场景特有的决策准则(让直行、让右侧来车、注意对向左转弯共享车道),然后把通用控制相关的内容暂时降权。这套“场景路由 + 子链加载”的设计,让复杂场景的决策准确率大幅提升,而且每个场景的提示词可以独立迭代,不用互相影响。
注意:场景路由本身也要设置“未知场景”出口。如果模型无法判断当前场景,必须直接进入保守模式,而不是强行套用某个子模板。这个出口如果漏掉,后果不堪设想。
3. 实操过程与核心环节实现:一个无保护左转场景的完整提示工程设计
3.1 场景定义与需求拆解
我在模拟环境某跨平台系统中跑的一个典型例子:无保护左转。所谓无保护,就是没有左转信号灯,驾驶员需要在对向直行车流中寻找安全间隙完成左转。这对人类来说都是高难度操作,对多模态大模型更是极限挑战。
需求拆解成三个子任务:
- 准确识别对向直行车的车速、距离和间隙是否足够
- 识别行人、非机动车等潜在冲突对象
- 在间隙足够时果断起步,在间隙不足时平稳等待
这三个子任务如果混在一个提示词里,模型往往会顾此失彼。我按分层提示链的思路,将决策拆成“优先级判断 + 间隙评估 + 动作生成”三个连续步骤。
3.2 提示词模板逐层编写实录
第一层场景判断层我给的提示模板核心内容如下:
当前道路场景描述:信号灯状态为无左转绿灯,对向直行车道车流密度中等,路口存在行人横道。请判断当前驾驶场景类型,候选:urban_left_turn_protected / urban_left_turn_unprotected / urban_straight / highway_cruise / unknown。若判断为unknown,请直接输出 conservative_stop 预案。 场景上下文: 自车速度=0km/h,位于最左侧车道。
第二层意图理解层模板侧重于找出“哪辆车在让行还是不让行”:
请理解以下对向车辆的行为意图:vehicle_08 当前速度=42km/h,距离路口=35m,加速度=0.2m/s²;vehicle_12 当前速度=58km/h,距离路口=80m,加速度=0.5m/s²;vehicle_15 当前速度=30km/h,距离路口=20m,加速度=-1.0m/s²。 判定规则:距离小于25m且速度大于25km/h的车辆,视为不减速直行;距离在25-60m且加速度小于0.3m/s²的车辆,视为可通过间隙窗口;速度大于55km/h的车辆即使距离较远也视为高风险。 输出:每辆车的意图分类(yield / not_yield / uncertain)。
第三层决策建议层:
基于场景判断与意图理解结果,决定自车左转动作。若存在安全间隙(对向直行车辆距离大于40m且相对速度小于5m/s),可选择accelerate_through_turn;若间隙不足,选择hold_position_wait;若存在行人冲突,选择decelerate_to_stop并附加提示等待。输出JSON格式,包含action、target_speed、reason、confidence、fallback_plan。 特别提醒:不得为了寻找间隙而将车头探出停车线超过1.5米。
3.3 参数选择与采样策略调优
提示词模板写好了,参数调优同样关键。我在这套左转场景上做了四组对照实验:
- 温度0.8 + 不做结构化约束:随机性太强,同一个场景出现跳跃式决策,不可复现
- 温度0.2 + 结构化约束:决策稳定,但偶尔过度保守,把可安全通过的间隙也放弃
- 温度0.4 + 结构化约束 + 间隙判定打分:最佳平衡点,既能复现,又保留必要的灵活性
- 温度0.0 + 贪婪解码:完全确定性,适合回归测试,上限发挥不出来
我把温度0.4作为在线运行的默认值,温度为0.0作为离线回归测试的固定配置。另外还把top_p限制在0.9,避免极端低概率token干扰驾驶决策。需要注意的是,这些值不是一成不变的,它跟模型的预训练分布强相关,换一个版本的大模型就得重新调。
3.4 基于模拟器的成效复盘
在模拟环境里,我记录了这套提示工程上线前后的关键指标。上线前模型在该场景的动作正确率只有62%,最典型的问题是有时把“可安全通过的间隙”误判为“风险过高”,导致路口拥堵;有时又激进到在间隙不够时强行左转,引发对向车辆急刹。
上线后三周迭代,正确率提升到88%,误判率趋于稳定。我最满意的一点是可解释性大幅提升:以往系统决策错了,团队要分析半天是感知丢了目标还是规划算错了路径;现在直接把三层输出的reason字段拉出来看一眼,问题出在哪一层一目了然。排查效率提升不是一点半点,工作日晚上被on-call电话叫醒的次数明显减少。
4. 常见问题与排查技巧实录:自动驾驶提示工程的五大坑
4.1 模型对静止车辆产生“视而不见”的幻觉
这是我在项目中遇到的第一个头疼问题:系统在高速巡航时,明明感知已给出前方静止事故车,模型却输出“保持当前速度继续行驶”,仿佛那辆车不存在。
排查发现,问题不在提示词本身,而在上下文组织。因为我把感知目标的描述统一写成“vehicle_stationary”,模型在长上下文中对这类token不敏感。后来我引入“显著性标记 + 冲突告警”的写法:
前方180米处存在静止障碍物(类型=事故车),位置与自车车道重叠。此目标属于 immediate_collision_risk 类别,必须优先分析。请评估当前车道继续行驶的风险,并给出停车或变道建议。
同时我把这类高风险对象放在上下文的开头位置,利用注意力机制对首部内容的天然偏置,效果立竿见影。从此之后,凡是高风险障碍物,一律置顶+标注risk,模型不再“失明”。
4.2 极端光线与天气下的上下文描述退化
有一次模拟雨天场景,模型突然把前方一辆白色货车误判为“可正常通过”。我们查了感知链路,发现视觉编码在雨滴干扰下产生了模糊特征,而提示词中又没有明确的对抗措施。
解决方式是在场景判断层增加环境状态输入,让系统先识别“weather=rainy,visibility=moderate”,然后在决策层挂载一段环境提示:
当前为雨天,视线受限,路面湿滑。请将有效刹车距离按干燥路面的1.5倍估算;当目标物识别置信度低于0.6时,默认按“存在潜在障碍物”处理,不得轻易规划高速通过。
这个“低置信度即风险”的原则,配合环境差异化惩罚系数,显著减少了恶劣天气下的误判。后来我又把夜晚、逆光、大雾也做了类似子模板,效果都很好。
4.3 推理延迟超限:链路优化的三板斧
自动驾驶对端到端延迟要求极高。我们模型单次推理一度耗时600ms,这在高速场景是不可接受的。我做了三项优化:
- 分层异步化:场景判断层可以低频运行(每秒5次),意图理解层与决策层以更高频率触发,避免所有层都在同一节奏上跑。
- 关键帧缓存:对于静止背景区域,视觉特征的差异很小,直接复用上一帧结果,不用每次重新跑完整编码器。
- 小模型预路由:用一个极小的文本分类器先判断“是否需要大模型介入”,简单场景走规则库,复杂场景才调大模型。
优化后典型延迟降到180ms,而复杂路口场景仍保持大模型全面分析。你会发现提示工程和系统架构设计其实分不开,提示词写得再漂亮,延迟超标一样白搭。
4.4 提示词版本管理与回滚机制
提示词在项目里迭代飞快,我经历过“昨天新增了一句约束,今天整个路口决策全部摆烂”的惨案。从那以后我上强制推行了严格的版本管理流程。
所有提示词改动必须提交到代码仓库,每一版都要跑一遍固定的回归场景集合。回归集合包含至少100个典型场景,覆盖路口左转、拥堵跟车、行人穿插、施工变道等;同时还有20个随机对抗场景,防止模型过拟合提示词模板。任何改动要同时通过两类测试才能合并到发布分支。
我还会对模型输出做指纹记录,每一次决策的完整调用链(输入上下文、各层输出、采样参数)都打成一个trace包。排查时直接回放trace,快速定位是提示词问题还是模型自身问题。这套机制上线后,因为提示词改动引起的线上问题减少了九成。
4.5 多目标冲突时的提示词优先级设计
自动驾驶提示工程最容易翻车的地方在于不同目标互相打架:要安全还是要效率?要变道还是继续等?要礼让行人还是保证通行速度?我一般通过“安全权重的显式声明”来化解。
在系统提示词里我会明确写入一条规则:
当安全性与效率发生冲突时,一律优先保证安全性。安全性包括:自车与一切交通参与者的最小安全间距、自车不进入禁行区域、自车不造成其他车辆紧急制动。在安全性有保障的前提下,再根据通行效率选择更快的决策方案。
这看起来很朴素,但缺了这条,模型大概率会为了“顺利完成左转”去逼近危险动作。提示工程本质上就是在跟模型的奖励对齐搏斗——预训练模型并不天然理解驾驶安全,你得把安全变成提示词里不可撼动的硬约束。
最后的经验分享
讲了这么多,我最后再分享一个做自动驾驶提示工程时最容易被忽略的思维转变:别把模型当“会开车的专家”,而是当“一个很聪明但没有常识的实习生”。
我之所以坚持做“场景判断 → 意图理解 → 决策生成”三层提示链,是因为这种结构逼着模型先在低层把基础理解做扎实,再往上输出看似聪明的驾驶策略。只要底层能力不到位,上层修改提示词只是掩盖问题。很多团队拿现成的视觉语言大模型直接套驾驶场景,失败后反复调提示词,问题越调越多——本质上就是跳过了能力建设这一环。
另外,实用的工程管理建议:一定要给每条提示词写变更记录,写出你改了什么、为什么改、核心期望是什么。我当时建立提示词变更表时身边的决策层还不理解,后来说不清谁改坏、查不出回归原因的锅越来越少,这套习惯的价值自然体现出来了。
自动驾驶提示工程这个方向才刚刚开始,后面还有交互式多模态推理、自监督场景生成、在线提示词自适应这些让人兴奋的课题等着折腾。但愿这篇实战拆解能帮少走一些弯路,让更多优秀的车端应用早日在路测中跑起来。