LangChain

随着LLM能力的飞速发展,一个核心问题摆在开发者面前:如何将 LLM 从一个单纯的文本生成器,转变为一个能够执行复杂、多步骤任务,并与外部世界进行动态交互的Agent?LangChain 为此提供了一个功能强大且极具扩展性的开源框架

为什么需要 LangChain

大型语言模型,如 OpenAI 的 GPT 系列,在自然语言的理解与生成方面展现了卓越的能力。然而,一个独立的 LLM 在本质上可以被视为一个无状态(Stateless)的函数调用。它缺乏与外部数据源的实时连接、没有持久化的记忆能力,并且难以独立地执行需要多步规划与推理的复杂任务。

为了构建真正具备高价值的 AI 应用,开发者必须围绕 LLM 构建一个复杂的“认知架构”(Cognitive Architecture)。这套架构需要处理状态管理、外部工具调用、数据检索与整合等一系列问题。这正是 LangChain 框架的核心价值所在。

LangChain 并非要替代 LLM,而是一个强大的编排框架。它通过提供一系列标准化的、模块化的抽象组件,帮助开发者将 LLM 与外部数据源、API 接口以及其他计算逻辑高效地“链接”(Chain)起来,从而构建出具备上下文感知数据驱动行动能力的复杂Agent。

核心组件

LangChain 是模块化的,它将构建复杂 LLM 应用所需的过程分解为一系列独立但可组合的核心组件

1. Models

这是任何 LLM 应用的基础。LangChain 提供了统一的接口来与各种语言模型进行交互,屏蔽了底层模型提供商(如 OpenAI, Hugging Face, Cohere 等)的 API 差异。它主要分为两类:

  • LLMs: 指的是纯文本补全模型,接收一个字符串作为输入,返回一个字符串。
  • Chat Models: 指的是对话模型,其接口更加结构化,接收一个消息列表(ChatMessage)作为输入,返回一个 AIMessage。这种结构更适合处理多轮对话场景。

2. Prompts

Prompt 即给模型的指令。在实际应用中,Prompt 往往是动态生成的。LangChain 提供了强大的提示管理功能:

  • Prompt Templates: 允许开发者创建参数化的提示模板。这使得提示可以根据不同的输入动态生成,提高了复用性和可维护性。代码示例中的 ChatPromptTemplate 就是一个典型的例子,它定义了系统角色和用户输入的结构。

3. Chains

Chain 是 LangChain 的核心概念,代表了一系列对组件的顺序化调用,其中可能包括模型调用、工具调用或数据预处理等。通过 LangChain 表达式语言 (LCEL),开发者可以像拼接管道一样轻松地将不同的组件组合起来,构建出从简单到复杂的逻辑流。最基础的 LLMChain 就是将一个 Prompt Template 和一个 Model 链接起来。

4. Retrieval

为了让 LLM 能够回答关于特定领域或私有数据的问题,需要引入外部数据,这一过程即 RAG。LangChain 为此提供了一整套工具链:

  • Document Loaders: 从各种来源(如文本文件、PDF、网页、数据库)加载数据为标准化的 Document 格式。
  • Text Splitters: 将加载的长文档分割成适合模型处理的、语义完整的小块。
  • Vector Stores & Embeddings: 使用嵌入模型(Embeddings)将文本块向量化,并存入向量数据库(Vector Stores)中,以便进行高效的相似度搜索。
  • Retrievers: 负责根据用户查询,从向量数据库中检索出最相关的文本块。

5. Agents and Tools

如果说 Chain 遵循预设的路径执行任务,那么 Agent 则具备动态决策的能力。

  • Tools: 工具是 Agent 可以使用的具体能力,本质上是接受特定输入并返回结果的函数。例如,执行代码、调用 API、查询数据库等。在下面的代码示例中,search 函数就是一个被 @tool 装饰器定义的工具。
  • Agents: Agent 内部包含一个作为“大脑”的 LLM。它不直接回答问题,而是根据用户的输入和可用的工具集,进行思考和规划,决定下一步应该调用哪个工具,或者直接向用户返回最终答案。
  • Agent Executor: 这是 Agent 的运行时环境,负责实际执行 Agent 的决策,调用工具,并将工具的输出返回给 Agent,循环往复,直到任务完成。

6. Memory

为了解决 LLM 的无状态问题,LangChain 引入了 Memory 组件。它允许 Chain 或 Agent 在多轮交互中“记住”之前的信息,并将这些历史信息(如对话记录)整合到下一次的 Prompt 中,从而实现有状态的、连贯的交互。

简单的代码示例