LangChain 从零入门

8 阅读14分钟

LangChain 从零入门,结合这个项目讲

1. 先说结论:LangChain 到底是什么

LangChain 是一个用来开发大模型应用的框架。

如果只用一句话解释它,可以说:

LangChain 帮我们把“大模型、提示词、知识库、工具、Agent、输出处理”这些零散能力连接起来,做成一个完整 AI 应用。

很多初学者一看到 LangChain,会误以为它本身就是“大模型”。

其实不是。

LangChain 更像:

  • 一个组织代码的框架
  • 一个搭建 AI 工作流的工具箱
  • 一个把模型和外部系统接起来的中间层

它不负责“创造模型”,而是负责“更好地使用模型”。


2. 如果没有 LangChain,会发生什么

假设你要自己写一个文档问答系统。

你可能要手动做这些事:

  1. 调用大模型 API
  2. 读 PDF / TXT / DOCX 文件
  3. 切分文本
  4. 生成 embedding
  5. 存入向量库
  6. 查询时再检索相关文本
  7. 把检索结果拼进 prompt
  8. 调模型生成答案
  9. 处理输出格式
  10. 如果还要 Agent,再自己写工具调用逻辑

这些当然都能自己写,但会比较散。

LangChain 的价值就在于:

  • 提供统一抽象
  • 提供现成组件
  • 提供常见链路组合方式
  • 降低 AI 应用开发成本

3. LangChain 里最核心的几个概念

刚学 LangChain,不要一上来就去看所有 API。

你先抓住这几个关键对象就够了:

  1. Model
  2. Prompt
  3. Output Parser
  4. Document
  5. Embeddings
  6. Vector Store
  7. Retriever
  8. Chain
  9. Tool
  10. Agent

下面我们一个个讲。


4. Model:模型

模型就是 LangChain 要调用的“大脑”。

在 LangChain 里,常见模型有两大类:

  1. Chat Model 用于聊天、问答、总结、推理
  2. Embedding Model 用于把文本转成向量

4.1 这个项目里的聊天模型

在这个项目里,聊天模型主要在:

  • backend/app/utils/factory.py

这里用的是:

  • ChatTongyi

也就是阿里云通义模型的 LangChain 封装。

代码的意思可以简单理解成:

给我一个可对话的大模型实例,后面 RAG 总结和 Agent 都会用它。

4.2 这个项目里的 embedding 模型

同一个文件里还创建了:

  • OllamaEmbeddings

它负责:

把文本转成向量,供向量检索使用

所以你要记住:

  • 聊天模型负责“说话”
  • embedding 模型负责“向量化”

它们不是一回事。


5. Prompt:提示词模板

Prompt 就是你发给模型的指令。

但在项目里,通常不会每次都手写一整段字符串,而是用模板。

LangChain 里常见的 Prompt 类型包括:

  • PromptTemplate
  • ChatPromptTemplate

5.1 PromptTemplate

适合普通文本模板,例如:

请根据以下资料回答问题:

问题:{input}
资料:{context}

这里的 {input}{context} 是变量。

运行时再填进去。

5.2 ChatPromptTemplate

适合聊天型模型。

它可以把消息拆成:

  • system
  • human
  • ai
  • history

这个项目里的 Agent 就用了:

  • ChatPromptTemplate
  • MessagesPlaceholder

意思就是:

把系统提示词、聊天历史、用户输入、Agent 中间思考过程,按聊天消息结构交给模型。

5.3 这个项目里 Prompt 放在哪里

在:

  • backend/app/prompt/

例如:

  • main_prompt.txt
  • rag_summarize.txt
  • reorder_prompt.txt

而读取这些 Prompt 的代码在:

  • backend/app/utils/prompt_loader.py

这个文件做的事情很简单:

  1. 先读 prompt.yaml
  2. 找到对应 prompt 文件路径
  3. 把文本内容读出来

这就是“配置化 Prompt”的典型做法。


6. Output Parser:输出解析器

模型返回的往往是文本。

但很多时候我们希望它输出成更明确的结构。

LangChain 里就有 Output Parser 这个概念。

这个项目在 rag_service.py 里用了:

  • StrOutputParser

它的作用很直接:

把模型输出解析成字符串

虽然看上去简单,但它体现了一个重要思想:

模型输出可以被“接一层处理器”,而不是直接裸用

以后你学更深入时,还会见到:

  • JSON 输出解析
  • Pydantic 输出解析
  • 结构化字段提取

7. Document:文档对象

在 LangChain 里,知识库里的文本通常不是裸字符串,而是 Document 对象。

一个 Document 一般包含:

  • page_content 真实文本内容
  • metadata 元数据

7.1 metadata 有什么用

例如你可以在 metadata 里放:

  • 文件名
  • 文件路径
  • 用户 ID
  • 页码
  • 来源链接

