开启左侧

深入解析 LangChain:架构、核心概念与实践详解

[复制链接]
PillsSkiny 发表于 2 小时前 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
作者:CSDN博客
1、LangChain 概述

什么是 LangChain? LangChain 是一个开源的应用框架,旨在简化使用大型语言模型(LLM)构建应用程序。作为一个语言模型的集成工具链,LangChain 提供标准接口来连接不同的语言模型,以及与外部工具和数据源的集成。简单来说,LangChain 让开发者能够方便地将LLM接入自己的程序,并串联起各种模块构建复杂的LLM驱动应用(如聊天机器人、问答系统、代码生成等)。借助 LangChain,开发者可以轻松地将多个大型模型“链”在一起,或将LLM与数据库、API等外部资源连接,使模型具备访问实时数据和执行操作的能力。例如,一个应用可以用一个LLM来解析用户意图,再调用另一个LLM来生成回应;又或者利用 LLM 来决定调用哪些工具(如网络搜索、计算器等)来完成用户任务。
发展历史与开源社区 LangChain 由 Harrison Chase 于 2022年10月在工作之余首次开源推出。恰逢随后一个月 OpenAI 发布 ChatGPT,掀起了业界对大模型应用的热潮,LangChain 在 2023 年上半年迅速蹿红。据统计,LangChain 是截至2023年6月增长最快的开源项目之一。在 GitHub 上,LangChain 发布一周年时其仓库已收获超过 6.5 万颗星标,拥有 1.7k+ 名贡献者,超过 3.3 万个项目将其作为依赖。凭借活跃的社区和庞大的用户基础,LangChain 很快从一个个人项目成长为一家创业公司,在种子轮获得数千万美元融资,估值一度达到2亿美元。目前 LangChain 社区非常活跃,官方提供了社区 Slack/Discord 供开发者交流问题,还有开放的Hub分享 Prompt 和 Agent 模板,数以千计的开发者在为 LangChain 贡献代码和内容。
生态系统与技术栈 LangChain 的生态系统丰富而模块化。核心项目以 Python 和 JavaScript 实现,开发者可在这两种主流语言中使用 LangChain。LangChain 对下游集成非常友好,已支持 70+ LLM 接入(OpenAI、Anthropic、Cohere、Google PaLM、Meta LLaMA 等)以及数百种工具和数据库的整合——包括文档加载器、文本分割器、向量数据库等,总计超过 700 种第三方集成组件。通过 LangChain,用户可以方便地切换底层模型或后端服务,而无需大改代码,这种模块化设计使得比较不同模型、不同 Prompt 策略变得简单。在向量数据库方面,LangChain 原生支持集成 Pinecone、FAISS、Chroma、Milvus 等流行方案,在模型接口上则支持 OpenAI API、Hugging Face Hub 甚至本地 Transformers 模型。整个 LangChain 生态还包括周边工具:如用于调试和监控的 LangSmith,用于复杂多 Agent 编排的 LangGraph,用于将链部署为 API 的 LangServe 等。凭借广泛的技术栈支持和开放的架构,LangChain 已成为构建各类生成式AI应用时一个不可忽视的基础框架。
2、核心组件解析

LangChain 将复杂的 LLM 应用拆解为若干模块化组件,开发者可以像搭积木一样组合这些组件来完成所需功能。主要的核心组件包括:模型接口 (Models)、提示模板 (Prompt Templates)、链 (Chains)、记忆 (Memory)、代理 (Agents) 以及 检索与向量存储 (Retrieval & Vector Store)。下面我们分别介绍这些组件及其作用。
2.1 模型接口(Models)

模型接口是对各类底层模型(尤其是LLM和嵌入模型)的抽象封装。LangChain 支持多种模型类型,包括:
    LLM(大型语言模型):即传统的“输入文本 -> 输出文本”的模型,如 GPT-4、BERT、LLaMA 等。这些模型接受一段文本提示,生成相应的文本输出。LangChain 对主流的开源或API提供的LLM都提供了统一接口,例如通过 OpenAI 类调用 OpenAI 的 GPT 系列模型,通过 HuggingFaceHub 或 HuggingFacePipeline 使用 HuggingFace 上的模型等。ChatModel(聊天模型):聊天模型是针对对话场景的LLM接口变体。与普通LLM直接处理纯文本不同,LangChain 的聊天模型接口以一系列对话消息作为输入/输出。例如 OpenAI 的 ChatGPT 就属于聊天模型:它不是简单地输入一段文本,而是要传入包括系统消息、用户消息在内的多轮消息列表。LangChain 提供标准的消息类(如 HumanMessage 表示用户消息,AIMessage 表示AI回复,SystemMessage 表示系统指令)来构建对话。使用 LangChain 的 ChatModel 接口,可以很方便地与聊天模型交互。例如:
  1. from langchain.chat_models import ChatOpenAI
  2. from langchain.schema import HumanMessage, SystemMessage
  3. chat = ChatOpenAI(openai_api_key="YOUR_KEY")
  4. messages =[
  5.     SystemMessage(content="你是一个友好的中英翻译助手。"),
  6.     HumanMessage(content="I love programming.")]
  7. response = chat(messages)
  8. print(response.content)# 输出翻译后的中文
