LangChain五大核心概念解析:从组件化到智能体构建
2026/7/23 1:56:46 网站建设 项目流程

在实际 AI 应用开发中,直接调用大语言模型 API 往往只能完成简单的问答。当需求变得复杂,例如需要模型记住对话历史、调用外部工具、处理长文档或执行多步骤推理时,代码会迅速变得臃肿且难以维护。这正是 LangChain 这类框架要解决的核心问题。它通过提供一套标准化的抽象组件,将复杂的 AI 应用流程模块化,让开发者能像搭积木一样构建功能强大的 AI Agent。

本文面向已经了解大语言模型基础调用,希望构建更复杂、更智能应用的开发者。我们将深入 LangChain 的五个核心概念:Model I/ORetrievalChainsMemoryAgents。理解这些概念不仅是使用 LangChain 的基础,更是理解现代 AI Agent 架构设计思想的关键。通过本文,你将能清晰地知道每个组件的作用、如何组合它们,并能够动手搭建一个具备记忆、工具调用和知识检索能力的简易 AI Agent。

1. 理解 LangChain 的核心设计思想:组件化与编排

在深入具体概念前,必须先理解 LangChain 的设计哲学。它不是一个黑盒的“AI 应用生成器”,而是一个组件化框架编排工具。其核心价值在于将 AI 应用开发中常见的模式抽象为可复用、可互换的“乐高积木”。

1.1 为什么需要组件化?

想象一下,你要开发一个能查询公司内部文档的聊天机器人。你需要处理以下问题:

  1. 将用户问题(自然语言)转换为模型能理解的格式(Prompt)。
  2. 从海量文档中快速找到相关片段(Retrieval)。
  3. 将找到的片段和用户问题组合成一个有效的指令,发给模型(Prompt Engineering)。
  4. 让模型能参考之前的对话历史(Memory)。
  5. 当问题涉及计算或实时信息时,让模型能调用计算器或搜索引擎(Tool Calling)。

如果不使用框架,你可能需要自己编写大量的胶水代码来处理这些环节之间的数据传递、错误处理和流程控制。LangChain 将这些环节标准化为组件,例如LLM(模型)、PromptTemplate(提示词模板)、DocumentLoader(文档加载器)、VectorStore(向量数据库)、Memory(记忆)和Tool(工具)。

1.2 编排(Orchestration)是关键

仅有组件还不够,如何将它们有序地连接起来执行一个任务,这就是编排。LangChain 提供了ChainAgent两种主要的编排范式。

  • Chain(链):预定义的、线性的执行流程。例如,“检索文档 -> 组合提示词 -> 调用模型 -> 解析输出”就是一个链。它稳定、可预测,适用于流程固定的任务。
  • Agent(智能体):由模型根据当前情况动态决定下一步执行哪个动作(如使用哪个工具)。它引入了推理和决策能力,适用于需要多步骤、条件判断的复杂任务。

理解了“组件化”和“编排”这两大支柱,我们再去看具体的五个核心概念,就会明白它们各自在架构中扮演的角色。

2. 核心概念一:Model I/O —— 与模型对话的标准化接口

Model I/O是 LangChain 中最基础的模块,它封装了与语言模型交互的整个过程,使其变得统一和可配置。这个过程主要分为三个子环节:输入(Prompt)、调用模型(LLM/ChatModel)、输出解析(OutputParser)。

2.1 Prompts:从字符串模板到动态构建

Prompt 是指导模型行为的指令。LangChain 的PromptTemplate允许你创建带有变量的模板。

from langchain.prompts import PromptTemplate # 创建一个简单的提示词模板 template = “请根据以下上下文回答问题。\n\n上下文:{context}\n\n问题:{question}\n\n答案:” prompt_template = PromptTemplate.from_template(template) # 动态填充变量 filled_prompt = prompt_template.format(context=“LangChain 是一个用于开发大语言模型应用的框架。”, question=“LangChain 是什么?”) print(filled_prompt)

输出将是:

请根据以下上下文回答问题。 上下文:LangChain 是一个用于开发大语言模型应用的框架。 问题:LangChain 是什么? 答案:

为什么重要?它实现了逻辑与内容的分离。你可以像管理配置文件一样管理不同的提示词模板,而无需在代码中拼接字符串。

2.2 Models:统一的模型调用层

LangChain 支持多种模型提供商(OpenAI, Anthropic, Google, 本地模型等)。通过抽象层,你可以用几乎相同的代码切换不同的模型。

from langchain_openai import ChatOpenAI from langchain_anthropic import ChatAnthropic # 使用 OpenAI GPT-4 llm_openai = ChatOpenAI(model=“gpt-4”, temperature=0) # 使用 Anthropic Claude llm_claude = ChatAnthropic(model=“claude-3-sonnet-20240229”, temperature=0) # 调用方式完全一致 # response = llm_openai.invoke(filled_prompt) # response = llm_claude.invoke(filled_prompt)

关键参数解释:

  • model:指定使用的模型名称。
  • temperature:控制输出的随机性(0-1)。值越低,输出越确定和一致;值越高,输出越有创造性。

2.3 Output Parsers:将模型输出结构化

模型的原始输出是文本。OutputParser负责将其解析为程序可用的结构化数据,如 JSON、列表或自定义对象。

from langchain.output_parsers import CommaSeparatedListOutputParser from langchain.prompts import PromptTemplate parser = CommaSeparatedListOutputParser() format_instructions = parser.get_format_instructions() # 获取格式说明,如“你的回答应该是一个用逗号分隔的列表。” prompt = PromptTemplate( template=“列举三种主要的水果。\n{format_instructions}\n”, input_variables=[], partial_variables={“format_instructions”: format_instructions} ) chain = prompt | llm_openai | parser # 使用 LangChain 表达式语言(LCEL)组合 result = chain.invoke({}) print(result) # 输出例如: [‘苹果’, ‘香蕉’, ‘橙子’]

为什么重要?它使得从模型获取的信息可以直接用于后续的程序逻辑,是实现自动化工作流的关键。

3. 核心概念二:Retrieval —— 让模型拥有“长期记忆”

大语言模型本身的知识受限于其训练数据,且无法记住非公开或实时信息。Retrieval(检索)模块通过从外部知识源(文档、数据库、API)中动态查找相关信息,并注入到提示词中,来扩展模型的能力。这是构建“知识库问答”系统的核心。

3.1 检索流程:从文档到答案

一个典型的检索流程包含以下步骤:

  1. 加载(Loading):从源(文件、网页、数据库)读取数据。
  2. 分割(Splitting):将长文档切分成语义相关的小块(chunks)。
  3. 向量化(Embedding):使用嵌入模型将文本块转换为数值向量。
  4. 存储(Storing):将向量存入向量数据库。
  5. 检索(Retrieval):将用户问题也向量化,并在数据库中查找最相似的文本块。
  6. 生成(Generation):将检索到的文本块作为上下文,与问题一起发送给模型生成答案。

3.2 关键组件与代码示例

from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings from langchain_chroma import Chroma # 1. 加载文档 loader = TextLoader(“./company_handbook.txt”) documents = loader.load() # 2. 分割文档 text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) docs = text_splitter.split_documents(documents) # 3. 初始化嵌入模型并存入向量数据库 embeddings = OpenAIEmbeddings() vectorstore = Chroma.from_documents(documents=docs, embedding=embeddings, persist_directory=“./chroma_db”) # 4. 创建检索器 retriever = vectorstore.as_retriever(search_kwargs={“k”: 2}) # 检索最相关的2个片段 # 5. 使用检索到的内容进行问答 from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI llm = ChatOpenAI(model=“gpt-3.5-turbo”, temperature=0) qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever) answer = qa_chain.invoke({“query”: “公司的年假政策是怎样的?”}) print(answer[“result”])

参数与注意事项:

  • chunk_size:每个文本块的大小。太小可能丢失上下文,太大可能包含无关信息。通常 500-1000 字符是常见起点。
  • chunk_overlap:块之间的重叠字符数。这有助于保持上下文的连贯性。
  • search_kwargs={“k”: n}:控制返回多少个相关片段。需要平衡信息完整性和提示词长度限制。

