code-vcli:截图识别的执行路径与输出契约
Node CLI 启动独立 Python 运行时,把截图转成 text、items 和 layout;OCR、VLM、Mix 三条路径、Web 模式的元素归并规则和数据契约。
code-vcli 的输入是一张截图,输出是 text、items 和 layout。支持 PNG、JPEG、WebP、BMP、TIFF,单图上限 20MB;Python 运行时、OCR 模型和 VLM 都在本机,图片不离开机器。
执行路径
CLI 在 Node 侧解析参数、检查工作区和安装状态,然后用 spawn 启动工作区里的 venv Python,执行 vcli_inference.py。子进程的 stdout 只承载 JSON,stderr 承载日志;环境固定 PYTHONIOENCODING=utf-8 和 PYTHONUNBUFFERED=1。VLM 和 Mix 默认超时 300_000ms,OCR-only 不设默认超时;超时会对子进程发 SIGTERM。
参数在 Node 侧先做组合校验:--mix 需要同时安装 OCR 和 VLM;--vlm 不使用 --ocr-backend;--mix-ocr-context-tokens 只在 --mix 下有效;--ocr-backend gpu 要求安装时选了 GPU。校验失败直接返回错误码,不进入 Python。
--json 的输出写到 ~/.code-vcli/files/:OCR 纯文本模式写 <image>_ocr_output.json,其它模式写 <image>_<mode>[_backend][_web]_output.json,stdout 返回文件路径。不带 --json 时 stdout 只有 text。
三条路径
OCR 是默认路径。PP-OCRv6 在 CPU 上走 OpenVINO,在 GPU 上走 RapidOCR 的 Torch CUDA/MPS;run_ppocr 把每个文本框整理成 text、confidence、bbox,先做一次去重。纯 OCR 的 JSON 只有 text、mode、engine;加 --web 才进入 UI 元素和布局分析。
VLM 走 Qwen2.5-VL。请求由 system prompt 和用户消息组成,用户消息包含图片、默认任务、可选的 -p;输出被约束为固定字段的 JSON:annotations、summary、elements、layout。生成参数是 max_new_tokens=4096、do_sample=False;elements 最多保留 30 个。解析失败时 _parse_vlm_json 会从截断的 JSON 中恢复已经闭合的顶层字段,并在 vlm.partial、vlm.recovered 里标记。
Mix 先跑 OCR,Web 模式下再跑 YOLO,然后释放 OCR/YOLO 的引用,再加载 VLM。OCR 结果不会原样进入 VLM,而是先经过 token 预算压缩,完整结果另存 artifact。
Web 模式的元素归并
Web 模式先用 PP-OCRv6 拿到文字框,再用 OmniParser V2 YOLO 以 conf=0.25 检测 UI 元素。assign_text_to_ui 按 YOLO 元素的顺序遍历:对每个尚未分配的文字框,如果 IoU >= 0.3 或中心距 <= 50px,并且 OCR 框面积 / UI 框面积 <= 2.5,就把它并入该 UI 元素;UI 元素面积小于 500px² 不参与匹配。一个文字框只会被第一个命中的 UI 元素占用,因此结果依赖 YOLO 的检测顺序。
合并后,text 为空且 confidence < 0.55 的 UI 误检被丢弃;剩余的空 UI 按 confidence 取前 100 个。所有元素按 (y, x) 排序,再用并查集聚类:两个元素中心距小于平均元素尺寸的 1.5 倍就归为同一组。每个 item 只保留 text、bbox、type、region、cluster_id,宽高比、组大小和排列方式移到 layout.cluster_summary,避免逐项重复。confidence 和 source 在输出前被移除。
VLM 的输出契约
system prompt 要求先检查截图上的叠加标注,再逐区覆盖文字、数字、状态、布局和可交互元素;annotations 记录标注文本、bbox、position、type 和 elementRef,summary 只保留视觉事实,elements 最多 30 个,layout 保留分区和阅读顺序。模型禁止猜测和自动纠错,无法确认的信息省略。
解析后的 elementRef 越界或缺失会归一为 -1;annotation 与目标元素文字相同且 IoU >= 0.5 的重复批注会被移除。layout.img_size 由原图实际尺寸补齐,不依赖模型输出。最终 text 由 summary 和 layout.sections 组装;为空且是 Mix 时,回退到 OCR 全文。运行诊断只进入 vlm,不混入 text。
边界
OCR-only 不带 --web 时,JSON 不输出坐标和布局;VLM 和 Mix 需要 GPU;NF4 只在 Windows/Linux 的 NVIDIA CUDA 上可用;纯 VLM 不经过 OCR;单图上限 20MB;OCR 无文字时返回 MODEL_TEXT_EMPTY,模型未安装或运行时缺失在进入推理前失败。它不点击页面,也不承担浏览器自动化。