让 RAG 看见网页截图
PixelRAG 的思路很直接:别急着把网页解析成纯文本,先把人眼看到的页面截图保存下来,再用视觉模型做检索。
现在做网页 RAG,很多人默认会走一条路:抓 HTML,转 Markdown,切 chunk,做 embedding,再塞进向量库。
这条路看起来标准,问题也藏在这里。
网页不是一串干净文本。表格、图表、卡片布局、脚注、侧栏、按钮状态、论文里的公式截图,很多信息是靠视觉结构表达的。 HTML 解析器一处理,这些东西很容易被压平、丢掉,或者变成一堆顺序错乱的文字。
PixelRAG 的做法很粗暴,也很有意思:不先把网页拆成文本,而是把网页、 PDF 、图片渲染成截图,再对截图做检索。检索到相关图块后,让视觉语言模型直接读像素。
简单说,它让 RAG 从“读解析器整理过的文本”,变成“看人眼真正看到的页面”。
![]()
它解决的不是小问题
传统文本 RAG 最怕的,不只是召回不到内容,还有“召回到一段看似相关、其实缺上下文的内容”。
比如一个网页里有表格。 HTML 转文本后,行列关系可能乱了。模型看到的是几个数字和字段,却不知道哪个数字属于哪一列。
再比如论文 PDF 。正文、图注、表格、公式、脚注,本来靠版式区分。转成纯文本以后,结构经常混在一起。
PixelRAG 把文档渲染成截图图块。表格还像表格,图表还像图表,布局也还在。视觉模型拿到的是一个更接近真实页面的输入。
这也是它和普通网页抓取工具最大的区别:PixelRAG 不追求把页面“清洗成文本”,而是把页面的可见形态当成检索对象。
PixelRAG 怎么跑
项目 README 里给了两个核心动作:渲染页面,搜索视觉索引。
先安装:
pip install pixelrag
把任意网页或文档渲染成截图图块:
pixelshot https://en.wikipedia.org/wiki/Python --output ./tiles
直接搜索官方托管的 Wikipedia 视觉索引:
curl -X POST https://api.pixelrag.ai/search \
-H "Content-Type: application/json" \
-d '{"queries": [{"text": "What is the capital of France?"}], "n_docs": 5}'
README 里说明,https://api.pixelrag.ai 提供一个预构建的 Wikipedia 索引,覆盖 828 万篇页面,不需要 API key 。 X 上的介绍还提到,团队构建过 3000 万级网页截图索引,并在文本问答任务上超过强文本 RAG baseline 18.1% 。
这个数字可以先当作项目方给出的实验信号。更适合动手验证的部分,是它提供了一套完整开源链路:渲染、切图、 embedding 、 FAISS 索引、搜索 API 。
![]()
一条完整链路长这样
PixelRAG 的流程可以拆成几步:
- 把网页、 PDF 、图片渲染成图片 tiles 。
- 用 Qwen3-VL-Embedding 生成图像向量。
- 构建 FAISS 索引。
- 查询时检索相关截图。
- 让视觉语言模型直接读截图里的答案。
它的一个好处是,读模型可以替换,索引不用重建。因为索引里存的是“页面长什么样”的向量,后面换更强的视觉语言模型,理论上可以直接提升回答质量。
如果想搭自己的索引,README 给了这个配置例子:
pip install 'pixelrag[index]'
cat > pixelrag.yaml << 'EOF'
source:
type: local
path: ./my_docs
embed:
model: Qwen/Qwen3-VL-Embedding-2B
device: cuda
gpu_ids: [0]
output: ./my_index
EOF
pixelrag index build
pixelrag serve --index-dir ./my_index --port 30001
然后查询本地服务:
curl -X POST http://localhost:30001/search \
-H "Content-Type: application/json" \
-d '{"queries": [{"text": "What is the capital of France?"}], "n_docs": 5}'
这不是一个轻量小玩具。要跑大规模索引,图片存储、 GPU embedding 、 FAISS 索引体积都会带来成本。 README 里提到,预构建的 base Wikipedia pixel index 大约 217G 。个人开发者更适合先用托管 API 或小文档集试验。
![]()
Claude Code 也能用
这个项目还带了一个 Claude Code 插件,叫 pixelbrowse 。
它的用途很明确:让 Claude 不只是抓 DOM 或读 HTML,而是先给页面截图,再基于截图理解页面。
安装命令:
pip install pixelrag
claude plugin marketplace add StarTrail-org/PixelRAG
claude plugin install pixelbrowse@pixelrag-plugins
之后可以直接让 Claude 看页面:
claude -p "screenshot https://news.ycombinator.com and summarize the top stories"
claude -p "screenshot https://arxiv.org/abs/2404.12387 and explain the key findings"
交互模式里也可以用:
/screenshot https://example.com
这个功能对调试网页、读论文页面、看 dashboard 、看本地开发页面都很实用。很多时候,网页真正的问题不在 DOM 文本里,而在页面渲染之后的样子里。
![]()
另一条线索:chunk 本身也有问题
第二条 X 长文讲的是另一个 RAG 问题:很多系统把“文本 chunk”当成知识单元,但 chunk 只是为了处理 token 限制做出来的切片。
它不知道一条观点从哪里开始、在哪里结束,也不知道这个段落来自哪个版本,谁有权限看。
所以企业知识库里经常出现这种情况:同一个事实在 SharePoint 、 Confluence 、 Git 里有十几个近似版本。 Top-K 检索拿回来五段相似内容,旧版本和新版本混在一起,模型再把它们合成一个自信但错误的答案。
长文提到的方案是把知识单元改成 question-answer packet,或者叫 IdeaBlock:一个问题、一个验证过的答案,再加上版本、权限、来源等结构化字段。
它给出的内部 benchmark 里,IdeaBlock 相比普通 chunk,让 query 到最佳匹配块的平均 cosine distance 从 0.3624 降到 0.1585;经过去重后,2042 个 raw IdeaBlocks 合并成 1200 个 canonical IdeaBlocks,词数从 88877 降到 44537,vector accuracy 提升 13.55% 。这些是项目方口径,不能直接当成通用结论,但方向值得参考。
这和 PixelRAG 放在一起看,会得到一个很清楚的判断:RAG 的问题不一定在最后的 LLM,也不一定靠换 embedding model 解决。很多错误发生在更前面。
网页被错误解析,后面再强也只能读残缺文本。
知识被随便切 chunk,后面再强也只能在碎片里猜。
适合谁试
PixelRAG 更适合这些场景:
- 网页里有大量表格、图表、卡片布局。
- PDF 和论文页面里的结构比纯文本更重要。
- 需要让 Agent 看实际页面,比如调试前端、读 dashboard 、检查本地网站。
- 普通 HTML-to-text 经常把页面转坏。
不太适合这些场景:
- 全部资料都是干净 Markdown 或纯文本。
- 没有 GPU,也不想承担图片索引成本。
- 只想做一个小型 FAQ,普通文本 RAG 已经够用。
可以先从最轻的方式试:安装 pixelrag,用 pixelshot 给几个页面截图,再用官方托管 API 看检索结果。如果只是给 Claude Code 加“眼睛”,插件路线更快。
源地址:
https://github.com/StarTrail-org/PixelRAG
这类项目给人的启发很直接:RAG 不只是“把文本喂给向量库”。输入长什么样,知识单元怎么定义,往往决定了后面能不能答对。