Garwin AI Projects Project Overview
Multimodal RAG / LangChain

Toyota Camry 车主手册 RAG V2

在 V1 纯文本 RAG 基础上重构的多模态版本。V2 使用 LangChain 统一 Document、VectorStore 与 Retriever, 保留原有的跨语言文本检索与 Reranker,同时从 PDF 中提取手册图片并与 Chunk 建立关联。 最终由 Qwen-VL 同时读取 Rerank 后的文本与候选图片,并在确有帮助时把正确示意图展示在回答中。

Python FastAPI LangChain langchain-chroma Chroma Qwen Embedding Qwen Reranker Qwen-VL Multimodal RAG PyMuPDF SQLite Nginx

从 V1 到 V2

V1 的核心能力是“中文问题 → 英文手册向量检索 → Reranker → 中文回答”, 但手册中大量信息依赖示意图,例如拖车钩位置、轮毂螺母拧紧顺序、仪表盘图标和操作部件位置。 V2 在保留稳定文本检索链路的基础上,让最终生成模型能够读取与命中 Chunk 对应的手册图片。

能力V1V2
检索框架直接调用 ChromaLangChain VectorStore / Retriever
知识输入纯文本 Chunk文本 Chunk + 对应手册图片
最终模型文本 LLMQwen-VL 多模态模型
图片展示不支持生成阶段识图LLM 判断是否需要展示,并选择相关图片
历史会话共用 SQLite chat.db,可同时显示文字与 V2 图片回答

多模态文档构建

文本继续沿用 V1 已验证过的句子级 Chunking。新增图片处理后,PDF 中的图片通过 PyMuPDF 独立提取, 再根据 PDF 页码与 Chunk 建立关联。图片本身不写入文本向量,只将 image_ids 保存在 Chunk metadata 中。

{
  "chunk_id": 430,
  "start_page": 255,
  "end_page": 256,
  "word_count": 180,
  "text": "...",
  "image_ids": [
    "page_255_img_01",
    "page_255_img_02",
    "page_256_img_01"
  ]
}

当前版本属于 Text-led Multimodal RAG:文本负责“找到正确页面”, Qwen-VL 负责“理解页面中的图片”。因此暂时不需要为整套图片单独建立视觉向量库。

LangChain 重构

V2 将原来手写的 Embedding、Chroma Query 和结果整理流程,改写为 LangChain 的标准抽象。 每个 Chunk 转换为 Document,正文放在 page_content, 页码、Chunk ID 和图片 ID 保存在 metadata。

chunks_multimodal.json
        ↓
LangChain Document
        ↓
Qwen Text Embedding
        ↓
langchain_chroma.Chroma
        ↓
VectorStore.as_retriever()
        ↓
List[Document]

Chroma 通过 persist_directory 持久化到服务器本地,因此部署时可以直接加载已经生成好的向量库, 无需重新处理整本手册。

V2 Retrieval & Generation Pipeline

Question
   ↓
Qwen Text Embedding
   ↓
LangChain Chroma Retriever
   ↓
Vector Top 20
   ↓
Qwen Text Reranker
   ↓
Top 5 Documents
   ↓
读取 Top 5 的 image_ids
   ↓
图片去重
   ↓
Top 5 Text + Candidate Images
   ↓
Qwen-VL
   ↓
Chinese Answer + PDF Citation
   ↓
可选:展示相关手册图片

Vector Retrieval 仍以召回率为优先,先获得较大的候选集,再通过 Reranker 提高最终上下文精度。 图片只在 Rerank 完成后收集,避免把 Vector Top 20 对应的大量无关图片全部发送给视觉模型。

图片选择与安全映射

候选图片不会直接以真实文件名暴露给模型。系统会为每次请求建立临时别名:

IMG_1 → page_226_img_03
IMG_2 → page_229_img_02
IMG_3 → page_230_img_01

Qwen-VL 只使用类似 [[SHOW_IMAGES:IMG_1]] 的控制标记选择图片, 后端再将临时编号映射回真实文件并生成前端图片 HTML。 这样可以减少模型把内部图片文件名直接写进正文的问题。

如果纯文字已经足够回答,则返回 SHOW_IMAGES:none; 对位置、顺序、图标外观或操作动作有明显帮助时,才展示手册示意图。

多模态问答场景

性能与 Token 统计

V2 保留 Retrieval、Rerank 和 Generation 的耗时与 Token 统计,并增加候选图片数量, 用于观察视觉输入带来的额外成本。

[RAG]
vector_candidates=20
rerank_docs=5
candidate_images=18
retrieval=0.547s
rerank=0.729s
rerank_tokens=5930

[LLM]
input_tokens=3374
output_tokens=259
total_tokens=3633
generation=4.192s

与 V1 相比,Reranker 成本基本保持一致,新增消耗主要来自 Qwen-VL 的视觉输入。 多张低分辨率手册线稿不会让 Token 数量失控,但候选图片过多仍可能影响模型选图稳定性, 因此图片筛选数量仍是后续可优化方向。

流式输出与会话系统

部署

camry-v1.garwin.duckdns.org
        ↓
      Nginx
        ↓
127.0.0.1:8001
        ↓
V1 Text RAG


camry-v2.garwin.duckdns.org
        ↓
      Nginx
        ↓
127.0.0.1:8003
        ↓
V2 Multimodal LangChain RAG

        ↓
共享 SQLite chat.db

两个版本同时部署在 Linux 云服务器,由 systemd 保持 FastAPI 服务常驻, Nginx 负责 HTTPS、统一认证和反向代理。V1 与 V2 使用独立服务端口,但共用历史会话数据库。

为什么当前没有单独建立图片向量库

当前主要问题仍可以由文本 Retriever 先定位到正确页面,再把对应图片交给 Qwen-VL 判断。 这样既保留 V1 已验证过的文本检索质量,又能以较小改动增加多模态能力。

如果后续加入“用户上传仪表盘照片 → 在手册图库中寻找相似图标”这类需求, 再增加视觉 Embedding 与图片向量库会更有价值。

项目总结

V2 的重点不是简单“把项目改成 LangChain”,而是用 LangChain 统一 Document、VectorStore 和 Retriever, 同时保留已经验证有效的 Qwen Embedding 与 Reranker。 在此基础上,项目增加 PDF 图片抽取、Chunk-Image 关联、Qwen-VL 多模态生成、 模型选图与前端图片展示,将 V1 的纯文本 RAG 扩展成可处理图文手册的多模态 RAG。