LlamaIndex 面试八股文 100 题:核心概念到生产实践

Cosolar 89 阅读 面试求职

面向大厂 AI / 大模型 / RAG 工程师岗位,覆盖 LlamaIndex 核心概念、组件原理、源码机制、生产实践,配套 Python 代码示例、对比表格与速记清单。

信息来源:LlamaIndex 官方文档(v0.10+/v0.12+/v0.13+)、CSDN/掘金/腾讯云开发者社区面经、daily.dev 招聘指南、RAGAs / DeepEval 官方文档、知乎/今日头条高频问答等。

标注说明:⭐ 为高频必考,🔥 为加分项/趋势题;🔥 大厂JD重点 为大厂 JD 明确要求的技能点。


一、基础概念(Q1 - Q8)

Q1. ⭐ 什么是 LlamaIndex?它的核心定位和"口号"是什么?

难度:入门

参考答案:

LlamaIndex(早期名 GPT Index)是一个面向上下文增强 LLM 应用(Context-Augmented LLM Applications)的数据框架。它把"私有/领域数据"和"大模型"之间的桥搭起来,本质是专门为 RAG 场景设计的数据层。

  • 官方口号:“为你的数据提供 LLM 接口”(A data framework for your LLM application)
  • 核心价值:
    1. 简化数据接入:支持 100+ 数据源(PDF、Word、Markdown、Notion、Slack、数据库、API 等)
    2. 多索引策略:向量索引、列表索引、树索引、关键字索引、属性图索引,按数据特点选型
    3. 高级检索:混合检索、重排序、递归检索、自动合并检索等开箱即用
    4. Agent 工具化:可把 Query Engine 包装成 Tool 接入 Agent / Workflow
  • 解决痛点:大模型不知道企业私域知识。RAG(检索增强生成)是性价比最高的解决方案——不重训模型,而是把相关上下文动态喂给 LLM。

来源:LlamaIndex 官方文档 https://docs.llamaindex.ai ;《面试题:LlamaIndex 全栈解析》http://m.toutiao.com/group/7641169856452166153/


Q2. ⭐ LlamaIndex 和 LangChain 有什么区别?真实项目里怎么选?

难度:入门

参考答案:

特性 LlamaIndex LangChain
焦点 数据连接与检索(RAG 专家) 应用编排与 Agent(通用框架)
核心功能 数据索引、高级查询、结构化数据提取 Chain、Agent、Tool、Memory 管理
设计哲学 提供开箱即用的数据管道,封装度高 提供高度灵活、可组合的底层组件
学习曲线 简单,3 行代码可起 RAG 较陡,抽象层多
关系 可作为 LangChain 的一个组件(LlamaIndexRetriever) 包含并集成多种检索方式
生态 LlamaHub(Reader 库)、LlamaParse(高级文档解析) LangSmith(追踪)、LangServe(部署)

选型建议:

  • 纯 RAG 知识库问答 → LlamaIndex 优先,检索组件更专业
  • 复杂多步 Agent、Tool 编排、工作流 → LangChain 优先
  • 真实生产里经常组合使用:LlamaIndex 做数据/检索,LangGraph 做流程/状态

来源:《AI 大模型面试题解析之 LangChain & LlamaIndex》https://blog.csdn.net/m0_59614665/article/details/152085484


Q3. ⭐ LlamaIndex 的核心组件有哪些?Data Framework 包含哪几层?

难度:入门

参考答案:

LlamaIndex 体系自下而上分为 5 层:

  1. Data Connectors(Reader/Loader):把 PDF/Word/Notion/DB 等异构数据读入为 Document 对象
  2. Data Indexes(Index):把 Document 切成 Node,再按选定策略构建索引结构(向量/列表/树/图)
  3. Query Engines / Chat Engines:对外提供查询接口,返回自然语言答案
  4. Agents / Workflows:把 Query Engine 包装成 Tool,让 LLM 自动决策调用
  5. Observability / Evaluators:回调埋点、Token 统计、检索/生成质量评估

核心数据对象:

  • Document:原始文档对象,含 text 和 metadata
  • Node:从 Document 切出的可检索单元,最小知识块
  • NodeWithScore:Node + 相似度得分(检索器返回类型)
  • QueryBundle:封装查询字符串及其转换

来源:LlamaIndex 官方文档;CSDN《深入理解三大核心组件》https://blog.csdn.net/xiangxi1204/article/details/154834658


Q4. ⭐ Document 和 Node 的区别是什么?

难度:入门

参考答案:

from llama_index.core import Document
from llama_index.core.node_parser import SentenceSplitter

# Document: 原始文档对象
doc = Document(
    text="LlamaIndex 是一个 RAG 框架...",
    metadata={"file_name": "intro.md", "category": "tech"}
)

# Node: 从 Document 切出的可检索单元
splitter = SentenceSplitter(chunk_size=512, chunk_overlap=50)
nodes = splitter.get_nodes_from_documents([doc])
for n in nodes:
    print(n.text, n.metadata, n.node_id)

关键区别:

维度 Document Node
定位 承载原始数据 进入索引和检索的最小单元
来源 Reader 读取直接得到 Document 切分后产生
元数据 含来源、文件名、页码等 继承 Document 元数据 + 节点 id、位置
关系 一对多 Document 可建立 Parent-Child/Prev-Next 关系

面试快答:Document 负责承载原始数据,Node 负责进入索引和检索。

来源:今日头条《LlamaIndex 全栈解析》http://m.toutiao.com/group/7641169856452166153/


Q5. ⭐ Retriever 和 Query Engine 的区别是什么?

难度:入门

参考答案:

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(documents)

# Retriever: 只负责找资料,返回 NodeWithScore 列表
retriever = index.as_retriever(similarity_top_k=3)
nodes = retriever.retrieve("什么是 RAG?")
for n in nodes:
    print(f"score={n.score:.3f} | {n.node.text[:80]}")

# Query Engine: 完整问答引擎,找资料+重排+生成
query_engine = index.as_query_engine(similarity_top_k=3)
response = query_engine.query("什么是 RAG?")
print(response)
print(response.source_nodes)  # 溯源节点

核心区别:

  • Retriever:检索器(I/O),输入 query,输出 List[NodeWithScore]
  • Query Engine:完整问答引擎(Pipeline),输入 query,输出 Response 对象(含答案 + source_nodes)

Query Engine 内部组成:Retriever + Node Postprocessor + Response Synthesizer。

来源:腾讯云《LlamaIndex RAG 系统工作流程详解》https://cloud.tencent.com/developer/article/2629911


Q6. ⭐ LlamaIndex 安装和包结构是怎样的?v0.10+ 有什么重要变更?

难度:入门

参考答案:

# v0.10+ 拆分式安装
pip install llama-index-core               # 核心
pip install llama-index-llms-openai        # OpenAI LLM
pip install llama-index-embeddings-openai  # OpenAI Embedding
pip install llama-index-vector-stores-chroma  # 向量库
pip install llama-index-readers-file       # 文件 Reader
# 一键全装
pip install llama-index[all]

v0.10+ 重大变更(2024年发布):

  1. 拆包:核心(llama-index-core)与各类集成(llama-index-llms-*、llama-index-vector-stores-* 等)独立
  2. ServiceContext 弃用 → 改用全局 Settings
  3. AgentRunner/AgentWorker 弃用 → 改用 AgentWorkflow + Workflows(事件驱动)
  4. GPTSimpleVectorIndex 改名 → VectorStoreIndex
  5. 提供 legacy 兼容包:from llama_index.legacy import ... 兜底
  6. CLI 工具:llamaindex-cli upgrade-file <file_path> 自动迁移

v0.12+/v0.13+ 进一步变化:

  • Settings 全面替代 ServiceContext,移除 service_context= 参数
  • 强化 Workflows(事件驱动,支持 Human-in-the-Loop 暂停恢复)
  • LCEL 兼容,RouterQueryEngine 成为标准

来源:LlamaIndex 官方迁移文档 https://developers.llamaindex.ai/python/framework/changes/deprecated_terms/


Q7. LlamaIndex 适合哪些场景?哪些场景不推荐?

难度:入门

参考答案:

✅ 适合:

  • 企业知识库 / 制度问答 / 客服机器人
  • 文档检索(合同、产品手册、技术白皮书)
  • 多模态 RAG(图搜图、PDF 图表理解)
  • Graph RAG(实体关系推理:金融风控、医疗、法律)
  • Agent 工具化(把不同知识库包装成 Tool 让 Agent 选择)

❌ 不推荐:

  • 纯聊天 / 闲聊场景(用 LLM 本身即可)
  • 高频写入、低频查询的 OLTP 系统
  • 强事务、强一致性的业务(向量库不是事务型存储)
  • 数据量极小(< 10 文档)——索引开销大于收益

经验法则:70% 的工作应该是数据质量(清洗、切片、metadata),而不是框架本身。框架只是工具,瓶颈在数据。

来源:daily.dev Hiring Guide https://recruiter.daily.dev/stacks/llamaindex/


Q8. LlamaIndex 最新版本(v0.12+/v0.13+)引入了哪些新特性?

难度:中级

参考答案:

核心新特性:

  1. Workflows 1.0 正式版(2025年6月发布):事件驱动框架,支持异步/并发/Human-in-the-Loop
  2. AgentWorkflow:基于 Workflows 的多 Agent 协作框架,支持 handoff
  3. PropertyGraphIndex 成熟化:替代旧的 KnowledgeGraphIndex,成为图索引首选
  4. 增强的多模态:LlamaParse + Multi-Modal Index 一键启用图文混合检索
  5. OpenTelemetry 原生支持:可观测性大幅提升
  6. Workflows 状态持久化:支持暂停-恢复,适合长任务/异步人工审批

废弃清单(必记):

  • ServiceContext → Settings
  • AgentRunner / AgentWorker → AgentWorkflow
  • QueryPipeline → Workflows
  • GPTSimpleVectorIndex → VectorStoreIndex
  • LLMPredictor → 直接用 LLM 类
  • PromptHelper → 拆分到 Settings

来源:LlamaIndex Breaking Changes https://theneuralbase.com/llamaindex-advanced/learn/beginner/version-upgrade-breaking-changes/


二、数据加载与处理(Q9 - Q18)

Q9. ⭐ LlamaIndex 怎么加载本地文件?SimpleDirectoryReader 的常见用法?

难度:入门

参考答案:

from llama_index.core import SimpleDirectoryReader

# 1. 加载整个目录(自动识别格式)
docs = SimpleDirectoryReader(input_dir="./data").load_data()

# 2. 递归加载子目录
docs = SimpleDirectoryReader(input_dir="./data", recursive=True).load_data()

# 3. 加载指定文件
docs = SimpleDirectoryReader(
    input_files=["a.pdf", "b.docx", "c.md"]
).load_data()

# 4. 限制扩展名 + 文件数
docs = SimpleDirectoryReader(
    input_dir="./data",
    required_exts=[".pdf", ".docx"],
    num_files_limit=100
).load_data()

# 5. 并行加载(Linux/Mac 才有收益)
docs = SimpleDirectoryReader(
    input_dir="./data",
    recursive=True
).load_data(num_workers=4)

默认支持的格式(无需额外依赖):.csv .docx .epub .hwp .ipynb .jpeg/.jpg .mbox .md .mp3/.mp4 .pdf .png .ppt/.pptx 等。

生产坑点:

  • 默认 UTF-8 编码,非 UTF-8 文件需传 encoding="latin-1"
  • 解析失败默认静默跳过,必须用 assert len(docs) == expected 校验
  • 大目录加载完立即设 doc.metadata["source_id"],否则后续需全量重索引

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/module_guides/loading/simpledirectory_reader/


Q10. ⭐ 怎么加载 PDF?PDF Reader 怎么选?

难度:中级

参考答案:

# 方案1: PyPDFReader (轻量,文本型 PDF)
from llama_index.readers.file import PyPDFReader
reader = PyPDFReader()
docs = reader.load_data(file="./paper.pdf")

# 方案2: PyMuPDFReader (速度快,支持扫描件) — 推荐
from llama_index.readers.file import PyMuPDFReader
reader = PyMuPDFReader()
docs = reader.load_data(file="./paper.pdf")

# 方案3: 在 SimpleDirectoryReader 中按需指定
from llama_index.core import SimpleDirectoryReader
from llama_index.readers.file import PDFReader
file_extractor = {".pdf": PDFReader()}
docs = SimpleDirectoryReader(
    "./data", file_extractor=file_extractor
).load_data()

选型建议:

Reader 适用场景 性能 表格识别
PDFReader 普通文本 PDF 中 弱
PyPDFReader 简单 PDF 中 弱
PyMuPDFReader 复杂 PDF / 扫描件 快 中
LlamaParse (云) 高精度生产(图表、公式) 慢但准 强

生产实践:复杂 PDF(年报、研报、技术白皮书)用 LlamaParse 云服务或 MinerU 等专业解析器,普通 PDF 用 PyMuPDFReader 即可。

来源:llama-index-readers-file 0.6.0 https://pypi.org/project/llama-index-readers-file/


Q11. ⭐ 文档切分(Chunking)为什么重要?有哪些策略?

难度:中级

参考答案:

为什么重要:

  • LLM 有上下文窗口限制,必须切块
  • 切片质量直接决定检索精度——块太大含噪声,太小丢上下文
  • 合理 overlap 避免句子割裂

策略对比:

策略 原理 适用场景
TokenTextSplitter 按 token 数切 通用
SentenceSplitter 按句子+token 边界切 最常用,默认推荐
RecursiveCharacterTextSplitter 递归尝试不同分隔符(\n\n→\n→.) 通用(来自 LangChain)
SemanticSplitter 用嵌入相似度在语义变化处切 高质量但慢
MarkdownNodeParser 按 Markdown 标题/层级切 Markdown 文档
CodeNodeParser 按代码函数/类切 代码库
SentenceWindowNodeParser 切句子+保留窗口 Small-to-Big 检索

推荐默认:SentenceSplitter(chunk_size=512, chunk_overlap=50),根据业务评估调整。

来源:CSDN《LlamaIndex 高级使用》https://www.cnblogs.com/shouyin/p/19493867


Q12. ⭐ chunk_size 和 chunk_overlap 怎么设?调优方法是什么?

难度:中级

参考答案:

经验值:

  • chunk_size:通用 512;技术文档 256-512;长文本总结 1024-2048
  • chunk_overlap:通常 10%-20% 的 chunk_size(50-100 tokens)

调优方法(重要):

  1. 建评估集:准备 50-100 个真实问题+人工标注的标准答案
  2. 扫参:从 (256, 25)、(512, 50)、(1024, 100) 起步
  3. 看检索指标:Hit Rate、MRR、NDCG@K
  4. 看生成指标:Faithfulness、Answer Relevancy
  5. 看 Badcase:是召回少、噪声多、还是上下文不全

判断准则:

  • 召回率低 → 加大 chunk_size + overlap,或加元数据
  • 噪声多 → 减小 chunk_size,或加 Rerank
  • 上下文不全 → 改用 Small-to-Big / Auto-Merging

来源:daily.dev Hiring Guide《Questions That Reveal Expertise》https://recruiter.daily.dev/stacks/llamaindex/


Q13. ⭐ SentenceSplitter 和 TokenTextSplitter 怎么选?

难度:中级

参考答案:

from llama_index.core.node_parser import SentenceSplitter, TokenTextSplitter

# 1. SentenceSplitter (推荐): 按句子边界切,再按 token 切
splitter = SentenceSplitter(
    chunk_size=512,
    chunk_overlap=50,
    paragraph_separator="\n\n\n",
    tokenizer=tiktoken.encoding_for_model("gpt-4").encode
)

