【AI应用开发】LangChain 中 Chain 和 Agent 核心区别?
1. 一句话回答
Chain 是"预定好的流水线"------每一步做什么已经定死了;Agent 是"自主决策者"------LLM 根据当前情况动态决定下一步做什么。Chain 是固定菜谱,Agent 是会自己翻冰箱做菜的厨师。
2. Chain 是什么
2.1 定义
Chain(链)= 把多个处理步骤按固定顺序串联起来,输入从第一个组件流向最后一个。
python
# Chain 的本质:一个固定的处理流水线
用户输入 → [步骤A] → [步骤B] → [步骤C] → 输出
# 你不能跳过步骤B,也不能在步骤C之后再回到步骤A
2.2 生活中的类比
Chain 就像:
- 工厂流水线:零件 → 打磨 → 喷漆 → 烘干 → 包装
- 自动售货机:投币 → 选货 → 出货
- 面包机:放料 → 和面 → 发酵 → 烘烤
每一步是固定的,顺序不能变。
2.3 最简单的 Chain 例子
python
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
# 一个简单的问答 Chain
prompt = PromptTemplate(
template="请用简洁的语言回答:{question}",
input_variables=["question"],
)
chain = LLMChain(llm=OpenAI(), prompt=prompt)
# 使用时:
answer = chain.run(question="什么是机器学习?")
# 内部执行:构造 Prompt → 调用 LLM → 返回答案
# 这是固定的,不能改变
2.4 更复杂的 Chain 例子
python
from langchain.chains import SequentialChain
# 多步骤 Chain:翻译 → 摘要 → 提取关键词
chain = SequentialChain(
chains=[
translate_chain, # 步骤1:必须翻译
summarize_chain, # 步骤2:必须摘要
keyword_chain, # 步骤3:必须提取关键词
],
input_variables=["text"],
output_variables=["translation", "summary", "keywords"],
)
# 每次调用都严格按 1→2→3 执行
# 无法跳过步骤2
# 无法根据翻译结果决定是否做摘要
3. Agent 是什么(LangChain 语境)
3.1 定义
Agent = LLM 作为"大脑",动态决策调用什么工具、以什么顺序调用。执行路径不是预先固定的。
python
# Agent 的本质:动态决策循环
用户输入 → LLM决策 → [可能需要工具A] → LLM再看 → [可能需要工具B] → ... → 输出
# 每次执行的步骤和顺序都可能不同,完全由 LLM 动态决定
3.2 生活中的类比
Agent 就像:
- 私人助理:你给目标,他自己决定怎么做
- 外卖小哥:看路况动态选择路线
- 自驾游:根据天气/兴趣临时改目的地
路径不是固定的,根据情况动态调整。
3.3 LangChain Agent 的最简例子
python
from langchain.agents import initialize_agent, AgentType
from langchain.tools import Tool
from langchain.llms import OpenAI
# 定义工具
tools = [
Tool(name="搜索", func=search_func, description="搜索互联网信息"),
Tool(name="计算器", func=calc_func, description="数学计算"),
]
# 初始化 Agent
agent = initialize_agent(
tools=tools,
llm=OpenAI(),
agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # ReAct 模式
verbose=True,
)
# 使用时:
# 场景1:用户问天气 → Agent 决定:需要搜索 → 调用搜索工具 → 回答
agent.run("北京今天天气怎么样?")
# 场景2:用户问数学 → Agent 决定:需要计算 → 调用计算器 → 回答
agent.run("1234 * 5678 等于多少?")
# 场景3:用户需要搜索+计算 → Agent 决定:先搜索再计算 → 回答
agent.run("苹果公司市值除以谷歌公司市值是多少?")
核心观察 :同一个 agent.run(),三个不同的问题,Agent 内部执行的步骤完全不同------这就是 Agent 和 Chain 最本质的区别。
4. 核心区别对比表
| 维度 | Chain | Agent |
|---|---|---|
| 执行路径 | 固定的、预定义的 | 动态的、LLM 决策的 |
| 决策权 | 开发者预先设定 | LLM 运行时决策 |
| 灵活性 | 低------不能偏离预设路径 | 高------可根据情况随时调整 |
| 可预测性 | 高------每次执行路径相同 | 低------每次可能走不同路径 |
| 工具使用 | 通常是固定的,每个节点调用固定工具 | 动态选择工具及其顺序 |
| 错误处理 | 预定义的 fallback | 可自主重试、换方案 |
| 适用任务 | 确定性、流程化的 | 非确定性、需要决策的 |
| 复杂度匹配 | 简单到中等 | 中等到复杂 |
| 调试难度 | 低------路径已知 | 高------路径不固定 |
| 稳定性 | 高 | 中(可能不稳定) |
| 成本 | 低(LLM 调用次数固定) | 不确定(取决于 LLM 决策) |
5. Chain 的工作机制详解
5.1 Chain 的内部结构
Chain 就像 DAG(有向无环图):
[输入]
│
▼
[节点 A] ←─ 执行某个函数
│
▼
[节点 B] ←─ 执行另一个函数
│
▼
[节点 C] ←─ 调用 LLM
│
▼
[输出]
所有边都是单向的,不会走回头路。
5.2 LangChain 中常见的 Chain 类型
① LLMChain(最基础)
python
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(
template="将以下文本翻译成英文:\n{text}",
input_variables=["text"],
)
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run(text="你好世界") # → "Hello World"
② SequentialChain(顺序执行)
python
from langchain.chains import SequentialChain, LLMChain
# 固定顺序:提取要点 → 扩展要点 → 润色
chain = SequentialChain(
chains=[extract_chain, expand_chain, polish_chain],
input_variables=["topic"],
output_variables=["extracted", "expanded", "polished"],
)
# 总是按 extract → expand → polish 的顺序
# 无法只做 extract 跳过 expand
③ RouterChain(条件路由)
python
from langchain.chains.router import MultiPromptChain
# 根据输入类型选择不同的 Prompt 模板
# 但路由规则是预定义的,不是 LLM 自由决定的
router_chain = MultiPromptChain(
router_chain=llm_chain,
destination_chains={
"physics": physics_chain,
"math": math_chain,
"general": general_chain,
},
default_chain=general_chain,
)
④ RetrievalQA Chain(RAG 专用)
python
from langchain.chains import RetrievalQA
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 把检索结果拼一起给 LLM
retriever=vector_store.as_retriever(),
)
# 固定流程:检索文档 → 拼 Prompt → LLM 回答
6. Agent 的工作机制详解
6.1 Agent 的内部结构
Agent 的核心 = AgentLoop(不是固定 DAG):
┌─────────────────────────────────┐
│ 用户输入 │
└────────────┬────────────────────┘
│
▼
┌──────────────────────────┐
│ LLM 分析(思考) │ ← "我该用什么工具?"
└────────────┬─────────────┘
│
┌────────┴────────┐
│ │
▼ ▼
[需要工具] [直接回答]
│ │
▼ ▼
调用工具 输出答案
│
▼
拿到结果
│
└──→ 回到 LLM 分析 ──→ 循环
6.2 Agent 的决策逻辑
python
# Agent 每次调 LLM 时,本质上在问:
# "基于当前状态,我应该做什么?"
# LLM 看到的信息:
{
"system": "你是一个能使用工具的助手...",
"tools": [
{"name": "search", "description": "搜索互联网"},
{"name": "calculator", "description": "数学计算"},
],
"history": [
{"question": "苹果市值"},
{"action": "search('苹果市值')"},
{"result": "2.8 万亿美元"},
],
"current_state": "你刚获得了苹果市值是2.8万亿",
}
# LLM 决策:现在还缺什么?
# → 还需要谷歌市值
# → Action: search("谷歌市值")
6.3 LangChain 中 Agent 的类型
| Agent 类型 | 决策方式 | 适用场景 |
|---|---|---|
| Zero-shot ReAct | 每次推理都从零开始,基于工具描述决策 | 工具少、任务简单 |
| Conversational ReAct | 带对话记忆的 ReAct | 多轮对话 |
| OpenAI Functions | 使用 OpenAI Function Calling | GPT 模型,生产推荐 |
| Structured Chat | 支持多参数的结构化工具 | 复杂工具参数 |
| Self-ask with Search | 自问自答式拆分问题 | 推理链长的搜索任务 |
7. 同一个任务的 Chain vs Agent 对比
任务:「查一下苹果和谷歌的市值,算平均值」
Chain 方案(固定步骤)
python
# 开发者必须提前知道并编码所有步骤
chain = SequentialChain(chains=[
search_step1, # 步骤1:搜索苹果市值 → 固定!
search_step2, # 步骤2:搜索谷歌市值 → 固定!
extract_step1, # 步骤3:提取苹果数值 → 固定!
extract_step2, # 步骤4:提取谷歌数值 → 固定!
calc_avg, # 步骤5:算平均值 → 固定!
])
# 问题:
# - 如果搜索结果格式变了,extract 步骤可能失败
# - 无法处理"搜索结果里同时提到两个公司"的情况
# - 如果第一步搜索就用错了关键词,后面全错
Agent 方案(动态决策)
python
agent = initialize_agent(
tools=[search_tool, calculator_tool],
llm=llm,
agent=AgentType.OPENAI_FUNCTIONS,
)
# Agent 内部执行(LLM 自主决策):
# Round 1: Thought: 需要查苹果市值 → Action: search("苹果市值")
# Round 2: Observation: "苹果市值2.8万亿" → Thought: 还需要谷歌
# Action: search("谷歌市值")
# Round 3: Observation: "谷歌市值1.7万亿" → Thought: 都有,可以算了
# Action: calculator("(2.8+1.7)/2")
# Round 4: Thought: 算好了 → Final Answer: "平均市值2.25万亿"
# 灵活性:
# - 如果搜索结果变了,LLM 能自适应提取
# - 如果搜索出错,LLM 可以换关键词重试
# - 如果一次搜索就返回了两个数据,少走一步
直观对比
Chain:
搜索A → 搜索B → 提取A → 提取B → 计算 → 回答
└────── 我只会这个,不能变 ──────┘
Agent:
搜索 → 看看 → 不够 → 再搜 → 够了 → 计算 → 回答
└── 走多少步、用什么工具,看情况决定 ──┘
8. 什么时候用 Chain,什么时候用 Agent
8.1 用 Chain 的场景
如果以下条件全部满足,Chain 就够了:
- ✅ 流程固定不变,不会因输入不同而改变步骤
- ✅ 不需要根据中间结果做决策
- ✅ 不需要动态选择工具
- ✅ 追求稳定性和可预测性
- ✅ 预算有限,需要控制 LLM 调用次数
典型例子:
- 翻译 + 摘要的固定流水线
- 固定格式的数据提取
- RAG 问答(检索→拼接→回答,路径固定)
- 文本分类 → 路由到不同处理
8.2 用 Agent 的场景
以下任一条件满足,就值得考虑 Agent:
- ✅ 需要根据情况动态决定调用哪些工具
- ✅ 步骤数不固定,取决于任务复杂度
- ✅ 需要自主纠错和重试
- ✅ 存在条件分支(if-else 逻辑)
- ✅ 任务需要多步推理
典型例子:
- 智能客服(查订单、改地址、退款的组合)
- 数据分析助手(需要判断用什么分析方法的)
- 自动化办公(查邮件→提取任务→创建日程的组合)
- 编码助手(读文件→写代码→运行→修bug的循环)
8.3 混合方案:Chain 内嵌套 Agent
实用模式:固定框架用 Chain,需要灵活的地方嵌入 Agent:
python
# 固定流程:
# 接受文档 → Agent分析(灵活) → 格式化输出(固定)
from langchain.chains import TransformChain
def analyze_with_agent(inputs):
"""用 Agent 灵活分析文档(路径不固定)"""
result = agent.run(f"分析这份文档:{inputs['document']}")
return {"analysis": result}
# 固定流程,但中间步骤使用了 Agent
hybrid_chain = SequentialChain(chains=[
load_document_chain, # 固定:加载文档
TransformChain( # 灵活:Agent 分析
transform=analyze_with_agent,
input_variables=["document"],
output_variables=["analysis"],
),
format_output_chain, # 固定:格式化输出
])
9. LangChain 主要 Chain 类型一览
| Chain 类型 | 用途 | 复杂度 |
|---|---|---|
| LLMChain | 基础:Prompt + LLM | ⭐ |
| SequentialChain | 多步骤流水线 | ⭐⭐ |
| RouterChain | 按规则路由到不同子 Chain | ⭐⭐ |
| RetrievalQA | RAG 问答专用 | ⭐⭐ |
| ConversationalRetrievalChain | 带对话历史的 RAG | ⭐⭐⭐ |
| MapReduceChain | 分片处理长文档后合并 | ⭐⭐⭐ |
| RefineChain | 逐步优化回答 | ⭐⭐⭐ |
| AgentExecutor | Agent 执行器(动态决策) | ⭐⭐⭐⭐ |
10. 代码对比:手写和理解
10.1 Chain 的本质
python
"""
Chain 的本质:一个 callable,输入进,输出出,中间流程固定
用原生 Python 写就是这样:
"""
def my_rag_chain(question: str) -> str:
"""固定流程的 RAG Chain"""
# 步骤1:检索相关文档(固定)
docs = vector_store.search(question, top_k=3)
# 步骤2:构造 Prompt(固定模板)
context = "\n".join(docs)
prompt = f"参考以下信息回答:\n{context}\n\n问题:{question}"
# 步骤3:调用 LLM(固定)
answer = llm(prompt)
# 步骤4:返回(固定)
return answer
# 这个函数就是 Chain 的本质:固定步骤的流水线
# LangChain 的 Chain 只是把这个包装得更好用和更通用
10.2 Agent 的本质
python
"""
Agent 的本质:while 循环 + LLM 决策
用原生 Python 写就是这样:
"""
def my_agent(user_input: str, tools: dict) -> str:
"""动态决策的 Agent"""
messages = [{"role": "user", "content": user_input}]
# 关键区别:while 循环!
while True:
response = llm.invoke(messages, tools=tools)
if not response.tool_calls:
return response.content # 完成了
# 执行工具调用(动态决定调用哪个、什么参数)
for tc in response.tool_calls:
result = tools[tc.name](**tc.args)
messages.append({"role": "tool", "content": result})
# 回到循环开头,让 LLM 基于新信息再次决策
# 这个 while 循环就是 Agent 和 Chain 的本质区别
# Chain 没有循环,Agent 有一个动态循环
11. 常见误区澄清
误区 1:「RouterChain 就是 Agent」
不是。 RouterChain 的路由规则是预定义的条件判断 (比如"如果是数学问题→路由到数学 Chain"),Agent 的路由是 LLM 动态推理决定。
python
# RouterChain:预定义规则
if "计算" in question:
route_to = calculator_chain
elif "天气" in question:
route_to = weather_chain
# 规则是死的
# Agent:LLM 推理
# LLM 自己分析:"这个问题需要先搜索再计算"
# 没有预定义的规则,完全靠 LLM 的语义理解
误区 2:「用了 LLM 就是 Agent」
不是。 简单的 LLMChain 也调用 LLM,但它只是"把 Prompt 给 LLM 拿到答案",没有决策循环。
python
# 这是 Chain,不是 Agent
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run("你好")
# 这是 Agent(有决策循环 + 工具)
agent = initialize_agent(tools=[...], llm=llm)
result = agent.run("帮我查天气")
误区 3:「Agent 一定比 Chain 好」
不是。 Agent 灵活但不可控。生产环境中很多场景用 Chain 更合适:
- 流程固定的场景 → Chain 更稳定、更便宜
- 需要审计的场景 → Chain 的行为可预测、可审计
- 成本敏感场景 → Chain 的 LLM 调用次数确定
12. 本篇总结与系列完结
本文总结
| 问题 | 答案 |
|---|---|
| Chain 是什么? | 固定步骤的流水线,输入流向输出,路径预定义 |
| Agent 是什么? | LLM 自主决策 + 动态工具调用的执行循环 |
| 核心区别? | Chain 路径固定(DAG),Agent 路径动态(while 循环) |
| 什么时候用 Chain? | 流程确定、可预测、预算可控的场景 |
| 什么时候用 Agent? | 需要动态决策、多步推理、条件分支的场景 |
| 能混用吗? | 能,Chain 中嵌入 Agent,各取所长 |
系列十篇完结总结
| 篇目 | 核心知识 | 面试要点 |
|---|---|---|
| 一:Agent vs RAG | Agent = LLM + 工具 + 循环 | RAG 回答,Agent 做事 |
| 二:ReAct 原理 | Thought→Action→Observation 循环 | 相比普通 LLM,多了外部数据获取能力 |
| 三:Function Calling | LLM 决策 + 代码执行 | 6 种失败场景,JSON Schema 约束 |
| 四:Agent Memory | 工作/短期/长期三层 | 每层的生命周期和存储方式 |
| 五:无限循环限制 | 5 层防御体系 | 步数+重复+Token+超时+监控 |
| 六:上下文窗口 | Token 上限、Lost in the Middle | 长不一定好,信噪比是关键 |
| 七:文本分块大小 | 300-1000 字最佳 | 太小语义碎,太大噪声多 |
| 八:向量维度 1536 | Ada-002 的遗产 | 高维不一定好,维度灾难 |
| 九:混合检索 | BM25 + 向量 + RRF | 精确词与语义互补 |
| 十:Chain vs Agent | 固定流水线 vs 动态循环 | 稳定选 Chain,灵活选 Agent |
一句话记住:Chain 是你编排好的流水线,Agent 是会自己思考的行动者------选哪个取决于你的任务需要的是"稳定可控"还是"灵活自主"。