注意:向量检索的质量高度依赖于文本分割策略和嵌入模型。生产环境中,需要根据实际文档类型(技术文档、对话记录、代码)调整分割参数,并可能测试不同的嵌入模型。

4. 核心概念三:Chains —— 将组件串联成固定流程

Chain是 LangChain 得名的原因。它将多个组件(或其他 Chain)按预定顺序连接起来,形成一个可执行的序列。这是实现复杂但流程固定的 AI 应用的主要方式。

4.1 链的类型与 LCEL

LangChain 提供了两种主要的构建链的方式:传统Chain类和更灵活强大的LangChain 表达式语言(LCEL)。LCEL 使用管道运算符|来连接组件,推荐在新项目中使用。

from langchain.prompts import ChatPromptTemplate from langchain_openai import ChatOpenAI from langchain.schema.output_parser import StrOutputParser # 使用 LCEL 构建一个翻译链 prompt = ChatPromptTemplate.from_template(“将以下英文翻译成中文:{text}”) llm = ChatOpenAI(model=“gpt-3.5-turbo”, temperature=0) output_parser = StrOutputParser() translation_chain = prompt | llm | output_parser result = translation_chain.invoke({“text”: “Hello, LangChain!”}) print(result) # 输出:你好,LangChain!

4.2 构建复杂链:顺序链与检索链

一个链可以包含多个步骤。例如,一个总结链可以先提取关键词,再根据关键词进行总结。

from langchain.prompts import PromptTemplate from langchain.chains import LLMChain, SimpleSequentialChain # 链1:生成关键词 keyword_prompt = PromptTemplate( input_variables=[“document”], template=“请从以下文档中提取三个核心关键词:\n{document}” ) keyword_chain = LLMChain(llm=llm, prompt=keyword_prompt) # 链2:根据关键词总结 summary_prompt = PromptTemplate( input_variables=[“keywords”], template=“请基于这三个关键词:{keywords}, 生成一段简短的文档摘要。” ) summary_chain = LLMChain(llm=llm, prompt=summary_prompt) # 顺序组合链 overall_chain = SimpleSequentialChain(chains=[keyword_chain, summary_chain], verbose=True) document_text = “LangChain 是一个开源框架...(此处为长文档内容)” final_result = overall_chain.invoke(document_text) print(final_result[‘output’])

verbose=True时,你会看到链的每一步执行过程和中间结果,这对于调试非常有用。

常见链类型:

  • LLMChain:最基本的链,组合一个 PromptTemplate 和一个 LLM。
  • SequentialChain:按顺序执行多个链,可以传递多个输入输出。
  • RetrievalQA:我们之前用过的,是专门为“检索-问答”模式封装的链。
  • ConversationalRetrievalChain:在RetrievalQA基础上增加了对话历史管理。

5. 核心概念四:Memory —— 为对话赋予上下文

Memory使链或 Agent 能够记住跨多次交互的信息。这对于聊天机器人、多轮对话分析等场景至关重要。

5.1 记忆的类型

LangChain 提供了多种记忆类型,适用于不同场景:

记忆类型描述适用场景
ConversationBufferMemory简单地将所有对话历史以字符串形式保存在缓冲区。对话轮次较少,需要完整历史。
ConversationBufferWindowMemory只保留最近 K 轮对话。避免提示词因历史过长而超出模型限制。
ConversationSummaryMemory使用 LLM 定期总结之前的对话,只保留总结。长对话,需要保留核心信息但节省 token。
ConversationEntityMemory记忆对话中提到的具体实体(人物、地点等)及其属性。需要跟踪具体对象细节的复杂对话。

5.2 在链中使用记忆

以下示例展示如何将一个普通的链升级为带记忆的对话链。

from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationChain from langchain_openai import ChatOpenAI # 初始化记忆和模型 memory = ConversationBufferMemory() llm = ChatOpenAI(model=“gpt-3.5-turbo”, temperature=0.7) # 创建对话链 conversation = ConversationChain(llm=llm, memory=memory, verbose=True) # 进行多轮对话 print(conversation.invoke({“input”: “你好,我叫小明。”})[‘response’]) print(conversation.invoke({“input”: “我的名字是什么?”})[‘response’]) # 模型会记得名字