# 2. TokenTextSplitter: 严格按 token 切,可能切到句子中间
splitter = TokenTextSplitter(
    chunk_size=512,
    chunk_overlap=50,
    separator=" "
)

核心区别:

  • SentenceSplitter:感知句子边界,避免把一个句子切两半
  • TokenTextSplitter:严格按 token 切,速度快但可能破坏语义
  • SentenceSplitter 是 LlamaIndex 默认推荐,对绝大多数场景更友好

坑点:中文场景 tiktoken 不准,建议用 SentenceSplitter 配合自定义分词器,或换 jieba 分句。

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q14. ⭐ Document 的 metadata 怎么设计?为什么重要?

难度:中级

参考答案:

必须设计的 metadata 字段:

doc = Document(
    text=content,
    metadata={
        # 1. 来源追溯
        "source": "合同库",
        "file_name": "服务协议_2024.pdf",
        "file_path": "/data/contracts/...",
        "page": 5,
        # 2. 业务分类
        "category": "服务合同",
        "department": "商务部",
        # 3. 权限控制
        "permission_level": "L2",  # 后续做 metadata filter
        # 4. 时效性
        "created_at": "2024-01-15",
        "effective_date": "2024-02-01",
        "expire_at": "2025-12-31",
        "version": "v2.1",
        # 5. 文档结构
        "heading_path": "第三章 违约责任 > 第二节 违约金",
        # 6. 业务标签
        "tags": ["SLA", "违约金", "高优先级"]
    }
)

为什么重要:

  1. 溯源:可解释性 + 合规审计
  2. 权限过滤:metadata filter 避免越权召回
  3. 时效控制:过期文档自动过滤
  4. 检索增强:用户问"2024年的合同"可以直接用时间字段过滤
  5. 避免重索引:metadata 可以在 indexing 之后修改而不重算 embedding

生产铁律:metadata 必须在 load_data 之后立刻注入,否则要全量重索引。

来源:今日头条《LlamaIndex 全栈解析》http://m.toutiao.com/group/7641169856452166153/


Q15. Transformations(Ingestion Pipeline)是什么?生产中怎么用?

难度:中级

参考答案:

from llama_index.core.ingestion import IngestionPipeline
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core.extractors import (
    TitleExtractor,
    SummaryExtractor,
    QuestionsAnsweredExtractor,
)
from llama_index.core import Settings

# 1. 定义 Pipeline
pipeline = IngestionPipeline(
    transformations=[
        SentenceSplitter(chunk_size=512, chunk_overlap=50),  # 切分
        TitleExtractor(nodes=5),                              # 抽取小标题
        SummaryExtractor(summaries=["self"]),                 # 摘要
        QuestionsAnsweredExtractor(questions=3),              # 抽取假设问题
    ]
)

# 2. 跑 Pipeline
nodes = pipeline.run(documents=documents)

# 3. 带缓存的 Pipeline(生产必备)
pipeline_with_cache = IngestionPipeline(
    transformations=[...],
    cache=True,  # 避免重复跑
)

生产价值:

  • 解耦:切分、metadata 抽取、嵌入、存储各步骤可独立配置
  • 缓存:相同输入不重跑,省 token
  • 可观测:每步都有 callback 埋点
  • 可组合:可以加自定义 TransformComponent

来源:LlamaIndex 官方 Ingestion Pipeline 文档


Q16. LlamaIndex 怎么加载数据库 / API / Notion / Slack 数据?

难度:中级

参考答案:

LlamaIndex 通过 LlamaHub(llama-hub.com)提供 100+ 数据源 Reader,常见的:

数据源 Reader
Notion NotionPageReader
Slack SlackReader
Discord DiscordReader
GitHub GithubRepositoryReader
PostgreSQL DatabaseReader
MongoDB MongoDBReader
Web SimpleWebPageReader、BeautifulSoupWebReader
YouTube YoutubeTranscriptReader
Twitter/X TwitterTweetReader
Gmail GmailReader
# 示例:加载 Notion
from llama_index.readers.notion import NotionPageReader
reader = NotionPageReader(integration_token="...")
docs = reader.load_data(page_ids=["..."])

生产建议:

  • Web 抓取一定要加 User-Agent 头
  • 定期同步任务用 IngestionPipeline + 缓存 避免重复消耗
  • API 类 Reader 做好限流和重试

来源:LlamaHub https://llamahub.ai


Q17. ⭐ 怎么处理复杂文档(PDF 表格、扫描件、多栏)?

难度:高级

参考答案:

核心难点:常规 PDF 解析器把表格打碎、扫描件无文字、栏间错位。

解决方案:

  1. 专业解析器:

    • LlamaParse(LlamaIndex 官方云服务,AI 增强,最推荐)
    • MinerU(开源,PDF/扫描件/公式支持强)
    • Unstructured.io(开源,layout 感知)
  2. OCR:扫描件需先 OCR(pytesseract、PaddleOCR)

  3. 视觉模型兜底:表格用 GPT-4V / Qwen-VL 直接看图

  4. 多模态索引:LlamaParse + Multi-Modal Indexing 一键启用图文混合检索

# LlamaParse 示例
from llama_parse import LlamaParse
parser = LlamaParse(
    api_key="llx-...",
    result_type="markdown",  # 或 "text"
    parsing_instruction="保留表格结构和数学公式"
)
docs = parser.load_data("./complex.pdf")

生产经验:70% RAG 失败是文档解析问题,不是模型问题。

来源:CSDN《Llama-Index 七大企业级落地场景实战》https://blog.csdn.net/fufan_llm/article/details/156057698


Q18. Ingestion Pipeline 的缓存机制怎么用?

难度:中级

参考答案:

from llama_index.core.ingestion import IngestionPipeline, DocstoreStrategy
from llama_index.core.node_parser import SentenceSplitter
from llama_index.core import StorageContext, SimpleDocumentStore

# 1. 初始化带 cache 的 pipeline(默认基于输入 hash)
pipeline = IngestionPipeline(
    transformations=[SentenceSplitter(chunk_size=512)],
    cache=True  # 默认 SimpleCache
)

# 2. 用 docstore 配合去重(生产推荐)
docstore = SimpleDocumentStore()
pipeline = IngestionPipeline(
    transformations=[SentenceSplitter()],
    docstore=docstore,
    docstore_strategy=DocstoreStrategy.UPSERTS,  # 增量更新
)

# 3. 跑一次,后续相同文件跳过
nodes = pipeline.run(documents=docs)
nodes2 = pipeline.run(documents=docs)  # 命中缓存,不重跑

三种 DocstoreStrategy:

  • DUPLICATES_ONLY:跳过重复
  • UPSERTS:增量更新(生产推荐)
  • UPSERTS_AND_DELETE:完全同步(删除源中已不存在的)

生产价值:100 万 PDF 切分可能跑 24 小时,开启缓存后增量更新只跑新文件,几分钟搞定。

来源:LlamaIndex 官方 https://docs.llamaindex.ai


三、核心组件(Q19 - Q30)

Q19. ⭐ Index 是什么?LlamaIndex 支持哪几种索引类型?

难度:入门

参考答案:

Index 是 LlamaIndex 中"组织 Node 让 LLM 高效查询"的数据结构。

官方支持的索引类型:

索引类型 核心思路 适用场景
VectorStoreIndex Node → Embedding → 向量库,相似度检索 最常用,通用 RAG
SummaryIndex(原 ListIndex) Node 顺序链,遍历/汇总 小规模总结、扫描全文
TreeIndex 层级树,从根到叶遍历 长文档摘要
KeywordTableIndex 提取关键词 → 映射 Node 关键词检索
PropertyGraphIndex 知识图谱(实体+关系+属性) 多跳推理、Graph RAG
MultiModalVectorStoreIndex 文本+图像多模态向量库 图文混排
DocumentSummaryIndex 文档级摘要 大规模文档

选型决策树:

  • 默认场景 → VectorStoreIndex
  • 跨文档总结 → SummaryIndex 或 TreeIndex
  • 实体关系强 → PropertyGraphIndex
  • 多模态 → MultiModalVectorStoreIndex
  • 复杂场景 → RouterQueryEngine 组合多索引

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/module_guides/indexing/lpg_index_guide/


Q20. ⭐ VectorStoreIndex 的工作原理是什么?

难度:中级

参考答案:

工作流程:

  1. 构建期:

    • 遍历 Node,通过 embed_model 把每段 text 转成向量(如 1536 维)
    • 把 (Node ID → 向量 → Node metadata) 存到 VectorStore
    • 原始 Node 存到 DocStore
  2. 查询期:

    • 用户 query 用相同 embed_model 转向量
    • 用余弦相似度/点积计算与所有 Node 的匹配度
    • 返回 Top-K 最相似的 Node
# 完整流程
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core.node_parser import SentenceSplitter

# 1. 加载 + 切分
docs = SimpleDirectoryReader("./data").load_data()
nodes = SentenceSplitter(chunk_size=512).get_nodes_from_documents(docs)

# 2. 构建索引(内部调 embed_model)
index = VectorStoreIndex(nodes)

# 3. 查询(内部用向量相似度)
retriever = index.as_retriever(similarity_top_k=3)
results = retriever.retrieve("RAG 的核心思想是什么?")

底层依赖:需要一个 BaseEmbedding(默认 OpenAIEmbedding)和一个 VectorStore(默认内存 SimpleVectorStore)。

生产部署:必须把 SimpleVectorStore 替换为生产级向量库(Chroma/Milvus/Qdrant/Weaviate/Pinecone)。

来源:腾讯云《LlamaIndex RAG 工作流程详解》https://cloud.tencent.com/developer/article/2629911


Q21. ⭐ SummaryIndex(原 ListIndex)什么时候用?怎么工作?

难度:中级

参考答案:

核心思路:把 Node 按顺序链接成 list,查询时默认加载所有 Node 给 LLM。适合"通读全文"类任务。

适用场景:

  • 文档量小(< 100 节点)
  • 总结/摘要/全局理解类问题
  • 不需要精确语义检索
  • 配合 embedding 检索做 keyword filter
from llama_index.core import SummaryIndex
index = SummaryIndex.from_documents(docs)
query_engine = index.as_retriever(retriever_mode="embedding")  # 嵌入检索
# 或
query_engine = index.as_query_engine(response_mode="tree_summarize")

三种检索模式:

  • default:返回所有 Node
  • embedding:embedding 相似度取 top-k
  • llm:用 LLM 迭代筛选

坑点:默认模式把所有 Node 都塞进 prompt,文档一大就爆 token。生产中用 embedding 模式 + tree_summarize。

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q22. ⭐ TreeIndex 是什么?适合什么场景?

难度:中级

参考答案:

TreeIndex 把 Node 构建成一棵层级树(根 → 中间节点 → 叶子)。查询时从根向下遍历。

构造过程:

  1. 叶子节点是原始 Node
  2. 每个父节点是其子节点的 LLM 生成摘要
  3. 一直向上汇总直到根节点

两种查询方式:

  • child_branch_factor=1:从根选 1 个子节点向下(精确但易漏)
  • child_branch_factor=2:从根选 2 个子节点(覆盖面广)
from llama_index.core import TreeIndex
index = TreeIndex.from_documents(docs, num_children=10)
query_engine = index.as_query_engine(child_branch_factor=2)

适用场景:

  • 超长文档(万级以上)
  • 摘要、归纳、概览类问题
  • 不推荐用于精确问答(检索召回率低)

面试要点:TreeIndex 本质是"用 LLM 调用换 token",构建期 1 个 Node 1 次 LLM 调用,慎用。

来源:LlamaIndex 官方文档


Q23. ⭐ PropertyGraphIndex 和 KnowledgeGraphIndex 有什么区别?v0.10+ 怎么迁移?

难度:高级

参考答案:

核心区别:

特性 PropertyGraphIndex(推荐) KnowledgeGraphIndex(已弃用)
数据模型 属性图(节点/边带 KV 属性) 知识图谱(实体-关系-实体三元组)
属性支持 强(节点和边都有) 弱(主要实体和关系)
关系类型 灵活,不强制 严格,需预定义 schema
可扩展性 强 中
抽取器 SimpleLLMPathExtractor、ImplicitPathExtractor SchemaLLMPathExtractor

v0.10+ 迁移要点:

  • 旧 KnowledgeGraphIndex → 新 PropertyGraphIndex
  • 旧 SchemaLLMPathExtractor(possible_relations=[...]) → 新 SimpleLLMPathExtractor(allowed_relations=[...])
  • 默认抽取器:SimpleLLMPathExtractor + ImplicitPathExtractor
from llama_index.core import PropertyGraphIndex
from llama_index.core.indices.property_graph import (
    SimpleLLMPathExtractor, ImplicitPathExtractor
)

index = PropertyGraphIndex.from_documents(
    docs,
    kg_extractors=[
        SimpleLLMPathExtractor(llm=llm, max_paths_per_chunk=10),
        ImplicitPathExtractor()
    ]
)
retriever = index.as_retriever(include_text=True, similarity_top_k=2)

类比:属性图像社交网络(可任意打 tag),知识图谱像族谱(关系类型严格)。

来源:CSDN《属性图索引》https://blog.csdn.net/csdn122345/article/details/155579705


Q24. ⭐ StorageContext 是什么?为什么不能只用一个向量库?

难度:中级

参考答案:

StorageContext 是 LlamaIndex 中管理所有存储组件的"上下文",包含 4 个核心 store:

from llama_index.core import StorageContext
from llama_index.core.vector_stores import SimpleVectorStore
from llama_index.core.storage.docstore import SimpleDocumentStore
from llama_index.core.storage.index_store import SimpleIndexStore
from llama_index.core.graph_stores import SimpleGraphStore

storage_context = StorageContext.from_defaults(
    vector_store=SimpleVectorStore(),       # 向量
    docstore=SimpleDocumentStore(),         # 原始 Node
    index_store=SimpleIndexStore(),         # 索引元数据
    graph_store=SimpleGraphStore(),         # 图结构
)

index = VectorStoreIndex(nodes, storage_context=storage_context)
index.storage_context.persist(persist_dir="./storage")  # 持久化

为什么不能只用一个向量库:

  • 向量库只解决相似度搜索,不存原文 / metadata / 图结构
  • 生产需要权限过滤、增量更新、文档版本、回滚、审计——这都要完整存储
  • 粗暴塞向量库 → 后期无法维护

生产铁律:DocStore 必须持久化原始 Node 文本,否则 response 溯源失效。

来源:今日头条《LlamaIndex 全栈解析》http://m.toutiao.com/group/7641169856452166153/


Q25. ⭐ SentenceWindowNodeParser 是什么?Small-to-Big 检索怎么用?

难度:高级

参考答案:

核心思想:“小索引,大窗口”——用小颗粒(句子级别)做精确检索,输出时自动扩展到大窗口(包含该句子的整个段落),解决"切片小检索准但丢上下文,切片大检索不准但上下文全"的矛盾。

from llama_index.core.node_parser import SentenceWindowNodeParser
from llama_index.core.postprocessor import MetadataReplacementPostProcessor

# 1. 切分(每个 Node 是单个句子,但带 window 上下文)
node_parser = SentenceWindowNodeParser.from_defaults(
    window_size=3,  # 包含前后各3个句子
)
nodes = node_parser.get_nodes_from_documents(docs)

# 2. 建索引
index = VectorStoreIndex(nodes)

# 3. 检索(按句子相似度)
retriever = index.as_retriever(similarity_top_k=5)