复制代码
在上述代码中,我们定义了一个系统消息指示角色身份,然后传入用户消息,ChatOpenAI 会返回一个 AI 消息对象,其中包含模型的回复文本。通过聊天模型接口,开发者能够方便地构造多轮对话,处理上下文消息列表等。LangChain 还支持批量对话调用以及流式响应等高级特性,用于提升调用效率和用户体验。
    Embedding 模型(嵌入向量模型):这类模型用于将文本、图像等数据转换为向量表示(embedding)。嵌入向量可用于语义检索、相似度匹配等。LangChain 提供统一的 Embeddings 接口,例如 OpenAIEmbeddings、HuggingFaceEmbeddings 等,可轻松调用 OpenAI 的 text-embedding-ada-002 模型或各种开源向量模型。典型用法是结合向量数据库,实现将文本转换为向量后存储以供语义搜索。与微调模型相比,利用嵌入向量做知识检索的优势在于无需额外训练,并且可以动态添加新数据而无需重新训练模型。
通过抽象的模型接口,LangChain 将底层不同厂商、不同类型的模型统一起来。无论您调用 OpenAI 的GPT-4,还是本地部署的Bloom模型,都可以采用相同的交互模式。这种设计大大降低了更换模型或同时使用多个模型的门槛,为应用灵活选择和组合LLM提供了便利。
2.2 提示模板(Prompt Templates)

提示模板是指预先设计的提示词模版,用于规范和复用与LLM交互时发送的 prompt 内容。由于对同一任务,不同的提示措辞可能显著影响模型输出质量,因此精心设计提示(即 Prompt Engineering)是一门重要技巧。LangChain 提供了 PromptTemplate 类来方便地创建和管理提示模板。
提示模板通常包含固定的指令或上下文,以及若干占位符供动态插入用户输入或上下文数据。例如,我们希望模型担任一个帮创业者起名字的顾问,可以设计模板:“我正在开一家新的{类型}店铺,请帮我想5个有创意的名字。”这里的 {类型} 就是一个占位符变量。使用 LangChain,可以这样构造和使用该模板:
  1. from langchain import PromptTemplate, OpenAI
  2. # 定义 Prompt 模板
  3. prompt = PromptTemplate(input_variables=["store_type"],
  4.     template="我正在开一家新的{store_type}店铺,请帮我想出 5 个有创意的名字。")# 将 OpenAI 的文本模型与模板封装成链
  5. llm = OpenAI(openai_api_key="YOUR_KEY", temperature=0.8)
  6. chain = LLMChain(llm=llm, prompt=prompt)
  7. result = chain.run({"store_type":"咖啡馆"})
  8. print(result)
复制代码
在这个例子中,我们只需提供店铺类型,LLMChain 会将模板渲染为完整提示并调用模型,返回5个名字。通过 PromptTemplate,开发者可以动态地根据用户输入生成 Prompt,避免每次手工拼接字符串。当有许多类似格式的请求时,使用模板能极大减少重复劳动,提高开发效率。
除了简单的模板插值,LangChain 还支持更高级的提示模板用法:
    Few-Shot Prompt:小样本提示。在提示中提供一系列范例输入-输出对,示范给模型期望的回答格式和风格。LangChain 提供 FewShotPromptTemplate,可将若干示例和当前用户输入一起格式化到提示中,从而引导模型按照这些示例来作答。这种方法常用于提高模型在特定任务上的性能,因为几个示例能在一定程度上弥补提示的信息不足。示例选择器(Example Selector):当拥有大量范例时,可以使用 ExampleSelector 自动为当前输入选择最相关的几例放入 few-shot 提示,从而既提供参考又避免提示过长。LangChain 内置了如 LengthBasedExampleSelector 等,根据输入长度或相似度挑选示例,确保提示不会超出上下文长度限制。输出解析器(Output Parser):虽然不属于提示本身,但常与Prompt配合。LangChain允许定制输出解析,将LLM生成的文本解析为所需格式(JSON、表格等),或提取其中的关键数据。这对保证模型输出符合预期格式很有用。
通过提示模板机制,LangChain 将 prompt 工程这一环节进行封装,使其更加模块化和可复用。我们可以方便地保存和分享优秀的 Prompt 模板(LangChain 提供了 Prompt Hub),并在不同应用中快速调整和应用这些模板。这为构建一致且高质量的模型交互奠定了基础。
2.3 链(Chains)及其不同类型

