首页 / 资讯中心 / 文章详情

自监督学习:用未标记数据提升AI Agent能力

自监督学习:用未标记数据提升AI Agent能力 ★ FEATURED ARTICLE
最近在折腾 AI Agent 的时候我越来越确定一件事真正卡住 Agent 的不是模型结构而是数据。市面上大多数 Agent 的能力都是靠人工标注堆出来的——让人写指令、标答案、标偏好成本高不说还很难把环境里那些“默认就会”的常识教给模型。我一度被这个问题卡到怀疑人生直到我把目光转向自监督学习直接用海量未标记数据让 Agent 自己从交互日志、状态序列和环境反馈里找规律。这篇文章就是我围绕“自监督学习如何利用未标记数据提升 AI Agent 能力”做的完整复盘会讲清楚技术路线、实操流程、评测方法以及我踩过的坑。不管你是刚接触 Agent 开发还是已经在做相关系统应该都能从里面拿到一些可以直接试的东西。我做了一个模拟项目 X目标是让 Agent 学会在网页上完成预定、查询、填表这类多步任务。一开始我天真地以为只要用监督学习堆标注就行后来发现人工标注根本跟不上需求。换成“自监督预训练 少量标注微调”的路线后同样的下游任务标注量直接砍掉了一大半效果反而更稳。下面我把整个思路和过程都拆开说。1. 自监督学习为什么对 AI Agent 这么重要1.1 Agent 能力短板其实在“表征”先说一个我观察到的现象。很多 Agent 在训练环境里跑得挺好到了新环境就崩。比如你在一个网页上让它学会点击“提交”按钮换个布局完全不同的页面它就可能找不到按钮了。表面上看是泛化能力差本质上其实是模型没有学到足够通用的“表征”——它学到的是“某个坐标附近有个可点击区域”而不是“这种视觉元素代表提交操作”以及“提交之前必须确保表单合法”。这类问题靠人工标注很难解决。因为人工标注往往只覆盖“任务级答案”输入一个 query输出一个答案或动作。但 Agent 在真实环境里需要理解的是状态转移、因果依赖、时间顺序这些信息并没有直接写在任何一个标签里。自监督学习恰好可以补这个缺口它不需要人去告诉模型“这个状态和那个状态相关”而是通过数据本身的结构——先后顺序、上下文一致性、未来可预测性——让模型自己把这些规律提炼出来。我后来常跟朋友打比方监督学习像考试刷题题目和答案都给你刷得越多分数越高自监督学习像学游泳教练不会在水里一直帮你摆腿你得靠水感、呼吸节奏和身体姿态的反饋自己调整。Agent 一旦有了这种从数据里总结规律的能力它的“体质”就不一样了。再去做具体任务时只需要少量标注就能快速适应。1.2 自监督学习的三个内在信号很多人以为“未标记数据”就是一堆没有意义的数据其实不是。未标记数据里天然藏着三种信号自监督学习就是把这些信号变成“伪标签”。第一个是时间结构。Agent 的交互日志是序列数据状态、动作、下一个状态。这个顺序本身就是信号。模型可以学习预测下一步状态相当于强迫自己理解环境动态。第二个是上下文一致性。同一类状态在多次交互里反复出现比如不同用户登录同一个系统都要经过登录页。模型可以通过对比学习把这些相似状态“拉近”把不同任务的状态“推开”从而学到不依赖表面特征的语义。第三个是未来可预测性。一段行为日志里前因后果往往是连贯的。模型如果能够根据前半段预测后半段说明它多少掌握了任务的内在逻辑。这个能力对 Agent 的规划非常重要。这三种信号全都来自数据本身不需要人工标注。所以你只需要想办法把日志、传感器数据、网页 DOM 记录等未标记数据收集起来然后设计合适的自监督目标就能训练出一个对环境有深层理解的编码器。1.3 自监督学习和 Agent 训练闭环的配合方式Agent 的训练通常分几步先在通用数据上做预训练再用模仿学习或强化学习去适配下游任务最后可能还要做偏好对齐。自监督学习主要作用在“前两步”。以我做的网页操作 Agent 为例。传统做法是直接拿用户操作日志做行为克隆问题是日志没有标签行为克隆需要知道“哪个动作是正确动作”这又得人工筛选。有了自监督预训练后我可以先用五十万条未标记操作日志训练一个状态编码器让它学会把“页面状态”和“操作序列”映射到同一个向量空间。之后做下游任务时模型已经知道哪些状态是相似的、哪些操作会带来什么后果强化学习阶段就不用完全从零开始盲目探索探索效率高很多。这里有一个容易混淆的点自监督学习不是要替代强化学习而是给强化学习提供一个更好的起点。两者是配合关系不是竞争关系。后面我会专门讲实操把这个关系再拉出来说清楚。2. 可落地的自监督技术路线2.1 掩码重建让 Agent 学会“填空”掩码重建是我最先尝试的技术路线也是目前最成熟的一类自监督方法。核心思路很朴素把一段输入随机遮住一部分让模型根据剩下的内容把遮住的部分预测出来。模型想预测成功就必须理解上下文的语义和时序关系。对于文本 Agent 来说我可以对网页的简化 DOM 序列做掩码。比如一个页面的结构是“表单框、姓名输入框、提交按钮”我随机遮住“提交按钮”让模型根据其他元素预测这里缺什么。模型要预测对就得学会“表单必须要有一个提交入口”这类隐含规则。实际操作时掩码比例很关键。我试过把比例调到 40%结果预测任务太难训练 loss 半天降不下去提取的表征质量也差。后来我按常见实践把掩码比例控制在 15% 到 30% 之间模型学得反而快。另外不是所有遮住的内容都一样有价值遮掉高价值的操作元素比遮掉空白文本更有用。所以我后面做了一个调整根据元素在历史操作里的被点击频率做加权掩码高频元素更容易被遮。这个细节让下游任务表现提升了近 5 个百分点。再说一个 Agent 场景下独有的坑不要只重建观察而不重建动作。如果只是遮住页面文本模型学到的是“页面语言模型”不是“决策模型”。我最终的预训练目标里同时包含了页面元素掩码和动作掩码遮住过去的动作让它从后续状态反推前一步动作遮住未来的状态让它在给定动作序列下预测环境变化。这样学出来的表征里既有感知信息又有动作信息才真正对 Agent 有用。2.2 对比学习让 Agent 学会“什么和什么是一类”对比学习是另一条我非常推荐的技术路线它的核心是让相似样本的表征靠近、不相似样本的表征远离。它的优势在于不依赖具体的预测目标而是直接优化表征的可分性。在 Agent 场景里怎么构造“相似样本”是个学问。我一开始的做法是同一个用户在同一任务上的两条不同操作轨迹抽取出同一阶段的子序列作为正样本对不同任务的轨迹作为负样本。听起来合理实际跑下来效果很差因为两条轨迹哪怕任务相同具体操作顺序也可能完全不同模型根本不知道应该对齐哪里。后来我换了一个策略对相同状态做基于上下文的增广。比如网页操作中同一个步骤可以表达为“点击提交按钮”和“按下回车键”这两种操作形式不同、功能相似我把它们构造为正样本对。再用同一轨迹中距离较远、语义不相关的片段作为负样本。这样模型被逼着去学“功能等价性”而不是“表面相似性”。这里给一个常用的对比损失形式方便你自己调整其中 是样本表征之间的相似度 是温度系数。温度控制对难负样本的敏感程度 越小模型越关注难分样本但太小会训练不稳定。我实测下来温度取 0.1 左右比较合适下游任务效果最稳。对比学习还有一个常见问题负样本数量。理论上负样本越多越好但显存和算力有限。工程上可以维护一个大的特征队列把最近几批样本的表征缓存下来这样既不增加显存又能让负样本库足够大。这个技巧我后面还会再说一遍因为真的能救活一个项目。2.3 状态预测与世界模型第三种路线是训练一个“世界模型”。所谓世界模型就是让模型学会描述环境动态给定当前状态和动作预测下一个状态。这个能力对 Agent 太重要了因为 Agent 要在脑子里模拟多种计划而不是每次都在真实环境里试错。具体做法不复杂。从一个环境中随机采样或者从历史日志中提取一批状态转移样本然后训练一个动态预测模型。对于离散状态用交叉熵损失对于连续状态用均方误差损失。关键是不要直接预测原始像素否则计算量巨大且容易过拟合到纹理。我建议先训练一个状态编码器然后在编码后的隐空间里做预测这样既快又稳。我在模拟项目 X 里做过一个很有价值的验证只让 Agent 在“想象环境”里推演计划然后挑一个预测成功率最高的动作去真实环境里执行。前几轮表现甚至比直接在真实环境里试错的 Agent 更好因为自监督预测隐式地避开了很多明显错误的动作。当然世界模型也有风险如果预测误差累积模型会在几步之后开始“幻觉”。解决办法是让模型同时输出不确定性估计当某个状态预测的不确定性过高时强制 Agent 切换到真实环境收集数据。这不只是理论实践里真的能救命。2.4 轨迹级自监督从行为日志里找子目标很多 Agent 任务都是长流程比如“订酒店”这个目标其实包括搜索、筛选、填写入住信息、确认支付等子步骤。如果模型不能自动识别这些子目标规划就只能靠人工规则适应性很差。轨迹级自监督就是干这个的。它把一整段行为日志作为输入让模型自己发现哪里是一个“子任务的边界”。我实现过一种思路在轨迹里随机抽出一个位置把轨迹切成前后两段然后让模型预测这两段是否属于同一个子任务。如果模型判断“前后段不连贯”说明它已经找到了子任务边界。这种做法听起来像是在制造伪标签但它确实有效。预训练完成后我把模型输出的分段结果可视化发现它能在没有人标注的情况下把“查询搜索结果页”和“填写表单”完整分开分界点跟人工标注的重合率超过 80%。这个分段能力直接帮助下游规划模块把任务拆成子目标再分配给不同技能模块执行。对于想让 Agent 学会长程规划的开发者这条路线值得重点研究。3. 实操从零做一次自监督预训练3.1 问题定义和未标记数据准备我以模拟项目 X 为例完整跑一遍流程。目标系统是一个网页操作 Agent需要完成航班查询、酒店预定、在线表单提交等任务。我收集了五十万条未标记的人机操作日志每一段日志大概长这样时间戳、当前页面的简化 DOM 摘要、用户执行的动作、动作生效后的新页面摘要。拿到日志后我先做了三轮清洗。第一轮去重日志里大量存在用户反复刷新页面的行为这些重复数据会干扰对比学习必须去掉。第二轮过滤异常会话时长小于 3 秒或者动作数少于 5 条的会话很可能是误触或系统异常直接丢弃。第三轮做子序列切分一条长日志可能横跨多个任务直接整段训练会让模型混淆任务边界所以按页面跳转和动作间隔把日志切成若干段每段尽量属于同一个原子任务。清洗之后剩下大概 30 万条有效片段。这个量级对于中小型模型已经够用。需要提醒的是未标记数据并不是“只要是数据就行”质量差的未标记数据反而会给表征引入噪声。我见过有人直接拿爬虫日志训练结果模型学到的全是广告区域的噪声下游任务一塌糊涂。把数据洗干净比多攒几百万条更重要。3.2 模型结构和自监督目标模型方面我选择了一个中小型 Transformer 编码器参数量约 1 亿。输入序列由三部分组成当前页面的 DOM token、分隔符、上一步动作 token、分隔符、下一步期望状态的特征向量。输出是一个统一的状态-动作隐向量。预训练目标我用了两个 loss 的组合掩码重建和对比学习。掩码重建负责捕捉局部语义对比学习负责拉近功能等价的状态。两个 loss 通过一个权重系数平衡我最终调到 0.6 比 0.4也就是掩码重建为主、对比学习为辅。这个比例不是我拍脑袋想的我从 1:1 开始调发现掩码重建比重稍大时收敛更稳定。训练配置方面我给出一个亲测可用的常见配置batch size 128峰值学习率 5e-5采用带 warmup 的优化器warmup 步数占训练总步数的 10%训练 20 个 epoch并使用混合精度训练。整套配置在单机多卡环境下大约跑了两天。如果你是个人开发者显存不够可以把模型缩小到 3000 万参数batch size 降到 32用梯度累积模拟大 batch效果也不会差太多。3.3 不加标注先验证预训练效果很多人训练完自监督模型之后很慌因为不知道学得好不好。我的习惯是不急着微调先做一步“不加标注的验证”。最常用的方法是线性探测把预训练好的编码器冻住只取它输出的向量接一个线性分类器用一小部分有标注的数据去训练这个分类器。如果线性分类器能达到不错的准确率说明表征本身已经是线性可分的质量没问题。我在模拟项目 X 里做了一个动作预测的线性探测。在没有预训练时直接用原始输入特征预测下一动作的 AUC 只有 0.52基本等于瞎猜。用预训练表征之后AUC 提升到 0.78。这说明模型确实把“页面结构”和“动作语义”之间的关系学到向量空间里了。还有一个小技巧把表征降维可视化。不用多复杂的工具直接抽样几百条样本把预训练表征画在二维平面上。如果相同任务类型的样本自动聚成几团说明预训练成功了如果全部混在一起那就要回去检查数据清洗是否干净、自监督目标是不是和任务不匹配。这种方法很直观省下来大量盲目调参的时间。3.4 用少量标注适配下游任务预训练只是“把内功练好”真正让 Agent 干活还需要少量标注。我做了一个对比实验第一组完全不预训练直接用人工标注数据做监督微调第二组用预训练权重初始化再做监督微调第三组只在预训练好的基础上做强化学习。各组可用的标注数据量不同任务成功率如下表方案标注数据量任务成功率不预训练直接微调5000 条41%不预训练直接微调20000 条52%自监督预训练 微调5000 条73%自监督预训练 强化学习5000 条78%这个结果让我很触动。5000 条标注对于人工来说不过是一个人数天的量配合自监督预训练后任务成功率直接高出完全不预训练一倍左右。这背后的原因不难理解预训练已经给了模型一个很好的“环境理解底座”下游只需要在这个底座上学习任务偏好。有了自监督原本需要两万条标注才能接近的效果现在不到三分之一就能搞定。4. 常见问题与排查技巧实录4.1 预训练 loss 降了下游任务反而变差这是我遇到的第一个大坑。预训练阶段训练集 loss 明明降得很漂亮表征可视化也有聚类趋势但一接到下游任务就崩比从头训练还差。后来我排查下来发现是“域不匹配”自监督预训练用的是历史人工操作日志下游任务的页面布局和操作规范已经变了预训练模型学到的是旧环境的结构自然对下游没帮助。排查思路是分三步走。第一步检查数据分布把预训练数据和下游数据分别抽样看状态特征的均值和方差是否出现明显偏移。第二步做线性探测如果探测结果在预训练数据上很高、在下游数据上很低就是域漂移。第三步调整预训练数据配比在预训练阶段掺入一部分下游环境的未标记数据哪怕只有 10% 到 20%也能显著缓解漂移。另一个可能原因是掩码重建和下游任务目标差异过大。如果你想让 Agent 学会“选择动作”就不要只做“重建页面文本”这种纯感知任务。我后来在自监督目标里加入了动作预测分支情况明显改善。关键思想是自监督目标要尽量靠近下游能力的核心而不是随便找个辅助任务就上。4.2 对比学习负样本怎么选才能避免效果忽高忽低对比学习里最常见的问题就是负样本构造不当。我一开始图省事直接把同一个 batch 里其他样本都当负样本结果同一个任务的两条相似轨迹经常被当成难负样本模型被逼着把相近状态分开反而破坏了表征的语义相似性。正确的做法是构建一个“同任务互斥”的负样本策略先从 batch 内部去掉同一个 episode 里的样本保证正样本对和负样本对之间没有重叠。其次要做困难负样本挖掘不要只随机挑选负样本而是挑选那些表征距离非常接近、但实际属于不同任务的样本作为训练难点。这样模型会不断接受更高难度的挑战表征逐渐变强。在工程实现上我建议维护一个特征队列长度设为 4096 或 8192保存最近几个 batch 的表征。每一轮训练时模型的梯度只通过当前 batch 更新但负样本可以来自整个队列。这样即使单卡显存不够也能享受到大负样本池的好处。我用了这个方案之后对比学习训练稳定多了下游结果不再忽上忽下。4.3 Agent 继续预训练时出现灾难性遗忘怎么办这个问题主要出现在“你已经有了一版不错的 Agent又来了一批新的未标记数据”的时候。直接在这批新数据上继续预训练旧任务能力可能断崖式下降。这就是灾难性遗忘。我第一次碰到时整个人都懵了后来总结出三个对策。第一个对策是联合回放。把旧数据按一定比例抽出来和新数据混合训练比例我常取 1:5也就是五份新数据配一份旧数据。第二个对策是降低学习率。继续预训练阶段的学习率不要和新训练阶段一样通常降低一个数量级比如从 5e-5 降到 5e-6让更新更平缓。第三个对策是冻结底层。Transformer 的前几层一般负责基础语法和通用特征这些不需要再变可以冻结它们只更新顶层靠近任务输出的部分。三者组合使用我基本能保住旧任务 90% 的能力。4.4 没有金标准怎么评估 Agent 能力提升自监督学习的一大难点是评估。监督学习有准确率强化学习有奖励自监督学习的“奖励”是自造的不容易判断到底有没有用。我的评估体系分三层。第一层是表征评估用线性探测、kNN 分类、聚类纯度这些方法直接看表征是否含有任务相关信息。这层不需要额外标注只需要少量的任务标签做探测即可。第二层是环境交互评估让 Agent 在没有人工奖励的目标环境里运行统计单位时间内完成的有意义子步骤数量、失败后的重试次数。虽然没有“标准答案”但好的表征会让 Agent 的行为明显更有方向。第三层才是最终任务评估用少量人工标注的下游任务做端到端测试计算任务成功率。三层评估结合基本能判断一次自监督训练到底有没有价值。我个人的经验是千万不要只看预训练 loss。loss 下降了只能说明模型拟合了伪任务不代表下游任务会变好。只有把下游评估也跑了你才敢说自监督带来了能力提升。5. 工程化落地的几条实在建议5.1 数据管线和框架选型自监督训练项目里最容易成为瓶颈的不是 GPU而是数据处理速度。我一开始用最简单的读取方式每个 epoch 光轮转数据就要花掉一半时间。后来把数据预处理搬到后台离线把日志切好、编码成统一序列训练时随机读取。做了这个改动训练吞吐量提高了好几倍。框架方面不需要太纠结。常见的自动微分框架都能满足需求关键在于你要会写训练循环、会开混合精度、会做梯度累积。如果你以前只调用过现成训练接口第一次写自监督训练可能有点手忙脚乱但一定不要回避。曲线自己控制训练过程之后调起参来会顺手得多。5.2 算力不够时的训练技巧很多读者问过我没有大集群能不能搞自监督预训练我的回答是能但要做好取舍。模型参数控制在几千万级别使用混合精度开启梯度检查点梯度累积到等效 batch size 为 128只需要单张 24G 显存的显卡就能跑起来。训练时间会长一些但很多结论在小模型上已经可以验证没必要一上来就训几十亿参数模型。另一个技巧是“分段释放”。如果整条序列太长可以把序列切段训练分别得到每段的表征再做一个表征收割。这样能大幅降低显存占用缺点是会损失长距离依赖信息。对于许多 Agent 任务来说段落内的局部依赖往往比段落间的全局依赖更重要所以这个取舍通常可以接受。5.3 容易踩的四个误区第一个误区未标记数据越多越好。完全不对。数据质量、领域匹配度远比数量重要。第二个误区照搬文本或图像领域的自监督方法到 Agent 上。Agent 数据有动作维度和时间维度直接套用静态数据的掩码或对比方案很可能学不到决策信息。第三个误区预训练时间越长越好。自监督预训练越往后收益越少甚至可能过度拟合伪任务。我一般用一个固定 checkpoint 策略每训练 25% 停一次跑一下下游线性探测选择探测结果最好的 checkpoint 作为最终预训练权重。第四个误区把自监督学习和强化学习对立起来。实际应用中两者是接力关系自监督做“起步”强化学习做“冲刺”组合起来效果远强于单用任何一种。最后再分享一点个人体会。自监督学习不是一个能包治百病的工具它最擅长的是在缺乏标注的环境里帮 Agent 建立一个通用表征底座。我踩过很多坑之后发现成功的核心往往不是堆模型复杂度而是认认真真想清楚三个问题你要让 Agent 学什么结构你手里未标记数据里有哪些信号能反映这个结构你该怎样把训练目标设计得足够贴近真实任务。想清楚这三件事自监督学习就真的能帮你用未标记数据把 Agent 的能力抬上一个台阶。如果看完这篇文章你只有一个收获我希望是这句话别急着花钱标数据先试试让 Agent 自己从数据里找规律。
阅读完成 · 觉得有帮助?
咨询建站