# 4. 关键:检索后用 MetadataReplacementPostProcessor 把句子替换为窗口
postproc = MetadataReplacementPostProcessor(
    target_metadata_key="window"
)
query_engine = index.as_query_engine(
    similarity_top_k=5,
    node_postprocessors=[postproc]
)
response = query_engine.query("...")

生产经验:在高精度 RAG 场景(法律、医疗)效果显著优于普通切片。

来源:CSDN《Llama-Index 高级特性》https://blog.csdn.net/Langchain/article/details/157909040


Q26. ⭐ AutoMergingRetriever 是什么?和 SentenceWindow 有什么区别?

难度:高级

参考答案:

AutoMergingRetriever 同样解决"小切片检索准、大切片上下文全"的矛盾,但思路不同:

工作原理:

  1. 把文档切分成层级 Node(小 chunk → 中 chunk → 大 chunk),建立父子关系
  2. 检索时按小 chunk 找
  3. 如果多个子节点命中同一个父节点,自动合并为父节点输出
  4. 否则保持子节点
from llama_index.core.node_parser import HierarchicalNodeParser, get_leaf_nodes
from llama_index.core.retrievers import AutoMergingRetriever

# 1. 层级切分
node_parser = HierarchicalNodeParser.from_defaults(
    chunk_sizes=[2048, 512, 128]  # 父→中→子
)
nodes = node_parser.get_nodes_from_documents(docs)

# 2. 只对叶子节点建索引(细粒度)
index = VectorStoreIndex(get_leaf_nodes(nodes))
index.storage_context.docstore.add_documents(nodes)  # 父节点放 docstore

# 3. 检索(自动合并)
retriever = AutoMergingRetriever(
    index.as_retriever(similarity_top_k=6),
    storage_context=index.storage_context
)

对比 SentenceWindow:

维度 SentenceWindow AutoMerging
切片方式 句子 + 固定窗口 层级 chunk_sizes
输出策略 强制替换为窗口 命中阈值才合并
灵活性 中 高
实现复杂度 简单 较复杂
适用 文档结构均匀 文档结构有章节

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q27. ⭐ Retriever 有哪些类型?怎么选?

难度:中级

参考答案:

主要 Retriever:

Retriever 原理 适用
VectorIndexRetriever 向量相似度 默认
BM25Retriever BM25 关键词统计 关键词精确匹配
KeywordTableSimpleRetriever 关键词表查找 简单关键词
SentenceWindowRetriever 句子级 + 窗口 Small-to-Big
AutoMergingRetriever 层级 chunk 合并 章节结构化文档
MultiVectorRetriever 同文档多向量 一文多角度
RecursiveRetriever 递归检索(小→大) 引用关系
RouterRetriever 路由到不同子检索器 多数据源
# 混合检索:BM25 + 向量 + Rerank
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.retrievers.bm25 import BM25Retriever

vector_retriever = index.as_retriever(similarity_top_k=10)
bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=10)

# 融合(用 QueryFusionRetriever)
from llama_index.core.retrievers import QueryFusionRetriever
fusion_retriever = QueryFusionRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    similarity_top_k=5,
    num_queries=4,  # 自动生成多个 query
    mode="reciprocal_rerank"  # RRF 融合
)

面试要点:实际生产中混合检索 + Rerank 几乎必用,单纯向量检索召回率有上限。

来源:LlamaIndex 官方文档


Q28. ⭐ Node Postprocessor 是什么?常用后处理器有哪些?

难度:中级

参考答案:

Node Postprocessor 在 Retriever 之后、Response Synthesizer 之前对节点做过滤/重排/增强。

常用后处理器:

from llama_index.core.postprocessor import (
    SimilarityPostprocessor,           # 相似度阈值过滤
    KeywordNodePostprocessor,         # 必含/排除关键词
    MetadataReplacementPostProcessor,  # 窗口替换
    SentenceEmbeddingOptimizer,       # 句子级精排
    CohereRerank,                     # Cohere Rerank
    LongContextReorder,               # 长上下文重排
    FixedRecencyPostprocessor,        # 时效性优先
)

# 1. 相似度过滤
postproc = SimilarityPostprocessor(similarity_cutoff=0.7)

# 2. Rerank(强烈推荐)
from llama_index.postprocessor.cohere_rerank import CohereRerank
rerank = CohereRerank(api_key=cohere_api_key, top_n=5)

# 3. BGE Rerank(开源免费)
from llama_index.postprocessor.bge_rerank import BGERerank
bge = BGERerank(top_n=5, model="BAAI/bge-reranker-large")

# 4. 链式:先过滤 + 再 Rerank
query_engine = index.as_query_engine(
    similarity_top_k=10,
    node_postprocessors=[
        SimilarityPostprocessor(similarity_cutoff=0.6),
        bge,
    ]
)

生产经验:Rerank 是性价比最高的优化(10→5 节点,精度大幅提升,成本只增 1 次小模型调用)。

来源:CSDN《Llama-Index 高级特性》https://blog.csdn.net/Langchain/article/details/157909040


Q29. ⭐ 怎么实现 Rerank?BGE Rerank 怎么用?

难度:中级

参考答案:

Rerank(重排序)是用更强的 Cross-Encoder 模型对初检结果精排,二阶段检索的标准做法。

# 1. BGE Rerank(开源、本地、免费)— 推荐生产
from llama_index.postprocessor.bge_rerank import BGERerank
bge = BGERerank(
    model="BAAI/bge-reranker-large",  # 或 bge-reranker-base
    top_n=5
)

# 2. Cohere Rerank(云端、要钱)
from llama_index.postprocessor.cohere_rerank import CohereRerank
cohere = CohereRerank(api_key="...", top_n=5)

# 3. 接入 Query Engine
query_engine = index.as_query_engine(
    similarity_top_k=20,  # 粗筛 20
    node_postprocessors=[bge]  # 精排到 5
)

# 4. 配合元数据过滤
from llama_index.core.postprocessor import MetadataReplacementPostProcessor
sentence_window = MetadataReplacementPostProcessor(target_metadata_key="window")
query_engine = index.as_query_engine(
    node_postprocessors=[bge, sentence_window]
)

Rerank 原理:用 Cross-Encoder 把 (query, doc) 一起编码,比向量相似度(Bi-Encoder)精度高但慢。

性能数据:粗排 20 → Rerank 精排 5,NDCG@10 通常能提升 10-30%。

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q30. ⭐ Hybrid Search(混合检索)怎么实现?有什么坑?

难度:高级

参考答案:

核心思路:向量检索(懂语义)+ 关键词检索(懂字面),融合后 Rerank。专治生僻词、专有名词、数字型号。

# 方案1: QueryFusionRetriever(推荐)
from llama_index.core.retrievers import QueryFusionRetriever
from llama_index.retrievers.bm25 import BM25Retriever

vector_retriever = index.as_retriever(similarity_top_k=10)
bm25_retriever = BM25Retriever.from_defaults(nodes=nodes, similarity_top_k=10)

fusion_retriever = QueryFusionRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    similarity_top_k=5,
    num_queries=4,  # 用 LLM 生成多 query 变体
    mode="reciprocal_rerank",  # RRF 融合算法
    use_async=True
)

# 方案2: 自定义融合(更灵活)
def hybrid_search(query, k=5):
    vector_nodes = vector_retriever.retrieve(query)
    bm25_nodes = bm25_retriever.retrieve(query)
    # RRF 融合
    fused = reciprocal_rerank_fusion([vector_nodes, bm25_nodes])
    return fused[:k]

坑点:

  1. BM25 对中文不友好,需配合 jieba 分词
  2. num_queries=4 会让 LLM 调用 4 次,慎用
  3. alpha 参数(向量权重):生僻词场景调低 alpha,通用场景保持 0.7+
  4. 必须做 Rerank,否则融合效果差

来源:CSDN《Llama-Index 七大企业实战》https://blog.csdn.net/fufan_llm/article/details/156057698


四、QueryEngine 与 ResponseSynthesizer(Q31 - Q40)

Q31. ⭐ QueryEngine 的工作流程是什么?6步走完一遍?

难度:入门

参考答案:

Query Engine 内部 6 步流程:

  1. 问题向量化:用 embed_model 把 query 转成向量
  2. 检索相关 Node:调 Retriever 取 Top-K Node
  3. 后处理:Node Postprocessor 过滤/重排/窗口替换
  4. Prompt 拼接:把 query + Node 文本拼成 LLM prompt
  5. 调 LLM 生成:原始回答
  6. 格式化输出:剔除冗余,返回 Response 对象(含 source_nodes)

手动组装版(看清全流程):

from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core import get_response_synthesizer
from llama_index.core.query_engine import RetrieverQueryEngine

# 1. 检索器
retriever = VectorIndexRetriever(index=index, similarity_top_k=3)

# 2. 合成器
synthesizer = get_response_synthesizer(response_mode="compact")

# 3. 引擎
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=synthesizer
)

关键特性:

  • 端到端封装:用户只调 query(),无需关注中间环节
  • 可扩展性:Retriever、LLM、Response Mode 均可自定义
  • 溯源性:response.source_nodes 可追溯到每个 Node
  • 异常处理:检索为空时 LLM 会自动 fallback 到通用知识(可配置)

来源:腾讯云《LlamaIndex RAG 系统工作流程详解》https://cloud.tencent.com/developer/article/2629911


Q32. ⭐ response_mode 有哪些?compact / refine / tree_summarize 怎么选?

难度:中级

参考答案:

8 种 response_mode 对比:

Mode 原理 LLM 调用 适用场景
compact (默认) 把尽可能多 chunk 塞进同一 prompt 1 次(必要时多轮 refine) 通用首选
refine 第 1 个 chunk 生成初稿,后续 chunk 迭代优化 N 次(每 chunk 1 次) 详细答案、多角度综合
tree_summarize 两两合成,再两两合成,树形汇总 log2(N) 次 长文总结、10+ chunk
simple_summarize 一次性截断拼接所有 chunk 直接生成 1 次 短答案
generation 不用检索结果,直接 LLM 回答 1 次 对比测试
no_text 不调 LLM,只返回 source nodes 0 次 调试检索
accumulate 每 chunk 单独 LLM 一次,返回 List[Response] N 次 保留各节点独立观点
compact_accumulate 合并后 accumulate N 次 整合+独立输出
# 切换 response_mode
qe = index.as_query_engine(response_mode="tree_summarize")
qe = index.as_query_engine(response_mode="refine")
qe = index.as_query_engine(response_mode="compact")

选型黄金法则:

  • 极致细节 → refine
  • 平衡效率 → compact(默认)
  • 长文总结 → tree_summarize
  • 保留观点 → accumulate
  • 调试 → no_text

来源:腾讯云《LlamaIndex RAG 详解》https://cloud.tencent.com/developer/article/2629911


Q33. ⭐ tree_summarize 和 refine 的性能成本差多少?

难度:中级

参考答案:

LLM 调用次数对比(10 个 Node 场景):

Mode LLM 调用 Token 成本 延迟
compact 1-2 次 1x 低
simple_summarize 1 次 1x(但截断风险) 最低
refine 10 次 ~10x 高
tree_summarize ~14 次(3层树) ~14x 最高
accumulate 10 次 ~10x 高

生产经验:

  • 默认 compact:大多数场景够用
  • 复杂多文档综合:tree_summarize 质量高但贵
  • 精确细节:refine,但 token 烧钱
  • 成本敏感:simple_summarize,但答案可能不完整

坑点:tree_summarize 在 10+ Node 上比 simple_summarize 贵 10-35 倍,小数据上反而贵不了多少。

来源:theneuralbase https://theneuralbase.com/llamaindex/learn/intermediate/choosing-the-right-synthesizer-for-your-use-case/


Q34. ⭐ Streaming(流式输出)怎么实现?有什么坑?

难度:中级

参考答案:

# 1. 启用流式(需要 LLM 支持 streaming)
from llama_index.core import VectorStoreIndex
query_engine = index.as_query_engine(
    streaming=True,
    similarity_top_k=3
)

# 2. 调用 query 返回 StreamingResponse
streaming_response = query_engine.query("什么是 RAG?")

# 3. 迭代 token
for text in streaming_response.response_gen:
    print(text, end="", flush=True)

# 4. 完整响应(流结束后可用)
print(streaming_response.get_response())

# 5. 或直接 print
streaming_response.print_response_stream()

坑点:

  1. 必须 LLM 支持:OpenAI / HuggingFace / LangChain LLM 支持;不支持的 LLM 会 raise NotImplementedError
  2. 多次 LLM 调用只流最后一段:refine 模式下只有最后一轮 stream
  3. 同步 vs 异步:生产推荐 await query_engine.aquery(...)
  4. SSE 推送到前端:FastAPI 配合 StreamingResponse

生产价值:用户感知延迟降低 2-3x,体感"秒回"。

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/module_guides/deploying/query_engine/streaming/


Q35. ⭐ 如何让 LLM 输出结构化结果(Pydantic / JSON)?

难度:中级

参考答案:

from pydantic import BaseModel, Field
from typing import List
from llama_index.core import get_response_synthesizer
from llama_index.core.query_engine import RetrieverQueryEngine

class PhoneInfo(BaseModel):
    name: str = Field(description="手机型号")
    description: str = Field(description="型号描述")
    features: List[str] = Field(description="主要功能")

# 方案1: 通过 output_cls
synthesizer = get_response_synthesizer(
    response_mode="tree_summarize",
    output_cls=PhoneInfo
)
query_engine = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=synthesizer
)
response = query_engine.query("介绍 iPhone 16 Pro")
# response 是结构化对象
print(response.name, response.features)

# 方案2: 通过 Pydantic 风格的 program
from llama_index.core.program import LLMTextCompletionProgram
prompt = """
根据上下文信息提取手机参数:
{context}
"""
program = LLMTextCompletionProgram.from_defaults(
    output_cls=PhoneInfo,
    prompt_template_str=prompt,
    llm=llm
)
result = program(context=context_str)

生产坑点:

  • 结构化输出会增加 LLM 调用次数
  • Pydantic schema 字段名要清晰,描述要具体
  • 配合 structured_answer_filtering=True 过滤无关节点

来源:CSDN《LlamaIndex ResponseSynthesizer》https://blog.csdn.net


Q36. ⭐ QueryEngine 的 as_query_engine() 常用参数有哪些?

难度:入门

参考答案:

query_engine = index.as_query_engine(
    # 检索参数
    similarity_top_k=3,                # 向量检索返回 top-k
    vector_store_query_mode="default",  # default / sparse / hybrid
    alpha=0.7,                          # hybrid 模式下向量权重
    filters=MetadataFilters(...),       # 元数据过滤
    
    # 响应参数
    response_mode="compact",            # compact / refine / tree_summarize
    text_qa_template=None,              # 自定义 QA prompt
    refine_template=None,               # 自定义 refine prompt
    
    # LLM
    llm=llm,                            # 自定义 LLM
    
    # 流式
    streaming=False,
    
    # 调试
    verbose=True,                       # 打印检索过程
    
    # 后处理
    node_postprocessors=[bge_rerank],   # 节点后处理器
    
    # 回调
    callback_manager=CallbackManager([handler])
)

易错点:

  • similarity_top_k 不是全局参数,是 query engine 级别
  • 改 response_mode 不改 similarity_top_k 不会自动同步

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q37. Query Engine 怎么查不到时强制"我不知道"?

难度:中级

参考答案:

# 方案1: 设置相似度阈值过滤
from llama_index.core.postprocessor import SimilarityPostprocessor
qe = index.as_query_engine(
    similarity_top_k=5,
    node_postprocessors=[
        SimilarityPostprocessor(similarity_cutoff=0.7)
    ]
)