链(Chain)是 LangChain 名字中“Chain”的由来,它表示将一系列操作步骤串联在一起,形成具有复杂功能的工作流。简单来说,Chain 定义了 LLM 应用的流程逻辑:可以包含提示构建、模型调用、输出处理,甚至把多个子链按顺序或条件连接。通过链,开发者能够将多个组件组合成一个连贯的任务处理管道。
最简单的链是将 PromptTemplate 和 LLM 封装起来,例如上面提到的 LLMChain:它接受一个提示模板,将用户输入格式化后传给LLM获取结果。事实上,LLMChain 是 LangChain 中使用最广泛的基础链,很多更复杂的链和代理都会在内部用到 LLMChain 来和模型交互。
LangChain 还提供了其他类型的链来处理不同的场景:
    Sequential Chain(顺序链):将多个子链首尾相接执行,其中前一环节的输出作为后一环节的输入。顺序链又分为简单顺序链(Single input/output,每步一个输入输出)和通用顺序链(Multiple inputs/outputs)。通过顺序链,我们可以把多个模型调用或数据处理步骤连起来。例如先用一个链从用户请求中解析出查询关键词,再将关键词传给下一个链去检索答案。Transform Chain(转换链):允许在链中插入自定义的Python函数,对数据进行任意转换处理,然后再交给后续步骤。例如可插入一个函数过滤掉用户提供的大段文本中的噪音,只保留前三段,再送入LLMChain总结要点。TransformChain提供了在链路中执行任意逻辑的扩展点。Router Chain(路由链):根据输入内容动态选择后续要执行的链。例如 MultiPromptChain 可以根据问题类型选择不同风格的提示或调用不同专家模型。当应用需要对不同输入采用不同处理流程时,路由链非常实用。Retrieval QA Chain(检索问答链):这是LangChain提供的一种预构建链,用于文档问答场景。它会结合向量检索和LLM:先根据用户问题检索相关文本片段,然后将片段和问题一起送入LLM生成答案。这类链实质上是对常见RAG(Retrieval-Augmented Generation)模式的封装,后面会详细介绍。
利用这些链,开发者可以像搭乐高一样将各种能力组合起来,构建出复杂的应用流程。相比每次从零开始写脚本串联调用,使用 LangChain 的 Chains 能确保每一步都由经过抽象的组件完成,减少重复代码,并提高可读性和可维护性。此外,链还支持保存与加载:可以将定义好的链配置保存成JSON或Python文件,下次直接加载复用,方便在不同场景下迁移组合。
2.4 记忆模块(Memory)

记忆(Memory)是让链或代理能够“记住”对话历史或先前交互信息的组件。由于基础的大语言模型本身是无状态的,每次调用并不会记忆之前发生的对话,因此如果要实现多轮对话,就需要每次调用时提供过去的聊天记录。LangChain 的 Memory 模块就是为了解决这个问题,自动管理对话历史并在调用LLM时注入上下文,从而赋予应用持续对话记忆。
LangChain 将记忆抽象为统一的 BaseMemory 接口,并提供了多种内置的记忆实现,以适配不同场景需求:
    ConversationBufferMemory:对话缓冲记忆。它在内部维护一份“缓冲区”,存储了对话的全部历史消息。当新一轮对话时,将历史记录全部附加到prompt中。这等价于我们手工把之前聊天内容每次都拼接在输入里,但有了Memory组件就不必每次重复这一过程。ConversationBufferWindowMemory:窗口记忆。相对于 BufferMemory 存所有记录,这种记忆只保留最近的 N 条对话。通过设定窗口大小,可以在长对话中避免提示长度过长,只给模型提供最近的对话作为上下文。ConversationTokenBufferMemory:基于 Token 的窗口记忆。它类似于 WindowMemory,但不是按消息数量而是按 token 数量截断上下文。这样可以更精细地控制 prompt 长度,使其不超过模型的上下文窗口限制。ConversationSummaryMemory:摘要记忆。它不保存所有具体对话,而是维护一个“对话摘要”作为历史。每次对话后,用模型将过去的交互总结成简短要点,下一次对话时仅提供累积摘要。这种方式能大幅压缩历史信息,保留关键内容。ConversationSummaryBufferMemory:结合窗口和摘要的记忆。既保留近期若干对话原文,也维护更久之前对话的摘要。这样既有详细的短期记忆,又有长期背景。VectorStoreRetrieverMemory:向量数据库记忆。它将过去所有对话转换为向量嵌入存储到向量数据库中,每次对话时根据新输入检索出与之最相关的K条历史记录。这种记忆适合超长对话或需要“长期记忆”的场景,通过语义搜索找出相关历史作为上下文提示给模型。
使用记忆模块非常简单:LangChain 提供了例如 ConversationChain 这种自带 Memory 的链,或 Agent 在初始化时可以传入 Memory。以下示例演示如何为一个对话链添加内存,使其能够记住上下文:
  1. from langchain.llms import OpenAI
  2. from langchain.chains import ConversationChain
  3. from langchain.memory import ConversationBufferMemory
  4. llm = OpenAI(openai_api_key="YOUR_API_KEY", temperature=0)
  5. conversation = ConversationChain(llm=llm, memory=ConversationBufferMemory())# 模拟两轮对话
  6. reply1 = conversation.predict(input="你好,LangChain是什么?")
  7. print("AI:", reply1)# 第二轮问一个上下文相关的问题
  8. reply2 = conversation.predict(input="它有哪些核心组件?")
  9. print("AI:", reply2)
