资讯动态

自动驾驶多代理协同决策:从意图共享到冲突仲裁的工程实践

发布时间:2026/10/17 7:46:06 来源:尧图企业网站定制
路上跑的不只是你的那台车。这句话听起来像废话但真正从单车智能转到多代理协同之后我才意识到把其他车当成障碍物来“预测”和把其他车当成有意图的“代理”来“交互”两者的差距远比想象中大。多代理系统在自动驾驶中要解决一个非常朴素的问题——多台车同时接近无信号路口凭什么决定谁先走、谁减速、谁换一条路径如果每辆车都按自己的预测模型去猜对方动作很容易出现“同时刹车”或者“同时抢行”的僵局。所谓协同决策机制就是让多个自动驾驶车辆通过车-车通信、意图共享和联合规划把原来分散的下一步动作变成一组一致、安全、高效的联合行动。这篇文章不是我抄教材是我在做模拟项目时的方案拆解、关键实现和踩坑记录适合已经有一点自动驾驶基础、正在研究或者实践多代理协同的读者。1. 为什么自动驾驶需要多代理系统这个视角1.1 单车智能的边界在哪里我最开始在模拟环境里做的方案是很“标准”的单车感知-预测-规划链路每辆车独立感知周围环境用轨迹预测模型估计其他车的未来几秒位置然后规划自车轨迹。看起来没问题但一放到无信号交叉口就露馅了。问题出在“预测”这件事上。自车预测对方会直行对方也在预测自车会直行两辆车都根据预测结果加速进入路口。如果预测模型足够保守两辆车又会同时停在停车线前谁也不动。这就是典型的交互死锁。传感器再准、算力再强只要决策模型里没有“对方会因为我而改变行为”这个自由度单车智能的上限就摆在那里。这也是多代理系统切入自动驾驶的核心原因车辆之间有交互耦合你的动作会影响别人的决策别人的决策反过来也会影响你的下一步动作。这种耦合不能靠单车视角中的“占据栅格”或者“动目标预测”来完整表达必须把每个交通参与者建模成具备独立决策能力的代理再显式地对它们的联合行为做优化。1.2 协同决策的本质从预测意图到交换意图我特别喜欢用一个类比来解释协同决策几个人搬一张大桌子过门。如果每个人都只盯着桌子边缘靠经验判断队友下一步怎么动大概率会卡住或者撞到门框。真正有效的方法是有人喊口令大家先对齐抬桌子的高度、转向的方向和移动节奏然后同时发力。多代理协同决策在自动驾驶里就是这件事。车辆之间不只交换“我在哪里、速度多少”更关键的是交换“我接下来打算做什么、有多大把握”。后者就是意图共享。比如一辆车广播说“我准备直行通过路口置信度0.9”另一辆车收到后知道自己左转会和它冲突就会提前把置信度降下来表示“我可以等你先过或者我调整速度晚点到冲突区”。这个过程把原来的“我猜你会做什么”变成了“你知道我要做什么我也知道你会据此调整”决策空间瞬间清楚了很多。在实际项目里我把意图信息设计成一个小型消息帧内容包含车辆位置、速度、航向角、目标车道、计划路径片段的编码以及一个置信度值。置信度不是简单的概率它代表这条计划在当前观测下有多大的可调整余地。置信度高说明车辆不太会让步置信度低说明车辆愿意通过减速或换道来配合他人。这个字段非常有用后面做冲突仲裁时它可以直接作为软优先级输入。1.3 协同决策的收益以及必须付出的代价把单车智能升级到多代理协同收益不仅体现在“场面好看”。我实测下来的最直接收益是路口通行效率明显提升因为车辆不用再互相试探。单车智能面对潜在冲突时默认策略是减速等待安全但保守协同决策里车辆能提前交换意图两个冲突方向的车可以协调出一先一后的窗口后到的车不需要刹停只要把速度从 12m/s 降到 8m/s就能在对方通过后正好进入路口。这个动作对乘客来说几乎没有感知平均通过时间却能降下来。收益的另一面是代价。多代理系统引入了通信依赖消息丢失、时钟不同步、延迟抖动都会直接影响决策质量。更麻烦的是协同决策一旦出错责任边界很模糊是发消息的车错了还是收消息的车错了这也是为什么我在项目一开始就强调协同决策只能作为“在安全兜底之上的效率优化层”绝对不能替代单车安全逻辑。你越早接受这个分层设计后面调试越轻松。2. 协同决策的架构设计与方案选型2.1 三种主流架构集中式、分布式、混合式多代理系统不是只有一种搭法。我梳理过三类比较常见的架构先把它们放在一张表里对比架构类型典型思路优点缺点适用场景集中式一个中心节点收集所有车辆状态统一计算全部动作全局信息完整容易得到全局最优解实现简单中心节点故障影响大通信时延高规模扩展性差矿区、封闭园区等有可控通信环境的场景分布式每辆车独立决策通过点对点通信交换状态和意图扩展性好无单点故障实时性强缺乏全局视角可能陷入局部冲突需要额外的协调机制高速编队、开放道路混合式车辆本地决策路侧节点或临时仲裁节点只对局部冲突做协调兼顾实时性与全局性可分级降级架构偏复杂仲裁节点仍是潜在瓶颈需要设计切换规则城市交叉路口、匝道汇入等典型冲突场景在项目初期我试着用过纯集中式方案。效果非常理想因为中心节点能看到所有车的真实位置优化起来很容易。但我在模拟通信故障时发现中心节点只要丢一帧整个路口的决策就瘫痪。这让我意识到真实场景里不能迷信集中式。分布式方案我也跑过。每辆车各自决策用广播消息交换状态实时性确实好但一到两辆车同时申请同一块冲突区域时缺少一个拍板的人经常出现“你以为对方会让对方也以为你让”的情况。调试多了我发现纯分布式对消息质量要求太高不适合作为复杂路口的基础架构。2.2 我的选择集中式训练 分布式执行最后我采用的是混合式中的一种具体变体业内叫“集中式训练、分布式执行”。这个思路的底层逻辑是训练阶段可以用全局信息让每个代理学到在完整视野下应该怎么做部署阶段不依赖全局信息每个代理只用自己的局部观测和收到的意图消息就能跑出和训练时接近的表现。听起来有点“作弊”但这是多代理强化学习里非常成熟的做法。训练时我让每个代理的“评论员网络”能看到所有代理的位置、速度和真实奖励用来精确评估当前局面而“演员网络”只输入自车的局部观测和一条从其他代理发来的意图消息负责输出动作。这样演员网络在部署时不需要全局观测也能隐式地学会“尊重其他代理的意图”。结构确定之后我开始设计执行时的分工。每个代理在路上独立运行自己的决策网络但遇到交叉路口这类冲突区域时路上会有一个临时的仲裁代理接收所有相关车辆的通行申请执行优先级仲裁。这个仲裁代理不一定是一个物理路侧设备在仿真里我直接让最先到达冲突区域边缘的车辆扮演这个角色等通过后再把仲裁权交给下一辆车。这样就没有固定的中心节点大部分时间没有单点故障。2.3 感知到决策的数据通路设计架构搭好之后更接地气的问题是数据到底怎么流动我在项目里把从感知到执行的链路分成这样几步本车感知 → 局部目标融合 → 自车意图生成 → 消息广播 → 接收邻车意图 → 冲突检查与仲裁 → 最终动作输出。每个代理维护一个意图消息以 20Hz 左右的频率向外广播。消息里除了车辆位置、速度、航向还包括一条经过采样的计划路径以及这条路径对应的置信度。收到消息的车辆不直接把这个路径当成障碍物来避让而是把它当作对方“打算占用空间-时间资源”的申请。仲裁模块会比较不同车辆的计划路径是否存在时空交集如果有就根据优先级规则安排谁先进、谁后进或者给后进车辆一个建议速度区间。为了让这条链路不会因为消息拥堵而卡死我在通信层做了非常简单的“最新消息优先”策略。每个消息包里有一个序号接收端只保留每个代理最新的序号比这个序号旧的直接丢弃。宁可少处理几帧也不要去处理过期数据。这个策略看起来简单实际对决策稳定性帮助很大。3. 核心机制拆解三个必须解决的协同问题3.1 意图共享与置信度传播协同决策的第一步是让每个代理具备“表达自己打算做什么”的能力。我一开始以为这不需要专门设计直接把目标点发给别人就行。后来发现不行两个代理的目标点可能本来就有重叠区域但它们可以选择不同的到达时刻来化解冲突这种灵活性不是目标点能表达的。所以我引入了置信度传播的思路。每个代理对当前计划输出的置信度不是固定值而是根据冲突检测结果动态调整。当代理发现自己与其他代理的计划冲突时会按“谁更容易调整”的原则降低自己的置信度。这里的“容易调整”在工程上可以量化距离冲突点更远、当前速度更低、或者转向自由度更大的代理拥有更高的可调整空间也就倾向于降低置信度表示让步。置信度更新的细节需要小心。我在仿真里做过一个错误版本每个代理都直接按对方置信度反向更新自己的置信度结果一发消息就把两边都降到0所有车全部停下来。后来改成按优先级和可调整空间加权更新才避免了“互相谦让死锁”。这个现象很值得新手注意协同决策并不是越谦让越好而是要让让步行为被另一个代理感知到同时保持整体决策的确定性。3.2 交互行为建模从博弈论到深度强化学习在规划多代理决策机制时我先后尝试过两条路线传统博弈论建模和深度多代理强化学习。博弈论视角确实很有解释力。每辆车在某一个状态下的动作可以看成是在推测其他车动作的前提下选择自己的最优反应。理论上如果所有车都同时达到最优反应就形成一个纳什均衡。但在真实路口这个均衡可能是“所有车都停下来”的安全均衡也可能是“所有车都抢行”的危险均衡。博弈论能帮助我分析局面却很难直接给出可部署的决策策略因为求解速度跟不上而且很难处理感知不确定性。深度多代理强化学习则把问题变成“用一个共享的联合奖励函数引导多个策略网络同时改进”。在这个框架下每个代理的策略不再是被单独训练去最大化自己的通行效率而是通过联合奖励知道“自己让一步”是有价值的因为最终能换来整体更顺畅的通行。我用的具体算法是 Actor-Critic 架构主要是因为它天然适合“训练时集中、执行时分布”的方案。评论员网络在训练时接收全局状态计算 TD 误差指导演员网络更新演员网络部署时只消耗局部输入。两个网络之间不需要在推理时交换额外信息这是它最合适的地方。3.3 冲突消解与优先级仲裁多代理系统里最核心的执行环节是冲突消解。我的做法是让每个代理在接近冲突区域前生成一条“空间-时间资源申请”。比如一辆车计划在 3.0 秒时进入路口中心占用 1.2 秒通过另一辆车计划在 3.4 秒时进入同一区域占用 1.5 秒通过。仲裁模块会检查这两个申请是否存在重叠如果重叠就按优先级规则把更晚的时间窗口分配给其中一辆车。优先级规则我设计得很简单但足够覆盖大多数路口情况紧急车辆最高优先级道路等级高的一方优先如果道路等级相同则“先到先停”的一方优先存在转向冲突时直行车辆优先于左转车辆。这些规则并不复杂关键作用是把决策变成一个强约束下的资源分配问题而不是让每个代理自由博弈。仲裁结果会以“建议速度”的形式发给低优先级车辆低优先级车辆通过调整到达时间错开冲突而不是停在原地干等。这个机制有点像会议室预约系统每辆车提前把要占用的“空间-时间块”提交出来管理员安排一个不冲突的排期车子按排期进场。多代理系统里“管理员”的角色可以由临时仲裁代理承担但前提是所有代理的消息格式和时间基准必须一致否则预约系统自己就会乱掉。4. 实操过程一个无信号交叉口的协同决策Demo4.1 场景定义与代理建模为了验证整个机制我搭了一个很直接的仿真场景一个无信号交叉路口四条道路分别从东西南北汇入每个方向一个车道模拟四辆自动驾驶车同时接近路口。场景范围是 80m×80m交叉区域中心点设在原点四辆车的起始位置离冲突点大约 40m。每个代理的动力学参数我压得很实。车长取 4.5m车宽 1.8m最大纵向加速度 2.5m/s²最大制动减速度 4.5m/s²目标车速范围设定在 0 到 15m/s。转向通过航向角变化来表示限制最大转向角速度避免出现现实中不可能完成的急转。代理之间的通信范围我设为 120m这个距离比路口场景更大保证起始位置就能完成意图交换。场景里最难定义的其实是“到达目标”的判定。我不是简单地把车辆开到某个坐标点而是要求车辆驶过交叉口对向出口边线后保持目标车道中心线行驶 10m 以上才算完成一次通行。这样能防止模型学会“完成任务式”地冲过路口就乱开。4.2 状态空间、动作空间与奖励函数设计状态空间我分成两部分本车状态和交互状态。本车状态包括位置坐标、速度、航向角、到冲突点的距离、以及目标车道方向。交互状态来自接收到的邻车意图消息包括邻车的相对位置、相对速度、计划路径和置信度。这一组状态加起来大约 30 维对于策略网络来说不算大但足以表达冲突关系。动作空间我用了 9 个离散动作由“目标速度三档5、10、15m/s”和“横向偏移三档-1.8、0、1.8m”组合而成。为什么用离散而不是连续主要因为离散动作在仿真里更容易约束安全边界也更容易调试。我可以直接对每个离散动作背后的轨迹做碰撞检查连续动作空间要做更复杂的运动学约束。奖励函数是这次项目里最让我纠结的部分。我最终采用的形式是R_total α_safe * R_safe α_progress * R_progress α_comf * R_comf α_coop * R_coop其中 R_safe 是安全项发生碰撞给 -10距离任何其他代理小于安全边距时给 -1 的持续惩罚。R_progress 是进度项每向目标点靠近 1 米给 0.01到达目标给 5。R_comf 是舒适项动作切换或加速度变化过猛时给 -0.05 的惩罚。R_coop 是合作项两个存在潜在冲突的代理在 1 秒内均无急刹且完成通行各自获得 0.5。系数方面α_safe10α_progress0.01α_comf0.1α_coop0.5。一开始我把合作项系数调到 1.0结果代理会刻意开得很慢来换取合作奖励整体效率反而下降。后来改成 0.5并且把进度项的间距奖励稍微调大才让代理学会“保持正常速度、只在必要时轻微减速让行”。4.3 训练流程与关键参数训练时我严格采用“集中式训练、分布式执行”框架。伪代码大概是这样for episode in range(max_episodes): obs env.reset() while not done: for agent in agents: local_obs collect_agent_obs(agent) intent_msg build_intent_msg(agent) # 构造意图消息 action actor_network(local_obs, intent_msg) # 安全兜底检查如果到达冲突点的时间太短直接接管 if time_to_conflict(agent) safe_ttc: action emergency_brake(agent) next_obs, reward, done env.step(actions) buffer.add(transition, global_obs) # 全局观测只存入训练缓冲 if len(buffer) batch_size: update_critic(buffer.sample(batch_size)) update_actor(buffer.sample(batch_size))这里的关键是全局观测只用于训练不用于推理。算法层面评论员网络输入所有代理的状态和动作计算联合价值演员网络只输入自己的局部观测和收到的意图消息。模型更新用 TD 误差学习率设 3e-4折扣因子 γ0.99批量大小 256回放缓冲区容量 10 万条目标网络每 500 步软更新一次。我总共训练了 3000 个轮次。前 500 轮基本乱跑碰撞频繁1000 轮左右开始出现“在冲突点前减速观察”的行为2000 轮后四辆车能够稳定地按不同时间窗通过路口。为了确认不是靠“运气”我在训练结束后固定了网络权重用 500 个随机初始化场景做评估。4.4 实测效果与对比数据我拿协同决策方案和原来的单车智能基线做了对比。基线方案是每辆车独立预测他人轨迹碰撞风险超过阈值就减速不交换意图。结果如下评价指标单车智能基线多代理协同决策相对变化每500次通行碰撞次数122-83%平均路口通过时间8.5s6.1s-28%急刹次数318-74%平均通行速度7.8m/s9.2m/s18%这些数据只是我模拟环境里的相对表现不能直接外推到真实道路但趋势是明显的协同决策不只是提高了效率更重要的是大幅减少了急刹和碰撞。我最关注的是“急刹次数”这个指标因为它直接关联到乘客体验和纵向稳定性。急刹从 31 次降到 8 次说明意图共享确实让车辆更早、更平顺地调整了速度而不是等离很近才做出反应。5. 工程落地中的拦路虎通信、时延与安全问题5.1 通信断连与过期消息模拟环境里一切都同步得完美但真实世界不是这样。我在测试时专门给通信层加了丢包模拟刚开始效果惨不忍睹一条消息丢了代理还按上次收到的内容去推理结果和对方真实状态差出好几米冲突判断全部失真。解决办法是给每条消息增加“新鲜度”判定。接收端为每个邻车维护一个最新消息缓存消息序号必须单调递增旧消息直接丢弃。同时记录消息接收时间如果超过 200ms 没有收到某辆车的新消息就把它的置信度置为 0并且从协同决策名单中暂时移除只用本地预测模型估计它的位置。超过 500ms 仍然没有消息就不再把它当作“协同代理”而是当作普通障碍物完全退回单车安全逻辑。这看起来是很简单的机制但效果立竿见影。消息“过期即失效”的原则比让模型去处理不确定性要可靠得多。5.2 时间同步协同决策最容易忽略的细节多代理协同里有一个非常隐蔽的坑不同车辆上的“当前时间”可能根本不在同一时刻上。如果两辆车基于各自本地时钟生成未来轨迹它们认为的“3 秒后”在实际物理世界中并不是同一个时刻冲突检测的结果自然就是错的。我估算过一个简单的误差车速 20m/s 时如果两车时钟偏差 50ms那么它们对彼此位置的计算误差就是 1m。这个误差足以把“本来会碰撞”判断成“不会碰撞”。所以在我的项目里所有消息帧在构造路径时都必须带一个时间戳接收端先把时间戳统一换算到本地时间轴再参与时空交集检查。仿真里我直接用逻辑时钟但工程实现上需要外部授时源来把不同代理的时钟误差控制在 20ms 以内。如果时间同步暂时做不到还有一个退而求其次的做法把冲突检测的安全距离加上“时钟误差×最大车速”作为额外余量。代价是系统会更保守一些但至少不会因为同步误差把碰撞风险漏掉。5.3 安全兜底当协同失效时怎么办无论握手机制多强大我都坚持一个原则协同决策只能给出“希望执行”的动作最终是否执行必须过一道安全闸门。这道闸门不依赖意图消息不依赖其他代理是否配合它只基于自车当前状态和最近一次感知结果。纵向安全距离我用一个非常经典的公式d_safe v * t_reaction v² / (2 * a_brake) ε其中 v 是当前速度t_reaction 取 0.2sa_brake 取 4.5m/s²ε 是额外余量。如果 v15m/s算出 d_safe 15×0.2 225/9 3 31m。只要前方冲突点到自车的距离小于 d_safe并且预测到达时间小于 2s就立即执行紧急制动把协同决策输出的动作覆盖掉。我测试过很多次这个兜底逻辑虽然简单却能在通信突然断开时防止最严重的事故。5.4 可靠性分层设计把上面这些机制梳理下来我的工程实现实际上分成了三层层级主要功能失效时的处理通信层意图消息收发、缓存、新鲜度管理丢弃过期消息缩短协同范围协同决策层意图融合、冲突仲裁、速度建议转为本地决策按预测模型处理单车安全层碰撞检查、最小风险操作独立运行不依赖任何外部信息这三层之间没有互相依赖的循环协同决策层可以调用单车安全层做检查但单车安全层不会因为协同决策层的输出而改变判断。这样的分层让我在排查问题时有非常清晰的边界如果是决策错误大概率在协同决策层如果是该刹车没刹车直接去查单车安全层而不是在通信代码里浪费时间。6. 常见问题与排查技巧实录6.1 问题速查表项目做下来我把遇到最多的问题整理成了一张表方便后续项目直接对照问题表现可能原因处理方法训练很长时间不收敛奖励系数不合理稀疏奖励占比过高降低碰撞惩罚绝对值增加进度奖励密度多车动作来回抖动意图消息更新频率低或者消息时间戳混乱提高消息频率检查时钟同步误差四辆车在路口全部停下仲裁优先级缺失或者让步置信度更新太激进加入确定性优先级规则让一部分车保持较高置信度通信轻微丢包后行为突变缓存机制缺失使用过期消息参与决策给消息增加序号、时间戳和有效期协同决策看似高效但急刹很多奖励函数只优化了通行时间没有惩罚急刹加入舒适项和加速度冲击惩罚6.2 训练不收敛的几轮调试心得这里想多说一点训练不收敛的问题。我最初把碰撞惩罚设得非常大碰撞一次给 -100结果所有代理都学会了“永远不动”因为原地等待永远不会碰撞。后来把碰撞惩罚降到 -10同时给微小但持续的进度奖励代理才开始愿意尝试前进。这个过程让我意识到奖励函数的绝对值大小不是问题比值才是问题安全惩罚太高模型变得极其保守进度奖励太高模型会学会走捷径甚至钻规则漏洞。另外稀疏奖励让训练很慢。我曾经只在“到达终点”时给一个 5 奖励结果前 1000 轮几乎没有有效梯度。后来改成每前进 1 米给 0.01效果立刻不一样。如果你也在做类似的多代理项目我建议先画一个奖励分量随时间变化的曲线很多训练问题其实一眼就能看出来某项奖励长期不为 0或者某项奖励一直漂移都是需要调整的信号。6.3 先跑双代理再跑多代理我在项目末尾想分享一个调试顺序的坑。最初我直接上了四辆车结果一出现问题根本不知道是哪两个代理之间的决策逻辑出了问题。后来我把场景改成最简单的两车冲突一辆直行一辆左转只调试这两个代理。等它们能在各种初始速度下稳定通过冲突区后我再增加车辆数最终才扩展到四车路口。这个“先双代理、后多代理”的习惯看起来损失了效率实际却省了大量时间。多代理系统的组合爆炸不是网络参数量而是代理之间交互状态的组合数量。一次只加一个代理能让每次引入的新问题都只有一个变量定位起来非常快。另外一个小技巧是我每次修改完奖励函数或者意图消息格式后都会优先看“急刹次数”和“停车等待比例”这两个指标而不是只看平均通过时间。平均通过时间可能因为某些车冒进而下降但急刹次数一旦上升说明系统是靠危险操作换来的效率。先保证平稳再追求效率这个顺序不能反。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