# 方案2: 自定义 Prompt 强制 LLM 答"不知道"
from llama_index.core import PromptTemplate
qa_prompt = PromptTemplate(
    "你是一个严谨的助手。基于以下上下文回答问题。\n"
    "如果上下文中没有答案,直接回答'我不知道',不要编造。\n"
    "上下文:\n{context_str}\n"
    "问题:{query_str}\n"
    "答案:"
)
qe = index.as_query_engine(text_qa_template=qa_prompt)

# 方案3: 配合 Faithfulness 评估检测幻觉

生产经验:"我不知道"是 RAG 系统的关键能力,比强行答错要好得多。

来源:CSDN《LlamaIndex 高级使用》https://www.cnblogs.com/shouyin/p/19493867


Q38. ⭐ MultiStepQueryEngine 和 SubQuestionQueryEngine 区别?

难度:高级

参考答案:

SubQuestionQueryEngine:把复杂问题拆成多个子问题,并行检索后汇总。

from llama_index.core.query_engine import SubQuestionQueryEngine
from llama_index.llms.openai import OpenAI

sub_qe = SubQuestionQueryEngine.from_args(
    index=index,
    llm=OpenAI(model="gpt-4"),
    use_async=True,  # 并行子问题
)
response = sub_qe.query("比较 LlamaIndex 和 LangChain 在 RAG 实现上的差异")

MultiStepQueryEngine:步骤间可以传递和迭代信息,前一步结果影响下一步问题。

from llama_index.core.query_engine import MultiStepQueryEngine
multi_qe = MultiStepQueryEngine(
    query_engine=base_qe,
    query_transform=step_decompose_transform
)

对比:

维度 SubQuestionQueryEngine MultiStepQueryEngine
拆解方式 一次性拆子问题,并行 步骤拆解,串行
信息流 各子问题独立 步骤间传递
适用 多角度独立问题 多跳推理、需要前步结果
复杂度 中 高

来源:LlamaIndex 官方文档


Q39. ⭐ RouterQueryEngine 是什么?怎么路由到不同索引?

难度:高级

参考答案:

RouterQueryEngine 是个路由器 + 多个子 Query Engine,根据用户问题自动选择最合适的子引擎。

from llama_index.core.query_engine import RouterQueryEngine
from llama_index.core.selectors import LLMSingleSelector, LLMMultiSelector
from llama_index.core.tools import QueryEngineTool

# 1. 定义子引擎
vector_tool = QueryEngineTool.from_defaults(
    query_engine=vector_qe,
    name="vector_search",
    description="用于语义相似度检索,例如事实查询、概念解释"
)
summary_tool = QueryEngineTool.from_defaults(
    query_engine=summary_qe,
    name="summary_search",
    description="用于文档总结、概览类问题"
)
kg_tool = QueryEngineTool.from_defaults(
    query_engine=kg_qe,
    name="kg_search",
    description="用于实体关系推理,例如'X 和 Y 的关系'"
)

# 2. 路由引擎
router_qe = RouterQueryEngine(
    selector=LLMSingleSelector.from_defaults(llm=llm),
    query_engine_tools=[vector_tool, summary_tool, kg_tool]
)
response = router_qe.query("总结今年的产品趋势")

两种 Selector:

  • LLMSingleSelector:选 1 个最合适(默认)
  • LLMMultiSelector:选多个,分别查询后综合

生产经验:RouterQueryEngine 替代了 LangChain 的 LLMChain,是 0.12+ 推荐的路由模式。

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q40. ⭐ 怎么实现 Multi-Document Agent(多文档 Agent 路由)?

难度:高级

参考答案:

from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.query_engine import RouterQueryEngine

# 1. 为每个数据源建索引
contract_index = VectorStoreIndex.from_documents(contract_docs)
hr_index = VectorStoreIndex.from_documents(hr_docs)
product_index = VectorStoreIndex.from_documents(product_docs)

# 2. 各自建 QueryEngine
contract_qe = contract_index.as_query_engine(similarity_top_k=3)
hr_qe = hr_index.as_query_engine(similarity_top_k=3)
product_qe = product_index.as_query_engine(similarity_top_k=3)

# 3. 包装成 Tool
contract_tool = QueryEngineTool(
    query_engine=contract_qe,
    metadata=ToolMetadata(
        name="合同库",
        description="查询合同条款、违约责任、SLA 条款"
    )
)
hr_tool = QueryEngineTool(
    query_engine=hr_qe,
    metadata=ToolMetadata(
        name="HR制度库",
        description="查询员工手册、年假、考勤制度"
    )
)
product_tool = QueryEngineTool(
    query_engine=product_qe,
    metadata=ToolMetadata(
        name="产品手册库",
        description="查询产品参数、功能、使用方法"
    )
)

# 4. RouterQueryEngine 整合
multi_doc_qe = RouterQueryEngine.from_defaults(
    query_engine_tools=[contract_tool, hr_tool, product_tool]
)

# 5. 复杂查询
response = multi_doc_qe.query("合同里关于员工培训的违约条款是什么?")

生产要点:

  • Tool description 写清楚:Selector 依赖 description 判断路由
  • description 模糊会导致路由失败:要具体说明适用场景

来源:theneuralbase https://theneuralbase.com/llamaindex-advanced/learn/beginner/version-upgrade-breaking-changes/


五、ChatEngine 与记忆(Q41 - Q47)

Q41. ⭐ ChatEngine 和 QueryEngine 有什么区别?

难度:入门

参考答案:

维度 QueryEngine ChatEngine
核心 单次问答(无状态) 多轮对话(有状态)
历史管理 不管 自动维护 chat history
API query() chat() / stream_chat()
记忆 无 内置 Memory
底层 Retriever + Synthesizer ChatEngine + Memory
# Query Engine
query_engine = index.as_query_engine()
response = query_engine.query("什么是 RAG?")

# Chat Engine(带记忆)
chat_engine = index.as_chat_engine()
response = chat_engine.chat("什么是 RAG?")
response = chat_engine.chat("它和微调有什么区别?")  # 记得上文

什么时候用:

  • 单次问答、API 调用 → QueryEngine
  • 机器人、对话系统 → ChatEngine

来源:LlamaIndex 官方文档


Q42. ⭐ ChatEngine 有哪几种模式?condense_question / context / react 区别?

难度:中级

参考答案:

4 种 ChatEngine 模式:

模式 原理 适用
SimpleChatEngine LLM 直接聊,不查知识库 闲聊
CondenseQuestionChatEngine 把历史 + 新问题压缩成独立问题,再检索 通用对话
ContextChatEngine 把历史 + 检索结果都喂给 LLM 强上下文依赖
ReActChatEngine ReAct 推理 + 工具调用 复杂决策
# 1. CondenseQuestion(默认)
from llama_index.core.chat_engine import CondenseQuestionChatEngine
chat_engine = CondenseQuestionChatEngine.from_defaults(
    query_engine=query_engine,
    llm=llm
)

# 2. Context 模式(带 chat history 作为 context)
from llama_index.core.chat_engine import ContextChatEngine
chat_engine = ContextChatEngine.from_defaults(
    retriever=retriever,
    llm=llm,
    chat_memory=memory
)

# 3. ReAct Agent Chat
chat_engine = index.as_chat_engine(chat_mode="react", verbose=True)

选型:

  • 简单 Q&A 机器人 → CondenseQuestion
  • 强上下文("它"指代上文)→ Context
  • 多工具决策 → ReAct

来源:LlamaIndex 官方文档


Q43. ⭐ ChatEngine 怎么管理 ChatMemory?Memory 类型有哪些?

难度:中级

参考答案:

from llama_index.core.memory import (
    ChatMemoryBuffer,
    VectorMemory,
    SimpleComposableMemory
)

# 1. 简单 buffer 记忆
memory = ChatMemoryBuffer.from_defaults(
    token_limit=3000,  # 控制 token 上限
)

# 2. 注入 ChatEngine
chat_engine = index.as_chat_engine(
    chat_mode="condense_question",
    memory=memory,
    system_prompt="你是一个专业的助手..."
)

# 3. 手动管理
memory.put("user", "你好")
memory.put("assistant", "你好,有什么可以帮你?")
chat_memory = memory.get()  # 获取全部

# 4. 自定义 Memory(多个来源组合)
custom_memory = SimpleComposableMemory.from_defaults(
    primary_memory=ChatMemoryBuffer.from_defaults(token_limit=2000),
    secondary_memory=[VectorMemory.from_defaults(...)]
)

Memory 类型:

  • ChatMemoryBuffer:FIFO 缓冲,按 token 限制
  • VectorMemory:用向量检索找相关历史
  • SimpleComposableMemory:组合多种 Memory

来源:LlamaIndex 官方文档


Q44. ⭐ 怎么让 ChatEngine 持久化记忆(跨 Session)?

难度:高级

参考答案:

# 方案1: 序列化到文件
import json
from llama_index.core.memory import ChatMemoryBuffer

# 保存
memory = ChatMemoryBuffer.from_defaults(token_limit=3000)
memory.put("user", "你好")
memory_data = {"chat_history": memory.chat_store.get_all()}  # 持久化

# 加载
from llama_index.core.llms import ChatMessage
restored = ChatMemoryBuffer.from_defaults(token_limit=3000)
for msg in memory_data["chat_history"]:
    restored.put(msg.role, msg.content)

# 方案2: 用外部存储(Redis / DB)
import redis
r = redis.Redis()
r.set(f"chat:{user_id}", json.dumps(memory.chat_store.get_all()))

生产方案:

  • Redis:分布式 session,最常用
  • PostgreSQL/MySQL:长时记忆,可分析
  • 向量库:长期历史检索增强
  • 多 Memory 组合:短期 buffer + 长期向量记忆

来源:LlamaIndex 官方 Memory 文档


Q45. ChatEngine 和 Agent 怎么选?

难度:中级

参考答案:

维度 ChatEngine Agent
目标 知识库对话 自主决策、调用工具
工具调用 不支持 支持(Function Call)
推理 单轮 多轮(ReAct)
适用 Q&A 机器人 复杂任务自动化
可控性 高 中(依赖 LLM 决策)

经验法则:

  • 强业务可控性 → ChatEngine(用 Router)
  • 灵活但要接受不确定性 → Agent
  • 生产首选:ChatEngine + Router + 多个 QueryEngineTool

来源:LlamaIndex 官方


Q46. ⭐ system_prompt 怎么写?有什么模板?

难度:入门

参考答案:

from llama_index.core import PromptTemplate

# 1. 直接传字符串
chat_engine = index.as_chat_engine(
    system_prompt="""
你是一个专业的金融知识助手,名叫小金。
规则:
1. 只基于上下文回答,不要编造。
2. 如果不知道,答"未找到相关信息"。
3. 回答不超过 200 字,使用专业语气。
4. 引用时附上文件名。
    """
)

# 2. 用 PromptTemplate 动态注入
prompt_tmpl = PromptTemplate("""
你是 {role},名叫 {name}。
当前用户:{user_name}
上下文:{context_str}
问题:{query_str}
""")
query_engine.update_prompts({"response_synthesizer:text_qa_template": prompt_tmpl})

# 3. 不同模式用不同模板
text_qa_template = PromptTemplate("基于上下文:{context_str}\n问题:{query_str}\n答案:")
refine_template = PromptTemplate("现有答案:{existing_answer}\n新上下文:{context_msg}\n问题:{query_str}\n优化答案:")
query_engine = index.as_query_engine(
    text_qa_template=text_qa_template,
    refine_template=refine_template
)

来源:LlamaIndex 官方 Prompt 文档


Q47. ChatEngine 流式输出怎么实现?

难度:中级

参考答案:

# 1. 启用 streaming
chat_engine = index.as_chat_engine(streaming=True)

# 2. 流式调用
streaming_response = chat_engine.stream_chat("什么是 RAG?")
for token in streaming_response.response_gen:
    print(token, end="", flush=True)

# 3. 同步 API
response = chat_engine.chat("什么是 RAG?")

异步版:

import asyncio
async def stream_chat():
    chat_engine = index.as_chat_engine(streaming=True)
    streaming_response = await chat_engine.astream_chat("什么是 RAG?")
    async for token in streaming_response.async_response_gen():
        print(token, end="", flush=True)
asyncio.run(stream_chat())

生产价值:配合 SSE/WebSocket 推送到前端,用户体感"秒回"。

来源:LlamaIndex 官方


六、Agent 与 Workflows(Q48 - Q58)

Q48. ⭐ LlamaIndex 的 Agent 类型有哪些?v0.10+ 怎么迁移?

难度:中级

参考答案:

v0.10+ Agent 体系:

Agent 位置 特点
ReActAgent llama_index.core.agent.workflow ReAct 推理循环
FunctionCallingAgent llama_index.core.agent.workflow OpenAI Function Calling
CodeActAgent llama_index.core.agent.workflow 代码执行
AgentWorkflow 多 Agent 协作 handoff / state

v0.9 → v0.10+ 迁移:

  • ❌ 旧:from llama_index.core.agent import AgentRunner, ReActAgent, FunctionCallingAgent
  • ✅ 新:from llama_index.core.agent.workflow import ReActAgent, FunctionCallingAgent, AgentWorkflow
  • ❌ 旧:agent = AgentRunner.from_agent_worker(...)
  • ✅ 新:agent = ReActAgent(tools=tools, llm=llm) 或 AgentWorkflow(agents=[...])
# ReActAgent 示例
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.tools import FunctionTool

def multiply(a: int, b: int) -> int:
    """Multiply two numbers"""
    return a * b

multiply_tool = FunctionTool.from_defaults(fn=multiply)
agent = ReActAgent(tools=[multiply_tool], llm=llm)
response = await agent.run(query="3 * 5 = ?")

来源:LlamaIndex Deprecated Terms 文档


Q49. ⭐ ReAct Agent 的工作原理是什么?

难度:中级

参考答案:

ReAct = Reason + Act:

Thought: 用户问 3*5,我需要计算
Action: multiply(3, 5)
Action Input: {"a": 3, "b": 5}
Observation: 15
Thought: 拿到结果了,可以回答
Final Answer: 3 * 5 = 15

核心循环:

  1. Think:LLM 思考下一步该做什么
  2. Act:选择工具和参数
  3. Execute:执行工具
  4. Observe:拿到结果
  5. 判断:是否拿到最终答案,否则回到 1
from llama_index.core.agent.workflow import ReActAgent
from llama_index.core.tools import FunctionTool
from llama_index.llms.openai import OpenAI

def search(query: str) -> str:
    """搜索工具"""
    return f"搜索结果: {query}"

agent = ReActAgent(
    tools=[FunctionTool.from_defaults(fn=search)],
    llm=OpenAI(model="gpt-4o"),
    verbose=True
)

response = await agent.run("北京今天天气如何?")
print(response)

生产坑点:

  • 最多 10-20 轮循环(防止死循环)
  • 工具 description 要清晰,否则选错工具
  • 复杂任务成本高(每轮 1 次 LLM 调用)

来源:CSDN《LangChain & LlamaIndex 面试题》


Q50. ⭐ FunctionCallingAgent 和 ReActAgent 怎么选?

难度:中级

参考答案:

维度 FunctionCallingAgent ReActAgent
原理 OpenAI Function Calling 原生支持 ReAct 文本循环
速度 快(原生支持) 较慢(解析文本)
稳定性 高(结构化输出) 中(依赖解析)
兼容性 需 LLM 支持 Function Call 几乎所有 LLM
可调试 较难(黑盒) 强(看 Thought/Action)
推荐 GPT-4 / Claude / Qwen 调试期 / 小模型
# FunctionCallingAgent
from llama_index.core.agent.workflow import FunctionCallingAgent
agent = FunctionCallingAgent(
    tools=tools,
    llm=OpenAI(model="gpt-4o"),
    verbose=True
)

