oh-my-pi snapcompact 实验 exp08:中央凹式两级读取协议与 ZOOM 放大回合提示词设计
2026/9/12 7:09:03 网站建设 项目流程

oh-my-pi snapcompact 实验 exp08:中央凹式两级读取协议与 ZOOM 放大回合提示词设计

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

导读

本文深入剖析 oh-my-pi 仓库中 snapcompact 的 SQuAD 召回实验 08(exp08_foveate,中央凹式两级读取):系统先把长文本以 5×8 像素字体压进 1568×1568 的位图"档案图",让视觉模型第一轮尽可能作答,再对读不清的区域按行带切片放大重渲染,进入第二轮精确作答。核心是 exp08-zoom.md 这份放大回合提示词——它定义了标签、行带、提取式回答、UNREADABLE 与编号输出这一整套协议。读完本文,你将掌握该两级协议的完整数据流、三种提示词变体(rows/phrase 定位)的差异、行带合并与放大的实现细节,以及如何复跑这套实验并解读其成本/精度指标。

背景:snapcompact 与"位图帧上下文压缩"

snapcompact 的核心理念是:与其让 LLM 去总结被丢弃的对话历史,不如把历史序列化成紧凑文本,再用像素字体渲染成密集 PNG 帧,让视觉模型直接"读回"这些位图。整个过程本地化、确定性执行,不消耗 LLM token 也不产生延迟(README 明确:Rasterization and PNG encoding happen in native code)。

在 research/ 目录下,这一理念被系统化评测:以 SQuAD v1.1 dev 全集(约 150 万字符,见 run.py)为语料,比较 text、compact、handoff、img-<字体>-<变体> 等条件的 QA 召回率。实验 08 就是其中一条重要的压缩路线:不再追求"一张图装进所有内容",而是主动接受第一轮读不清,用第二轮按需放大来补齐

exp08 协议总览:一图两读,按行放大

exp08_foveate.py 的模块 docstring 给出了实验全貌:

  • 第一轮(档案图):用 5×8 字体渲染档案图。在 1568×1568 画布上,capacity计算得到 313 列 × 196 行 = 61348 字符/页,比此前 6×10 最优解(40716 字符/页,见 run.py)密 1.5 倍。模型先读这张"尽力而为"的图并回答问题。
  • 放大请求:对读不清的区域,模型在答案中回复ZOOM rows A-B这样的命令(或带锚点短语的变体)。
  • 第二轮(放大回合):harness 从块文本中按行带切片——行 r 覆盖字符区间[(r-1)*cols, r*cols)——用 8×13 舒适字体重新渲染为放大图,把放大图 + 待答问题继续发给模型。
  • 合并评分:两轮答案合并,用官方 SQuAD EM/F1 与成本,对比img-6x10-sent基线。

整体流程见run_cell_chunk(exp08_foveate.py):qa1存档回合 → 解析zoom请求 →merge_bands合并行带 →zoom_renders渲染放大图 →qa2放大回合 → 合并final答案。

exp08-zoom.md:放大回合的提示词逐条解读

exp08-zoom.md 全文六行,构成放大回合的全部指令,逐条拆解如下。

1. 内容定位与标签协议

Below are high-resolution re-renderings of the archive row bands you requested. Each image is preceded by a label giving the archive row range it covers; the text inside is identical to those rows, re-flowed to the new line width.

要点有二:

  • 明确告知模型:图中的文字与档案图中对应行的文字完全一致,只是按新行宽重新排版(re-flowed to the new line width)。这消除了"放大图是不是新内容"的歧义,也提示模型文本是连续重排的,不必按原行号对应回去。
  • 标签协议:每张放大图前都有一行标签,说明该图覆盖的档案行范围。对应到代码里,是z_content中的f"Zoom of archive rows {a}-{b}:"文本块(exp08_foveate.py)。标签是模型把放大内容与"我到底在问哪块"对齐的锚点。

2. 回答范围指令

Answer your remaining questions, listed after the images, using the zoomed images plus anything you already read. Keep the same question numbers as before.

这是多轮对话语义的关键:放大回合不重发所有问题,只重发待解决(pending)的问题(代码中pending列表,exp08_foveate.py),且必须保持原有编号。同时允许结合第一轮已读到的内容(plus anything you already read),因为放大图可能只覆盖了问题答案所在的一小条带,上下文仍需要第一轮的全局信息。

3. 提取式答案

Give short extractive answers: a word or phrase copied from the text.

与第一轮提示词一致(exp08-archive.md),要求答案是从原文中逐字抄录的词或短语,便于squad.parse_numbered提取后与 golden answer 做字符串级 EM/F1 匹配。

4. 兜底协议:UNREADABLE

If you still cannot read the answer, reply exactly UNREADABLE.

即使放大也读不出来,就精确回复UNREADABLE。代码在合并阶段用answers2[i] or "UNREADABLE"兜底(exp08_foveate.py),并在指标中统计abstained数量。这套"弃权"机制让模型宁可弃权也不猜,把"看不清"和"答错"分开计量。

5. 输出格式

