Homestead
Blog260905 · LlamaIndex 数据架构

从 RAG 应用浅析 LlamaIndex 架构

这篇文章基于一个 PostgreSQL + pgvector 的 RAG demo:6 条中文电影资料先被包装成 Document,再转换成 TextNode,由 VectorStoreIndex 生成 embedding,并通过 StorageContext 写入 PGVectorStore。查询时,QueryEngine 复用同一套索引,把 Top-K 电影节点交给 DeepSeek 生成推荐理由。

发表时间:2026.09.05 阅读时长:约 10 分钟 RAG / PostgreSQL + pgvector / LlamaIndex
01 / architecture

LlamaIndex 不是一个“向量数据库”,而是 RAG 的数据编排层

在这个 demo 里,LlamaIndex 做的事情可以分成两层:上层把业务资料变成统一的数据对象,下层把对象连接到 embedding 模型、向量存储和 LLM。PostgreSQL + pgvector 负责存储和相似度搜索,DeepSeek 负责生成自然语言答案,LlamaIndex 负责把它们串成一条可靠的数据流水线。

原始电影资料不是直接交给 LLM,而是先被转换成 Document,再加工成 TextNode。VectorStoreIndex 负责触发 embedding 生成,StorageContext 负责把索引过程连接到 PGVectorStore,最终落到 PostgreSQL + pgvector。

用户提问时,QueryEngine 把问题向量化,用 pgvector 找到最接近的 TextNode,再把这些上下文交给 LLM 生成回答。

LLM 在这里不是“查库的人”,它更像“读材料并组织语言的人”。真正缩小信息范围的是 embedding 检索阶段。
ingest
movies.json->Document->TextNode->embedding
index
VectorStoreIndex->StorageContext->PGVectorStore
storage
PostgreSQL+pgvector->data_movie_rag
query
QueryEngine->Top-K TextNodes->DeepSeek answer
02 / objects

六个概念不是并列名词,而是一条接力路线

把它们放回 demo 的运行顺序里,概念会清楚很多:Document 是输入形态,TextNode 是检索颗粒度,VectorStoreIndex 是索引执行者,StorageContext 是存储接线,PGVectorStore 是 PostgreSQL 适配器,QueryEngine 是面向问题的入口。

输入对象 Document

电影 JSON 被包装成 text + metadata。它保留业务语义,是资料进入 LlamaIndex 的入口。

检索颗粒 TextNode

Document 被转换成节点,获得 node_id。embedding、召回和上下文引用都围绕它发生。

索引执行 VectorStoreIndex

写入时生成节点向量;查询时从已有 vector store 恢复成可检索索引视图。

存储接线 StorageContext

把索引过程连接到指定后端,告诉 LlamaIndex 节点、元数据和向量要写到哪里。

向量存储 PGVectorStore

把 LlamaIndex 节点落到 PostgreSQL + pgvector,形成 data_movie_rag 表。

查询入口 QueryEngine

接收用户问题,检索 Top-K TextNode,再把上下文交给 DeepSeek 生成答案。

03 / ingestion

写入链路:把 6 部电影变成 6 条可检索节点

ingestion 阶段的目标不是“回答”,而是“准备可被回答的知识”。demo 中 6 条中文电影资料会被整理成 Document,再转换成 TextNode,每个节点生成一个 512 维 embedding,最终写入 PostgreSQL。

业务资料
movies.json电影名、类型、关键词、简介
拼接文本让检索看到完整语义
metadata保留 title / genre
6 部电影火星救援、星际穿越等
LlamaIndex
Document统一输入容器
TextNode检索和引用单位
VectorStoreIndex创建索引并批量插入
StorageContext绑定存储后端
存储与模型
HuggingFacebge-small-zh-v1.5
PGVectorStorePostgreSQL 适配器
pgvectorvector(512) 相似度计算
data_movie_rag6 行节点记录
Document(
  text="""
电影名:火星救援
类型:科幻
关键词:火星, 宇航员, 科学求生, 工程, 救援
简介:一名宇航员被困火星,依靠植物学、
工程能力和团队救援计划努力生存。
""",
  metadata={
    "title": "火星救援",
    "genre": "科幻"
  }
)
vector_store = PGVectorStore.from_params(
  database=settings.db_name,
  host=settings.db_host,
  port=settings.db_port,
  user=settings.db_user,
  password=settings.db_password,
  table_name=settings.pgvector_table,
  embed_dim=512
)