这样后面检索出来时,不只是拿到文本,还知道它从哪来。

这个项目在向量库处理时也会围绕 Document 工作。


8. Embeddings:向量化

Embedding 是 LangChain 里和 RAG 最相关的能力之一。

它的本质是:

把文本变成一组数字,让“语义相似”可以被计算机计算

8.1 为什么要向量化

因为数据库没法直接理解“这两句话意思差不多”。

但如果把它们都映射到向量空间,语义相近的文本就可能距离更近。

于是就能做:

  • 语义搜索
  • 相似文本匹配
  • 文档召回

8.2 这个项目里的 Embedding 流程

在这个项目里:

  1. 文件被加载
  2. 文本被切分
  3. 每个分块生成 embedding
  4. 写入 Chroma 向量库
  5. 用户提问时,再把问题转成向量去检索

这条线主要发生在:

  • backend/app/rag/vector_store.py

9. Vector Store:向量库

LangChain 里可以对接很多向量库,比如:

  • Chroma
  • FAISS
  • Milvus
  • Pinecone
  • Weaviate

这个项目用的是:

  • Chroma

9.1 向量库干什么

它主要负责:

  • 存储文本向量
  • 存储对应文本内容
  • 在查询时找最相似的内容

9.2 这个项目里的 Chroma

vector_store.py 里有:

  • Chroma(...)

它会根据配置创建一个向量库实例。

你可以把它理解成:

这个项目的知识库底座

以后无论是上传文件、构建知识库、检索文档,都会围绕它展开。


10. Retriever:检索器

Retriever 是 LangChain 里专门负责“取资料”的组件。

记住一句话:

Retriever 不负责回答,它只负责找相关内容。

10.1 常见检索方式

  1. 向量检索 适合语义匹配
  2. BM25 检索 适合关键词匹配
  3. 混合检索 把多种方式结合起来

10.2 这个项目里的混合检索

vector_store.py 里用了:

  • BM25Retriever
  • self.vectors_store.as_retriever(...)
  • EnsembleRetriever

这说明项目并没有只依赖单一检索方式,而是做了融合。

10.3 为什么混合检索更实用

因为真实问题里会同时存在两种情况:

  • 有的查询是明确关键词
  • 有的查询是自然语言语义表达

混合检索通常更稳。

10.4 动态权重

这个项目还根据 query 的长度和词密度调整检索权重。

这个思路很值得你记住:

RAG 不是只有“查一下”,很多系统都会根据问题类型动态优化检索策略。


11. Text Splitter:文本切分

文本切分虽然容易被忽视,但它非常重要。

因为:

  • 文档太长不能整块放进去
  • 检索粒度太粗会不准
  • 块太短又容易丢上下文

这个项目里有:

  • backend/app/rag/text_spliter.py

从命名看,它负责异步文本切分。

11.1 为什么切分很重要

同样一份 PDF:

  • 切分得太大,检索不精准
  • 切分得太小,语义不完整

所以切分策略经常决定 RAG 效果的下限。

项目里也通过配置来控制:

  • chunk_size
  • chunk_overlap
  • separators

这就是典型的工程化做法。


12. Chain:链

Chain 是 LangChain 非常核心的思想。

你可以把它理解成:

把多个步骤串起来,形成一个可执行流程

例如:

  1. 构造 Prompt
  2. 调用模型
  3. 解析输出

这 3 步串起来,就是一个简单的 chain。

12.1 这个项目里的 Chain

rag_service.py 里有:

chain = (
    self.prompt_template
    | self.chat_model
    | StrOutputParser()
)

这段是 LangChain 很典型的写法。

意思是:

  1. 先把输入填进 prompt
  2. 再交给聊天模型
  3. 再把输出解析成字符串

这就是一个最小可用链条。

12.2 为什么 Chain 很重要

因为 AI 应用本质上通常不是单步。

它经常是:

  • 输入处理
  • 检索
  • Prompt 拼接
  • 模型生成
  • 输出清洗

Chain 可以让这些步骤组织得更清楚。


13. Runnable:LangChain 的现代执行风格

虽然你现在不一定需要深究,但看到 | 这种写法时要有概念。

LangChain 现在很多组件都遵循一种“可串联执行”的接口风格。

于是你会看到:

  • Prompt 可以接模型
  • 模型可以接解析器
  • 最后形成一个可执行对象

然后再调用:

  • invoke
  • ainvoke
  • stream
  • astream

13.1 这个项目里常见的是异步调用

因为后端是 FastAPI,很多地方用了:

  • ainvoke
  • astream

这是很正常的,因为:

  • 网络调用适合异步
  • 流式返回适合异步
  • 并发检索和总结也适合异步

14. Tool:工具

Tool 是 Agent 场景里最关键的组件。

你可以把 Tool 理解成:

