如何使用 OmniTool 的轨迹日志功能保存 Agent 截图与步骤决策数据
【免费下载链接】OmniParserA simple screen parsing tool towards pure vision based GUI agent项目地址: https://gitcode.com/GitHub_Trending/omn/OmniParser
在 OmniParser + OmniTool 跑完一次 Agent 任务后,界面里的推理过程会随对话滚走,事后无法复现"每一步看到了什么屏幕、模型决定了什么动作"。如果你需要把任务执行过程留档——用于构建训练数据管线或逐步回放排查——可以使用轨迹日志功能:在每一轮循环中把原始截图、Set-of-Mark 标注截图和该步的决策 JSON 写入本地目录,任务计划则单独落盘为plan.json。README 的 News 条目(2025/3)明确说明:"We support local logging of trajecotry so that you can use OmniParser+OmniTool to build training data pipeline for your favorate agent in your domain. [Documentation WIP]",因此本文的操作细节以 omnitool/readme.md 与轨迹日志的实现代码为准。
前置条件:先把 OmniTool 的三个组件跑起来
轨迹日志由 Gradio 端在 Agent 循环内写入,所以必须先完成 omnitool/readme.md 中 Setup 一节描述的三件套,且只列出与本文直接相关的要点:
omniparserserver:在
OmniParser根目录下创建 conda 环境并安装依赖,下载权重后,在OmniParser/omnitool/omniparserserver目录启动:python -m omniparserserver该服务的参数(默认端口 8000、caption 模型路径等)定义在 omniparserserver.py。
omnibox:在
OmniParser/omnitool/omnibox/scripts目录下用./manage_vm.sh create创建 Windows 11 虚拟机,完成后终端会显示VM + server is up and running!;之后用./manage_vm.sh start/./manage_vm.sh stop管理。Gradio UI:必须在 conda 环境
omni中运行(conda activate omni)。
此外还需要一个可用的 LLM API Key。API Key 可以在 Gradio 界面中粘贴,环境会从OPENAI_API_KEY、ANTHROPIC_API_KEY等环境变量读取初始值(见 app_new.py 的setup_state)。
一个关键前提:只有名称带-orchestrated后缀的模型会写轨迹日志。在 loop.py 中,save_folder只传给VLMOrchestratedAgent:
elif model in set(["omniparser + gpt-4o-orchestrated", "omniparser + o1-orchestrated", "omniparser + o3-mini-orchestrated", "omniparser + R1-orchestrated", "omniparser + qwen2.5vl-orchestrated"]): actor = VLMOrchestratedAgent( ... save_folder=save_folder )选择omniparser + gpt-4o、omniparser + R1等非 orchestrated 模型或claude-3-5-sonnet-20241022时,Agent 只走聊天展示,不会生成下面的文件。
启动 Gradio UI 并指定轨迹保存目录
在OmniParser/omnitool/gradio目录启动app_new.py(其文件头注释给出的启动方式):
python app_new.py --windows_host_url localhost:8006 --omniparser_server_url localhost:8000 --run_folder ./tmp/outputs--windows_host_url、--omniparser_server_url分别为 omnibox VNC 服务与 omniparserserver 的地址,上面是文档默认值,跨机器部署时按实际地址替换。--run_folder指定轨迹日志的根目录,不传时默认为./tmp/outputs。
注意 app_new.py 在启动时会追加一个时间戳子目录:
RUN_FOLDER = Path(os.path.join(args.run_folder, datetime.now().strftime('%Y%m%d_%H%M'))) RUN_FOLDER.mkdir(parents=True, exist_ok=True)也就是说每次启动 UI 都会新建一个形如./tmp/outputs/20250301_1530的目录,本次运行(以及你在界面里上传的文件)都落在这个目录里,多次启动互不覆盖。
界面操作:
- 在 Settings 的 Model 下拉框选择
-orchestrated模型(app_new.py的默认值就是omniparser + gpt-4o-orchestrated;R1-orchestrated 走 Groq,qwen2.5vl-orchestrated 走 DashScope)。 - 粘贴对应 Provider 的 API Key。
- 在输入框输入任务(例如打开浏览器并搜索某个网站),点 Send。发送前 UI 会探测
localhost:5000与 omniparserserver 的/probe接口,若提示 "Windows Host is not responding" 或 "OmniParser Server is not responding",先按 omnitool/readme.md 的 "Common setup errors" 一节排查(例如确认 omnibox 初始化完成、omniparserserver 已启动)。
任务运行期间生成了哪些文件
每执行一步,VLMOrchestratedAgent(见 vlm_agent_with_orchestrator.py)都会:
- 把本轮 OmniParser 解析所用原始截图解码保存为
screenshot_{步骤序号}.png; - 把带 Set-of-Mark 标注框的截图保存为
som_screenshot_{步骤序号}.png; - 调用视觉模型得到本步决策后,向
trajectory.json追加一条记录(打开方式为 append,每行一个独立 JSON 对象,不是 JSON 数组),记录结构为:
{ "screenshot_path": "...", "som_screenshot_path": "...", "screen_info": "...", "latency_omniparser": 0.0, "latency_vlm": 0.0, "vlm_response_json": {}, "ledger": null }各字段含义(以源码为准):
screenshot_path/som_screenshot_path:本步两张截图的保存路径,命名规则同上;screen_info:OmniParser 解析出的屏幕元素列表文本(带 ID 的 text/icon 条目),即模型决策时看到的结构化信息;latency_omniparser:OmniParser 服务返回的解析耗时;latency_vlm:本地测量的视觉模型调用耗时;vlm_response_json:模型输出的完整决策 JSON(含Reasoning、Next Action、Box ID、value等字段),这是"步骤决策数据"的核心;ledger:任务进度台账。第 1 步为null(ledger初始为None),从第 2 步起保存_update_ledger的输出(判断请求是否完成、是否陷入循环、是否在推进的 JSON)。
另外,任务第 1 步时 Agent 会先调用模型生成一个 bullet-point 计划并写入运行目录的plan.json,成功时终端打印Plan successfully saved to {路径}(见 vlm_agent_with_orchestrator.py)。
验证轨迹数据已保存
- 终端:第 1 步执行时看到
Plan successfully saved to ...说明plan.json写入成功。 - 运行目录:任务进行或结束后,检查本次启动生成的时间戳目录,应有
plan.json、screenshot_1.png、som_screenshot_1.png、trajectory.json;任务跑了 N 步就应有screenshot_1.png…screenshot_N.png,且trajectory.json有 N 行。 - Gradio 界面:
app_new.py的 File Upload & Management 面板会扫描RUN_FOLDER并列出新出现的文件(每 5 秒自动刷新,也可点 Refresh Files),把 Display Mode 切到 File Viewer 后可以在界面里直接查看图片与 JSON 内容。 - 任务结束信号:Agent 输出
"Next Action": "None"后,Gradio 端打印End of task. Close the loop.,此时本轮轨迹即为完整轨迹。
边界与限制
- 非 orchestrated 模型不落盘:
loop.py中只有-orchestrated系列模型会创建VLMOrchestratedAgent并接收save_folder,其余模型(包括 Claude)不产生上述文件。 - 旧版 UI 的默认保存位置不同:
app.py调用sampling_loop_sync时未传save_folder,走 loop.py 的默认值./uploads;只有app_new.py通过--run_folder暴露了可控的运行目录。 - 运行目录不纯:
app_new.py的文件上传功能会把上传文件复制进同一个RUN_FOLDER,整理数据时需与screenshot_*、som_screenshot_*、trajectory.json、plan.json区分。 - 另有一批 UUID 命名的截图:
OmniParserClient每轮还会把 SOM 标注图写到固定路径./tmp/outputs/screenshot_som_{uuid}.png(见 omniparserclient.py),VM 截图端点也在./tmp/outputs下保存原始截图(见 screen_capture.py)。--run_folder默认恰好指向./tmp/outputs,但两者命名方式不同(uuid vs 步骤序号),按步骤号命名的是轨迹日志正式产物。 trajectory.json的格式:按行追加、无外层数组,用标准 JSON 解析工具逐行读取即可,不要按 JSON 数组整体解析。
完成一次任务后,运行目录中的plan.json+ 逐步截图 +trajectory.json就构成一条完整的轨迹记录,可作为该领域 Agent 的标注/训练数据来源,或用于逐步回放模型决策。
【免费下载链接】OmniParserA simple screen parsing tool towards pure vision based GUI agent项目地址: https://gitcode.com/GitHub_Trending/omn/OmniParser
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考