复制代码
在这个例子中,第二个问题中的“它”指代前文的 LangChain,若没有记忆支持,模型可能无法理解。但有了 ConversationBufferMemory,链会自动在提示中附加先前的对话“User: 你好,LangChain是什么? AI: …(回答)”,模型因此知晓“它”指 LangChain,从而给出准确的回答。由此可见,Memory 对于实现多轮对话、上下文相关问答至关重要。
需要注意内存带来的提示长度和成本问题:每次对话附带越多历史,调用LLM的字数就越多,可能增加延迟和费用。因此应根据实际需求选择合适的记忆策略(如窗口大小、摘要粒度等),在保持效果和性能开销之间取得平衡。总的来说,Memory 模块为构建拟人对话、连续推理等场景提供了必要的“短期记忆”,配合向量检索甚至可以模拟一定程度的“长期记忆”。
2.5 代理(Agents)及工具(Tools)

随着需求复杂度提高,很多应用场景下,固定顺序的链条不足以应对动态决策。代理(Agent)的概念由此引入:它通过让 LLM 自主地决策调用何种工具、采取何种行动,来完成用户交给的更复杂目标。简单来说,Agent 是一种特殊的链,其内部逻辑不是写死的顺序,而是由 LLM 根据当前状态逐步推理出来的。借助 Agent,LLM 不仅是被动回答,还可以像一个智能体那样行动:调用外部工具、查知识库、再处理信息,直到完成任务。
LangChain 的 Agent 接口提供了高度的灵活性,允许我们给模型配备一组可以使用的工具(Tools)。工具可以是各种功能函数,例如:网络搜索、计算器、数据库查询、第三方API调用等等。Agent 接收到用户请求后,会进入一个思考-行动循环:LLM 先阅读请求和当前上下文,决定下一步动作是直接回答还是使用某个工具;如果决定用工具,就输出一个特定格式包含要调用的工具名和参数,LangChain 执行该工具得到结果,再把结果反馈给 LLM;LLM 接收工具结果,更新自己的思考,再决定下一步… 如此循环,直到LLM决定给出最后答案为止。这个过程在LangChain中称为 ReAct Agent 模式(Reason + Act)——即模型一边“思考”,一边“行动”。

Agent 相比普通 Chain 最显著的特点就是自治性。它不再按照预定义顺序执行,而是每一步都由 LLM自己决定下一步做什么。这使得应用具有探索未知问题的能力。例如对于一个复杂问题,Agent 可以先调用搜索工具获取信息,再调用计算器处理数据,最后综合整理回答——整个决策流程并不是开发者硬编码的,而是由模型推理产生。当然,为了使这种自主决策可靠,我们需要给 Agent 设计良好的 Prompt(包括工具使用格式、停止条件等)来引导 LLM 有逻辑地行动。
LangChain 内置了许多工具(Tools)供 Agent 使用,也允许开发者自定义新工具。内置工具包括: 网页搜索、Wikipedia查询、数学计算、Python REPL、网页爬取、SQL数据库查询、向量数据库检索等等,基本覆盖了常见操作类型。官方还提供了工具集合(Toolkits),将一组相关工具打包,比如针对浏览网页的Browser Toolkit等。开发者也可以使用@tool装饰器将任意Python函数注册为工具。值得注意的是,如果希望Agent输出结构化结果,LangChain 也支持OpenAI Function格式的工具调用和JSON格式输出解析等,能够让Agent严格按照指定结构返回答案。
在 LangChain 中实现一个 Agent 非常方便。以下是一个使用 OpenAI 大模型并绑定自定义工具的简单示例:
  1. from langchain.agents import initialize_agent, Tool
  2. from langchain.llms import OpenAI
  3. # 定义自定义工具函数
  4. defget_weather(city: str) -> str:
  5.     """获取指定城市当前天气"""
  6.     # 这里调用实际天气API,示例返回假数据
  7.     returnf"{city}当前气温 25°C,晴朗"
  8. weather_tool = Tool(name="get_weather",
  9.     func=get_weather,
  10.     description="获取城市当前天气,例如输入: get_weather('杭州')")# 初始化Agent,赋予工具
  11. llm = OpenAI(openai_api_key="YOUR_KEY", temperature=0)
  12. agent = initialize_agent([weather_tool], llm, agent="zero-shot-react-description", verbose=True)# 让Agent回答问题
  13. response = agent.run("今天杭州的天气怎么样?")
  14. print(response)
