1. 从“失败”中学习推理时自我改进的核心理念最近在折腾各种AI智能体Agent特别是那些能操作电脑、完成实际任务的“计算机使用智能体”Computer-Use Agents我发现一个挺有意思的现象很多智能体在第一次执行任务时表现往往不尽如人意。比如你让它“打开浏览器搜索最近的咖啡店并把地址复制到记事本里”它可能会卡在某个步骤——也许是没找到正确的搜索框也许是复制粘贴操作错了地方。传统的做法是我们作为开发者会去分析日志修改提示词Prompt或者调整智能体的决策逻辑然后重新训练模型再部署一个新版本。这个过程周期长成本高而且智能体在部署后遇到新问题依然会“犯傻”。“Learning from Failure: Inference-Time Self-Improvement” 这个概念直译过来是“从失败中学习推理时的自我改进”它瞄准的正是这个痛点。它不主张在训练阶段就把所有情况都教给模型而是让智能体在实际运行推理过程中一旦发现自己“搞砸了”就能立刻分析原因并当场调整自己的行为策略尝试用更好的方法再试一次。这就像一个有经验的程序员在代码运行报错时不是立刻去问别人而是自己看错误日志、调试、修改然后重新运行直到成功。这个能力对于追求真正自主和实用的AI智能体来说至关重要。为什么要在“推理时”自我改进因为真实世界是开放、动态且充满不确定性的。训练数据再丰富也无法覆盖所有可能的软件界面、网络状态、用户意图的细微差别。一个只能在训练集上表现完美的智能体一旦投入实际使用面对千变万化的环境其脆弱性就会暴露无遗。推理时自我改进相当于给智能体装上了“实时纠错”和“经验学习”的机制让它能适应非训练时见过的场景从而大幅提升其鲁棒性和任务成功率。这不仅仅是让智能体“更聪明”更是让它变得更“皮实”和“可靠”。2. 计算机使用智能体的独特挑战与失败模式要理解“从失败中学习”的价值我们得先看看计算机使用智能体通常会在哪些地方“翻车”。这类智能体的核心任务是理解自然语言指令并将其转化为一系列对图形用户界面GUI或操作系统的精确操作比如点击、输入、滚动、切换窗口等。它的工作流可以简化为观察屏幕或DOM结构- 理解任务 - 规划步骤 - 执行动作 - 观察结果 - 循环直至任务完成。在这个过程中失败是家常便饭。我根据实际开发和测试经验把这些失败模式大致归为以下几类2.1 感知与理解错误这是最基础的错误。智能体“看”错了屏幕。元素定位失败这是最常见的问题。智能体基于当前的屏幕截图或可访问性树Accessibility Tree寻找一个按钮比如“搜索”按钮。但由于界面主题变化、窗口缩放、动态加载的元素如“加载更多”按钮出现前后、或是使用了非标准的UI组件库智能体用来识别元素的特征如文本内容、控件类型、相对位置失效了导致它要么找不到目标要么错误地点击了另一个相似的元素。状态误判智能体无法准确判断某个交互元素当前的状态。例如一个复选框到底是勾选了还是没勾选一个下拉菜单是展开的还是收起的一个按钮是可点击的还是灰显的如果判断错误后续的操作序列就会完全乱套。任务意图理解偏差用户说“整理一下桌面”智能体可能理解为删除所有文件而用户的真实意图可能是将文件按类型归类到文件夹。这种高级语义理解的偏差会导致整个任务方向错误。2.2 规划与执行错误即使“看”对了也可能“做”错。操作序列规划不合理任务需要多个步骤智能体规划的顺序有问题。比如它可能试图在未登录的情况下就去访问需要权限的页面或者在保存文件之前就关闭了编辑窗口。这种规划错误源于对任务流程的常识或领域知识缺失。动作执行不精确找到了正确的按钮但点击的坐标有细微偏差可能点到了按钮边缘导致没反应或者更糟点开了旁边的菜单。对于拖拽操作起始点和结束点的判断失误更是常见。缺乏等待与容错智能体执行了一个操作如点击“提交”但网络延迟或应用程序处理需要时间界面不会立刻更新。如果智能体没有“等待”的机制或者等待时间设置不当它会在新界面加载完成前就进行下一步操作从而导致失败。它也需要处理弹窗、错误提示等意外中断。2.3 环境与上下文错误环境的变化超出了智能体的瞬时感知范围。多窗口与焦点管理任务可能涉及多个应用程序窗口。智能体可能在一个窗口中完成了部分操作但需要切换到另一个窗口时错误地激活了第三个无关窗口或者根本没有执行切换操作。外部依赖变化智能体操作依赖于某个网站或服务的特定布局。一旦该网站前端更新UI元素ID或结构发生变化智能体原有的定位策略立即失效。资源竞争与状态冲突例如智能体试图写入一个已被其他进程锁定的文件或者尝试安装一个需要管理员权限但当前没有的软件。这些失败模式往往是交织在一起的。一个感知错误可能导致规划错误进而引发一连串的执行错误。传统的、静态的智能体在面对这些失败时通常就“卡住”了要么无限循环要么直接报错退出等待人工干预。而“推理时自我改进”的目标就是让智能体自己具备诊断这些失败并尝试修复的能力。3. 实现推理时自我改进的关键技术组件让一个智能体在运行时自我改进听起来很科幻但其技术实现路径正在变得清晰。它不是一个单一的技术而是一个由多个组件协同工作的系统。结合当前开源社区如与OpenCUA-72B相关的探索和业界的前沿实践我们可以梳理出以下几个核心组件3.1 精细化的失败检测与归因模块这是自我改进的起点。智能体必须能明确知道自己“失败了”并且最好能知道“大概败在哪儿”。这比听起来要难因为很多失败没有明确的错误信号。基于目标的检查最直接的方式。智能体有一个明确的任务目标例如“记事本中应包含‘拿铁咖啡’的文字”。在关键步骤后它可以主动检查这个目标状态是否达成。如果未达成则标记该步骤可能失败。基于预期与现实的对比智能体在执行一个动作前会对动作的结果有一个预期例如“点击‘搜索’按钮后应出现一个搜索输入框”。动作执行后它通过再次观察屏幕对比现实状态与预期状态是否匹配。如果不匹配则说明该动作可能未产生预期效果。基于环境反馈的推断操作系统或应用程序有时会提供明确的反馈如错误弹窗、状态栏提示音、或控制台输出错误日志。智能体需要集成对这些反馈信号的监听和解析能力。超时与无进展检测如果智能体在一段时间内反复执行相似操作而屏幕状态没有发生任何有意义的变化则可以推断它可能陷入了死循环或无效操作这也是一种失败信号。归因则更近一步它需要将失败信号与具体的决策环节关联起来。是元素定位错了还是动作执行无效或者是整个任务规划的前提就不对这通常需要结合动作历史、观察历史和内部决策日志来进行分析。3.2 动态提示工程与策略记忆库这是自我改进的核心执行机制。当检测到失败并初步归因后智能体不能简单地重试而需要调整策略。动态提示词Prompt改写大型语言模型LLM是许多现代智能体的“大脑”。它的行为很大程度上由我们给的系统提示词System Prompt和上下文Context决定。在失败时智能体可以动态地修改或增补这些提示词。例如如果是因为元素定位模糊导致点击错误可以在后续的提示中增加“特别注意目标按钮的文本可能包含‘Search’而不是‘Find’且其颜色是蓝色的。”如果是因为缺乏等待可以增加“在执行任何点击操作后等待至少2秒直到界面元素稳定再观察。”这相当于让智能体在运行时给自己“打补丁”注入针对当前失败场景的特定指引。策略记忆与检索智能体可以将每次成功和失败的经验以结构化的方式如任务描述 初始状态 采取的动作序列 结果状态 成功/失败原因存储到一个记忆库中。当遇到类似的新任务或相同的失败信号时它可以快速从这个记忆库中检索出历史上有效的解决方案或需要避开的坑并将其作为上下文信息提供给LLM从而影响本次的决策。这就是“吃一堑长一智”的数字化体现。3.3 基于强化学习的动作策略微调对于更底层的、重复性的操作问题动态提示可能不够高效。这时可以引入轻量级的强化学习RL机制在推理时对动作策略进行在线微调。状态-动作价值函数在线更新智能体的每个动作如在某个坐标点击都可以被评估。如果一系列动作后任务成功了这些动作会获得正向奖励如果失败了则获得负向奖励。智能体可以在运行时用一个非常小的、专门负责动作选择的模型或价值函数来快速更新这些“状态-动作对”的价值估计。下次再遇到相似界面状态时它会更倾向于选择历史上带来高价值的动作如更精确的点击位置而避免低价值动作。探索-利用策略调整在未知环境中智能体需要一定的随机探索来发现新解法。但在经历失败后它可以动态降低探索率更多地利用已知的有效策略或者转向针对失败点进行有目的的探索例如只在之前点击失败的按钮周围小范围尝试其他坐标。3.4 分层级的反思与重规划机制对于复杂的、多步骤的任务失败可能需要更高层级的调整。子目标反思与回溯当任务在某个子目标上卡住时智能体可以反思这个子目标是否必须是否有替代路径例如任务要求“从网站A下载报告然后用邮件发送”。如果网站A暂时无法访问智能体可以反思并决定“子目标‘从网站A下载报告’当前不可行启用备用方案从本地备份文件夹B中寻找最新的报告文件。” 然后它回溯任务规划替换掉失败的子目标生成一个新的可行计划。工具使用策略调整智能体可用的操作工具可能不止一套。比如要获取一个文本框的内容既可以通过模拟鼠标选择后复制也可以通过读取应用程序的可访问性接口。如果一种方法持续失败智能体可以反思并切换到另一种工具或方法。这些技术组件并非孤立而是需要被集成在一个统一的智能体架构中。一个典型的推理时自我改进循环可能是这样的执行与监控智能体按初始计划执行动作同时运行失败检测模块。失败识别检测模块触发确认当前步骤失败。分析与归因结合历史记录分析失败可能的原因如元素X未找到点击后无响应。策略调整查询策略记忆库看是否有类似问题的解决方案。动态修改提示词加入更精确的元素描述或操作提醒。轻微调整动作策略如点击坐标。重试或重规划如果失败点在当前步骤用调整后的策略重试该步骤。如果失败点涉及更高层规划则启动重规划生成新的步骤序列。经验固化无论最终成功与否将这次“失败-分析-调整”的完整经历存储到记忆库中供未来参考。4. 实战构建一个简单的推理时自我改进智能体原型理论说了这么多我们来动手设计一个极简化的原型看看核心思想如何落地。假设我们要构建一个能操作特定Web应用的智能体并为其添加基础的推理时自我改进能力。我们将使用基于LLM的架构。4.1 基础架构搭建首先我们需要一个基础的工作流观察Observation使用工具如Selenium、Playwright获取当前网页的DOM结构或可访问性树并将其简化为LLM可理解的文本描述。例如“页面顶部有一个导航栏包含‘Home’ ‘Products’ ‘Contact’链接。主体部分有一个标题为‘Login’的文本框其下方有一个‘Submit’按钮。”思考与规划Think Plan将用户指令“请登录系统”和当前观察到的状态一起发送给LLM例如通过API调用OpenCUA-72B或类似开源模型。LLM的输出需要被约束为一种特定的结构化格式比如JSON{ thought: 用户要求登录。我看到了登录框和提交按钮。我需要先在登录框中输入用户名然后可能需要找到密码框输入密码最后点击提交。, action: { type: click, selector: #username, // 假设的CSS选择器 confidence: 0.9 } }执行Act智能体解析LLM返回的JSON根据action字段执行相应的自动化操作如用playwright.locator(#username).click()。循环执行后再次观察新状态重复步骤1-3直到LLM输出一个标记任务完成的特殊动作如{action: {type: finish}}。4.2 注入失败检测与改进循环现在我们在基础循环中插入自我改进的钩子。第一步增强观察与状态对比在执行动作前我们不仅记录屏幕的“描述”还可以记录关键元素的“快照”。执行动作后我们再次观察。# 伪代码示例 def execute_action_with_self_improvement(agent_state, llm_client): previous_observation agent_state[current_observation] planned_action agent_state[planned_action] # 来自LLM的规划 # 执行前记录我们期望的变化基于LLM的‘thought’或简单规则 expected_change fAfter {planned_action}, the element {planned_action[selector]} should be focused/clicked, and maybe a new input field appears. # 执行动作 actual_success automation_tool.execute(planned_action) # 获取执行后的新观察 new_observation get_observation() # 简单的失败检测逻辑 failure_detected False failure_reason # 检测1动作本身是否执行成功如元素不存在无法点击 if not actual_success: failure_detected True failure_reason fAction execution failed. Selector {planned_action[selector]} might be invalid or element not interactable. # 检测2关键预期是否达成这里用简单字符串匹配模拟 elif password in expected_change.lower() and password not in new_observation.lower(): failure_detected True failure_reason fExpected a password field to appear after action, but not found in new observation. # 检测3状态是否长时间无变化对比前后观察的哈希值 elif compute_similarity(previous_observation, new_observation) 0.95: failure_detected True failure_reason fScreen state did not change significantly after action, might be stuck. if failure_detected: # 进入改进流程 improved_plan self_improve(agent_state, failure_reason, llm_client) return improved_plan # 返回新的行动计划外层循环用这个重试 else: # 正常更新状态继续下一步 agent_state[current_observation] new_observation return None # 指示继续 def self_improve(agent_state, failure_reason, llm_client): # 构建改进提示词 improvement_prompt f 你是一个计算机操作智能体。你刚刚尝试执行一个动作但失败了。 失败原因{failure_reason} 当前屏幕状态描述{agent_state[current_observation]} 你的原始任务目标是{agent_state[original_goal]} 你刚刚计划执行的动作是{agent_state[planned_action]} 请分析失败原因并给出一个修正后的下一步行动计划。你的输出必须是JSON格式 {{ analysis: 简短分析为什么失败以及如何调整, new_action: {{ type: click|type|..., selector: 新的或修正后的选择器, value: 如果需要输入的话, confidence: 0.8 }} }} response llm_client.complete(improvement_prompt) # 解析response中的JSON返回new_action部分 return parse_new_action_from_response(response)第二步维护一个简易的策略记忆库我们可以用一个内存中的列表或小数据库来存储经验。experience_db [] def record_experience(goal, initial_state, action, result_state, success, failure_reasonNone): experience { goal: goal, initial_state_hash: hash(initial_state), # 简化处理 action: action, result_state_hash: hash(result_state), success: success, reason: failure_reason, timestamp: time.time() } experience_db.append(experience) # 可以设置一个大小限制只保留最近N条经验 def retrieve_similar_experience(current_state, goal): current_hash hash(current_state) for exp in reversed(experience_db): # 从最新开始查 # 简单的相似度匹配目标相似且初始状态相似 if exp[goal] goal and abs(exp[initial_state_hash] - current_hash) SIMILARITY_THRESHOLD: return exp return None在self_improve函数中可以先查询记忆库similar_exp retrieve_similar_experience(current_obs, original_goal)。如果找到并且那次经验是成功的可以直接采用当时的action如果是失败的可以在提示词中明确加入“历史上在类似状态下尝试动作X导致了失败原因是Y请避免。”4.3 原型运行的注意事项与局限这个原型非常简陋但体现了核心思想。在实际操作中你会遇到更多挑战状态表示与相似度计算用字符串哈希或简单匹配来比较“状态”过于粗糙。真实场景需要更复杂的表示方法比如提取关键UI元素的特征向量。LLM的稳定性要求LLM输出严格JSON格式并且在改进提示下能给出合理分析和新动作这对提示词设计和模型能力都有要求。可能需要多轮调试和少量示例Few-shot来稳定其行为。改进循环的终止条件必须设置一个最大重试次数或时间限制防止智能体在死循环中不断“改进”却无法脱身。性能开销每次失败都调用LLM进行分析和重新规划会增加延迟和API成本。需要权衡改进的收益与开销。尽管有这些局限这个原型已经能够处理一些简单场景了比如第一次点击#submitBtn失败因为实际ID是#submit-button失败检测触发LLM在改进提示下分析屏幕描述可能发现另一个高亮度的按钮描述是“提交”从而输出一个新的选择器.primary-button智能体重试后成功。这个过程完全发生在一次任务执行的推理过程中无需重新训练模型。5. 开源生态与未来展望OpenCUA-72B与超越当我们讨论“推理时自我改进”这类前沿概念时开源社区和大型基础模型的进展是不可忽视的推动力。像“OpenCUA-72B”这样的模型从其命名推测可能是一个拥有720亿参数的开源通用智能体模型如果属实将为此提供强大的“大脑”基础。更大的参数规模通常意味着更强的上下文理解、任务规划和指令跟随能力这对于在运行时进行复杂的失败分析和策略调整至关重要。开源生态的价值在于提供了可复现、可修改、可研究的基线。开发者可以基于这样的开源大模型构建我们上面讨论的改进框架而不必从零开始训练一个昂贵的专用模型。社区可以共同贡献各种“失败-改进”的经验模式、提示词模板和记忆库结构加速这类智能体的实用化进程。展望未来我认为推理时自我改进技术会朝着以下几个方向发展更轻量、更快速的改进机制目前严重依赖LLM进行反思延迟高。未来可能会出现专用的、参数更小的“反思模型”或“策略校正器”专门负责快速诊断和微调与主规划模型协同工作。跨任务、跨应用的通用经验迁移一个智能体在操作浏览器时学会的“等待页面加载”策略能否被抽象成通用规则应用于操作桌面软件如何构建一个通用的“计算机操作常识”记忆库让智能体在新应用上也能快速上手与模仿学习、强化学习的深度融合将推理时的改进经验以一种安全、高效的方式反哺到智能体底层模型的微调中实现从“在线学习”到“持续学习”的跨越让智能体越用越聪明。安全与可控性的挑战自我改进是一把双刃剑。智能体可能会“学习”到一些意想不到的、甚至有害的规避策略。如何为它的改进过程设置安全护栏Safety Guardrails确保其行为始终符合设计者的意图和伦理规范将是一个至关重要的课题。说到底构建一个能从失败中学习的计算机使用智能体就像教一个孩子学用电脑。你不可能预先教会他所有软件的所有操作。但你可以教会他一些基本原则看屏幕反馈、尝试不同的方法、记住什么管用、什么不管用。推理时自我改进就是在给AI智能体注入这种“基本原则”。这条路还很长但每一次让智能体自己成功解决一个之前会失败的任务都让我们离真正智能、自主的数字助手更近了一步。在实际开发中从小处着手从一个具体的失败场景开始构建你的改进循环你会对这个问题有更深刻、更实际的理解。