Output a numbered list (original numbering), one answer per line, no commentary.

要求按原编号输出、每行一条、不加注释,正是为了配合 squad.py 中parse_numbered的正则解析:r"\s*(\d+)[.):]\s*(.*\S)?\s*$"逐行提取1. 答案形式的条目,未命中则留空。

三种协议变体:fov / fov2 / fov3 与 zoom 请求格式

exp08_foveate.py 中PROTO字典定义了三种提示词组合,其差异决定了模型如何表达"我要放大哪里":

变体档案回合提示词放大 padding定位方式特征
fovexp08-archive.md2 行行号(rows)保守策略:只有太小/太糊才申请放大,紧凑 padding
fov2exp08-archive-eager.md12 行行号(rows)激进策略:不完全确定就申请放大,宽 padding
fov3exp08-archive-phrase.md12 行短语(phrase)激进策略 + 模型引用半读出的锚点词,harness 模糊定位后放大该行带

行号定位(rows)与解析

fov/fov2用行号。第一轮提示词要求:reply exactly ZOOM rows A-B(如ZOOM rows 41-47)。解析由三个正则完成(exp08_foveate.py):

  • _ZOOM_RANGEZOOM rows 41-4741–4741 to 47均命中,且自动把A>B的情况交换为有序区间;
  • _ZOOM_SINGLEZOOM rows 41这样的单行请求,解析为(41, 41)
  • _ZOOM_PHRASEZOOM "anchor words"形式的短语请求。

短语定位(phrase)与模糊匹配