storage_context = StorageContext.from_defaults(
  vector_store=vector_store
)

VectorStoreIndex.from_documents(
  documents,
  storage_context=storage_context,
  show_progress=True
)
04 / query

查询链路:QueryEngine 把“问题”变成“有证据的回答”

查询阶段不会重新写入 6 部电影,而是连接已有 PGVectorStore。VectorStoreIndex.from_vector_store(...) 创建的是一个查询视图;index.as_query_engine(similarity_top_k=3) 才是面向用户问题的接口。

当用户问“太空科幻、宇航员、火星或星际旅行”时,QueryEngine 会先把问题送进同一个 embedding 模型,生成 query vector。接着,PGVectorStore 让 PostgreSQL 在 data_movie_rag.embedding 上执行相似度检索,返回最接近的 3 个 TextNode。

这里有一个很重要的边界:pgvector 返回的是相关节点,DeepSeek 负责把这些节点组织成自然语言推荐理由。也就是说,LLM 的工作不是遍历数据库,而是基于检索出的上下文做表达。

index = VectorStoreIndex.from_vector_store(
  vector_store=vector_store
)

query_engine = index.as_query_engine(
  similarity_top_k=3
)

response = query_engine.query(
  "我想看太空科幻电影,最好有宇航员、火星或星际旅行"
)
Top 1

火星救援

直接命中“火星”“宇航员”“科学求生”“救援”等核心语义,是最贴近问题的节点。

Top 2

星际穿越

命中“星际旅行”“宇航员”“虫洞”“黑洞”等空间探索语义,与问题意图高度相关。

Top 3

流浪地球

属于太空科幻和人类未来主题,相关性成立,但比前两部少了火星或宇航员的直接匹配。

05 / storage

从数据库看,RAG 不是神秘对象,而是一张可检查的表

demo 的 PostgreSQL 容器由 pgvector/pgvector:pg16 镜像启动,数据库启用 vector extension。校验脚本能看到 vector 0.8.6,并通过 <-> 运算符完成一次向量距离测试。

字段或对象 来自哪里 在 RAG 中的意义
textTextNode.textLLM 最终读取和引用的上下文内容。embedding 本身不能解释电影,文本才是答案材料。
metadata_Document.metadata 传递到 TextNode记录 title、genre、document_id、ref_doc_id 等信息,方便展示来源、过滤和后续治理。
node_idLlamaIndex 创建的节点标识让系统能追踪每个检索颗粒,支持更新、删除、引用、去重等工程操作。
embeddingHuggingFace embedding 模型512 维语义向量,pgvector 用它计算问题和节点之间的距离。
PGVectorStoreLlamaIndex vector store integration把 LlamaIndex 的节点写入 PostgreSQL,也把相似度检索结果转回 LlamaIndex 可用的节点。
06 / principles

真正值得带走的是组件边界

这个 demo 小到只有 6 部电影,但它展示的是可以扩展到真实系统的分工:数据对象、索引、存储、检索和生成各管一段,彼此通过清晰接口连接。

Document 让资料进入系统,TextNode 决定检索颗粒度,VectorStoreIndex 发起索引构建,StorageContext 决定写到哪里,PGVectorStore 把向量落进 PostgreSQL,QueryEngine 把问题变成有上下文的回答。

  • 不要把 RAG 简化成 prompt。 prompt 之前,还有资料整理、节点切分、向量化、落库和检索。
  • embedding 找相似,LLM 讲清楚。 这两个职责分开,答案才更可控。
  • StorageContext 是可替换性的来源。 换成别的 vector store 时,索引逻辑不必整篇重写。
  • metadata 是生产系统的治理入口。 权限、来源、业务域、时间范围,通常都要靠 metadata 过滤。
  • Top-K 是检索质量旋钮。 demo 用 3 让结果容易观察;真实项目需要结合噪声、上下文长度和答案质量调参。
一句话总结

这是一个面向学习的 RAG demo:用 Docker 启动 PostgreSQL + pgvector,用 HuggingFace embedding 把中文电影文本转成向量,用 LlamaIndex 编排 ingestion 和 query 流程,最后让 DeepSeek 基于检索结果生成中文电影推荐理由。