Appearance
100. LangChain 核心组件详解
难度 P1 高频 · 岗位 应用 · 频率 ★★★ · 预计阅读 19 min
本题阅读地图
- 💡 简要回答
- 📝 详细解析
- 🎯 面试总结
👔面试官:详细说说 LangChain 的几个核心组件:Agent、Chain、Prompt Template、Output Parser、Memory……都是怎么用的?
🙋♂️我:Agent 是智能体,可以调用工具自动执行任务;Chain 是组件链式组合;Prompt Template 是提示词模板;Output Parser 解析输出;Memory 存对话历史……
👔面试官:说得比较泛。Prompt Template 有哪些类型?Few-shot Prompt 怎么实现?Output Parser 具体怎么解析结构化输出?Memory 有哪些实现方式,各有什么适用场景?
🙋♂️我:Prompt Template 有……普通的和带变量的?Few-shot 就是在 prompt 里加示例?Output Parser 用正则或者 JSON 解析?Memory 有 BufferMemory 和 SummaryMemory?
👔面试官:对,但不够深入。Few-shot 示例可以动态选择而不是固定放所有;Output Parser 可以用 Pydantic 做类型安全的解析;Memory 有 Buffer、Summary、Vector 等多种策略。下面详细展开。
💡 简要回答
LangChain 的核心组件我分几类来理解:
构建块:Prompt Template(提示词模板)、LLM(模型接口)、Output Parser(输出解析器)
组合机制:Chain(链式组合,LCEL 语法)、Agent(自主决策的智能体)
扩展能力:Memory(记忆管理)、Retriever(文档检索)、Tool(外部工具)
高级功能:Example Selector(动态选择示例)、Document Loader(文档加载)、Text Splitter(文本分割)
📝 详细解析
Agent:自主决策的智能体
Agent 是 LangChain 最核心的功能之一,它封装了 ReAct 等推理模式,让 LLM 能自主决策、调用工具。
python
from langchain.agents import create_openai_tools_agent, AgentExecutor
from langchain_core.tools import tool
# 1. 定义工具
@tool
def search_weather(city: str) -> str:
"""查询指定城市的天气"""
return f"{city}今天晴天,25°C"
@tool
def send_email(to: str, subject: str, body: str) -> str:
"""发送邮件"""
return f"邮件已发送给 {to}"
tools = [search_weather, send_email]
# 2. 创建 Agent
agent = create_openai_tools_agent(llm, tools, prompt)
# 3. 执行(自动循环直到完成)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = agent_executor.invoke({"input": "查一下北京天气,然后发邮件给老板"})
# Agent 自动:查天气 → 生成邮件内容 → 调用发送邮件create_openai_tools_agent 是基于 OpenAI Function Calling 的现代 Agent,比旧的 ReAct Agent 更可靠。
Prompt Template:灵活的提示词管理
Prompt Template 支持变量插值、条件渲染、消息格式化。
python
from langchain_core.prompts import (
PromptTemplate, # 单轮文本提示
ChatPromptTemplate, # 多轮对话提示
FewShotPromptTemplate, # 带示例的提示
MessagesPlaceholder # 动态消息占位
)
# 1. 基础模板 - 变量插值
prompt = PromptTemplate.from_template(
"你是一个{role}专家,请回答:{question}"
)
prompt.format(role="医疗", question="头痛怎么办?")
# 输出:你是一个医疗专家,请回答:头痛怎么办?
# 2. Chat Prompt - 多轮对话
chat_prompt = ChatPromptTemplate.from_messages([
("system", "你是{role}助手"),
("human", "{question}"),
MessagesPlaceholder(variable_name="history"), # 动态插入历史消息
("human", "{follow_up}")
])
# 3. Few-shot Prompt - 带示例学习
examples = [
{"question": "2+2=?", "answer": "4"},
{"question": "5*6=?", "answer": "30"},
]
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=PromptTemplate(
input_variables=["question", "answer"],
template="Q: {question}\nA: {answer}"
),
suffix="Q: {input}\nA:", # 最终的问题
input_variables=["input"]
)Example Selector:动态选择最相关示例
Few-shot 示例不是越多越好,太多会占用大量 token。应该根据当前问题,动态选择最相关的几个示例。
python
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
# 示例库
examples = [
{"input": "你好", "output": "你好!有什么可以帮你?"},
{"input": "退款", "output": "请提供订单号,我帮您查询退款政策。"},
{"input": "投诉", "output": "非常抱歉给您带来不便,请详细描述问题..."},
]
# 动态选择器:根据语义相似度选最相关的 k 个
selector = SemanticSimilarityExampleSelector.from_examples(
examples,
OpenAIEmbeddings(),
Chroma,
k=2 # 只选 2 个最相关的
)
# 当前问题是关于退款的,会自动选 "退款" 相关的示例
selected = selector.select_examples({"input": "我要退货"})Output Parser:结构化输出解析
LLM 输出是文本,但往往需要解析成结构化数据(JSON、对象等)。
python
from langchain.output_parsers import (
PydanticOutputParser, # 解析为 Pydantic 模型
CommaSeparatedListOutputParser, # 解析为列表
StructuredOutputParser # 解析为结构化字典
)
from pydantic import BaseModel, Field
# 1. Pydantic Output Parser(推荐)
class Person(BaseModel):
name: str = Field(description="人物姓名")
age: int = Field(description="年龄")
skills: list[str] = Field(description="技能列表")
parser = PydanticOutputParser(pydantic_object=Person)
# Parser 会自动生成格式指令,要求 LLM 按 JSON 输出
format_instructions = parser.get_format_instructions()
# 输出:{"name": string, "age": integer, "skills": [string, ...]}
prompt = PromptTemplate(
template="提取以下文本中的人物信息。\n{format_instructions}\n\n文本:{text}\n",
input_variables=["text"],
partial_variables={"format_instructions": format_instructions}
)
llm_output = llm.invoke(prompt.format(text="张三,30岁,会Python和Java"))
person = parser.parse(llm_output) # 自动解析为 Person 对象
print(person.name) # "张三"
print(person.skills) # ["Python", "Java"]
# 2. 列表解析器
list_parser = CommaSeparatedListOutputParser()
llm_output = "苹果, 香蕉, 橙子"
items = list_parser.parse(llm_output) # ["苹果", "香蕉", "橙子"]Memory:对话记忆管理
LangChain 提供了多种 Memory 实现,适应不同场景:
python
from langchain.memory import (
ConversationBufferMemory, # 原始缓冲,存所有消息
ConversationBufferWindowMemory, # 滑动窗口,只存最近 k 轮
ConversationSummaryMemory, # 摘要记忆,对旧对话做摘要
ConversationSummaryBufferMemory, # 混合:近期完整 + 久远摘要
VectorStoreRetrieverMemory # 向量检索记忆
)
# 1. Buffer Memory - 简单但容易超 token
memory = ConversationBufferMemory()
memory.save_context(
{"input": "你好"},
{"output": "你好!有什么可以帮你?"}
)
memory.load_memory_variables({}) # 返回完整历史
# 2. Window Memory - 只保留最近 k 轮
window_memory = ConversationBufferWindowMemory(k=5)
# 3. Summary Memory - 对旧对话做摘要(推荐)
summary_memory = ConversationSummaryMemory(llm=llm)
# 早期对话 → LLM 摘要
# 近期对话 → 保留原文
# 4. Summary Buffer Memory - 混合策略(最佳实践)
buffer_summary = ConversationSummaryBufferMemory(
llm=llm,
max_token_limit=2000 # 超过后触发摘要
)Retriever:RAG 检索
Retriever 是 RAG 的核心,从向量库检索相关文档。
python
from langchain_community.vectorstores import Chroma, FAISS
from langchain_openai import OpenAIEmbeddings
# 1. 创建向量库
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)
# 2. 获取 Retriever
retriever = vectorstore.as_retriever(
search_type="similarity", # 或 "mmr"(最大边际相关性)
search_kwargs={"k": 4} # 返回 4 个最相关文档
)
# 3. 检索
relevant_docs = retriever.invoke("什么是 RAG?")🎯 面试总结
面试回答 LangChain 组件,要能说出每个组件的作用和使用场景:
| 组件 | 核心作用 | 关键用法 |
|---|---|---|
| Agent | 自主决策、调用工具 | create_openai_tools_agent |
| Prompt Template | 提示词模板化 | 变量插值、Few-shot、消息占位 |
| Example Selector | 动态选示例 | 语义相似度选择,减少 token |
| Output Parser | 结构化解析 | PydanticOutputParser 类型安全 |
| Memory | 对话历史管理 | SummaryBufferMemory 平衡完整与精简 |
| Retriever | 文档检索 | as_retriever() 统一接口 |