# ReActAgent
from llama_index.core.agent.workflow import ReActAgent
agent = ReActAgent(tools=tools, llm=llm, verbose=True)

选型:

  • 生产 + 主流 LLM → FunctionCallingAgent
  • 调试 + 兼容性优先 → ReActAgent

来源:LlamaIndex 官方文档


Q51. ⭐ QueryEngineTool 是什么?怎么把 Query Engine 变成 Tool?

难度:中级

参考答案:

from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core import VectorStoreIndex

# 1. 假设有两个索引
contract_index = VectorStoreIndex.from_documents(contract_docs)
hr_index = VectorStoreIndex.from_documents(hr_docs)

# 2. 把每个索引变成 Tool
contract_tool = QueryEngineTool(
    query_engine=contract_index.as_query_engine(),
    metadata=ToolMetadata(
        name="contract_search",
        description="查询合同条款、违约责任、SLA 条款相关问题"
    )
)
hr_tool = QueryEngineTool(
    query_engine=hr_index.as_query_engine(),
    metadata=ToolMetadata(
        name="hr_search",
        description="查询员工手册、年假、考勤制度等 HR 问题"
    )
)

# 3. 给 Agent 使用
from llama_index.core.agent.workflow import FunctionCallingAgent
agent = FunctionCallingAgent(
    tools=[contract_tool, hr_tool],
    llm=llm
)
response = await agent.run("合同里关于年假的规定是什么?")

关键点:

  • description 决定路由:Agent 靠它选工具,写得不好直接路由失败
  • name 要唯一:Agent 返回的 Action 会引用它
  • production 经验:description 写"用于 X 类问题,例如 Y、Z"

来源:LlamaIndex 官方文档


Q52. ⭐ FunctionTool 怎么自定义?复杂参数怎么传?

难度:中级

参考答案:

from llama_index.core.tools import FunctionTool
from typing import Optional, List
from pydantic import BaseModel, Field

# 1. 简单函数
def search_weather(city: str) -> str:
    """查询指定城市的天气"""
    return f"{city} 今天晴,25度"

tool = FunctionTool.from_defaults(fn=search_weather)

# 2. 复杂参数(用 Pydantic)
class SearchQuery(BaseModel):
    keyword: str = Field(description="搜索关键词")
    max_results: int = Field(default=10, description="返回结果数量")
    language: str = Field(default="zh", description="语言")

def advanced_search(query: SearchQuery) -> List[str]:
    """高级搜索工具"""
    return [f"结果 {i}: {query.keyword}" for i in range(query.max_results)]

tool = FunctionTool.from_defaults(fn=advanced_search)

# 3. 异步函数
async def async_fetch(url: str) -> str:
    """异步抓取网页"""
    import aiohttp
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as resp:
            return await resp.text()

async_tool = FunctionTool.from_defaults(fn=async_fetch)

生产要点:

  • docstring 写清楚:Agent 靠 docstring 理解功能
  • 参数类型注解必须:LLM 用类型生成参数
  • Pydantic Field description:复杂参数必备

来源:LlamaIndex 官方文档


Q53. ⭐ 🔥 LlamaIndex Workflows 是什么?事件驱动架构怎么理解?

难度:高级

参考答案:

Workflows 是 LlamaIndex 推出的轻量级事件驱动框架(2024年发布,2025年6月 1.0 正式版),用来编排复杂多步 AI 应用。

核心组件:

from llama_index.core.workflow import (
    Workflow, step, Event, StartEvent, StopEvent, Context
)
from llama_index.llms.openai import OpenAI

# 1. 定义事件
class JokeEvent(Event):
    joke: str

class AnalysisEvent(Event):
    analysis: str

# 2. 定义 Workflow
class JokeFlow(Workflow):
    llm = OpenAI(model="gpt-4o-mini")

    @step
    async def generate_joke(self, ev: StartEvent) -> JokeEvent:
        topic = ev.topic
        prompt = f"讲一个关于{topic}的笑话"
        response = await self.llm.acomplete(prompt)
        return JokeEvent(joke=str(response))

    @step
    async def critique_joke(self, ev: JokeEvent) -> StopEvent:
        prompt = f"分析笑话笑点: {ev.joke}"
        response = await self.llm.acomplete(prompt)
        return StopEvent(result=str(response))

# 3. 运行
w = JokeFlow(timeout=60, verbose=True)
result = await w.run(topic="程序员")
print(result)

核心概念:

  • Event:事件,Pydantic 模型
  • StartEvent / StopEvent:内置起止事件
  • @step 装饰器:标记方法为步骤(基于入参/返回类型自动连接)
  • Context:全局共享状态,类似"数据黑板"

核心优势:异步/并发/可观测/可视化调试/支持 Human-in-the-Loop。

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/workflows/


Q54. ⭐ 🔥 Workflows 的 Context 是什么?怎么用?

难度:高级

参考答案:

Context 是工作流中全局共享的状态对象(数据黑板),解决事件传递数据的繁琐。

from llama_index.core.workflow import Context

class MyWorkflow(Workflow):
    @step
    async def step1(self, ctx: Context, ev: StartEvent) -> SomeEvent:
        # 写 Context
        await ctx.set("user_name", ev.user_name)
        await ctx.set("query", ev.query)
        return SomeEvent(...)

    @step
    async def step2(self, ctx: Context, ev: SomeEvent) -> StopEvent:
        # 读 Context
        user_name = await ctx.get("user_name")
        query = await ctx.get("query")
        return StopEvent(result=...)

高级用法:

# 1. Context 存 LLM 调用的中间结果
@step
async def retrieve_step(self, ctx: Context, ev: StartEvent) -> NextEvent:
    nodes = retriever.retrieve(ev.query)
    await ctx.set("nodes", nodes)
    return NextEvent(...)

# 2. 多步骤共享数据
@step
async def process_step(self, ctx: Context, ev: NextEvent) -> StopEvent:
    nodes = await ctx.get("nodes")
    # ...

# 3. 流式事件(context 在多 step 间共享)
async for event in wf.stream(topic="..."):
    print(event)

坑点:ctx 操作是 async,必须 await!

来源:CSDN《LlamaIndex Workflows 从入门到实战》https://blog.csdn.net/SearchB/article/details/159896003


Q55. ⭐ 🔥 Workflows Human-in-the-Loop(HITL)怎么实现?

难度:高级

参考答案:

from llama_index.core.workflow import (
    InputRequiredEvent, HumanResponseEvent, Context
)

class DangerousTool:
    async def execute(self, ctx: Context) -> str:
        question = "确认要删除这条记录吗?(yes/no)"
        # 发出中断事件
        response = await ctx.wait_for_event(
            HumanResponseEvent,
            waiter_id=question,
            waiter_event=InputRequiredEvent(question)
        )
        if response.user_response.lower().startswith("y"):
            return "已删除"
        else:
            return "操作取消"

# 配合外部系统
# 前端监听 InputRequiredEvent → 展示问题
# 用户回答后 → 触发 HumanResponseEvent → 继续 Workflow

生产级持久化模式:

# 1. 启动 Workflow,序列化状态
ctx_dict = ctx.to_dict()
db.save(f"workflow:{user_id}", ctx_dict)

# 2. 用户回答后,从 DB 恢复
ctx = Context.from_dict(workflow, ctx_dict)
ctx.send_event(HumanResponseEvent(user_response="yes"))

# 3. 继续运行
result = await wf.run(ctx=ctx)

生产场景:

  • 危险操作确认(删库、转账)
  • 人工审校(AI 写报告,主管确认)
  • 多轮决策(AI 给选项,用户选)

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/workflows/


Q56. ⭐ AgentWorkflow 多 Agent 协作(handoff)怎么用?

难度:高级

参考答案:

from llama_index.core.agent.workflow import AgentWorkflow, ReActAgent
from llama_index.core.tools import FunctionTool
from llama_index.llms.openai import OpenAI

# 1. 定义多个 Agent
def search_docs(query: str) -> str:
    """搜索文档"""
    return f"找到 {query} 相关文档"

def write_report(topic: str) -> str:
    """写报告"""
    return f"已生成 {topic} 报告"

research_agent = ReActAgent(
    name="research_agent",
    description="负责检索资料",
    tools=[FunctionTool.from_defaults(fn=search_docs)],
    llm=OpenAI(model="gpt-4o"),
    system_prompt="你是研究助理"
)

write_agent = ReActAgent(
    name="write_agent",
    description="负责写报告",
    tools=[FunctionTool.from_defaults(fn=write_report)],
    llm=OpenAI(model="gpt-4o"),
    system_prompt="你是写作助理"
)

# 2. 编排多 Agent
workflow = AgentWorkflow(
    agents=[research_agent, write_agent],
    root_agent="research_agent",  # 入口
)

# 3. 运行(agent 间自动 handoff)
response = await workflow.run("研究 AI Agent 最新进展并写报告")
print(response)

生产经验:

  • 按职责拆分 agent,不要把每个微操都拆
  • handoff 时记得传上下文(state 显式维护对话历史)
  • state 要精简,大对象只存 ID/摘要

来源:CSDN《AgentWorkflow 实战》https://blog.csdn.net/puzi0315/article/details/152566151


Q57. ⭐ Workflows 的可视化调试怎么用?

难度:中级

参考答案:

# 安装工具
# pip install llama-index-utils-workflow

from llama_index.utils.workflow import (
    draw_all_possible_flows,        # 静态流程图
    draw_most_recent_execution      # 动态执行轨迹
)

# 1. 静态流程图(基于代码分析)
draw_all_possible_flows(MyWorkflow, filename="workflow_structure.html")

# 2. 动态执行图(最近一次)
workflow = MyWorkflow()
await workflow.run(topic="程序员")
draw_most_recent_execution(workflow, filename="recent_execution.html")

# 3. 流式事件调试
async for event in workflow.stream(topic="..."):
    print(f"事件: {type(event).__name__}, 数据: {event}")

价值:

  • 结构图看清有哪些步骤、怎么连
  • 执行图看出实际走了哪条分支、哪步慢
  • 流式事件实时调试

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/workflows/


Q58. Workflows 和 LangGraph 怎么选?

难度:高级

参考答案:

维度 LlamaIndex Workflows LangGraph
定位 LlamaIndex 生态的事件框架 LangChain 生态的图编排
核心抽象 事件 + Step Node + Edge + State
状态管理 Context(数据黑板) State(结构化状态)
可视化 内置(draw_all_possible_flows) 需 LangSmith
HITL 原生(InputRequiredEvent) 需配置 interrupt
多 Agent AgentWorkflow(handoff) 原生支持
学习曲线 中 较陡

选型:

  • 项目以 LlamaIndex 为主 → Workflows
  • 复杂图(条件分支、循环、状态机)→ LangGraph(更灵活)
  • 真实项目经常组合:LlamaIndex 做检索,LangGraph 做主流程

来源:CSDN《LlamaIndex Workflows》


七、向量数据库与 Embedding(Q59 - Q67)

Q59. ⭐ LlamaIndex 怎么对接主流向量数据库(Chroma / Milvus / Qdrant / FAISS)?

难度:中级

参考答案:

通用模式:

from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.core.vector_stores import ...

# 1. Chroma
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
chroma_client = chromadb.PersistentClient(path="./chroma_db")
chroma_store = ChromaVectorStore(chroma_collection=chroma_client.get_or_create_collection("docs"))

# 2. Milvus
from llama_index.vector_stores.milvus import MilvusVectorStore
milvus_store = MilvusVectorStore(
    uri="./milvus.db",
    collection_name="docs",
    dim=1536,
    overwrite=True
)

# 3. Qdrant
from llama_index.vector_stores.qdrant import QdrantVectorStore
import qdrant_client
qclient = qdrant_client.QdrantClient(path="./qdrant_db")
qdrant_store = QdrantVectorStore(client=qclient, collection_name="docs")

# 4. FAISS
from llama_index.vector_stores.faiss import FaissVectorStore
import faiss
faiss_index = faiss.IndexFlatL2(1536)
faiss_store = FaissVectorStore(faiss_index=faiss_index)

然后:

storage_context = StorageContext.from_defaults(vector_store=<your_store>)
index = VectorStoreIndex(nodes, storage_context=storage_context)

来源:LlamaIndex 官方 https://docs.llamaindex.ai


Q60. ⭐ 主流向量库选型对比?

难度:中级

参考答案:

向量库 性能 规模 运维 适用
Chroma 中 小-中(< 1M) 极简 原型 / 中小项目
FAISS 最快(CPU) 中(亿级) 自管 离线 / 嵌入引擎
Milvus 高(GPU) 大(百亿级) 重 大规模生产
Qdrant 高 中-大 中 通用生产
Weaviate 中 中 中 需 GraphQL?
Pinecone 高 大 零运维 不想运维的云生产
pgvector 中 小-中 SQL 一体 已有 PG 栈

选型建议:

  • 个人/小项目 → Chroma
  • 生产且不愿运维 → Pinecone / Zilliz Cloud
  • 大规模 + 自有运维 → Milvus
  • 已有 PG → pgvector
  • 离线/嵌入式 → FAISS

来源:LlamaIndex Vector Store Integrations


Q61. ⭐ LlamaIndex 支持哪些 Embedding 模型?怎么切换?

难度:入门

参考答案:

# 1. OpenAI(默认)
from llama_index.embeddings.openai import OpenAIEmbedding
embed_model = OpenAIEmbedding(model="text-embedding-3-small", api_key="...")

# 2. BGE(开源、中文强)
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-large-zh-v1.5")

# 3. Cohere
from llama_index.embeddings.cohere import CohereEmbedding
embed_model = CohereEmbedding(api_key="...", model="embed-english-v3.0")

# 4. 本地 Sentence-Transformers
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
embed_model = HuggingFaceEmbedding(model_name="sentence-transformers/all-MiniLM-L6-v2")

# 5. 全局设置(v0.10+ 推荐)
from llama_index.core import Settings
Settings.embed_model = embed_model

模型选型建议:

  • 英文通用 → text-embedding-3-small / bge-large-en-v1.5
  • 中文 → bge-large-zh-v1.5 / M3E
  • 多语言 → bge-m3 / text-embedding-3-large
  • 代码 → code-embeddings / jina-embeddings

来源:LlamaIndex Embeddings 文档


Q62. ⭐ 自定义 Embedding 模型怎么实现?

难度:高级

参考答案:

from llama_index.core.embeddings import BaseEmbedding
from typing import List
import numpy as np

class MyCustomEmbedding(BaseEmbedding):
    def __init__(self, model_path: str, **kwargs):
        super().__init__(**kwargs)
        # 加载自定义模型
        from sentence_transformers import SentenceTransformer
        self._model = SentenceTransformer(model_path)

    def _get_query_embedding(self, query: str) -> List[float]:
        emb = self._model.encode(query)
        return emb.tolist()

    def _get_text_embedding(self, text: str) -> List[float]:
        return self._model.encode(text).tolist()

    async def _aget_query_embedding(self, query: str) -> List[float]:
        return self._get_query_embedding(query)

    async def _aget_text_embedding(self, text: str) -> List[float]:
        return self._get_text_embedding(text)

# 使用
embed_model = MyCustomEmbedding(model_path="BAAI/bge-large-zh-v1.5")

生产要点:

  • 实现所有 4 个方法(同步 query / text + 异步 query / text)
  • batch encode 提高性能
  • 缓存常见 query 减少重复计算

来源:LlamaIndex Embeddings 自定义文档