复制代码
在这个例子中,我们创建了一个get_weather工具并赋予 Agent。当用户问“今天杭州的天气怎么样?”,Agent 会判断需要调用get_weather工具获取天气信息,LangChain执行该函数返回结果后,Agent 再根据工具结果生成最终回答。执行过程在日志中可以看到清晰的 ReAct 推理链路(先Thought思考要使用哪个工具,Action调用工具,Observation观察结果,最后Thought得出结论并Answer)。这体现了 Agent 通过 LLM 的推理能力,将问题拆解成一系列操作来完成任务的过程。
值得一提的是,LangChain 提供了两大类 Agent 架构:
    行动-反应式 Agent(Action Agents):也就是上述 ReAct 模式,LLM每一步根据当前观察到的结果决定下一动作,适合开放式任务。计划-执行 Agent(Plan-and-Execute Agents):LLM先对任务规划出完整步骤链,然后按照计划依次执行各步骤。这种方式在某些需要先整体规划的场景下有用,但也可能因为缺少中途反馈而不如行动-反应模式灵活。
开发者可根据需求选择 Agent 类型。无论哪种,Agent 都代表了让模型从被动应答进化为主动决策的重要方向。在复杂对话、任务规划、工具使用等应用中,引入 Agent 能显著提升系统的智能性和自动化程度。
2.6 检索与向量存储(Retrieval and Vector Stores)

大型语言模型的一个局限是知识截止和上下文长度受限。模型无法预先包含最新的或专业领域的知识,而且输入不能无限长。这导致模型有时会产生不正确的回答(幻觉)或无法回答超出训练知识范围的问题。为了解决这点,业界提出了RAG(Retrieval-Augmented Generation,检索增强生成)的思路:在生成回答前,先根据用户问题检索相关的外部知识,然后将知识提供给模型,辅助其生成更准确的答案。LangChain 在这方面提供了一整套组件,涵盖文档加载、文本分割、向量存储、检索等,使开发者可以轻松构建 RAG 管道。
LangChain 将与文档知识相关的功能归纳为「Indexes(索引)」模块。主要涉及以下子组件:
    文档加载器(Document Loader):用于从各种数据源加载文档文本。例如从本地的PDF、Word、网页HTML、数据库等提取纯文本内容。LangChain 内置了丰富的文档加载器适配器。文本分割器(Text Splitter):将长文本切分为适合模型处理的小块。因为模型上下文有限,过长的文档需要分段。LangChain 提供多种分割策略(按长度、按句段、按特殊标记等)以确保语义连贯地切分文档,例如 RecursiveCharacterTextSplitter 等。向量存储(Vector Store):用于存储文本片段的向量表示,并提供相似度检索功能。常见实现包括本地向量数据库 FAISS、Annoy,云向量数据库如 Pinecone、Milvus 以及内存中的简单列表等。LangChain 对这些向量库做了统一封装,因此使用 FAISS.from_texts(…) 或 Pinecone 接口都可以方便地创建向量索引并插入数据。检索器(Retriever):定义了从向量存储中检索相似文本的接口。LangChain 规定 Retriever 至少实现一个 get_relevant_texts(query) 方法,输入查询返回相关文档列表。很多向量存储类本身就实现了 Retriever 接口(如 FAISS 的 .as_retriever()),也可以通过 VectorStoreRetriever 将向量库包装为 Retriever。
通过以上组件,我们可以建立一个向量索引:先用 Document Loader 读入原始资料 -> 用 Text Splitter 切成段落 -> 用 Embedding 模型将段落转成向量并存入 Vector Store。之后,对于用户提出的问题,使用 Retriever 从向量库中找出语义相似的文本段落,然后将这些段落连同问题一起提交给 LLM,生成答案。这整个流程称为检索增强问答(Retrieval QA)。

RAG 技术在问答系统中非常实用。通过将外部知识引入,模型能够回答超出自身训练范围的问题,大幅降低“胡编乱造”(幻觉)的概率。例如没有RAG时,ChatGPT被问到某公司的最新动态可能因知识截止而无法回答或乱答;引入RAG后,它可以检索该公司的新闻公告并基于真实资料作答【37†】。另一方面,相比直接fine-tune模型,RAG可以保持模型对新信息的实时更新,而且不会把机密数据直接教给模型,从安全和数据私密性上也更有优势。
在 LangChain 中实现一个简单的检索问答应用也非常容易。假设我们有一批文档,想让模型基于这些文档回答问题,典型流程如下:
  1. from langchain.embeddings import OpenAIEmbeddings
  2. from langchain.vectorstores import FAISS
  3. from langchain.chains import RetrievalQA
  4. from langchain.llms import OpenAI
  5. # 1. 文本准备:假定我们已有文本列表 docs# 2. 建立向量存储(使用 OpenAI Embedding 和 FAISS)
  6. embeddings = OpenAIEmbeddings(openai_api_key="YOUR_API_KEY")
  7. vectorstore = FAISS.from_texts(docs, embedding=embeddings)# 3. 构建检索式问答链
  8. qa_chain = RetrievalQA.from_chain_type(llm=OpenAI(openai_api_key="YOUR_API_KEY"),
  9.     chain_type="stuff",
  10.     retriever=vectorstore.as_retriever())# 4. 提问
  11. result = qa_chain.run("请问上述文档集合中提到的LangChain核心组件有哪些?")
  12. print(result)