暴露给大模型调用的函数

例如:

  • 查天气
  • 查时间
  • 查用户信息
  • 检索知识库
  • 重排序文档

14.1 这个项目里的工具定义

在:

  • backend/app/agent/agent_tools.py

里面用到了:

  • @tool

这个装饰器的意思就是:

把一个 Python 函数包装成 LangChain 可识别的工具

14.2 这个项目里有哪些工具

主要有:

  • rag_summary_tools
  • reorder_documents_tools
  • get_user_info_tools
  • get_weather_tools
  • what_time_is_now

这说明它的 Agent 不只是聊天,而是有“外部能力”的。

14.3 Tool 的本质

你一定要分清:

  • Tool 不是模型
  • Tool 是模型可调用的函数

模型负责:

  • 判断要不要调用
  • 传什么参数

Tool 负责:

  • 真正执行逻辑
  • 把结果返回给模型

15. Agent:智能体

Agent 是 LangChain 里最容易让人兴奋、也最容易让人困惑的部分。

简单说:

Agent 是让模型不仅会回答,还会自己判断是否要调用工具、按什么顺序调用。

15.1 Agent 和普通 Chain 的区别

普通 Chain 通常是固定流程:

输入 -> Prompt -> 模型 -> 输出

Agent 更像动态流程:

输入 -> 模型判断 -> 选工具 -> 调工具 -> 再判断 -> 最终输出

所以:

  • Chain 更固定
  • Agent 更灵活

15.2 这个项目里的 Agent

核心在:

  • backend/app/agent/agent.py

这里用了:

  • create_tool_calling_agent
  • AgentExecutor

大致意思是:

  1. 创建一个支持工具调用的 Agent
  2. 再用执行器去跑它

15.3 AgentFactory 的意义

项目里专门写了一个 AgentFactory

这其实是很好的工程习惯。

它把下面这些东西集中管理:

  • 默认模型
  • 默认工具
  • 默认系统提示词
  • 默认中间件
  • AgentExecutor 创建逻辑

这样做的好处是:

  • 结构清晰
  • 可扩展
  • 不容易把创建逻辑散落到各处

16. Messages 和 History:聊天历史

LangChain 在聊天场景下,不只是传一个字符串,还会传消息列表。

常见消息类型包括:

  • system message
  • human message
  • ai message

这个项目里在 Agent 执行前,会把数据库中的会话历史转成:

  • HumanMessage
  • AIMessage

这样模型才能理解:

  • 哪些话是用户说的
  • 哪些话是助手说的

这就是多轮对话得以成立的关键。


17. Streaming:流式输出

LangChain 支持流式返回。

也就是模型不是等全部生成完再给你,而是一边生成一边输出。

17.1 为什么流式输出重要

因为用户体验会更好:

  • 更快看到内容
  • 等待感更弱
  • 更像 ChatGPT

17.2 这个项目里的流式 Agent

agent.py 里有:

  • get_agent_stream_response

它内部用:

  • agent_executor.astream(...)

然后把结果包装成 SSE 风格发回前端。

所以你可以把这一层理解成:

LangChain 负责流式产出 token,FastAPI 负责把它持续推给前端。


18. LangChain 在这个项目里到底扮演什么角色

这是最重要的一段。

如果你要把这个项目和 LangChain 的关系讲明白,可以这样理解:

18.1 LangChain 负责模型抽象

比如:

  • ChatTongyi
  • OllamaEmbeddings

通过 LangChain 提供统一接口。

18.2 LangChain 负责 Prompt 组织

比如:

  • PromptTemplate
  • ChatPromptTemplate
  • MessagesPlaceholder

18.3 LangChain 负责 RAG 主链路中的关键组件

比如:

  • Document
  • Chroma
  • BM25Retriever
  • EnsembleRetriever

18.4 LangChain 负责 Agent 工具调用机制

比如:

  • @tool
  • create_tool_calling_agent
  • AgentExecutor

18.5 LangChain 负责链式组合

比如:

  • Prompt -> Model -> Parser

所以,LangChain 在这个项目里不是“附属功能”,而是整个 AI 层的核心组织框架。


19. 结合这个项目,走一遍 RAG 链路

为了让你更具体感受到 LangChain 的作用,我们走一遍这个项目里的 RAG。

第一步:加载配置和模型

在:

  • backend/app/utils/config.py
  • backend/app/utils/factory.py

这里会先准备:

  • 聊天模型
  • embedding 模型
  • 各类配置

第二步:加载文档

在:

  • backend/app/rag/vector_store.py

项目会读取各种格式的文件,转成文档对象。

第三步:切分和建库

还是在 vector_store.py 中,文档会被切分,然后写入 Chroma。

第四步:创建 Retriever

同一个文件里会创建:

  • 向量检索器
  • BM25 检索器
  • 混合检索器