Q63. ⭐ 怎么持久化和加载 VectorStoreIndex?

难度:入门

参考答案:

# 1. 持久化
index = VectorStoreIndex.from_documents(docs)
index.storage_context.persist(persist_dir="./storage")

# 2. 加载
from llama_index.core import StorageContext, load_index_from_storage
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)

# 3. 继续用
query_engine = index.as_query_engine()
response = query_engine.query("...")

生产要点:

  • 持久化会保存 4 个 store(vector / docstore / index_store / graph_store)
  • 大索引加载慢,建议启动时预热
  • 增量更新:index.insert_nodes(new_nodes),再 persist

来源:LlamaIndex 官方文档


Q64. 怎么实现 Embedding 的混合向量(稠密 + 稀疏)?

难度:高级

参考答案:

# 方案1: 用支持 sparse+dense 的向量库(如 Qdrant / Milvus)
from qdrant_client import models
# 上传时同时给 dense 和 sparse vector
qclient.upsert(
    collection_name="docs",
    points=[
        models.PointStruct(
            id=1,
            vector={
                "dense": dense_emb,           # BGE
                "sparse": sparse_emb,         # BM25
            },
            payload={"text": "..."}
        )
    ]
)

# 方案2: LlamaIndex 内置 hybrid(QueryFusionRetriever)
# 见 Q30

生产建议:

  • 真正需要混合检索就用 Qdrant/Milvus 原生 hybrid
  • LlamaIndex 的 QueryFusionRetriever 已经够用
  • 谨慎使用 num_queries=4(LLM 调用 4 次)

来源:Qdrant / Milvus 官方文档


Q65. ⭐ Embedding 模型微调怎么做?

难度:高级

参考答案:

# 1. 准备数据(query, positive_doc, negative_doc)
train_data = [
    {
        "query": "如何申请年假?",
        "positive": "年假申请流程:登录 OA → 提交申请",
        "negative": "病假申请流程:..."
    },
    # ...
]

# 2. 用 sentence-transformers 微调
from sentence_transformers import InputExample, losses
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("BAAI/bge-small-zh")
train_examples = [InputExample(texts=[d["query"], d["positive"], d["negative"]]) for d in train_data]
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16)
train_loss = losses.MultipleNegativesRankingLoss(model)

model.fit(
    train_objectives=[(train_dataloader, train_loss)],
    epochs=3,
    output_path="./fine_tuned_bge"
)

# 3. 接入 LlamaIndex
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
embed_model = HuggingFaceEmbedding(model_name="./fine_tuned_bge")

微调要点:

  • 数据质量 > 数量(100 条高质量 > 10000 条噪声)
  • 用 MultipleNegativesRankingLoss(对比学习)
  • 必须有 evaluation set 防止过拟合
  • Hard negative mining 很重要

来源:sentence-transformers 文档


Q66. ⭐ 怎么提升 Embedding 的中文效果?

难度:中级

参考答案:

  1. 选对模型:

    • BAAI/bge-large-zh-v1.5(最常用)
    • BAAI/bge-m3(多语言 + 长文本)
    • MokaAI/M3E-large(开源)
    • shibing624/text2vec-large-chinese
  2. 领域微调:用业务数据 fine-tune(见 Q65)

  3. 混合检索:BM25 + 向量(见 Q30)

  4. 查询重写:用 LLM 把口语化 query 改写为标准化 query

  5. 元数据过滤:减少搜索空间

# 查询重写示例
from llama_index.core.query_engine import TransformQueryEngine
from llama_index.core.indices.query.query_transform import HyDEQueryTransform

hyde = HyDEQueryTransform(llm=llm, include_original=True)
transformed_qe = TransformQueryEngine(qe, query_transform=hyde)
response = transformed_qe.query("用户口语化的问题")

来源:LlamaIndex HyDE 文档


Q67. Embedding 维度对成本和精度的影响?

难度:中级

参考答案:

模型 维度 精度 成本/1M token 存储
text-embedding-3-small 512-1536 中 $0.02 中
text-embedding-3-large 256-3072 高 $0.13 大
BGE-small-zh 512 中 免费 小
BGE-large-zh 1024 高 免费 大
BGE-M3 1024 高 免费 大

生产经验:

  • 小型项目 / 原型:512 维够用
  • 高精度场景:1024-1536 维
  • 降维:text-embedding-3 支持 dimensions=512 参数动态降维
  • 存储成本:1M 向量 × 1536 维 × 4 bytes ≈ 6GB

来源:OpenAI Embeddings 定价、LlamaIndex 官方


八、嵌入向量化与 RAG 流程(Q68 - Q75)

Q68. ⭐ 完整的 RAG Pipeline 代码怎么写?

难度:中级

参考答案:

from llama_index.core import (
    VectorStoreIndex, SimpleDirectoryReader, Settings
)
from llama_index.core.node_parser import SentenceSplitter
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.llms.openai import OpenAI
from llama_index.core.postprocessor import SimilarityPostprocessor
from llama_index.postprocessor.bge_rerank import BGERerank

# 1. 全局配置
Settings.llm = OpenAI(model="gpt-4o-mini", temperature=0)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-small")
Settings.node_parser = SentenceSplitter(chunk_size=512, chunk_overlap=50)

# 2. 加载
docs = SimpleDirectoryReader("./data", recursive=True).load_data()

# 3. 注入 metadata
for doc in docs:
    doc.metadata["source"] = "公司制度"
    doc.metadata["version"] = "v2.1"

# 4. 建索引
index = VectorStoreIndex.from_documents(docs)

# 5. 建 Query Engine(带 Rerank + 阈值)
bge = BGERerank(top_n=5, model="BAAI/bge-reranker-large")
sim = SimilarityPostprocessor(similarity_cutoff=0.7)
query_engine = index.as_query_engine(
    similarity_top_k=10,
    node_postprocessors=[sim, bge],
    response_mode="compact",
    streaming=True
)

# 6. 查询
response = query_engine.query("公司年假政策是什么?")
print(response)
for node in response.source_nodes:
    print(f"  score={node.score:.3f} | {node.node.text[:100]}")

来源:LlamaIndex 官方 Quickstart


Q69. ⭐ Graph RAG / Property Graph RAG 怎么实现?

难度:高级

参考答案:

from llama_index.core import PropertyGraphIndex, SimpleDirectoryReader
from llama_index.core.indices.property_graph import (
    SimpleLLMPathExtractor, ImplicitPathExtractor
)

# 1. 加载
docs = SimpleDirectoryReader("./data").load_data()

# 2. 建图索引
pg_index = PropertyGraphIndex.from_documents(
    docs,
    kg_extractors=[
        SimpleLLMPathExtractor(llm=llm, max_paths_per_chunk=10),
        ImplicitPathExtractor()
    ]
)

# 3. 查询
query_engine = pg_index.as_query_engine(
    include_text=True,         # 返回 source text
    similarity_top_k=2
)
response = query_engine.query("苹果公司的 CEO 是谁?")
# 自动找 实体(苹果公司) - 关系(CEO_of) - 实体(Tim Cook)

# 4. 自定义子检索器
from llama_index.core.indices.property_graph import (
    VectorContextRetriever, LLMSynonymRetriever
)

retriever = pg_index.as_retriever(
    sub_retrievers=[
        VectorContextRetriever(pg_index.property_graph_store, embed_model=embed_model),
        LLMSynonymRetriever(llm=llm)
    ]
)

Graph RAG vs 向量 RAG:

维度 向量 RAG Graph RAG
适合 语义相似 实体关系、多跳推理
召回 模糊 精确
成本 低 高(LLM 抽取三元组)
维护 易 难

来源:LlamaIndex 官方 https://docs.llamaindex.ai/en/stable/module_guides/indexing/lpg_index_guide/


Q70. ⭐ Multi-Modal RAG 怎么实现?

难度:高级

参考答案:

# 方案1: LlamaParse + Multi-Modal Index(最简单)
from llama_parse import LlamaParse
from llama_index.core import SimpleDirectoryReader

parser = LlamaParse(api_key="llx-...", result_type="markdown")
file_extractor = {".pdf": parser}
docs = SimpleDirectoryReader("./pdfs", file_extractor=file_extractor).load_data()

# 启用多模态检索
from llama_index.indices.managed.llama_cloud import LlamaParseIndex
index = LlamaParseIndex(name="my_index", project_name="default", api_key="llx-...")
retriever = index.as_retriever(retrieve_image_nodes=True)

# 方案2: 自定义多模态查询引擎
from llama_index.core.query_engine import CustomQueryEngine
from llama_index.multi_modal_llms.openai import OpenAIMultiModal

class MultimodalQueryEngine(CustomQueryEngine):
    qa_prompt: PromptTemplate
    retriever: BaseRetriever
    multi_modal_llm: OpenAIMultiModal

    def custom_query(self, query_str: str):
        nodes = self.retriever.retrieve(query_str)
        img_nodes = [n for n in nodes if isinstance(n.node, ImageNode)]
        text_nodes = [n for n in nodes if isinstance(n.node, TextNode)]
        context_str = "\n\n".join([r.get_content() for r in nodes])
        prompt = self.qa_prompt.format(context_str=context_str, query_str=query_str)
        llm_response = self.multi_modal_llm.complete(
            prompt=prompt,
            image_documents=[n.node for n in img_nodes]
        )
        return Response(response=str(llm_response), source_nodes=nodes)

生产要点:

  • 多模态 LLM 选型:GPT-4o(贵但强)、Claude 3.5 Sonnet、Qwen-VL(性价比高)
  • 图文混合检索必须用专门的 multi-modal embedder
  • 注意 token 成本(图片 = 几百到几千 token)

来源:CSDN《07-LlamaIndex 多模态与企业级》https://blog.csdn.net/wayle123/article/details/159518324


Q71. ⭐ SQL RAG 怎么实现?让 LLM 查数据库?

难度:高级

参考答案:

from llama_index.core.query_engine import NLSQLTableQueryEngine, SQLTableRetrieverQueryEngine
from llama_index.core import SQLDatabase
from sqlalchemy import create_engine

# 1. 连接数据库
engine = create_engine("sqlite:///example.db")
sql_db = SQLDatabase(engine, include_tables=["users", "orders"])

# 2. NLSQLTableQueryEngine(单表)
query_engine = NLSQLTableQueryEngine(
    sql_database=sql_db,
    tables=["users", "orders"]
)
response = query_engine.query("查询 2024 年注册用户数")

# 3. SQLTableRetrieverQueryEngine(多表 + 表检索)
from llama_index.core.indices.struct_store import SQLTableRetrieverQueryEngine
from llama_index.core.objects import SQLTableNodeMapping, ObjectIndex, SQLTableSchema
from llama_index.core import VectorStoreIndex

table_node_mapping = SQLTableNodeMapping(sql_db)
table_schema_objs = [
    SQLTableSchema(table_name="users"),
    SQLTableSchema(table_name="orders")
]
obj_index = ObjectIndex.from_objects(
    table_schema_objs,
    table_node_mapping,
    VectorStoreIndex,
)
table_retriever = obj_index.as_retriever(similarity_top_k=1)

query_engine = SQLTableRetrieverQueryEngine(
    sql_database=sql_db,
    table_retriever=table_retriever
)
response = query_engine.query("查 2024 年订单量最高的用户")

生产经验:

  • 必须设数据库只读账户,防 SQL 注入
  • 用 Text-to-SQL Guardrails 验证生成的 SQL
  • 大表要分表 / 预聚合,避免扫描全表

来源:LlamaIndex Structured Data 文档


Q72. ⭐ Agentic RAG 和普通 RAG 区别是什么?

难度:高级

参考答案:

普通 RAG:固定流程(retrieve → generate)
Agentic RAG:Agent 自主决策检索策略

Agentic RAG 实现:

from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.core.agent.workflow import FunctionCallingAgent

# 1. 多种检索策略建多个 Tool
vector_tool = QueryEngineTool(
    query_engine=vector_qe,
    metadata=ToolMetadata(name="vector_search", description="语义检索")
)
keyword_tool = QueryEngineTool(
    query_engine=bm25_qe,
    metadata=ToolMetadata(name="keyword_search", description="关键词检索")
)
sql_tool = QueryEngineTool(
    query_engine=sql_qe,
    metadata=ToolMetadata(name="sql_search", description="查结构化数据库")
)

# 2. Agent 决策
agent = FunctionCallingAgent(
    tools=[vector_tool, keyword_tool, sql_tool],
    llm=llm
)
response = await agent.run("查 2024 年 Q3 销售额最高的产品的客户评价")
# Agent 自动选:先 SQL 查产品,再向量查评价

对比:

维度 普通 RAG Agentic RAG
流程 固定 灵活
成本 低 高(多次 LLM)
准确性 中 高
延迟 低 高
适用 通用 Q&A 复杂决策

来源:LlamaIndex Agentic RAG 文档


Q73. ⭐ HyDE(Hypothetical Document Embeddings)是什么?怎么用?

难度:高级

参考答案:

HyDE = 让 LLM 先生成"假设答案",再用假设答案做检索。原理是 query 和 answer 都在同一 embedding 空间。

from llama_index.core.indices.query.query_transform import HyDEQueryTransform
from llama_index.core.query_engine import TransformQueryEngine

hyde = HyDEQueryTransform(llm=llm, include_original=True)
transformed_qe = TransformQueryEngine(query_engine, query_transform=hyde)

response = transformed_qe.query("RAG 的核心思想")
# 1. LLM 生成"假设答案":RAG 是检索增强生成...
# 2. 用假设答案做向量检索
# 3. 用检索到的真实 Node 生成最终答案

适用:

  • Query 短 / 不规范
  • 用户用口语化表达
  • 检索质量不理想时

坑点:

  • 多 1 次 LLM 调用(成本翻倍)
  • 假设答案可能不准确

来源:LlamaIndex 官方文档


Q74. ⭐ Recursive Retriever 是什么?怎么用?

难度:高级

参考答案:

Recursive Retriever 处理有引用关系的文档(如论文里引用其他论文、小节引用章节)。

from llama_index.core.retrievers import RecursiveRetriever
from llama_index.core.query_engine import RetrieverQueryEngine

# 场景:doc 里有 [REF:其他doc_id] 这种引用
recursive_retriever = RecursiveRetriever(
    root_id="root",
    retriever_dict={
        "root": vector_retriever,
        "other_doc": other_retriever,  # 引用目标
    }
)

# 用法
nodes = recursive_retriever.retrieve("查找所有相关引用")

应用:

  • 论文知识图谱(引用关系)
  • 文档-摘要 双层
  • 多跳检索

来源:LlamaIndex 官方文档


Q75. ⭐ 怎么在生产环境部署 LlamaIndex 应用?

难度:高级

参考答案:

部署方式:

  1. REST API(FastAPI):
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()
query_engine = index.as_query_engine(streaming=True)

class Query(BaseModel):
    question: str

@app.post("/query")
async def query(q: Query):
    response = await query_engine.aquery(q.question)
    return {"answer": str(response), "sources": [n.node.text for n in response.source_nodes]}
  1. LlamaIndex Server(v0.10+ 推荐):
from llama_index.server import LlamaIndexServer
server = LlamaIndexServer(index=index)
server.run(host="0.0.0.0", port=8000)
  1. Serverless:AWS Lambda / Vercel Functions

  2. Docker + K8s:标准容器化

生产铁律:

  • 预热模型:启动时 load 索引,避免冷启动
  • 异步优先:aquery / astream_query
  • 限流熔断:防止 OOM
  • 监控埋点:Callback + Prometheus
  • 健康检查:索引可加载

来源:LlamaIndex 部署文档


