资讯动态

VLM识别屏幕+LLM定时参考:桌面监控智能体的实践与优化

发布时间:2026/10/18 3:06:36 来源:尧图企业网站定制
1. 先给结论这套“VLM识别屏幕历史上下文LLM定时参考”的方案方向没问题但不能直接照搬我最近在做一个桌面监控类的内部项目就是想实现“让LLM持续盯着屏幕干活”这个目标。一开始我采用的思路和这个问题描述的几乎一样视觉语言模型VLM负责周期性截屏、识别屏幕内容把识别结果写入历史对话记录再让LLM每两分钟参考历史记录做一次判断。这个标题问“效果好吗”可以说问到了关键点上。我先说我的实测结论能跑通但直接把识别文本一股脑塞进历史、再用固定定时器唤醒LLM这种方式跑不了太久就会出问题。效果好不好主要取决于三个细节识别输出干不干净、历史记录有没有做分层压缩、两分钟这个周期和你监控的业务节奏是否匹配。这个方案解决的是真实痛点LLM本身没有实时视觉能力很多需要“盯着屏幕变化”的任务比如界面巡检、流程自动化、数据看板监控靠人盯着太累靠单一模型又兼顾不了“看见画面”和“逻辑推理”。所以用VLM当眼睛、LLM当大脑这种多模型组合是很自然的设计。适合参考这篇文章的人主要是在做智能体、桌面自动化、UI自动化测试、看盘助手或者后台监控工具并且正在纠结“到底要不要加历史记忆、多久参考一次”的读者。先说一句结论防止大家看完文章才发现方向不对这个方案完全可以做但你在设计时不能把“把历史直接都丢给LLM”当成终极方案也不能迷信两分钟这个固定数字。下面我详细拆开讲。1.1 这个方案的本质是给LLM装了一双眼睛和一个日记本如果你把一个LLM单独丢到屏幕前它什么也看不见唯一的输入就是用户写的指令。VLM的加入相当于给LLM配了一个速记员每次截屏VLM把画面中的关键信息转述成文字比如“当前页面显示用户登录成功”“后台任务进度条已到80%”。这些文字进入历史对话就变成LLM能阅读的连续记录。定时唤醒也很关键。让LLM一直持续推理、每秒钟都判断一次成本高且没必要每两分钟唤醒一次是在“反应及时性”和“算力成本”之间做一个折中。所以这个标题里的三个元素——VLM识别、历史记录、两分钟周期——本质上是在构建一个具备持续感知和记忆能力的循环系统思路是符合多模态智能体主流实践的不是异想天开。1.2 为什么我又说“直接照搬效果不会好”问题在于这三样东西单独拿出来都对拼在一起却容易出现三个毛病。第一个毛病VLM识别出的内容不等于“历史记录”。如果你把每一帧画面的转述都原样写进历史几分钟后历史里全是高度重复的描述“当前页面与上一轮相同仍是数据看板”“页面无变化进度条仍在88%”。这种重复信息既浪费token又会淹没真正关键的变化LLM反而找不到重点。第二个毛病LLM能阅读的文字有上下文上限而屏幕监控是一种持续产生日志的任务早晚会超出限制。我实测过一分钟记录一条每条平均60个token两小时就能攒下七千多token更不用说跑一整天了。如果不做分层和压缩越往后LLM越像一个手里拿着厚厚一沓无关文件的人反而找不到关键内容。第三个毛病两分钟固定周期对某些场景太慢、对另一些场景又快得没必要。比如监控一个会弹错误弹窗的安装程序两分钟才去看一次弹窗可能在你没注意的时候已经把后续流程卡住了而如果监控的是一个长时间不变化的仪表盘两分钟一次的轮询大部分是在空转。固定周期本质上是在忽略业务本身的变化节奏。所以“效果好吗”这个问题的准确答案是架构方向对但需要把“视觉识别输出”“记忆管理”“唤醒策略”这三块重新设计一遍才能真正好用。后面几个章节我会把每一块的实现细节和踩坑经验展开说。2. 三个“为什么”识别输出、记忆结构、轮询周期才是真正的效果开关这一章先把理论层面的关键点讲透。很多人一开始会把“VLM识别”和“VLM截屏”混为一谈觉得只要把画面转成文字就完事了实则差得很远。我把这三个因素一个一个拆开。2.1 第一关键VLM输出的不是“历史”而是“事件”必须在源头做结构化我在项目里第一次这么做时直接把VLM的描述塞入历史跑了一个小时后再让LLM总结“刚才发生了什么”结果它给出的答案非常零散甚至把某一帧的边角内容当成了主线事件。原因很简单屏幕画面里不是所有东西都有记录价值。一个系统的桌面可能有静态壁纸、工具栏、通知图标、弹窗、加载动画如果把整幅画面都描述一遍重要变化反而没有任何标记。正确的做法是让VLM只抽取“事件”和“状态”并且用约定的格式输出。我给VLM的Prompt大致是这样你是一个屏幕状态观测器。请观察提供的截图只输出两种内容 1. 事件与上一帧相比出现了哪些新变化例如弹窗出现、按钮状态切换、任务新增。 2. 当前关键状态例如进度数值、页面路径、错误信息、关键元素可见性。 要求 - 没有变化时只输出 {event: none, status: unchanged}。 - 不要描述图标样式、背景颜色等与任务无关的视觉细节。 - 请严格输出JSON不要附带其他文字。输出示例{event: 新弹窗出现提示磁盘空间不足, status: 当前页面系统设置进度条78%}这一步的收益是巨大的。历史记录里不再出现“页面与上一轮相同”式的废话只有真正的状态变化才占一条记录同时因为输出统一为JSON程序可以对它做过滤、去重、压缩后续处理非常顺手。记住一句话VLM是你的速记员不是你的复读机一定要在源头限制它只记重点。2.2 第二关键历史记录不能全量堆积要分短期、中期、长期三层管理我知道有人会想“现在大模型上下文窗口不是动不动就128K、200K吗全量塞进去不就行了”但屏幕监控是持续任务不是聊天一小时、两小时确实塞得下跑半天、一整天哪怕200K窗口也会被填满退一步说即使窗口够大信息过载也会让模型判断力下降窗口大不代表模型能记住重点。我在项目中把历史记录分成三层管理短期层最近10到20条结构化事件按时间排列这是LLM做判断时必看的“最新现场”。中期层每15分钟或每30条事件让一个模型做一次摘要压缩成“这个时间段发生了什么、当前整体状态是什么”。长期层用户目标、已完成的关键步骤、尚未完成的事项从摘要中提取始终常驻提示词。每次唤醒LLM时我给它看的不是全部历史而是“长期目标 中期摘要 最近事件 当前屏幕状态”的组合。这样上下文长度被严格控制在合理范围内模型每一次推理都聚焦在最新近况上不会迷失在冗长的日志里。你可以把它理解为人的记忆机制你不需要回忆每一秒的细节但你清楚地记得“我在干什么、刚才做到哪了、现在该做什么”。2.3 第三关键两分钟是结果不是起点周期应该由业务事件密度决定两分钟这个数字看起来通用实际上非常尴尬。如果屏幕内容每分钟都在剧烈变化两分钟会漏掉大量关键中间态如果内容每小时才变一次两分钟轮询等于拿高射炮打蚊子还把日志、token和调用次数全部浪费掉。我在项目里验证过一种更合理的策略先做一次事件密度统计再决定基准周期。具体做法是让VLM在每次截屏后判断画面是否有变化同时记录变化频次。观察一个小时得到“平均每多少秒出现一次有意义的画面变化”比如平均2.5分钟变一次那基准轮询可以设为1分钟或1.5分钟平均30秒变一次轮询就要加密到10到15秒或者干脆改成事件驱动。事件驱动的思路是VLM识别发现“有变化”时才写入历史变化发生后立即触发LLM做判断而不是等着下一个两分钟节点。这么做能避免弹窗出现后两分钟才被发现的尴尬。我个人推荐用“事件驱动为主、固定轮询为兜底”的双触发策略平时画面静止不调用一旦有事件立刻处理如果一段时间完全没有事件再用固定周期唤醒一次确认状态。这个策略我在后文会给到具体实现。3. 实操链路一个可落地的屏幕感知助手是怎么搭起来的理论说完了这一章给出一个可以直接参考的工程实现。我用的环境是普通的桌面电脑没有特殊硬件所有代码都以伪代码和配置片段的形式呈现方便你移植到自己的项目里。3.1 整体架构高频VLM干粗活低频LLM干细活不少人会把一个大模型又做识别又做推理跑了几轮就发现成本高、速度慢。我在设计中把模型拆成两层层级模型定位频率主要职责感知层轻量级VLM高频秒级到十秒级截屏、判断画面变化、抽取结构化事件推理层较强LLM低频事件触发或分钟级综合历史与当前状态给出判断和动作指令轻量级VLM可以是一个能在本地跑的小模型也可以是对应视觉能力的开源模型关键是速度快、成本低因为它需要频繁调用。推理层的LLM不必频繁参与只在需要做决策时出现因此可以使用能力更强、逻辑更复杂的模型。这种“小模型盯梢、大模型决策”的组合能有效平衡成本与效果。模块上这套系统至少需要四块截图模块、VLM识别模块、历史记忆模块、LLM决策模块。截图模块负责按策略抓取屏幕帧识别模块负责把帧转成结构化事件记忆模块负责存储事件、生成摘要决策模块负责在触发条件满足时向LLM组装上下文并在得到输出后执行动作。3.2 核心实现一用感知哈希判断画面变化避免重复识别第一版代码里我是不管三七二十一每隔几秒就截图丢给VLM结果日志里全是“无变化”的记录而且无意义地消耗了大量算力。后来加了一道前置过滤先对屏幕帧做感知哈希如果哈希值与上一帧差异小于阈值就不调用VLM不产生任何记录。伪代码如下import imagehash from PIL import ImageGrab prev_hash None CHANGE_THRESHOLD 8 # 汉明距离阈值需要根据实际屏幕调 def grab_and_check(): global prev_hash img ImageGrab.grab() h imagehash.phash(img) if prev_hash is None or h - prev_hash CHANGE_THRESHOLD: prev_hash h return img return None感知哈希的优点是速度快不依赖模型适合做前级过滤。阈值需要根据你的屏幕实际情况来定如果阈值太小细微的光标闪动也会触发识别如果阈值太大真正的弹窗变化会被漏掉。建议先拿到两到三天的日志人工看一遍哪些是有效变化再反过来标定阈值。这一道关卡可以把VLM调用量直接降到原来的五分之一甚至更低。3.3 核心实现二LLM每次唤醒看到的上下文模板固定的轮询周期也好事件触发也好LLM每次被唤醒时给它组装什么样的上下文直接决定它的判断质量。我建议采用下面这个模板结构【用户目标】 监控安装流程在出现错误弹窗时提醒我并在任务完成后发送总结。 【长期状态】 - 已完成下载安装包、解压、初始化环境 - 当前阶段执行安装脚本进度78% - 未完成等待安装结束、验证安装结果 【中期摘要】最近30分钟 安装过程正常推进无错误中间出现过一次网络波动系统自动重试后恢复。 【最近事件】 - 14:02:35 事件安装进度从72%推进到78% - 14:05:10 事件无变化 - 14:07:48 事件弹出提示窗口内容为“磁盘剩余空间不足” - 14:09:20 事件提示窗口仍在系统等待用户确认 【当前屏幕状态】 检测到弹窗“磁盘剩余空间不足”路径选择页面处于激活状态。 【推理要求】 请结合以上信息判断当前是否需要用户介入。如果需要请说明原因和建议动作如果不需要请回复“保持监控”。注意几点细节。用户目标永远放在最前面让LLM知道“我为什么在这里”。长期状态提供骨架中期摘要提供这段时间的走向最近事件负责精确到分钟的细节当前状态则是现场。这样的组合信息密度高、层级清晰LLM不需要从大段原始日志里自己推断“现在重点是什么”。另外推理要求里明确给出“不需要时回复保持监控”这样的闸门能减少无效动作输出。3.4 周期怎么定先用事件密度统计再做成动态调整这一节回答标题里最核心的“两分钟”问题。我建议你第一周不要直接定周期而是先让系统全量记录事件这种模式下每5秒截屏并计算哈希有变化才由VLM生成事件。记录一天后统计事件分布看每两起有效变化之间的间隔。比如发现大多数变化发生在30秒到90秒之间那固定周期定在30秒比两分钟更合适如果平均间隔是3分钟那两分钟可以是一个合理的底线但依然可以更懒一些。实现动态周期的思路并不复杂。维护一个“最近事件时间戳”变量LLM决策模块有两个触发源事件触发VLM检测到新事件后立即唤醒LLM。兜底轮询如果距上次LLM推理超过动态上限比如基准周期的两倍强制唤醒一次确认一切正常。这样就把“每两分钟固定看一次”改成了“有事马上处理、没事定期确认”既不会漏掉关键变化又能明显减少调用次数。实际项目中这种方式下的LLM调用量比固定两分钟要低40%左右关键事件响应延迟则从“最多两分钟”降到了“秒级”。标题里问的“效果好吗”我认为改成“事件驱动兜底轮询”之后效果才能真正令人满意。4. 实测中遇到的典型问题与排查经验不管方案设计得多充分跑起来都会遇到各种意外。这一章我从实际调试记录里挑了四个最有代表性的问题逐个记录现象、原因和解决办法当作一份速查清单。4.1 上下文越滚越长模型在长日志里抓不住重点这个问题出现在第一版。当时我把VLM产生的每条JSON事件都直接追加到系统提示词后面跑了一个多小时以后LLM开始频繁出现“根据记录安装已经完成了”之类的错误判断而实际上安装一直在正常推进并没有完成。我打开上下文一看才发现最近的事件被淹没在海量历史条目里模型被旧信息带偏了。排查思路很简单把每次调用LLM的完整上下文打印到本地日志人工读一遍就能定位是哪个区域把模型带偏。解决办法就是我前面说的分层记忆。我改成“长期目标长期状态中期摘要最近事件”的结构之后模型再也没有混淆过阶段状态。这里想强调一个容易被忽略的点不是所有中间步骤都需要保留给LLM看凡是能压缩成一句摘要的就不要给它看原始细节。4.2 屏幕长时间无变化但历史记录里刷满了无意义日志第一次跑全天监控时我第二天打开日志文件发现大量记录是“无变化状态不变”或者“当前页面与上一轮相同”。这些记录本身没有错但有两个副作用一是占满了存储和token二是在事件序列里掺杂了大量干扰信号让LLM难以分辨真实的“变化点”。解决方法是两道关卡第一次在截图模块用感知哈希过滤画面不变就不调用VLM从源头挡住大部分无变化记录第二次在VLM输出侧在Prompt里明确要求“没有变化只输出标准JSON”随后程序丢弃event为空且status不变的记录。这样做之后一天的有效事件量从三千多条降到一百多条而覆盖的信息几乎没有丢失。4.3 VLM把屏幕上的次要视觉元素当成重大事件上报有一回监控程序莫名其妙被触发了十几次我看日志才发现VLM把桌面右下角一个自动弹出的音量调节浮窗识别成了“系统警告”并生成了事件。这种情况本质上是VLM缺少任务上下文它只看到画面变化不知道哪些变化值得关注。解决办法有两个方向。最简单的是在Prompt里增加“关注区域”和“关注元素”白名单明确告诉模型哪些区域出现的元素需要报关。比如重点关注区域安装日志窗口、错误弹窗、进度条区域。 忽略区域系统托盘、桌面背景、用户个人文件夹。更进一步的方案是给截图做裁剪只把任务相关区域裁出来再交给VLM识别。裁剪可以手工配置坐标也可以让VLM先在全屏图中定位一次后续按固定区域识别。这样既能减少VLM的干扰项也能降低token消耗。4.4 固定两分钟周期在快速操作场景下会漏掉关键时间窗最让我印象深刻的是一次安装流程监控安装进程在某个阶段会连续弹出三次不同的授权确认窗口每次都只停留30秒左右如果等用户不点击就会自动取消。两分钟一次的轮询根本赶不上节奏导致授权窗口被漏掉流程中断。这次事故让我彻底放弃了固定周期。我后来在双触发的基础上额外加了一个“活跃侦测”逻辑当画面变化频率超过某个阈值时系统自动把轮询间隔缩短到10秒当画面持续稳定时再逐步拉长回基准周期。这个逻辑本质上是用前一段时间的平均变化频率动态调整下一阶段的采样间隔实现简单效果却很明显。典型问题根本原因解决措施上下文越长判断越差历史全量堆积、重点信息被淹没分层记忆摘要最近事件当前状态日志里大量无意义记录画面无变化仍未过滤感知哈希去重 VLM标准JSON输出VLM误报次要视觉元素缺少任务相关区域约束白名单 裁剪关注区域固定周期漏掉快速事件周期与事件节奏不匹配事件驱动为主 兜底轮询4.5 什么情况下我建议你直接放弃这套方案不是所有场景都适合“VLM识别LLM决策”。如果你需要的不是“理解状态、做判断”而是逐帧连续的精细控制比如要移动鼠标画一条平滑曲线或者实时追踪一个快速移动的物体那这套两分钟甚至秒级的轮询架构本质上是跟不上的应当改用端到端的视觉控制模型或经典自动化脚本而不是硬套LLM。另外如果你的屏幕画面稳定且任务逻辑简单比如只需要判断进度条是否走完那直接写一个像素点颜色检测脚本就足够了用VLM和LLM是严重的过度设计。判断标准很简单任务是否需要理解语义、是否需要结合一段历史状态做推断、是否需要根据上下文生成非固定动作。三个都满足才值得上这套多模型组合方案。5. 想复现这套方案给你一条低成本的验证路径我知道看完前面这些内容很多人想立刻动手试。但直接搭全链路可能比较费时间我建议先用两三个小时做一个最小验证拿到真实数据之后再决定要不要继续深挖。5.1 最小验证清单先用日志再上模型第一步先不接任何模型只用感知哈希加截图把屏幕变化记录成带时间戳的日志。这一步能回答很多关键问题你的屏幕一天到底变多少次每次变化间隔是多少哪些时间点变化密集、哪些时间段完全静止这些数据是决定轮询策略的基础而且完全不需要花钱调用模型。第二步选一个轻量级VLM只让它做“事件抽取”跑两个小时然后把输出存成JSON文件。这一步用来评估识别质量看看有多少误报、多少漏报、多少描述是把重要变化说偏了的。如果识别质量让你无法接受先调整Prompt或换模型不要急着接LLM。第三步等你觉得事件质量稳定了再接入LLM做决策层并逐步引入分层记忆。哪怕是最简单的EXECL表格存储也行关键是先在数据层面建立“事件、摘要、关键状态”的区分而不是直接把JSON堆在一起。5.2 效果怎么评估四类指标一个都不能少“效果好不好”不能靠感觉我建议你从四个角度量化评估识别准确率随机抽取一天的事件日志人工比对录屏统计正确识别、误报、漏报的数量。摘要覆盖度检查中期摘要是否包含当天所有关键转折点比如错误是否被记录、任务阶段切换是否被描述。决策命中率把LLM每次的输出与人工期望做对比统计“该提醒时提醒了”“不该行动时没有行动”的比例。经济成本记下每天的模型调用次数、token消耗、响应延迟判断这套机制长期跑是否划算。我自己的做法是把LLM的每次判断结果连同屏幕录屏一起保存下来第二天翻看时像看回放一样逐条对照。这个方法虽然原始但比任何自动化评测都更能暴露问题。5.3 一些能帮你少走弯路的工程细节最后分享几个从项目中沉淀下来的工程细节它们不复杂但每一处都能避免一次事故。调用超时与重试要设计好。LLM偶尔会超时不能因为一次超时就丢掉整个事件流至少需要一个带指数退避的重试机制并且要把失败事件重新放回队列避免吞掉关键状态。输出必须做幂等控制。如果LLM给出的是“点击某个按钮”这类动作指令要保证这个动作不会因为重复触发而被执行两遍。我见过最简单的实现是给每个事件分配一个唯一IDLLM决策时携带“已处理事件ID列表”新的事件才会触发动作。敏感操作加审批闸门。如果你的屏幕助手会代替人操作鼠标键盘我强烈建议在动作层加一个人工确认模式LLM可以提出“将要执行的动作”由用户确认后再执行。否则一旦模型判断失误后果会很快。多屏幕和分辨率变化要考虑。VLM识别的是像素画面不同分辨率和缩放比例下同一界面的布局会差很多如果项目要跨设备运行最好在识别前先统一截图缩放比例或者对模型做少量新场景的适配。6. 最后说点我自己的体会这轮验证做下来我对“把VLM识别屏幕加入历史对话上下文然后LLM定时参考”这个思路有几个更具体的感受。第一方向本身是成立的多模态智能体不可能一直在等待用户输入它需要自己观察、自己记录、自己决定什么时候行动这套链路就是这种能力的雏形。第二效果好坏不在于“两分钟”这个具体数字而在于历史怎么被组织、事件怎么被定义、唤醒怎么被触发。把这三个问题想清楚了哪怕周期是三分钟或者三十秒方案都能稳定跑下去想不清楚换任何一个固定周期都不会有本质变化。如果你现在正打算做类似的东西我的建议是先别急着堆大模型。花一两天时间把你自己屏幕上的变化日志统计出来你会对“我的场景到底需要多快、多久看一次”有一个非常直观的认识。很多时候能靠轻量脚本解决的问题别轻易上大模型但一旦真需要理解语义和连续状态这套VLM加LLM的组合确实是当前综合成本与效果都比较优的解法。希望这篇分享能帮你少踩几个坑。

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

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

免费获取报价 →
↑