复制代码
以上代码中,我们使用 OpenAI 的文本嵌入模型将文档向量化,并使用 FAISS 建立本地向量索引。然后通过 RetrievalQA 链,将 OpenAI 的LLM与我们构建的 retriever 绑定,直接实现了“先检索再作答”的逻辑。只需调用 run() 提出问题,链会自动完成向量检索并调用 LLM 得出答案。
需要注意,在生产场景下应根据语料大小和查询性能选择合适的向量数据库方案,例如数据量很大时可能选用分布式向量数据库(如 Milvus 或 ElasticSearch 的向量检索)。LangChain 屏蔽了具体向量库实现的差异,统一通过 VectorStore 接口使用,使得我们可以方便地更换底层存储而代码几乎无需改动。
通过 Retrieval 组件,LangChain 极大拓展了 LLM 应用的边界,使其能接入私有知识和实时信息。无论是构建企业内部知识库问答、学术文献助手,还是连接网络实时搜索,向量检索+大模型生成的组合都是当前效果卓著的范式。LangChain 将这一范式封装成易于使用的模块,开发者只需关注提供高质量的数据,剩下检索匹配的细节都可交由 LangChain 处理。
3、 LangChain 的技术架构

了解了 LangChain 提供的核心组件后,从架构层面来看,LangChain 本身也体现出高度模块化和可扩展的设计理念。其技术架构既包括代码层面的包结构划分,也包括运行时的数据流转和交互机制。本节我们从整体架构、数据处理流程以及与底层大模型的接口交互三个方面,对 LangChain 进行剖析。
3.1 模块化设计理念

LangChain 的架构思想可以用“乐高式”的模块化架构来形容:通过对系统基本组件的合理抽象,找到构建复杂系统的统一规律,从而以较低的复杂度实现高度的扩展性。正如前文所述,LangChain 将大模型应用划分为若干核心模块(模型、提示、链、工具、内存、索引等),每个模块内部有清晰的接口定义,方便插拔替换。这种模块化设计带来的好处是显而易见的:
    解耦与复用:各模块职责单一,相互独立。比如Prompt模板、Memory、LLM接口可以独立更换或重复利用。同样的Prompt模板可以用于不同链,不同LLM;Memory可以添加到任何支持记忆的链或代理中。这种解耦使得开发者不用从零开始构建整套流程,而是通过组装现成组件快速搭建应用易于扩展:LangChain 针对每类组件都定义了基类接口(如 BaseLLM、BaseChain、BaseTool 等)。开发者可以在遵循接口的前提下,自行实现新的组件类型或集成新的第三方服务。例如,要接入一个新的向量数据库,只需继承 BaseVectorStore 实现相应方法即可被 LangChain 统一使用。这种架构为社区贡献打开大门,正因如此 LangChain 短时间内涌现了大量第三方集成。演进稳定:模块边界清晰意味着内部实现可以演进而不影响外部调用。例如LangChain曾对Memory模块进行过重构,但由于对外接口保持一致,升级版本后对业务代码影响很小。模块化也方便进行性能优化(替换更高效实现)或功能增强(增加新接口方法)而不破坏整体架构。
从代码仓库来看,LangChain 最新版本的代码被拆分为多个包,每个包对应架构中的不同层次:
    langchain-core:核心模块层,包含各种组件的基础抽象类定义以及通用工具(例如消息类定义、缓存机制等)。这个层次不依赖任何第三方服务,实现尽可能轻量。langchain(主包):构建应用“认知架构”的主体,包含了链、代理、检索等高层逻辑的实现。这些实现是通用的,不绑定具体厂商。例如RetrievalQA链并不指定用哪个向量库,只定义了利用Retriever接口进行问答的流程。Integrator Packages(集成扩展包):针对流行的模型和服务,每个都有独立的pip包。例如 langchain-openai 封装OpenAI接口,langchain-huggingface 对接Transformers,本地模型,langchain-weaviate 对接 Weaviate 向量库等。这样做的好处是不同集成可以独立发布版本,且用户按需安装,避免主包依赖过于庞大。langchain-community:社区贡献的集成包集合,涵盖了更广泛的第三方服务支持。这些组件由社区提供,可能更新较快,因此与核心解耦,不影响主框架的稳定。•LangServe、LangSmith、LangGraph 等:这是LangChain团队在框架基础上推出的周边产品,用于补充部署、监控、复杂应用编排等功能。它们通过调用langchain核心或扩展模块实现特定高级功能,进一步丰富了生态层次。