九、评估与可观测性(Q76 - Q85)

Q76. ⭐ LlamaIndex 怎么评估 RAG 质量?内置评估指标有哪些?

难度:中级

参考答案:

LlamaIndex 内置指标:

from llama_index.core.evaluation import (
    FaithfulnessEvaluator,         # 答案是否忠实于上下文
    AnswerRelevancyEvaluator,      # 答案与问题相关性
    ContextRelevancyEvaluator,     # 上下文与问题相关性
    CorrectnessEvaluator,          # 答案正确性(需 ground_truth)
    PairwiseComparisonEvaluator,   # 两个引擎对比
)

# 1. Faithfulness
evaluator = FaithfulnessEvaluator(llm=llm)
result = evaluator.evaluate_response(
    query="什么是 RAG?",
    response=response
)
print(f"Faithfulness: {result.score}, passing: {result.passing}")

# 2. 批量评估
from llama_index.core.evaluation import BatchEvalRunner
runner = BatchEvalRunner(
    {
        "faithfulness": FaithfulnessEvaluator(llm=llm),
        "relevancy": AnswerRelevancyEvaluator(llm=llm),
    },
    workers=4
)
results = await runner.aevaluate_queries(
    query_engine=query_engine,
    queries=["q1", "q2", ...]
)

指标含义:

  • Faithfulness:答案内容是否源自上下文(抗幻觉关键)
  • Answer Relevancy:答案和问题的匹配度
  • Context Relevancy:召回的上下文是否相关
  • Correctness:vs 人工标注的标准答案

来源:CSDN《评估大模型 RAG》https://blog.csdn.net/m0_59596990/article/details/140058653


Q77. ⭐ RAGAs 怎么和 LlamaIndex 集成?

难度:中级

参考答案:

from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
    context_relevancy,
)
from ragas.llama_index import evaluate

# 1. 准备数据
questions = ["什么是 RAG?", "RAG 和微调的区别?"]
ground_truth = ["RAG 是检索增强生成...", "RAG 实时检索,微调改模型参数..."]

# 2. 评估
metrics = [faithfulness, answer_relevancy, context_precision, context_recall]
result = evaluate(query_engine, metrics, questions, ground_truth)
print(result)
# {'faithfulness': 0.9, 'answer_relevancy': 0.89, ...}

# 3. 转 DataFrame 分析
df = result.to_pandas()
df.to_csv("eval_results.csv", index=False)

4 大核心指标:

  • Faithfulness:答案忠实上下文(0-1,越高越好)
  • Answer Relevancy:答案相关问题
  • Context Precision:相关 context 排序是否靠前
  • Context Recall:答案是否覆盖 ground truth

生产价值:每次改 pipeline(换 embedder、换 chunk size)就跑一遍,看指标变化。

来源:RAGAs 官方 https://docs.ragas.io/en/v0.1.21/howtos/integrations/llamaindex.html


Q78. ⭐ Faithfulness 和 Correctness 有什么区别?

难度:中级

参考答案:

指标 衡量 需要的输入
Faithfulness 答案是否基于上下文(无幻觉) query + response
Correctness 答案是否等于 ground truth query + response + reference

Faithfulness 测的是"幻觉程度"——LLM 自己加戏了没?
Correctness 测的是"准确性"——答对了没?

# Faithfulness
from llama_index.core.evaluation import FaithfulnessEvaluator
f_eval = FaithfulnessEvaluator(llm=llm)
result = f_eval.evaluate(query="X是什么?", response=response)
# score 接近 1 = 答案都来自上下文
# score 接近 0 = LLM 编造内容

# Correctness
from llama_index.core.evaluation import CorrectnessEvaluator
c_eval = CorrectnessEvaluator(llm=llm)
result = c_eval.evaluate(
    query="X是什么?",
    response=response,
    reference="X 的标准答案..."
)
# score 0-5,5 = 完全正确

生产组合:Faithfulness 必用(保底),Correctness 抽样用(需 ground truth)。

来源:CSDN《Advanced RAG 03》https://blog.csdn.net/Baihai_IDP/article/details/137865226


Q79. ⭐ DeepEval 怎么和 LlamaIndex 集成?

难度:中级

参考答案:

from deepeval.metrics import (
    AnswerRelevancyMetric,
    FaithfulnessMetric,
    ContextualPrecisionMetric,
)
from deepeval.test_case import LLMTestCase

# 1. 定义指标
answer_relevancy = AnswerRelevancyMetric()
faithfulness = FaithfulnessMetric()
contextual_precision = ContextualPrecisionMetric()

# 2. 运行 RAG 应用拿到 response
rag_application = RetrieverQueryEngine(
    retriever=retriever,
    response_synthesizer=synthesizer,
    node_postprocessors=[SimilarityPostprocessor(similarity_cutoff=0.7)]
)
response = rag_application.query("What is LlamaIndex?")

# 3. 创建 TestCase
test_case = LLMTestCase(
    input="What is LlamaIndex?",
    actual_output=str(response),
    retrieval_context=[n.node.get_content() for n in response.source_nodes]
)

# 4. 评估
answer_relevancy.measure(test_case)
faithfulness.measure(test_case)
contextual_precision.measure(test_case)
print(f"Answer Relevancy: {answer_relevancy.score}")
print(f"Faithfulness: {faithfulness.score}")
print(f"Contextual Precision: {contextual_precision.score}")

DeepEval vs RAGAs:

  • RAGAs:开源、轻量
  • DeepEval:50+ 指标、多模态支持、企业级

来源:LlamaIndex 博客 https://www.llamaindex.ai/blog/evaluating-rag-with-deepeval-and-llamaindex


Q80. ⭐ Callback 机制是什么?Token 计数怎么实现?

难度:中级

参考答案:

from llama_index.core.callbacks import CallbackManager, TokenCountingHandler
import tiktoken

# 1. Token 计数 handler
token_counter = TokenCountingHandler(
    tokenizer=tiktoken.encoding_for_model("gpt-4").encode,
    verbose=True
)

# 2. 注册到 Settings
Settings.callback_manager = CallbackManager([token_counter])

# 3. 跑 query
response = query_engine.query("什么是 RAG?")

# 4. 查看 token 用量
print(f"Total LLM tokens: {token_counter.total_llm_token_count}")
print(f"Prompt tokens: {token_counter.prompt_llm_token_count}")
print(f"Completion tokens: {token_counter.completion_llm_token_count}")
print(f"Embedding tokens: {token_counter.total_embedding_token_count}")

# 5. 重置
token_counter.reset_counts()

生产价值:监控 LLM 成本、优化 token 消耗、限流。

来源:LlamaIndex Token Counter 文档 https://docs.llamaindex.ai/en/stable/api_reference/callbacks/token_counter/


Q81. ⭐ 自定义 Callback Handler 怎么写?

难度:高级

参考答案:

from llama_index.core.callbacks import BaseCallbackHandler
from llama_index.core.callbacks.schema import CBEventType

class MyObservabilityHandler(BaseCallbackHandler):
    def __init__(self):
        super().__init__()
        self.llm_calls = []
        self.retrieve_calls = []

    def on_event_start(
        self,
        event_type: CBEventType,
        payload: Optional[Dict] = None,
        event_id: str = "",
        parent_id: str = "",
        **kwargs
    ) -> str:
        return event_id

    def on_event_end(
        self,
        event_type: CBEventType,
        payload: Optional[Dict] = None,
        event_id: str = "",
        **kwargs
    ) -> None:
        if event_type == CBEventType.LLM:
            self.llm_calls.append({
                "timestamp": time.time(),
                "payload": payload,
            })
        elif event_type == CBEventType.RETRIEVE:
            self.retrieve_calls.append({
                "timestamp": time.time(),
                "nodes": len(payload.get("nodes", [])),
            })

# 注册
handler = MyObservabilityHandler()
Settings.callback_manager = CallbackManager([handler])

生产场景:

  • 推送 LLM 调用日志到 ELK / Datadog
  • 实时监控慢检索
  • 统计每个 Node 被召回次数(优化索引)

来源:LlamaIndex Callback 文档


Q82. ⭐ LlamaIndex 可观测性怎么做?生产监控指标有哪些?

难度:高级

参考答案:

生产监控体系:

  1. LlamaIndex 原生 OpenTelemetry:
from llama_index.core import set_global_handler
set_global_handler("arize_phoenix")  # 推送到 Phoenix
# 或
set_global_handler("langfuse")        # 推送到 Langfuse
  1. 关键指标:
类别 指标 监控工具
性能 Query 延迟 P50/P95/P99 Prometheus + Grafana
质量 Faithfulness、Answer Relevancy RAGAs + 定时任务
成本 LLM Token、Embedding Token TokenCountingHandler
检索 召回率、TopK 命中 自定义 Callback
业务 答案采纳率、用户反馈 前端埋点
  1. 告警规则:
  • 延迟 P95 > 5s → 告警
  • Faithfulness < 0.7 → 告警
  • Token 消耗超预算 → 告警

来源:LlamaIndex Observability 文档


Q83. ⭐ 怎么生成 RAG 评估集(TestSet)?

难度:中级

参考答案:

# RAGAs Testset Generator
from ragas.testset.generator import TestsetGenerator
from ragas.testset.evolutions import simple, reasoning, multi_context
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding

# 1. 加载文档
documents = SimpleDirectoryReader("./data").load_data()

# 2. 初始化生成器
generator_llm = OpenAI(model="gpt-3.5-turbo-16k")
critic_llm = OpenAI(model="gpt-4")
embeddings = OpenAIEmbedding()
generator = TestsetGenerator.from_llama_index(
    generator_llm=generator_llm,
    critic_llm=critic_llm,
    embeddings=embeddings,
)

# 3. 生成测试集
testset = generator.generate_with_llamaindex_docs(
    documents,
    test_size=50,
    distributions={simple: 0.4, reasoning: 0.3, multi_context: 0.3}
)

3 种 Question Evolution:

  • Simple:单文档直接答案
  • Reasoning:需要多步推理
  • Multi-Context:跨文档综合

来源:RAGAs 官方文档


Q84. Pairwise Comparison 评估怎么做?

难度:中级

参考答案:

from llama_index.core.evaluation import PairwiseComparisonEvaluator

# 比较两个 query engine 的输出
evaluator = PairwiseComparisonEvaluator(llm=llm)
result = evaluator.evaluate(
    query="什么是 RAG?",
    response_a=engine_a.query("什么是 RAG?"),
    response_b=engine_b.query("什么是 RAG?"),
)
# 返回哪个更好
print(f"Winner: {result.choice}")  # "A" / "B" / "Tie"
print(f"Score: {result.score}")

生产场景:

  • A/B test 两个版本的 RAG pipeline
  • 对比不同 chunk_size / embedder / LLM
  • 比单一指标更贴近真实偏好

来源:LlamaIndex 官方评估文档


Q85. 检索评估的 Hit Rate、MRR、NDCG 怎么算?

难度:中级

参考答案:

# Hit Rate: 至少有一个相关 doc 在 top-k
hit_rate = 1 if any(g in retrieved[:k] for g in ground_truth) else 0

# MRR (Mean Reciprocal Rank): 第一个相关 doc 排名的倒数
rr = 1 / rank_of_first_relevant_doc
mrr = mean(rr for all queries)

# NDCG (Normalized Discounted Cumulative Gain)
import numpy as np
def dcg(relevances, k):
    relevances = relevances[:k]
    return sum(rel / np.log2(i + 2) for i, rel in enumerate(relevances))
def ndcg(retrieved, ground_truth, k=10):
    relevances = [1 if d in ground_truth else 0 for d in retrieved[:k]]
    ideal = sorted(relevances, reverse=True)
    return dcg(relevances, k) / (dcg(ideal, k) + 1e-10)

目标值:

  • Hit Rate@10 > 0.85
  • MRR@10 > 0.6
  • NDCG@10 > 0.7

来源:RAG 评估通用指标


十、性能优化与生产实践(Q86 - Q93)

Q86. ⭐ LlamaIndex 性能调优有哪些关键点?

难度:高级

参考答案:

全链路优化清单:

环节 优化 收益
加载 多进程 num_workers=4 50%↓
切分 合理 chunk_size + overlap 20%↑ 质量
嵌入 用本地 BGE 替代 OpenAI 成本 0、延迟 -200ms
检索 向量库用 HNSW 索引 10x 速度
检索 加 Rerank 质量 +30%
检索 混合检索 召回 +15%
生成 异步 aquery 并发 10x
生成 streaming 体感延迟 -50%
生成 Prompt 压缩 token -30%
缓存 相同 query 缓存 成本 -50%
缓存 Token 计数监控 防止爆预算

来源:LlamaIndex 官方 Performance 文档


Q87. ⭐ 异步和流式怎么用?

难度:中级

参考答案:

import asyncio

# 1. 异步查询
async def async_query():
    response = await query_engine.aquery("什么是 RAG?")
    return response

# 2. 异步流式
async def stream_query():
    streaming_response = await query_engine.astream_query("什么是 RAG?")
    async for token in streaming_response.async_response_gen():
        print(token, end="", flush=True)

# 3. 并发多个 query
async def batch_queries():
    queries = ["q1", "q2", "q3"]
    tasks = [query_engine.aquery(q) for q in queries]
    responses = await asyncio.gather(*tasks)
    return responses

# 4. 异步 + 多个索引
async def multi_index_query():
    tasks = [
        index_a.aquery(q) for q in queries
    ] + [
        index_b.aquery(q) for q in queries
    ]
    responses = await asyncio.gather(*tasks)
    return responses

asyncio.run(async_query())

生产经验:

  • 同步代码改异步是性价比最高的优化(吞吐提升 5-10x)
  • async 让 LLM 的网络等待时间不阻塞

来源:LlamaIndex 官方 async 文档


Q88. ⭐ 怎么实现 LLM 调用缓存?生产怎么做?

难度:中级

参考答案:

# 方案1: LangChain Cache(如果有 LangChain 集成)
from langchain.cache import InMemoryCache
import langchain
langchain.llm_cache = InMemoryCache()

# 方案2: LlamaIndex 自带缓存(基于 query hash)
from llama_index.core.callbacks import CallbackManager
from llama_index.core import Settings

# 方案3: Redis 分布式缓存
import redis
r = redis.Redis()

def cached_query(q):
    key = f"rag:{hash(q)}"
    cached = r.get(key)
    if cached:
        return cached.decode()
    response = query_engine.query(q)
    r.setex(key, 3600, str(response))  # TTL 1h
    return str(response)

生产经验:

  • 缓存命中率通常 30-60%
  • 缓存粒度:按 query / query 改写后 hash
  • 配合查询改写(HyDE/Query Rewriting)提高命中率

来源:LlamaIndex 缓存文档


Q89. ⭐ Token 优化怎么做?

难度:中级

参考答案:

5 大优化策略:

  1. 减少 Prompt 长度:

    • 合理 similarity_top_k(5-10 别太多)
    • 用 compact 模式替代 refine
    • 缩短 system_prompt
  2. 压缩检索结果:

from llama_index.core.postprocessor import LongContextReorder
from llama_index.core.response_synthesizers import CompactAndRefine

# 上下文压缩(用小 LLM 提取关键信息)
from llama_index.core.postprocessor import SentenceEmbeddingOptimizer
optimizer = SentenceEmbeddingOptimizer(percentile_cutoff=0.5)
  1. Embedding 压缩:

    • 减小维度(text-embedding-3 支持 dimensions=512)
    • 量化(int8)
  2. 缓存(见 Q88)

  3. 小模型:

    • 默认用 gpt-4o-mini,关键场景用 gpt-4o
    • 评估/QA 用 gpt-3.5-turbo
    • 嵌入用 BGE 本地

