🧠AI 框架与编排

LangChain 与 LlamaIndex

难度:⭐⭐ | 高频指数:🔥🔥🔥 | 应用岗相关度:★★★

面试回答

常见问法

  • LangChain 和 LlamaIndex 各自定位是什么,怎么选?
  • 你们项目里用了框架吗?踩过哪些坑?
  • 为什么很多团队用着用着就开始”去框架化”?
  • LangChain 的 Chain / Agent / Tool 这套抽象在生产上有什么问题?
  • LlamaIndex 在 RAG 场景上比 LangChain 强在哪?
  • 如果让你重新搭一套,会基于哪个框架,还是直接裸写?

回答

两者都是 LLM 应用层框架,但定位不一样。

LangChain 是通用编排框架,覆盖 Prompt、Chain、Agent、Tool、Memory、Callback 这一整套,目标是任何 LLM 应用都能搭起来。 LlamaIndex 是 RAG 专用框架,从一开始就围绕”数据接入 + 索引 + 检索”做深,对文档解析、Chunk 策略、检索器组合更专业。

工程上的关键认知是:框架的价值集中在原型阶段。一周内出第一版能跑的应用,框架能省下大量样板代码;但一旦上了线,开始追性能、追可调试、追定制化,框架的抽象层会逐步变成阻碍——这也是为什么很多团队最终都走向”框架灵感 + 自研落地”的混合形态。

面试时要表现出的判断力是:会用框架不等于理解系统,框架能屏蔽掉的复杂度才是面试官想问的部分。

追问

  • Chain 和 Agent 的区别是什么?什么场景该用哪个?
  • LlamaIndex 的 Node / Index / Retriever 三层抽象怎么对应到 RAG 流程?
  • 框架的 Callback / Trace 机制为什么在线上经常不够用?
  • 流式输出(streaming)在两个框架里支持得怎么样?
  • 如果要把 LangChain Agent 替换成自研 Loop,最难的部分是什么?
  • 你怎么评估”该不该上框架”这个决策?

原理展开

1. 两个框架的出身和定位

LangChain 起步早(2022 年底),赶上了 ChatGPT 爆发,定位就是”LLM 应用的瑞士军刀”,目标覆盖所有场景——Prompt 拼装、链式调用、工具调用、Agent、Memory、Eval、Callback 全做。

LlamaIndex 几乎同期出现(最初叫 GPT Index),定位窄得多:就是要把企业里那些 PDF、Confluence、Notion、数据库内容接入 LLM。围绕这一件事做深,所以它的强项是文档解析器、分层索引、检索器组合、Query Engine。

两边后来都在扩——LangChain 补 RAG,LlamaIndex 补 Agent——但底子和品味是不一样的:LangChain 偏”通用抽象”,LlamaIndex 偏”垂直深度”。

2. LangChain 的核心抽象

# 典型 LangChain 链路
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.agents import initialize_agent, Tool

prompt = PromptTemplate.from_template("回答问题:{q}")
chain = LLMChain(llm=llm, prompt=prompt)

agent = initialize_agent(
    tools=[Tool(name="search", func=web_search, description="...")],
    llm=llm,
    agent="zero-shot-react-description",
)

几个关键概念:

  • Chain:把多个调用串成流水线,输入输出契约固定
  • Agent:让 LLM 自己决定下一步调什么 Tool,循环到结束条件
  • Tool:可被 Agent 调用的外部能力,统一接口
  • Memory:把历史对话或中间状态持久化在 Chain 里
  • Callback:在 Chain/Agent 各生命周期点注入观测和钩子

设计上偏 OOP,模块层数多,每一层都做了通用抽象。上手快,但深入定制时常常要继承重写。

3. LlamaIndex 的核心抽象

# 典型 LlamaIndex RAG
from llama_index import VectorStoreIndex, SimpleDirectoryReader

docs = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(docs)
query_engine = index.as_query_engine(similarity_top_k=5)

response = query_engine.query("公司的差旅报销政策是什么?")

围绕 RAG 三层抽象:

  • Node:文档切片后的最小检索单元,带 metadata
  • Index:组织 Node 的结构,可以是向量索引、关键词索引、树索引、知识图谱索引
  • Retriever / QueryEngine:检索 + 生成的组合

它的强项不在于这套抽象本身——抽象其实跟自己写 RAG 没差太多——而在于周边生态:100+ 文档解析器、20+ 索引类型、各种高级检索策略(HyDE、子查询、路由)开箱即用。

4. 两个框架重合的部分和差异

维度LangChainLlamaIndex
Agent / Tool完整生态,是核心卖点后来补的,相对薄
RAG有,但抽象偏底层核心场景,封装最深
文档解析接第三方为主自家 LlamaParse 是头部
Prompt 管理模板 + Hub较弱
Memory多种实现(buffer / summary / vector)偏简单
Callback / 观测自带 + LangSmith自带 + 接 Phoenix / OpenTelemetry
抽象厚度厚(学习曲线陡)薄 + 垂直深

简单记:Agent / 通用编排选 LangChain,纯 RAG 选 LlamaIndex,两者都能搭,但各自最舒服的赛道不一样。

5. 为什么团队用着用着会”去框架化”

这个问题面试很爱问,因为能看出实战深度。常见原因有三类:

调试链路太深。 框架把多层 wrap 套起来后,一个 Prompt 真正发给模型时长什么样、Tool 调用为什么没触发、为什么 retry 了三次——经常要打开框架源码翻三四层才能看清。Trace 工具能缓解一部分,但本质上还是抽象成本。

定制困难。 比如想给 Agent 加一个”调用前先做 PII 脱敏”的钩子,框架的 Callback 接口可能不够灵活;想换一个奇怪的 Tool 调用协议,可能要重写一整个 Agent 类型。框架抽象总是基于”大家都这么做”的假设,业务一旦稍微偏,就要逆着抽象走。

性能边角料藏太深。 重试策略、batch、流式合并、token 用量统计、并行调用,框架的实现可能不是你团队需要的形态。一旦要严格控成本或控延迟,自己写一遍反而清爽。

6. 框架抽象的代价

抽象不是免费的,代价主要有:

  • 理解成本:要先理解框架的”心智模型”才能写出符合它的代码
  • 隐藏调用链:一行代码背后可能跑了 5 次 LLM 调用 + 3 次重试
  • 版本不稳定:LangChain 在 0.x → 1.x 阶段反复破坏式升级,迁移痛苦
  • 性能上限:框架内部的串行/同步实现,要并行化经常得自己绕
  • 定制粒度:钩子点有限,要插入业务逻辑往往得继承重写

工程上的判断标准是:如果框架抽象帮你省的代码 < 它带来的理解和定制成本,就该考虑去框架化。

7. 选型时怎么判断

按”项目阶段 × 团队规模 × 定制需求”三个维度判断:

原型 / 小团队 / 定制少    → 直接上框架,能跑就行
PoC 转生产 / 性能敏感     → 框架做底层,关键链路改写
长期项目 / 大团队 / 重定制 → 拆框架,留概念不留代码

实战里我倾向于:

  • 第一周用框架快速跑通,验证业务流程
  • 进入第二迭代时识别热点链路(最高频、最难调试、最性能敏感的那部分)
  • 把热点链路下沉成自研代码,框架只在边缘场景保留

8. “半自研”通常长什么样

很多团队最后落地的形态是这样的:

  • Prompt 管理:自己写 template + 版本管理,不用框架 PromptTemplate
  • LLM 调用层:直接调 OpenAI / Anthropic / vLLM SDK,自己加重试、限流、缓存、token 统计
  • RAG 检索层:参考 LlamaIndex 的设计,但用自己的 Retriever 接口,方便定制
  • Agent Loop:自己写一个 30 行的 while 循环,比框架 Agent 简单且可控
  • Trace:直接接 OpenTelemetry / LangFuse,不依赖框架自带 callback

保留的是设计灵感,丢掉的是抽象层。 这套做法的代价是初期慢,收益是后期可控、可调试、可演进。

对比总结

场景推荐
一周内出 demo / 内部工具LangChain(最全)
企业知识库 / 文档问答LlamaIndex
复杂 Agent + 多工具LangChain(Agent 生态强)
长期生产系统半自研(参考两者设计,自己写)
学习 RAG 各种模式LlamaIndex(实现最干净)
学习 Agent 模式LangChain(样例最多)

易错点

  • 把”会用框架”等同于”理解 LLM 系统”——面试官真正想问的是抽象背后的机制
  • 混淆 Chain 和 Agent——Chain 是固定流水线,Agent 是 LLM 自己决策下一步
  • 以为 LlamaIndex 只能做 RAG——它现在也能做 Agent,只是不是主战场
  • 不区分原型阶段和生产阶段——框架在两个阶段的 ROI 完全不同
  • 过度信任框架的默认实现——比如 LangChain 默认重试、默认 Chunk 大小、默认 prompt 都不一定适合你的场景
  • 小看版本升级成本——LangChain 历史上多次破坏式升级,绑死大版本要慎重

记忆技巧

记三组锚点就够:

  1. 定位差异:LangChain = 通用编排 / Agent 强;LlamaIndex = RAG 垂直 / 文档解析强
  2. 核心抽象:LangChain = Chain / Agent / Tool;LlamaIndex = Node / Index / Retriever
  3. 生产去化:原型上、生产下;保留设计,丢掉抽象

面试速答版

LangChain 和 LlamaIndex 都是 LLM 应用层框架,但定位不同——LangChain 偏通用编排,覆盖 Chain、Agent、Tool、Memory 全栈;LlamaIndex 围绕 RAG 做深,强项是文档接入、索引、检索器组合。

工程上,框架的价值集中在原型阶段,能快速出第一版;但生产系统里抽象会变成阻碍——调试链路深、定制困难、性能边角料藏太深,所以很多团队最后都走向”借鉴框架设计 + 自研关键链路”的形态。

选型判断:原型期用框架,生产期看团队和定制需求,热点链路尽量自己掌控。

面试加分版

如果想多讲一层,可以补:

  • 观测能力是框架真正的护城河:LangSmith / LlamaIndex Observability 提供的 Trace 体验,比自己接 OTel 要省事很多——这是即使去框架化也很难放弃的部分
  • 抽象的代价随业务复杂度非线性增长:简单场景框架是减法,复杂场景框架是加法
  • 框架的最大风险是”看起来好像懂了”——能跑通不等于知道为什么跑通,面试时被追问内部机制经常露馅
Related · 框架与编排