总的来说,LangChain 在架构上秉承“高内聚、低耦合”的原则,将各个功能单元模块化。其分层设计使得框架既保持了核心的精简和稳定,又通过外围扩展满足多样化的集成需求。这种理念也指导我们在使用LangChain时,应尽量利用其提供的抽象接口来构建,而非在业务逻辑中紧耦合具体实现,以便未来能灵活拓展演进。
3.2 数据流与处理流程

从运行时行为看,LangChain 应用的数据流一般会经历输入解析 -> 处理 -> 输出三个阶段,其中可能穿插对LLM的多次调用和对工具/知识库的访问。不同的链或代理在流程控制上有所不同,但核心机制类似。下面以常见的几个场景,说明 LangChain 内部的数据处理流程:
    简单链处理流程:对于固定顺序的链(如 LLMChain 或 SequentialChain),流程是线性执行的。以 LLMChain 为例:
整个链路数据流是单向顺序的,没有分支和循环。这种简单链通常作为构建块被包裹在更复杂逻辑中,例如代理或路由链里。
    接收输入:链从外部接收用户输入(或上一级链的输出)。如果配置了 Memory,会先将历史对话和当前输入打包整理。准备提示:链调用其内部的 PromptTemplate,将输入填充进模板,生成要发送给模型的完整 Prompt 文本。调用模型:通过模型接口(LLM)发送提示并获取模型生成的结果。LangChain 在这一过程中也会处理超时、重试、流式输出等底层事务,确保拿到模型响应。输出处理:如果有 Output Parser,应用解析规则将原始模型输出转换为所需格式;否则直接作为链的输出返回。Memory 模块则会将这一轮的对话(输入和回复)存储,用于下次调用时提供上下文。

    Agent 处理流程:代理的流程带有循环和决策。以一个典型的 ReAct Agent 为例:
在这个过程中,数据在LLM和各工具之间来回流转,Agent 充当了中枢控制:驱动 LLM 进行推理,在需要时调动工具,将工具输出反馈给LLM继续推理,直至得到结果。这体现了一个封闭反馈回路的数据流模型,强化了模型与外部环境(工具和知识)的交互能力。LangChain 针对这种循环流程做了优化,比如防止死循环、设置最大步数、格式错误的宽容处理等,使Agent能可靠地收敛到答案。
    初始化:Agent 会先将用户询问、预设的系统指令(如可用工具列表及使用方法)等组成初始 Prompt,发送给 LLM。LLM决策:LLM 根据Prompt输出一个Action(动作决策),这通常是一个结构化指令,指明选择哪个工具以及给它什么输入。例如模型可能输出:Action: Search[“LangChain memory mechanism”],表示调用搜索工具查询“LangChain 记忆机制”。执行工具:LangChain 解析出模型要用的工具及参数,调用相应工具函数(比如Search工具会执行网络搜索)得到结果。然后将结果封装成 Observation(观察)信息。反馈模型:将该 Observation 附加到对话历史中,作为新一轮提示,再次发送给 LLM,请它基于新信息继续决策。循环往复:LLM 看到自己先前的Action结果,可能选择下一个 Action,LangChain再去执行,获取Observation… 如此循环,直到LLM最终输出 Action: Finish[…] 或直接给出最后的答案。

    RAG 检索流程:对于 RetrievalQA 这样的链,数据流体现为“先检索再生成”。当收到查询时,链会:
这里与简单链的区别在于多了一个面向数据存储的分支。LangChain 内部实现保证检索部分和生成部分无缝衔接,例如 Retriever 未找到内容时模板会略有不同,或对太长的检索结果自动截断等。通过这样的流程,数据从知识库流向模型,再流向用户,实现知识补充。
    调用 Retriever 的 get_relevant_texts(query) 方法,从向量存储中找出相关文档列表。将检索到的文本片段拼接进Prompt模板(通常模板包括一个 {context} 占位,用于放置文档内容)。将填充了 context 的 Prompt 提交给 LLM 生成答案。返回答案给用户,通常还可以把引用的文档来源一并返回以提供支撑证据。
无论哪种流程,LangChain 实际上扮演了协调者的角色:协调输入、提示、模型调用、工具执行、结果处理等步骤有序进行。从开发者角度看,这大大简化了实现流程控制的工作——很多以前需要手写的逻辑,LangChain 都已有成熟实现,只需按需配置。比如Agent循环中的解析LLM意图、匹配工具、错误重试,在LangChain里都是透明发生的。
值得注意的是,LangChain 提供了Callback钩子和链路跟踪功能,例如通过 Callbacks 和 LangSmith,可以监视每一步数据流,经常用于调试Agent决策过程或记录链路运行情况。总体而言,LangChain 将复杂应用中数据在各模块间流动的过程标准化、自动化,让开发者能更专注于高层任务逻辑,而不用为底层繁杂的交互细节操心。
3.3 与大模型的交互机制

