简介这是一份面向AI算法工程师、研究者和学生的技术分享型PDF系统梳理从强化学习多智能体到大语言模型多智能体的十年演进路径并解读各阶段代表工作。资源为单个PDF文件压缩包大小约9.81MB图文排版清晰便于直接阅读、投影或打印参考。内容明确划分“十年脉络梳理”“代表工作选讲”“企业实践心得”三大板块逐层展开Deep RL、Transformer-based RL、LLM-based AI Agent三类方法涉及DQN、PPO、MADDPG、AlphaGo、ChatGPT插件、斯坦福小镇等代表性案例与时间线同时也覆盖从单智能体到多智能体、从传统RL到LLM驱动Agent的迁移脉络可帮助读者快速建立智能体技术发展的整体认知框架。作者结合快手科技大模型知识增强研发经验分享一线落地中的心得体会为后续实践提供参考。已有30人学习下载适合希望系统理解智能体演进脉络的算法工程师与研究人员。1. 两类多智能体看着都叫多智能体选错架构的第一天就注定翻车如果是让一组智能体完成一次调研任务——拆解问题、读文档、调数据、交叉验证、写结论大语言模型多智能体是当下比较顺手的路子如果是让两台机械臂协同抓取板材、让一组无人车在路口协商通行强化学习多智能体才是能扛住毫秒级决策的那个。许多读者拿到《强化学习(多)智能体 和 大语言模型(多)智能体》这类对比资料容易犯的错是把它当成交叉选型题实际上两个方向在决策机制、训练来源、落地成本上几乎没有重叠。这篇笔记按“是什么 → 怎么做 → 坑在哪”把两条线各自的最小可运行方案讲清楚后面附上参数、踩坑和一种把两者接在一起的进阶做法适合正在做智能体编排、机器人控制、多智能体仿真以及被多智能体训练折磨的从业者。2. 本质差异先立住策略梯度训练出来的是肌肉记忆上下文推理长出来的是议事规则2.1 决策机制差一个维度连续控制与离散Token先看强化学习多智能体。它的核心构件是一个策略网络输入是观测输出是动作分布机械臂的关节扭矩、无人机的电机油门都是这类。一次决策的耗时在毫秒到百毫秒级别动作空间通常连续策略不是被“告知”的而是用策略梯度一步步推出来的环境根据动作给奖励梯度更新网络智能体在大量试错里把“什么状态下该出什么动作”固化成肌肉记忆。所以RL智能体一旦训练完成执行时不需要停下来“思考”更像是条件反射。大语言模型多智能体完全是另一套逻辑。模型本质上不是策略网络而是一个预训练的世界模型加对话引擎动作空间是Token空间。智能体的“决策”表现为生成一段文本、决定调用哪个工具、或者把某个子任务交给另一个智能体单次决策以秒到分钟计。常说的涌现能力来源是海量文本上的下一Token预测而不是环境里的奖惩信号。这意味着它没有“试错更新”这一环行为风格在推理时基本冻结只有靠上下文工程去引导。再看可解释性。RL策略学到的是一堆权重你很难说清“为什么这个时刻给这个力矩”LLM智能体则能把推理链显式写在消息里这也是它在任务编排、查询规划这类场景被优先选用的原因。两类系统不是同一个东西的两种实现而是不同时间尺度、不同动作空间、不同训练来源的两种产物。选型时硬套“哪个更先进”没有意义先看你的任务落在哪个尺度上。2.2 训练来源决定成本的量级强化学习多智能体的成本大头在现场试错。你得先有一个能快速返回状态和奖励的环境然后让智能体在里面跑几十万步。单智能体尚可多智能体的问题在于每个策略都在变化一个Agent的策略更新会改变其他Agent看到的观测分布整个过程是非平稳的。这也是多智能体强化训练曲线出了名的玄学的根源你无法保证一个稳定的优化地形。遇到这类项目预算里必须预留大量仿真资源和调奖励的时间。LLM多智能体的成本结构相反。基座模型的预训练成本已经由上游模型承担你落地时主要付推理成本也就是Token开销。它的能力边界基本由基座决定项目的核心工程不是“训练更新”而是怎么把任务拆解、把上下文管好、把工具接对。如果需要训练常见做法是做偏好对齐也就是用一批带偏好的数据微调而不是像RL那样从随机策略死磕。这样一来落地节奏快得多但上限也受限于模型本身的表现。成本之外还有一类隐性成本维护成本。RL系统上线后奖励结构一旦变动就要重新训练属于“慢迭代”LLM系统上线后Prompt变了就要重新走一遍回归测试属于“快迭代但难稳定”。如果任务是高频执行、状态可枚举、奖励可计算砸在强化学习上划算如果任务需要读上下文、归纳、判断、协商Token成本比自研一套决策器便宜得多。这里没有优劣只看哪边的成本你付得起。2.3 五分钟评估表判断项目该走哪条线纸上谈兵容易落到选型可以用下面几个维度快速过一遍。我一般会建议项目组先用十分钟填这张表再决定架构别一上来就搭框架。判断维度适合强化学习多智能体适合大语言模型多智能体决策频率毫秒到百毫秒级实时控制秒级以上任务规划与信息处理动作空间连续值、数值控制离散选择、文本、工具调用环境依赖必须有可交互仿真环境不依赖物理仿真依赖数据与接口奖励来源需要明确可计算奖励难以用数值奖励靠目标函数人工反馈可解释性低模型是黑匣子高推理链可输出查看典型场景多机协作、博弈对抗、调度控制多角色协作、知识问答、自动化流程填完之后落在左列的把重心放到环境搭建、奖励设计和策略训练上落在右列的把重心放到角色划分、工具协议和上下文预算上。最麻烦的是左右都沾一点的任务常见做法是分层上层用LLM多智能体做任务分解与决策下层用RL多智能体做具体动作执行。两层之间的接口就是状态文本和指令文本后面第6章会展开讲其中一种混合方式。先保证别把这个顺序做反不要让RL去读长文本做规划也不要让LLM去扛毫秒级控制这是最容易踩的第一个坑。3. 强化学习多智能体的最小落地独立PPO从骨架到参数3.1 为什么独立PPO是稳妥的起点多智能体强化学习的算法族很多有MADDPG、QMIX、MAPPO等。如果从零起步独立PPOIndependent PPO简称IPPO是最省事的答案每个智能体各自维护一套actor-critic用自己观测训练大家只共享环境不共享梯度。它之所以靠谱原因在于PPO本体收敛性好配参数少而且多智能体场景下“各自独立”反而避开了一部分集中训练带来的工程复杂度。很多对比实验里IPPO的表现并不比复杂的合作协议差尤其动作空间是离散或低维连续时。如果你的任务里智能体之间有强耦合、需要明确互相配合再考虑往集中式Critic方向走也就是Critic能看到全局信息而Actor只看局部观测。这个方向的实现比IPPO复杂一截我的建议是先跑通IPPO拿到基线确认任务可学再换MAPPO这类方案对比收益。别一开始就上复杂算法否则连环境和奖励的问题是谁造成的都分不清。下面这套骨架就是按IPPO写的。3.2 独立PPO的多智能体训练骨架下面是训练骨架的核心代码环境接口按标准的reset/step约定观测是每个Agent各自的局部观测。你可以在这一步先用单机仿真环境验证再替换成自己的物理仿真或游戏环境。import torch import torch.nn as nn import torch.optim as optim # 每个智能体一套独立的actor-critic网络 class ActorCritic(nn.Module): def __init__(self, obs_dim, act_dim): super().__init__() self.fc1 nn.Linear(obs_dim, 128) self.fc2 nn.Linear(128, 128) self.mean nn.Linear(128, act_dim) # 连续动作均值 self.log_std nn.Parameter(torch.zeros(act_dim)) self.critic nn.Linear(128, 1) # 状态价值函数 def forward(self, obs): h torch.relu(self.fc1(obs)) h torch.relu(self.fc2(h)) return self.mean(h), self.log_std, self.critic(h) def sample_action(self, obs): mean, log_std, _ self.forward(obs) std log_std.exp().clamp(max2.0) dist torch.distributions.Normal(mean, std) action dist.sample() log_prob dist.log_prob(action).sum(dim-1) # 连续动作取对数概率 return action, log_prob这段代码里有一个关键习惯把log_std暴露为独立参数而不是网络输出能让标准差的学习稳定很多。动作采样返回的log_prob用于后续PPO的importance sampling计算时把多维动作的对数概率求和否则梯度会错。再来看主训练循环这里只保留了最核心的rollout收集和PPO更新步骤def train_ppo(agents, env, epochs3000, rollout_len256, lr3e-4, gamma0.99, gae_lambda0.95, clip_ratio0.2, entropy_coef0.01): optimizers [optim.Adam(a.parameters(), lrlr) for a in agents] for step in range(epochs): # 收集一条rollout长度为rollout_len obs env.reset() rollout {i: [] for i in range(len(agents))} for t in range(rollout_len): with torch.no_grad(): actions, log_probs [], [] for i, agent in enumerate(agents): a, lp agent.sample_action(obs[i]) actions.append(a); log_probs.append(lp) next_obs, rewards, done env.step(actions) for i, agent in enumerate(agents): rollout[i].append((obs[i], actions[i], rewards[i], log_probs[i].item(), done)) obs next_obs # 对每个智能体独立做一次PPO更新带GAE advantage for i, agent in enumerate(agents): states torch.stack([x[0] for x in rollout[i]]) value agent.critic(states).squeeze(-1) adv compute_gae(rollout[i], value, gamma, gae_lambda) # PPO clip更新细节与单智能体PPO完全一致 update_ppo(agent, optimizers[i], rollout[i], adv, clip_ratio, entropy_coef)这段骨架里最关键的设计是“每个智能体独立更新”。它在代码上体现为两层循环外层遍历所有智能体内层是每个智能体各跑一次PPO。训练多智能体时最忌讳把多个智能体的数据拼成一个batch做一次更新那样等价于训练了一个策略来拟合所有人耦合反而会降低稳定性。compute_gae和update_ppo这两步和单智能体PPO完全一样直接复用你本地已有的PPO实现即可不需要为多智能体发明新的更新公式。参数说明lr3e-4起步PPO对学习率敏感涨到1e-3容易出现灾难性波动。clip_ratio0.2是默认任务收敛慢时可以降到0.1。gae_lambda0.95平衡偏差与方差稀疏奖励任务可以拉到0.98。entropy_coef0.01给策略一点探索余量如果发现策略过早坍缩调大到0.05。rollout_len256是短任务的下限任务状态空间大就加长到512或1024。3.3 必调参数与训练失败时看什么先把参数表格列出来这组数值是我在多个仿真项目里的起点不是最优值但你从这些值起步大概率不会第一天就爆炸。参数名常见起点调整方向lr3e-4曲线锯齿状不收敛时降到1e-4clip_ratio0.2更新步长过大时降到0.1gamma0.99长期收益任务调到0.995短期任务0.95gae_lambda0.95稀疏奖励拉高到0.98entropy_coef0.01策略提前收敛时调高到0.05rollout_len256训练震荡时加长到512或1024obs normalization开观测量纲差大时必须开训练中盯三个症状。第一个症状是每个Agent的奖励都在涨但系统级指标在下降这大概率是奖励设计只激励了个体局部行为出现了“刷分”现象要去检查奖励分解。第二个症状是Critic loss反复跳变甚至变NaN常见原因是奖励数值跨了好几个数量级给reward做clip是实际验证过的最快解法。第三个症状是策略熵迅速掉到接近0训练曲线也停了这表示策略过早自信给了太多梯度在优势大的轨迹上需要调大entropy_coef或者减少更新轮数。还有个多智能体特有的现象要单独拎出来加入更多智能体之后单智能体能学好的任务反而学不出来了。这未必是参数问题而是环境的非平稳性导致旧经验失效。常见做法是加大rollout长度到1024让更新时看到更多元的数据或者改成集中式Critic对照。如果改完还是不行先回到单智能体把环境本身的问题排掉再逐步加智能体数量。这套排查顺序比调任何一个参数都重要。4. 大语言模型多智能体的落地协议消息驱动协作与上下文控制4.1 骨架与分工角色、记忆、工具、消息大语言模型多智能体的工程化经验是把“多智能体”拆成四件套角色定义、记忆管理、工具绑定、消息协议。角色定义就是给每个Agent一段系统提示词明确它负责什么、愿意接收什么信息、可以调用什么动作。记忆管理负责把对话历史、中间结果、最终结论分层存放防止上下文窗口被无关内容塞满。工具绑定决定Agent能操作外部系统的哪些能力比如读文件、查库、执行代码。消息协议则是Agent之间唯一的通信方式它的设计直接决定协作是否稳定。很多团队第一批项目翻车不是模型不支持而是在这一步没把协议定清楚。让Agent自由对话看起来很美但两个Agent闲聊十分钟后开始胡言乱语是常态。我的做法是让所有消息走一个总线每条消息带sender、receiver、msg_type三个字段协作流程由外层编排器控制Agent之间不允许直接互相调用。这样做虽然少了一点“自由涌现”的味道但可控性高很多。对于生产场景可控优先于浪漫。4.2 消息驱动的一次最小协作实现下面这个骨架展示两个Agent协作完成一个“读数据-写结论”的任务。代码里抽象了一个llm.chat接口真实项目里替换成你部署的模型服务即可。# 消息统一由总线转发Agent之间不直接通信 class Message: def __init__(self, sender, receiver, msg_type, content): self.sender sender # 发送方名字 self.receiver receiver # 接收方名字broadcast表示所有Agent self.msg_type msg_type # request / response / tool_result / done self.content content class Agent: def __init__(self, name, role_prompt, llm, toolsNone): self.name name self.role_prompt role_prompt self.llm llm self.tools tools or {} self.history [{role: system, content: role_prompt}] def step(self, message): # 把新消息追加到上下文再让模型输出结构化JSON self.history.append({role: user, content: f[{message.msg_type}] {message.content}}) raw self.llm.chat(self.history, temperature0.2) parsed json.loads(raw) # 真实项目这里要有try-except和格式修复 action parsed.get(action, ) if action in self.tools: result self.tools[action](parsed.get(args, {})) self.history.append({role: user, content: f工具返回: {result}}) return Message(self.name, parsed.get(next, broadcast), parsed.get(type, response), parsed.get(reply, )) # 编排器控制协作者按顺序step planner Agent(planner, 你负责把任务拆成不超过两个子步骤并指定下一个执行者, llm) worker Agent(worker, 你负责执行数据提取并返回最终结果, llm, tools{read_data: read_data}) # read_data是实际的数据读取函数逻辑说明Message的msg_type字段是防“串话”的核心它把请求、结果、执行状态区分开模型看到消息类型后知道该用哪套交互规则。工具调用走action字段而不是让模型在回复正文里自由发挥解析成功的概率会高很多。编排器按消息的next字段决定下一步发给谁实际上是一个有限状态机。参数说明temperature0.2适合执行类和规划类Agent太高的温度会让工具参数随机变化做创意类Agent可以到0.7以上但每个Agent配一个温度而不是全局一套。json.loads失败时不要无限重试常见做法是带上错误信息让模型自己修复一次再失败就把这条消息交给人工。工具调用的结果要回填进history否则模型下一轮无法基于真实结果继续推理。4.3 上下文管理、工具调用与成本控制大语言模型多智能体最大的隐性坑是上下文滚雪球。消息一多每个Agent的history都在膨胀除了Token成本上升模型还会开始遗漏早期约束反复输出重复内容。我常用的策略是三重分层原始消息存到外部存储history里只保留最近的N条对话加上一个压缩后的SummarizedMemory关键事实单独存成一个facts列表每次组装提示词时把facts放最前面。这里的N通常取20到40根据模型上下文窗口调整N太大照样丢信息N太小会丢掉任务背景。工具调用方面给模型绑定工具时schema里要写清楚参数类型和枚举值并且每个工具配一个使用示例。模型常常在字段名上自由发挥不是因为它“笨”而是提示词里没有给足约束。错误重试最多一次第二次失败就返回错误给编排器不要让Agent自己反复尝试。工具调用次数也要记账配上总预算超过预算就让编排器终止任务这一步是控制成本最直接的手段。还有一个容易被低估的参数是并发。多智能体协作时并发过高会让模型服务被打满导致大量超时重试Token花了两遍效果还很差。我的经验是并发数先从和Agent数量一致开始再根据响应延迟逐步上调。真正的性能瓶颈往往不在模型而在编排器对消息处理的无序性给每条消息加一个独立的序号处理完再排序能省掉不少排查时间。5. 两类多智能体落地避坑五个翻车现场与排查方法5.1 强化学习线的三个翻车现场翻车现场一奖励曲线在涨系统指标在掉。现象每个Agent的个体奖励稳步上升但任务完成率、完成时间这类系统指标不升反降训练越久表现越怪。原因奖励设计给了太多局部激励Agent发现刷局部奖励比完成任务回报更快。多智能体场景里这个现象比单智能体常见得多因为单智能体没有“甩锅”对象多智能体里每个Agent都可以把失败归因到队友身上。解决把奖励拆成团队奖励和个体奖励两部分团队奖励占比至少一半更彻底的办法是用差异奖励也就是“这个Agent对团队结果的边际贡献”需要额外跑一次反事实估计工程量大一些但能根治刷分。翻车现场二Critic loss爆炸训练曲线变心电图。现象训练到几千步后Critic loss突然变成NaN或者跳变到训练初期的几十倍之后策略越来越差怎么调学习率都回不来。原因观测特征或奖励值的量纲跨了数量级。多智能体场景里不同Agent的观测可能来自不同传感器有的量级是0.01有的是10000进了同一个网络就会让梯度震荡。解决对所有观测做归一化按维度记录running mean和std奖励做clip常见做法是把单步奖励限制在-10到10之间优化器加梯度clip到0.5。这套组合拳能解决九成以上的训练发散问题。翻车现场三单Agent版本正常多Agent版本学不出来。现象同一个任务单Agent训练能稳定收敛加第二个Agent后整个训练完全摆烂奖励长期停留在随机策略水平。原因多智能体环境的非平稳性。每个Agent的策略都在变观测分布跟着变旧经验很快过期导致更新方向互相打架。解决先加大rollout_len保证每次更新看到的样本覆盖更多状态再考虑参数共享或集中式Critic让个体策略从全局经验里借力。如果都不见效就逐步增加Agent数量一次只加一个定位是哪个加入后打破了稳定。5.2 大语言模型线的两个翻车现场翻车现场四子Agent之间“串话”思考变成指令。现象任务进行到一半某个Agent把另一Agent的推理过程当成执行指令开始做无意义的操作比如把别人的一句话当成了代码去执行。原因消息协议里没有区分消息类型模型只看到文本分不清哪段是思考、哪段是请求、哪段是工具结果。而LLM天然会把用户消息当成指令优先响应。解决消息协议强制要求msg_type字段并且每个Agent的system prompt里写清楚“只响应request和tool_result忽略thought”。如果模型服务支持结构化输出直接用它约束消息格式比在文本里靠提示词强得多。翻车现场五上下文越滚越长成本失控、幻觉增多。现象任务后半段Agent开始重复输出或者引用一个根本不存在的中间结果看起来像是“失忆”了。Token账单也在同步膨胀。原因history太长超出了模型的有效注意力范围模型会优先关注最近几条消息早期的任务约束被挤了出去。解决做上下文压缩固定保留最近N条原始消息更早的内容交给一个轻量摘要模块定期生成压缩记忆关键事实单独存成facts列表每次组装提示词时放在最前面。压缩之后的回复质量一般不会下降成本却能省掉一半以上。工具调用解析失败、JSON字段名对不上这类问题也多半和上下文过长有关系做完压缩后一起缓解。6. 进阶把LLM变成RL智能体的奖励信号拧成一股绳6.1 稀疏奖励是无底洞LLM打分可以当奖励多智能体强化学习的落地瓶颈一半在非平稳另一半就是奖励稀疏。像“谈判结果是否合理”“摘要是否抓住了重点”这类指标很难写成公式。单靠规则奖励训练会长期停滞在随机策略附近不动。常见的补救是人工设计奖励函数但多智能体场景下人工奖励一旦设计偏了就回到第5章说的刷分问题。这几年比较靠谱的进阶做法是把LLM当成奖励模型让LLM对RL智能体的一段交互轨迹打分分数作为奖励信号喂回策略更新。LLM具备判断“动作是否合理”“结果是否达成”的能力用它补足稀疏与规则难以描述的奖励比从头设计一个奖励函数省力得多。# LLM把一条轨迹映射为标量奖励交给RL使用 def llm_reward(trajectory_text, llm): prompt (判断以下多智能体交互是否达成了目标 输出JSON: {\score\: 0-10}) raw llm.chat([{role: user, content: prompt}], temperature0) try: return json.loads(raw)[score] except Exception: return 0.0 # 解析失败给默认低分避免污染训练逻辑并不复杂这个函数不能在线每个step都调用Token开销会失控。常见做法是先离线采样一批轨迹让LLM打分用这批分数微调一个小奖励模型再用这个奖励模型在线给RL提供奖励。RL侧把它当成普通奖励接入即可训练骨架与第3章的PPO完全兼容。temperature0是为了让打分稳定解析失败给默认分数是因为异常值对RL的破坏力比漏一个低分更大。6.2 混合架构怎么接这套玩法真正上线时推荐的接线方式是LLM负责“结果评价”和“异常干预”RL负责“过程执行”。比如一个多机协作任务LLM只看最终是否完成了搬运、路径是否安全打完分就退场RL智能体依然走自己的毫秒级策略。两者之间只传一个标量分数不传长文本这样既保住了RL的执行实时性又拿到了LLM的判断力。我自己的习惯是先在纯RL线上跑一个小规模实验确认任务可以被学习再逐步把LLM奖励接入接入后对比时用同一个随机种子跑五个回合看奖励分布的均值和中位数不要只看最好的一次。某开发者就是这么做的一开始坚持纯规则奖励奖励工程调了快一个月后来加了这个LLM奖励通道任务才真正收敛。如果你手头也有一个奖励写不清楚的多智能体任务这条混线是值得优先尝试的希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?