来源:LlamaIndex 性能文档


Q90. ⭐ 索引重建 vs 增量更新怎么选?

难度:高级

参考答案:

全量重建(drop & rebuild):

# 1. 删除旧索引
import shutil
shutil.rmtree("./storage")

# 2. 重新构建
docs = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(docs)
index.storage_context.persist(persist_dir="./storage")

增量更新(推荐):

# 1. 加载旧索引
storage_context = StorageContext.from_defaults(persist_dir="./storage")
index = load_index_from_storage(storage_context)

# 2. 增量插入新文档
new_docs = SimpleDirectoryReader("./new_data").load_data()
for doc in new_docs:
    index.insert(doc)

# 3. 删除过期文档
index.delete_ref_doc(doc_id="old_doc_id")

# 4. 保存
index.storage_context.persist(persist_dir="./storage")

决策:

  • < 1M Node:增量更新
  • > 10M Node + 频繁更新:考虑重建 + 版本号
  • 嵌入模型升级:必须全量重建

生产经验:版本化索引 + 蓝绿发布(新索引构建完再切流量)。

来源:LlamaIndex Ingestion Pipeline 文档


Q91. ⭐ 怎么处理大批量文档(百万级)的索引构建?

难度:高级

参考答案:

完整生产方案:

# 1. 加载阶段
reader = SimpleDirectoryReader(
    "./data",
    recursive=True,
    required_exts=[".pdf", ".docx"]
)
docs = reader.load_data(num_workers=8)  # 并行

# 2. 切分 + 嵌入(分批处理避免 OOM)
from llama_index.core.node_parser import SentenceSplitter
splitter = SentenceSplitter(chunk_size=512, chunk_overlap=50)

# 3. 写入生产级向量库
import chromadb
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core import VectorStoreIndex, StorageContext

chroma_client = chromadb.PersistentClient(path="./chroma_prod")
collection = chroma_client.get_or_create_collection(
    "docs",
    metadata={"hnsw:space": "cosine"}
)
chroma_store = ChromaVectorStore(chroma_collection=collection)

storage_context = StorageContext.from_defaults(vector_store=chroma_store)

# 4. 分批构建
batch_size = 1000
all_nodes = splitter.get_nodes_from_documents(docs)
for i in range(0, len(all_nodes), batch_size):
    batch = all_nodes[i:i+batch_size]
    index = VectorStoreIndex(batch, storage_context=storage_context)
    print(f"Processed {i+len(batch)}/{len(all_nodes)} nodes")

生产经验:

  • 先小批测试,再放大
  • 持久化中间状态(IngestionPipeline + 缓存)
  • HNSW 索引参数调优:M=16, ef_construction=200 是好的起点

来源:LlamaIndex 官方 Ingestion 文档


Q92. ⭐ LlamaIndex 的 open_source_helpers(observability 生态)有哪些?

难度:中级

参考答案:

主要可观测性平台:

# 1. Phoenix (Arize)
import phoenix as px
from llama_index.core import set_global_handler
set_global_handler("arize_phoenix")

# 2. Langfuse
set_global_handler("langfuse")

# 3. OpenLLMetry (Traceloop)
set_global_handler("traceloop")

# 4. HoneyHive
set_global_handler("honeyhive")

# 5. Weights & Biases
set_global_handler("wandb")

生产推荐:

  • Phoenix:开源、本地、自部署
  • Langfuse:开源 + 云、易用
  • Arize:企业级
  • OpenLLMetry:OpenTelemetry 标准

统一标准:OpenTelemetry(OTel),所有平台都支持。

来源:LlamaIndex Observability 文档


Q93. ⭐ LlamaIndex 在企业级落地需要补哪些能力?

难度:高级

参考答案:

Demo 能跑 ≠ 生产能用。企业级必须补齐:

  1. 数据治理:

    • 权限过滤(metadata level)
    • 文档版本管理
    • 增量更新
    • 删除机制
  2. 质量保障:

    • 评估闭环(RAGAs + 定时)
    • Badcase 收集 + 回流
    • A/B test
    • 答案引用(溯源)
  3. 可观测性:

    • 全链路 trace
    • Token 监控
    • 告警机制
    • 用户反馈采集
  4. 性能与成本:

    • 异步 + 流式
    • 缓存层
    • 模型分级(小模型优先)
    • 冷热数据分离
  5. 安全合规:

    • 敏感数据脱敏
    • 审计日志
    • API 限流
    • 鉴权
  6. 工程化:

    • CI/CD
    • 容器化部署
    • 灾备
    • 灰度发布

来源:今日头条《LlamaIndex 全栈解析》


十一、高级特性与趋势(Q94 - Q100)

Q94. ⭐ SentenceWindowNodeParser 和 Small-to-Big 检索的优缺点?

难度:高级

参考答案:

优点:

  • 检索精度高:小颗粒(句子)匹配精确
  • 生成上下文全:大窗口给 LLM 完整语义
  • 实现简单:配置少,效果明显

缺点:

  • 节点多,存储大:每句 1 个 Node
  • 窗口固定:不能跨窗口合并
  • 依赖 PostProcessor:必须用 MetadataReplacementPostProcessor

适用场景:

  • 文档结构相对均匀
  • 需要精确引用(如法律条文)
  • 句子级别证据

生产数据:在合同/法律 RAG 场景,NDCG@10 比普通切片高 15-25%。

来源:CSDN《Llama-Index RAG 黑科技》


Q95. ⭐ RecursiveRetriever 怎么用?和 ParentDocumentRetriever 关系?

难度:高级

参考答案:

RecursiveRetriever 处理"小节点检索,父节点输出"的场景(类似 AutoMerging):

from llama_index.core.retrievers import RecursiveRetriever
from llama_index.core.query_engine import RetrieverQueryEngine

# 场景:小 node(精确检索)→ 大 node(完整上下文)
recursive_retriever = RecursiveRetriever(
    root_id="root",
    retriever_dict={
        "root": small_node_retriever,    # 小 node 检索
        # 自动跳转到对应父节点
    },
    node_dict=node_dict,  # id → Node 映射
)

和 AutoMerging 的关系:

  • 思路相同(先小后大)
  • AutoMerging 用父子关系,RecursiveRetriever 用 id 索引
  • AutoMerging 更推荐(API 更优雅)

来源:LlamaIndex 官方文档


Q96. ⭐ KnowledgeGraphIndex 在 v0.10+ 后为什么被替代?

难度:高级

参考答案:

替代原因:

  1. Schema 过于僵硬:SchemaLLMPathExtractor(possible_relations=[...]) 必须预定义关系类型
  2. 属性支持弱:节点和边只能存基本三元组,不能存丰富属性
  3. Graph RAG 需求变化:现代应用需要更灵活的数据模型

PropertyGraphIndex 优势:

  • 属性丰富:节点/边都支持 KV 属性
  • 结构灵活:无需预定义 schema
  • 多种 Extractor 组合:SimpleLLMPathExtractor + ImplicitPathExtractor
  • 多 sub-retriever 融合:向量 + 关键词 + 文本

迁移:

# 旧
from llama_index.core import KnowledgeGraphIndex
kg_index = KnowledgeGraphIndex.from_documents(docs)

# 新
from llama_index.core import PropertyGraphIndex
pg_index = PropertyGraphIndex.from_documents(
    docs,
    kg_extractors=[SimpleLLMPathExtractor(llm=llm)]
)

来源:LlamaIndex 官方迁移文档


Q97. ⭐ Structured Data Extraction(结构化数据抽取)怎么实现?

难度:中级

参考答案:

from pydantic import BaseModel, Field
from llama_index.core.program import LLMTextCompletionProgram

class Invoice(BaseModel):
    """发票信息"""
    invoice_no: str = Field(description="发票号码")
    amount: float = Field(description="金额")
    date: str = Field(description="开票日期")
    items: list[str] = Field(description="项目明细")

# 1. Pydantic 风格抽取
prompt = """
从以下文本中抽取发票信息:
{text}
"""
program = LLMTextCompletionProgram.from_defaults(
    output_cls=Invoice,
    prompt_template_str=prompt,
    llm=llm
)
invoice = program(text="发票号 12345,金额 1000 元...")
print(invoice.invoice_no, invoice.amount)

# 2. 批量抽取
from llama_index.core.extractors import PydanticExtractor
extractor = PydanticExtractor(
    output_cls=Invoice,
    llm=llm
)
extracted_nodes = extractor.extract(nodes)

生产应用:

  • 合同关键信息抽取
  • 简历解析
  • 发票/订单结构化
  • 知识图谱实体抽取

来源:LlamaIndex 官方 Structured Data 文档


Q98. ⭐ LangChain 和 LlamaIndex 2025-2026 趋势:哪个更值得学?

难度:高级

参考答案:

当前趋势:

  1. LlamaIndex 持续强化数据层:

    • Workflows 1.0 正式版
    • LlamaParse(云服务)成为强项
    • PropertyGraphIndex 成熟
    • 企业级多模态 RAG 落地
  2. LangChain 持续强化编排层:

    • LangGraph(图编排)
    • LangSmith(追踪)
    • LangServe(部署)
    • LCEL(表达式语言)
  3. 生态融合:

    • langchain-llama-index 互操作
    • LlamaIndexRetriever 可被 LangChain 链调用
    • 真实项目99% 都是组合使用

学习建议:

  • RAG 方向:LlamaIndex 优先(数据层更专业)
  • Agent 方向:LangGraph 优先(图编排更灵活)
  • 面试:两个都要懂,LlamaIndex 重点(题目要求)

来源:综合 LlamaIndex / LangChain 2025-2026 路线图


Q99. ⭐ LlamaIndex 在大厂面试中的高频追问有哪些?

难度:高级

参考答案:

大厂高频追问 TOP 20:

  1. ⭐ LlamaIndex 和 LangChain 区别?怎么选?
  2. ⭐ 100 万 PDF 怎么建索引?详细方案
  3. ⭐ chunk_size 怎么选?调优方法?
  4. ⭐ 用户反馈答案不准,你怎么 debug?
  5. ⭐ 召回率和答案质量哪个重要?怎么平衡?
  6. ⭐ 怎么评估 RAG?指标有哪些?
  7. ⭐ Graph RAG 和向量 RAG 区别?什么场景用?
  8. ⭐ 多模态 RAG 怎么做?图文混合检索?
  9. ⭐ v0.10+ 怎么从 ServiceContext 迁移?
  10. ⭐ Workflows 是什么?和 Agent 关系?
  11. ⭐ Function Calling 和 ReAct 区别?
  12. ⭐ 索引重建 vs 增量更新?
  13. ⭐ 怎么实现权限过滤?
  14. ⭐ 怎么降低 LLM 成本?Token 优化方法?
  15. ⭐ 流式输出怎么实现?
  16. ⭐ Multi-Document Agent 怎么路由?
  17. ⭐ SQL RAG / Text-to-SQL 怎么保证安全?
  18. ⭐ PropertyGraphIndex 和 KnowledgeGraphIndex 区别?
  19. ⭐ HyDE / Query Rewrite 怎么用?
  20. ⭐ 生产环境怎么监控 RAG 质量?

来源:CSDN/掘金/腾讯云开发者社区高频面经


Q100. ⭐ 大模型时代,RAG 和微调(Fine-tuning)怎么选?

难度:高级

参考答案:

维度 RAG 微调(Fine-tuning)
适用 知识更新频繁 / 需要溯源 改变模型行为/风格/格式
数据需求 文档库(结构化/非结构化) 高质量 QA 对(千-万级)
成本 低(检索+生成) 高(GPU + 数据标注)
更新速度 实时 慢(重新训练)
可解释性 强(能引用) 弱(黑盒)
风险 召回不准 灾难性遗忘、幻觉
典型场景 客服、知识库、合同 文风统一、格式转换

实战建议:

  • 80% 场景 RAG 优先
  • 两者经常组合:用 RAG 提供事实 + 微调控制风格
  • 微调不是越多越好,能 RAG 就别微调
  • “企业知识更新快” → 100% RAG
  • “模型需要遵循特定行业话术” → 微调

趋势:Agent + RAG 是 2025-2026 主旋律,小模型 + RAG 比"大模型一刀切"更经济。

来源:综合大厂 JD 和面经


🔥 速记清单(面试前 1 小时过一遍)

# 知识点 一句话总结
1 LlamaIndex 定位 数据层框架,RAG 专家
2 vs LangChain 数据 vs 编排,常组合
3 核心组件 Document→Node→Index→Retriever→QueryEngine
4 索引类型 VectorStoreIndex 是默认,PropertyGraphIndex 是图
5 ServiceContext→Settings v0.10+ 必须用 Settings 全局配置
6 Retriever vs QueryEngine 检索器 vs 完整问答引擎
7 response_mode compact 默认,tree_summarize 适合多 Node 总结
8 Hybrid Search 向量 + BM25 混合,专治生僻词
9 Rerank 性价比最高的优化,10 粗筛 → 5 精排
10 Small-to-Big 小索引大窗口,SentenceWindow/AutoMerging
11 Workflows v0.10+ 事件驱动框架,async + HITL
12 Agent 类型 FunctionCallingAgent 优先,ReAct 调试用
13 AgentWorkflow 多 Agent 协作 + handoff
14 Multi-Modal LlamaParse + MultiModalVectorStoreIndex
15 Graph RAG PropertyGraphIndex + SimpleLLMPathExtractor
16 KnowledgeGraphIndex 已弃用,被 PropertyGraphIndex 替代
17 评估 Faithfulness 必用 + RAGAs 集成
18 性能优化 async + streaming + cache + 小模型 + Rerank
19 生产铁律 70% 功夫在数据,metadata 必须设计好
20 趋势 Workflows + Agent + RAG 三件套

📚 参考资料

  1. LlamaIndex 官方文档:https://docs.llamaindex.ai
  2. LlamaIndex Deprecated Terms:https://developers.llamaindex.ai/python/framework/changes/deprecated_terms/
  3. LlamaIndex Workflows:https://docs.llamaindex.ai/en/stable/workflows/
  4. RAGAs 官方文档:https://docs.ragas.io/en/v0.1.21/howtos/integrations/llamaindex.html
  5. DeepEval + LlamaIndex:https://www.llamaindex.ai/blog/evaluating-rag-with-deepeval-and-llamaindex
  6. LlamaIndex Multi-Modal RAG:https://www.llamaindex.ai/blog/multi-modal-rag-621de7525fea
  7. CSDN 大模型面试题系列:https://blog.csdn.net/m0_59614665/article/details/152085484
  8. 腾讯云 LlamaIndex RAG 详解:https://cloud.tencent.com/developer/article/2629911
  9. CSDN LlamaIndex Workflows:https://blog.csdn.net/SearchB/article/details/159896003
  10. daily.dev LlamaIndex Hiring Guide:https://recruiter.daily.dev/stacks/llamaindex/
  11. CSDN LlamaIndex 高级使用:https://www.cnblogs.com/shouyin/p/19493867
  12. CSDN 属性图索引:https://blog.csdn.net/csdn122345/article/details/155579705
  13. CSDN AgentWorkflow 实战:https://blog.csdn.net/puzi0315/article/details/152566151
  14. theneuralbase Breaking Changes:https://theneuralbase.com/llamaindex-advanced/learn/beginner/version-upgrade-breaking-changes/

文档生成于 2025-2026 大模型面试备考季,配套大厂 AI/RAG 工程师岗位。如有错误欢迎指正。


本内容由 Coze AI 生成,请遵循相关法律法规及《人工智能生成合成内容标识办法》使用与传播。