侧边栏壁纸
  • 累计撰写 56 篇文章
  • 累计创建 5 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

LlamaIndex面试100题

温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

LlamaIndex 面试八股文 · 100题

面向大厂 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:原始文档对象,含 textmetadata
  • 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 状态持久化:支持暂停-恢复,适合长任务/异步人工审批

废弃清单(必记):

  • ServiceContextSettings
  • AgentRunner / AgentWorkerAgentWorkflow
  • QueryPipelineWorkflows
  • GPTSimpleVectorIndexVectorStoreIndex
  • 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 通过 LlamaHubllama-hub.com)提供 100+ 数据源 Reader,常见的:

数据源 Reader
Notion NotionPageReader
Slack SlackReader
Discord DiscordReader
GitHub GithubRepositoryReader
PostgreSQL DatabaseReader
MongoDB MongoDBReader
Web SimpleWebPageReaderBeautifulSoupWebReader
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
  • 跨文档总结 → SummaryIndexTreeIndex
  • 实体关系强 → 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
可扩展性
抽取器 SimpleLLMPathExtractorImplicitPathExtractor 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 Termshttps://developers.llamaindex.ai/python/framework/changes/deprecated_terms/
  3. LlamaIndex Workflowshttps://docs.llamaindex.ai/en/stable/workflows/
  4. RAGAs 官方文档https://docs.ragas.io/en/v0.1.21/howtos/integrations/llamaindex.html
  5. DeepEval + LlamaIndexhttps://www.llamaindex.ai/blog/evaluating-rag-with-deepeval-and-llamaindex
  6. LlamaIndex Multi-Modal RAGhttps://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 Workflowshttps://blog.csdn.net/SearchB/article/details/159896003
  10. daily.dev LlamaIndex Hiring Guidehttps://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 Changeshttps://theneuralbase.com/llamaindex-advanced/learn/beginner/version-upgrade-breaking-changes/

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


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

0

评论区