第五步:RAG 服务发起检索

在:

  • backend/app/rag/rag_service.py

会调用 retriever 找到相关文档。

第六步:构造 Prompt + 调模型

同样在 rag_service.py 里:

  • 把 query 和 context 放入 PromptTemplate
  • 调聊天模型
  • 再交给 StrOutputParser

第七步:返回摘要答案

最终形成给前端或接口层使用的结果。

这整条线如果没有 LangChain,代码会散很多。


20. 再走一遍 Agent 链路

第一步:定义工具

在:

  • backend/app/agent/agent_tools.py

把 Python 函数用 @tool 注册。

第二步:创建 Agent Prompt

在:

  • backend/app/agent/agent.py

通过 ChatPromptTemplate.from_messages(...) 组织:

  • system prompt
  • 聊天历史
  • 用户输入
  • agent scratchpad

第三步:创建 Tool Calling Agent

也是在 agent.py

  • create_tool_calling_agent(...)

这表示模型具备调用工具的能力。

第四步:用 AgentExecutor 执行

执行器负责:

  • 驱动整个 Agent 运行
  • 处理工具调用循环
  • 输出最终结果

第五步:记录中间步骤

项目里还把:

  • thought
  • tool
  • tool_input
  • tool_output

都记录下来。

这对调试 Agent 很重要。


21. 为什么这个项目没有把所有逻辑都写死,而是用了 LangChain

因为这个项目明显已经不是“只发一句 prompt 给模型”的简单 demo。

它有这些需求:

  • 要支持多轮对话
  • 要支持文档知识库
  • 要支持混合检索
  • 要支持重排序
  • 要支持工具调用
  • 要支持流式输出

这种复杂度下,LangChain 的价值就很明显:

  • 减少重复造轮子
  • 统一抽象
  • 便于组合扩展

22. 初学 LangChain 时最容易踩的坑

22.1 把 LangChain 当成模型

错。

LangChain 是框架,不是模型本身。

22.2 以为用了 LangChain 效果就一定好

也错。

LangChain 只是让你更容易搭系统,不保证效果自动变好。

真正影响效果的仍然包括:

  • 模型能力
  • prompt 设计
  • 检索策略
  • 文档质量
  • 切分方式
  • rerank 质量

22.3 一上来就学 Agent

这也是常见误区。

更合理的顺序应该是:

  1. 先学 Prompt
  2. 再学 Model
  3. 再学 Chain
  4. 再学 RAG
  5. 最后学 Agent

因为 Agent 是建立在前面这些概念之上的。


23. 你应该怎么学这个项目里的 LangChain

给你一个最适合初学者的阅读顺序:

第一层:先看“模型和配置”

看:

  • backend/app/utils/config.py
  • backend/app/utils/factory.py
  • backend/app/utils/prompt_loader.py

搞懂:

  • 模型从哪来
  • 配置从哪来
  • prompt 从哪来

第二层:看 RAG

看:

  • backend/app/rag/vector_store.py
  • backend/app/rag/rag_service.py

搞懂:

  • 文档怎么处理
  • 向量库怎么用
  • 检索怎么做
  • 最终回答怎么生成

第三层:看 Agent

看:

  • backend/app/agent/agent_tools.py
  • backend/app/agent/agent.py

搞懂:

  • 工具怎么定义
  • Agent 怎么创建
  • 执行器怎么跑
  • 流式怎么实现

第四层:回到路由层

看:

  • backend/app/router/chat.py

搞懂:

  • 这些 AI 能力最终是怎么通过 API 暴露出去的

24. 一张图总结 LangChain 在这个项目中的位置

flowchart TD
    A["前端请求"] --> B["FastAPI 路由"]
    B --> C["LangChain RAG 流程"]
    B --> D["LangChain Agent 流程"]

    C --> C1["PromptTemplate"]
    C --> C2["Embedding Model"]
    C --> C3["Chroma Vector Store"]
    C --> C4["Retriever"]
    C --> C5["Chat Model"]
    C --> C6["Output Parser"]

    D --> D1["ChatPromptTemplate"]
    D --> D2["@tool 工具"]
    D --> D3["Tool Calling Agent"]
    D --> D4["AgentExecutor"]
    D --> D5["Streaming 输出"]

25. 最后做个一句话总结

如果你以后要向别人解释 LangChain,可以直接说:

LangChain 不是大模型,而是一个帮助我们把模型、Prompt、知识库、检索、工具和 Agent 串起来的开发框架。在这个项目里,它既支撑了 RAG 文档问答,也支撑了 Agent 的多工具调用能力,是整个 AI 后端的核心组织层。

如果你愿意,我下一步可以继续帮你把这篇再升级成:

  • “更适合面试复述”的精简版
  • “每个 LangChain 类都对应到项目源码位置”的对照版