LangChain 的核心价值之一在于封装了与各种大模型(以及相关服务)的交互细节,提供统一且健壮的接口。对于最终用户来说,调用LLM只是简简单单地调用llm.predict()或chain.run()方法,但在这背后LangChain做了大量工作来可靠地对接模型:
    统一API封装:不同的模型提供商API各异,比如 OpenAI 要走 REST 接口、一些开源模型跑本地推理或走HuggingFace Hub接口等。LangChain 针对主流模型都适配了驱动,使得调用各模型的代码接口尽量保持一致。例如无论是 OpenAI、Cohere 还是 Azure OpenAI,只需用不同的模型类初始化,调用方法和返回对象基本相同。这种适配器模式让开发者可以很轻松地切换模型后端,而不必修改业务逻辑代码。调用控制与优化:LangChain 在调用LLM时提供了多种参数和功能支持,例如:温度、最大token、top_p 等生成参数控制,流式输出(streaming)支持,并发批量调用(提高吞吐量),以及重试和超时机制等。这些特性可以通过LangChain的配置或接口参数直接使用,避免我们直接使用模型API时重复处理这些常见需求。例如,设置 streaming=True 就能边生成边拿到部分结果,从而实现响应的实时流式输出。再如内置的 RetryingLLM 机制会在模型API偶尔超时或出错时自动重试一定次数,提升稳健性。缓存与成本控制:调用大模型是昂贵的操作。LangChain 贴心地提供了LLM结果缓存功能,可以选择将请求-响应结果缓存在内存或数据库中。当下次有完全相同的请求时,直接复用缓存结果而不再次付费调用模型。这对一些重复问答或测试调试阶段非常有用。缓存后端支持多种方案(SQLite、Redis等)。通过合理使用缓存,能够在不影响体验的情况下显著降低API调用成本。除了缓存,检索式问答RAG本身也是降低token消耗的有效方式:只让模型阅读相关内容而非整库内容,从而减少不必要的token占用。多模型协同:LangChain 允许在一个链路中同时对接多个模型类型。例如先用 Embedding 模型向量化查询,再用LLM生成答案;又或者Agent的决策模型和执行模型分开(规划步骤用一个小模型,执行回答用一个大模型)。这些协同在LangChain框架下都十分自然,因为不同模型接口统一且可组合。在未来,多模态的模型(图像、音频、视频)接入后,也可以与现有文本模型一同协作完成任务。权限与安全:LangChain 并没有忽略调用外部模型的安全问题。对于需要密钥的服务(如OpenAI API),LangChain 支持从环境变量或配置文件读取密钥,避免硬编码泄露。同时可以针对性地设置接口的调用频率、并发限制,防止因为逻辑错误触发API滥用。LangChain 的Agent在调用工具时也有内置的一些防护,例如对输出进行验证,避免某些潜在危险操作直接执行。
综上,LangChain 在底层为我们处理好了与大模型交互的繁琐部分。开发者可以用一致的方式调用任何支持的模型,不用关心HTTP请求如何构造、返回格式如何解析,也不必重复造轮子实现日志、重试等机制。这种接口封装和调度优化能力确保了我们专注于应用逻辑时,底层模型的调用是高效且可靠的。随着越来越多模型(包括非文本的模型)接入 LangChain,其作为“模型中间件”的价值得到进一步体现——连接人和各种AI模型的桥梁变得稳固且易用。
如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
深入解析 LangChain:架构、核心概念与实践详解-3.png


深入解析 LangChain:架构、核心概念与实践详解-4.jpg


第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
    大模型 AI 能干什么?大模型是怎样获得「智能」的?用好 AI 的核心心法大模型应用业务架构大模型应用技术架构代码示例:向 GPT-3.5 灌入新知识提示工程的意义和核心思想Prompt 典型构成指令调优方法论思维链和思维树Prompt 攻击和防范…
第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
    为什么要做 RAG搭建一个简单的 ChatPDF检索的基础概念什么是向量表示(Embeddings)向量数据库与向量检索基于向量检索的 RAG搭建 RAG 系统的扩展知识混合检索与 RAG-Fusion 简介向量模型本地部署…
第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
    为什么要做 RAG什么是模型什么是模型训练求解器 & 损失函数简介小实验2:手写一个简单的神经网络并训练它什么是训练/预训练/微调/轻量化微调Transformer结构简介轻量化微调实验数据集的构建…
第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
    硬件选型带你了解全球大模型使用国产大模型服务搭建 OpenAI 代理热身:基于阿里云 PAI 部署 Stable Diffusion在本地计算机运行大模型大模型的私有化部署基于 vLLM 部署大模型案例:如何优雅地在阿里云私有部署开源大模型部署一套开源 LLM 项目内容安全互联网信息服务算法备案…
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】







原文地址:https://blog.csdn.net/Z987421/article/details/146333797
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

发布主题
阅读排行更多+

Powered by Discuz! X3.4© 2001-2013 Discuz Team.( 京ICP备17022993号-3 )