fov3走锚点短语路线:提示词要求模型引用"在区域内或紧邻区域能部分辨认出的 3~8 个连续单词",harness用 locate_phrase 在块文本里模糊定位:

  1. 先把 chunk 与短语都归一化(只留字母数字、以空格连接),长度保持对齐;
  2. 先尝试精确子串匹配;
  3. 失败则滑窗打分——窗口大小k = max(2*len(p), 8)个词,统计与短语词集的命中数;
  4. 分数达到max(2, (len(p)+1)//2)才接受,命中位置换算回行号:span[0] // cols + 1

这套设计允许模型"读错几个字符"(提示词明说a few wrong characters are fine),把模糊的视觉感知容错地映射到精确的行带。

三种变体的完整字面量差异体现在提示词语气上:fov是"大部分能读,个别区域不行"的中性描述;fov2/fov3则警告this font is rendered BELOW the size you can read reliably... Be skeptical of your own reading,并强调Zooming is cheap and encouraged; guessing is penalized(exp08-archive-eager.md)。注意:所有第一轮提示词都禁止猜测——读不清要么ZOOM,要么UNREADABLE

放大回合的工程实现:行带合并、切片与重渲染

行带合并与 padding

模型可能对多个问题分别请求放大,这些行带需要合并。merge_bands(exp08_foveate.py)做三件事:

  • 每个 band 向外扩pad行(fov 为 2 行,fov2/fov3 为 12 行),并 clamp 到[1, max_row]——因为模型给的行号是估计值,需要余量兜住;
  • 排序后合并重叠或相邻(间隔 ≤1 行)的 band,避免同一区域渲染两张图;
  • 输出互不相交的有序区间列表。

按字符切片与分页

每个 band 在 chunk 文本中的字符区间是[(pa-1)*arch_cols : pb*arch_cols](exp08_foveate.py),随后zoom_renders判断:若 band 超过一张放大图能容纳的行数(由capacity(zcfg, ZOOM_SIZES[-1])[2] // arch_cols计算,exp08_foveate.py),自动拆成多页。

放大尺寸自适应

ZOOM_SIZES = (520, 784, 1040, 1568) # smallest square that fits the band wins

exp08_foveate.py 用 4 档画布尺寸,按"能容纳这段文本的最小正方形"选取,避免小 band 也渲染大图造成浪费。渲染函数bdf.render(txt, zcfg, CACHE, size, "bw")复用 bdf.py 的位图渲染管线(黑白变体,8×13 字距)。

磁盘缓存与原子写

放大图以内容哈希命名:f"exp08-zoom-{ZOOM_FONT}-{size}-{sha8(txt)}.png"(exp08_foveate.py),命中直接复用;写文件走atomic_png——先写临时文件再 rename,避免并发任务读到半成品(exp08_foveate.py)。

双轮问答的完整数据流

run_cell_chunk为主线,一次 chunk 的完整生命周期如下(exp08_foveate.py):

  1. 采样squad.sample_chunk_questions从完全落在 chunk 内的段落中均匀采样至多--qpc(默认 30)个问题,并记录pos_rel(段落起点在 chunk 中的相对位置 0~1),便于后续按位置四分位分析。
  2. 渲染档案图render(chunk_text, FONTS["5x8"], CACHE, args.size, variant),variant 为bwsent(对应 conditionsfov-5x8-bwfov-5x8-sent)。
  3. 第一轮 QA:消息 = 档案提示词(含{cols}/{rows}格式化) + 档案图 + 编号问题块,经llm_complete调用(providers.py 按模型名自动分派 OpenAI / OpenRouter / Anthropic 三家)。结果按 payload 哈希缓存,截断(stop == "max_tokens")响应不缓存不重放(exp08_foveate.py)。
  4. 解析 zoom 请求:对每个答案检查是否含zoomfov3优先短语定位,失败则回退行号解析。请求了 zoom 但 band 无法解析的,该题直接置为UNREADABLE(宁可弃权也不猜)。
  5. 放大回合pending问题 + 放大图组装z_content(提示词 exp08-zoom.md + 逐图标签 + 编号问题块),作为第二轮 user 消息追加在qa1之后形成完整对话历史。
  6. 合并与评分answers2覆盖pending项,squad.parse_numbered解析,exact_match/f1按官方 SQuAD 归一化(去标点、去 a/an/the)逐题打分(squad.py),每条记录写入records.jsonl

成本建模与基线对比

成本核算在aggregate_phase_cost(exp08_foveate.py):

  • token 分in/out/cache_w/cache_r统计,其中缓存写按 1.25×、缓存读按 0.1× 输入单价折算(与 run.py 的 Anthropic 定价口径一致);
  • 放大回合(qa2阶段)的增量成本单独统计为cost_zoom_usd,用于回答"按需放大到底贵不贵";
  • zoom_rate= 申请过放大的问题占比,zoom_chunks= 实际发生放大回合的 chunk 数。

基线定义在 exp08_foveate.py:img-6x10-sent最优配置的 (f1, se, cost$)。例如gpt-5.5长度 150 的基线是 f1=0.8218、$0.2452。汇总时每个 cell 输出d_f1d_cost_usd,直接对比两级协议相对单图基线的精度差与成本差。

复跑实验:CLI 与参数速查

实验依赖 uv 与 pillow(# /// script头声明requires-python >= 3.10dependencies = ["pillow"]),在packages/snapcompact/research/目录下运行:

uv run exp08_foveate.py

main暴露的关键参数(exp08_foveate.py):

参数默认值说明
--modelsgpt-5.5,google/gemini-3.5-flash逗号分隔的模型列表;OpenAI 模型名以gpt-开头、OpenRouter 模型名含/(见 providers.py)
--lengths50,150使用的语料段落数(corpus 前缀)
--conditionsfov-5x8-bw,fov-5x8-sent实验条件,格式为<proto>-<font>-<variant>
--qpc30每个 chunk 采样的问题数
--seed42采样随机种子(可复现)
--size1568档案图边长像素
--workers3并发线程数
--max-tokens32768每轮 QA 输出预算
--effort思考力度(low/medium/high/xhigh/max等)
--fresh关闭忽略缓存强制重跑
--env~/.env存放OPENAI_API_KEY/OPENROUTER_API_KEY的环境文件(最后赋值生效,见 providers.py)
--outexp08-foveate结果子目录名

输出三份产物到research/results/<out>/records.jsonl(逐题记录,含zoomedzoom_bandanchorabstained等字段)、summary.json(按模型×长度×条件聚合)、matrix.csv。模型的输入/输出单价在MODELS字典中显式配置(如gpt-5.5: (2.0, 16.0)美元/百万 token,exp08_foveate.py)。所有响应按 (model, tag, payload) 哈希缓存于research/.cache/qa/,中断重跑免费续传。

从实验到产品:位图帧形状的选取依据

exp08 这类 SQuAD 召回实验的结论直接指导了 snapcompact 的产品参数。README 明确"Frame shapes are provider-aware, chosen by SQuAD recall evals (seeresearch/) against real provider billing"(README),并给出各 reader 的默认形状:Anthropic11on16-bw(X.org 8x13 字形、11px 步进)、Google8on22-bw@2048、OpenAI8on22-bwdetail: "original")。也就是说,"档案 + 按需放大"的实验框架并非孤立研究,而是 oh-my-pi 压缩管线(compactAPI 的preserveData中持久化图像帧,见 README)中帧几何选择的方法论来源。

相关文件索引

  • 放大回合提示词:exp08-zoom.md
  • 档案回合提示词三变体:exp08-archive.md、exp08-archive-eager.md、exp08-archive-phrase.md
  • 实验主程序:exp08_foveate.py
  • 位图渲染基础设施(BDF/HEX 解析、capacity、render、variant):bdf.py
  • 语料与评分(SQuAD v1.1 dev、EM/F1、编号解析):squad.py
  • 模型分派与用量归一化:providers.py
  • 通用评测框架与字体表:run.py
  • 产品侧形态选择:README

结语

exp08-zoom.md虽只有六行,却是整个中央凹式两级读取协议承上启下的关键一环:它用"标签对齐 + 保持原编号 + 提取式答案 + UNREADABLE 兜底 + 严格输出格式"五条指令,把第一轮档案图的模糊感知与第二轮放大图的精确阅读无缝衔接。配合 harness 侧的行带合并、自适应分页、模糊短语定位与内容寻址缓存,这一协议实现了"档案图极致压缩、放大成本按需支付"的工程闭环——这也是 oh-my-pi 为视觉上下文压缩寻找最优帧几何时,被实际采用的实验方法论。

【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询