运行上述代码,在verbose模式下,你可以看到发送给模型的提示词中包含了之前的对话历史。

5.3 记忆与检索的结合

RetrievalQA中,如果需要结合历史对话,应使用ConversationalRetrievalChain。它会自动将当前问题与历史对话重新组合(rewrite),形成一个独立的、包含上下文的问题,再去检索和回答。

from langchain.chains import ConversationalRetrievalChain from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory(memory_key=“chat_history”, return_messages=True) qa_chain = ConversationalRetrievalChain.from_llm( llm=llm, retriever=retriever, # 上一节定义的检索器 memory=memory, verbose=True ) # 现在可以进行多轮基于知识库的问答了

6. 核心概念五:Agents —— 让模型自主决策与执行

Agent是 LangChain 中最能体现“智能体”概念的部分。与固定流程的Chain不同,Agent将语言模型作为“大脑”,动态地决定为了完成一个目标,需要执行哪些动作(调用哪些工具),并根据执行结果决定下一步。

6.1 Agent 的核心组件

一个 Agent 通常由以下几部分组成:

  1. LLM:负责推理和决策的大脑。
  2. Tools:Agent 可以调用的函数。例如:搜索引擎、计算器、数据库查询、代码执行器等。
  3. Toolkits:为特定领域(如 SQL、文件系统)预置的一组工具。
  4. Agent Executor:运行 Agent 的引擎,负责调用模型、解析输出、执行工具、并将结果反馈给模型,循环直到任务完成或达到限制。

6.2 构建一个简单的 Agent

以下示例创建一个能使用搜索引擎和计算器的 Agent。

from langchain.agents import AgentExecutor, create_react_agent from langchain import hub from langchain.tools import Tool from langchain_community.utilities import SerpAPIWrapper from langchain.agents import load_tools import math # 1. 定义自定义工具 def calculate_power(base: float, exponent: float) -> float: “”“计算幂。”“” return math.pow(base, exponent) # 2. 创建工具列表 search = SerpAPIWrapper() # 需要 SERPAPI_API_KEY 环境变量 tools = [ Tool( name=“Search”, func=search.run, description=“在互联网上搜索当前事件或事实信息。当你需要回答关于近期事件或具体事实的问题时使用。” ), Tool( name=“Calculator”, func=lambda x: eval(x), # 注意:生产环境请使用更安全的计算库,如 `numexpr` description=“执行数学计算。输入一个数学表达式字符串,如 ‘2 + 2’ 或 ‘sqrt(16)’。” ), Tool( name=“Power”, func=lambda x: calculate_power(**eval(x)), description=“计算幂。输入一个字典字符串,如 ‘{\“base\“: 2, \“exponent\“: 3}’, 返回 base^exponent。” ) ] # 3. 获取 ReAct 提示词模板,并创建 Agent prompt = hub.pull(“hwchase17/react”) llm = ChatOpenAI(model=“gpt-4”, temperature=0) agent = create_react_agent(llm, tools, prompt) # 4. 创建执行器 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, handle_parsing_errors=True) # 5. 运行 Agent result = agent_executor.invoke({“input”: “苹果公司最新的股价是多少?然后用这个股价计算一下如果我买100股需要多少钱。”}) print(result[“output”])

关键点解释:

  • create_react_agent:使用 ReAct(Reasoning + Acting)框架,该框架鼓励模型以“思考 -> 行动 -> 观察”的循环来解决问题。
  • Tooldescription:至关重要!模型根据工具的描述来决定在什么情况下使用哪个工具。描述必须清晰准确。
  • verbose=True:会打印出 Agent 的完整思考过程,包括它的“Thought”(思考)、“Action”(选择工具)、“Action Input”(工具输入)和“Observation”(工具输出)。
  • handle_parsing_errors=True:当模型输出的指令无法被解析为有效的工具调用时,让执行器尝试修复,而不是直接崩溃。

6.3 Agent 执行流程与排错

运行上述代码,你会看到类似以下的输出(已简化):

Thought: 用户问了两个问题。首先需要获取苹果公司的最新股价,这是一个事实性问题,我需要搜索。然后需要用这个股价进行计算。 Action: Search Action Input: 苹果公司最新股价 Observation: [搜索引擎返回的结果,例如:苹果公司(AAPL)最新股价为 $172.33] Thought: 我已经获得了股价 $172.33。现在需要计算购买100股的总金额。这是一个数学计算,应该使用计算器。 Action: Calculator Action Input: 172.33 * 100 Observation: 17233.0 Thought: 我计算出了总金额是17233美元。现在可以给出最终答案了。 Final Answer: 苹果公司最新股价约为172.33美元。购买100股需要大约17,233美元。

常见问题与排查:

  1. Agent 不调用工具,直接回答:检查工具描述是否清晰。模型可能认为自己的知识足以回答问题。尝试在问题中明确要求“请使用搜索工具查找”。
  2. 解析错误(Parsing Error):模型输出的格式不符合工具调用指令。确保使用handle_parsing_errors=True,并检查提示词模板是否合适。ReAct 模板通常比较稳定。
  3. 无限循环:模型可能陷入“思考-行动”的死循环。通过max_iterationsmax_execution_time参数限制执行器的运行次数和时间。

7. 综合实战:构建一个具备记忆、知识和工具调用能力的 AI Agent

现在,我们将前面所有概念组合起来,构建一个相对完整的 AI Agent。这个 Agent 能够:

  1. 记住与用户的对话历史(Memory)。
  2. 从内部知识库中查找信息(Retrieval)。
  3. 在需要时使用计算和搜索工具(Agent + Tools)。
  4. 通过一个统一的接口处理用户请求。

7.1 架构设计与组件选择

我们将采用“路由”的思想。设计一个主 Agent,它根据用户问题的类型,决定走哪条子链:

  • 通用聊天:使用带记忆的ConversationChain
  • 知识库问答:使用带记忆的ConversationalRetrievalChain
  • 需要计算或实时信息:使用Tool-calling Agent

由于 LangChain 本身不直接提供这种高级路由,我们可以通过一个简单的判断逻辑或使用LLMRouterChain来模拟。这里为了清晰,我们用一个基于关键词的简单路由逻辑来演示。

7.2 代码实现

from langchain.chains import ConversationChain, ConversationalRetrievalChain from langchain.agents import AgentExecutor, create_react_agent from langchain.memory import ConversationBufferMemory from langchain.prompts import PromptTemplate from langchain import hub import re class MultiCapabilityAgent: def __init__(self, llm, retriever, tools): self.llm = llm self.retriever = retriever self.tools = tools # 初始化通用聊天记忆和链 self.chat_memory = ConversationBufferMemory() self.chat_chain = ConversationChain(llm=llm, memory=self.chat_memory) # 初始化知识库问答记忆和链 self.qa_memory = ConversationBufferMemory(memory_key=“chat_history”, return_messages=True) self.qa_chain = ConversationalRetrievalChain.from_llm( llm=llm, retriever=retriever, memory=self.qa_memory, verbose=False ) # 初始化工具调用 Agent agent_prompt = hub.pull(“hwchase17/react”) agent = create_react_agent(llm, tools, agent_prompt) self.agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False, handle_parsing_errors=True, max_iterations=3) def route_question(self, query): “”“简单的基于关键词的路由逻辑。”“” query_lower = query.lower() # 如果包含“计算”、“多少”、“+”、“-”、“*”、“/”等,优先考虑工具 Agent(尤其是计算) if re.search(r‘计算|多少|^[\d\s\+\-\*\/\(\)]+$’, query_lower): return “agent” # 如果包含公司、产品、政策等特定名词,假设需要知识库 elif re.search(r‘公司|产品|政策|流程|手册’, query_lower): return “qa” # 否则,走通用聊天 else: return “chat” def invoke(self, query): route = self.route_question(query) print(f“路由决策:{route}”) if route == “agent”: try: result = self.agent_executor.invoke({“input”: query}) return result[“output”] except Exception as e: return f“工具调用失败,将转为通用聊天。错误:{e}” elif route == “qa”: result = self.qa_chain.invoke({“question”: query}) return result[“answer”] else: # chat result = self.chat_chain.invoke({“input”: query}) return result[“response”] # 初始化组件(假设 retriever 和 tools 已按前文定义好) # llm = ChatOpenAI(...) # retriever = vectorstore.as_retriever(...) # tools = [Tool(...), ...] # 创建全能 Agent my_agent = MultiCapabilityAgent(llm=llm, retriever=retriever, tools=tools) # 进行多轮交互 questions = [ “你好!”, “我们公司的年假有多少天?”, “计算一下 15 天的年假折算成小时是多少?(按每天8小时计)”, “刚才我们聊了什么?” ] for q in questions: print(f“用户:{q}”) response = my_agent.invoke(q) print(f“Agent:{response}\n”)

7.3 运行分析与优化方向

这个简易的 Agent 展示了如何整合多个 LangChain 模块。在实际生产中,你需要考虑以下优化:

  1. 更智能的路由:使用一个 LLM 来决策路由(LLMRouterChain),而不是简单的关键词匹配。
  2. 记忆共享:目前聊天记忆和问答记忆是分离的。可以考虑使用更高级的记忆结构,或在路由时传递相关历史。
  3. 错误处理与降级:如代码所示,当工具调用失败时,应有降级策略(如转为聊天或直接搜索)。
  4. 提示词工程:为每个链和 Agent 精心设计提示词,以优化其表现。
  5. 性能与成本:检索和工具调用可能涉及网络 I/O 和额外费用。需要考虑缓存、异步调用和成本控制。

8. 生产环境部署与最佳实践

将基于 LangChain 的 AI Agent 从开发环境推向生产,需要关注稳定性、可维护性和性能。

8.1 配置管理

切勿将 API 密钥等敏感信息硬编码在代码中。使用环境变量或专业的配置管理工具。

# .env 文件 OPENAI_API_KEY=sk-... SERPAPI_API_KEY=...
# 在代码中读取 from dotenv import load_dotenv import os load_dotenv() openai_api_key = os.getenv(“OPENAI_API_KEY”)

8.2 日志与监控

LangChain 内置的verbose=True在开发时很有用,但在生产环境应接入结构化的日志系统(如 Logging 模块, JSON 格式输出),并监控关键指标:

  • 每次调用的 Token 消耗。
  • 链/Agent 的执行耗时。
  • 工具调用的成功/失败率。
  • 用户反馈(如有)。

8.3 性能优化

  • 向量检索优化:索引优化、选择合适的嵌入模型、调整chunk_size和检索的k值。
  • 缓存:对频繁且结果不变的 LLM 调用或检索结果进行缓存。LangChain 提供了Cache接口,可以对接内存(InMemoryCache)或数据库(如RedisCache)。
  • 异步调用:对于 I/O 密集型的操作(如调用多个工具、批量处理文档),使用异步接口(ainvokeabatch)可以显著提升吞吐量。

8.4 安全与合规

  • 工具调用安全:像eval()这样的函数极其危险。为工具提供严格的输入验证和白名单机制,或使用沙箱环境。
  • 内容过滤:在 LLM 的输入和输出端部署内容安全过滤器,防止生成有害或不当内容。
  • 数据隐私:确保上传到外部 API(如 OpenAI)的数据不包含敏感个人信息。考虑对数据进行脱敏或使用本地模型。

8.5 版本管理与测试

  • 依赖锁定:使用poetrypipenv锁定 LangChain 及其组件的版本,避免因自动升级导致的不兼容。
  • 集成测试:为你的关键链和 Agent 编写测试,模拟用户输入并验证输出是否符合预期。这有助于在迭代提示词或升级组件时快速发现回归问题。

理解 LangChain 的五大核心概念是构建可维护、可扩展 AI 应用的基石。从标准化的Model I/O开始,用Retrieval扩展模型的知识,用Chains编排固定流程,用Memory引入上下文,最后用Agents实现动态决策。在实际项目中,你很少会用到所有概念,但清晰理解每个组件的职责和边界,能让你在设计和调试时游刃有余。下一步,可以深入探索 LangChain 更高级的特性,如LangGraph用于构建有状态的、循环的复杂工作流,或者研究如何将你构建的 Agent 封装为 API 服务。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询