LangChain 入门教程:Python AI 应用开发五大组件
🎯 本节目标
Section titled “🎯 本节目标”学完这一节,你能:
- 说清楚为什么需要 LangChain——用“做菜用不用切丝器”的比方讲给家里人听
- 拼出第一条 LCEL 链(
prompt | model),理解“接水管”是怎么把组件连起来的 - 加记忆让模型记得三句话之前你说过啥(模块 1 那个“无状态”的老毛病,这节给它治)
🍎 生活化类比
Section titled “🍎 生活化类比”LangChain = AI 应用的“厨房工具套装”。
回想模块 1,你用 10 行代码调通 API——好比你想吃土豆丝,直接拿菜刀一根一根切。能切吗?能。但宴客要做 50 道菜呢?手会废掉。
聪明的厨房里有工具套装:切丝器、压蒜器、削皮刀……每个工具只干一件事,但干得又快又稳。你只要把食材从一个工具递给下一个,一道菜就出来了。
LangChain 就是 AI 应用的这套工具:
- 模块 1 裸写
chat()= 手拿菜刀切土豆(项目小没事,项目大了手忙脚乱) - 模块 2 用 Coze/Dify = 去饭店点菜(现成,但你不能改厨房)
- LangChain = 自己开厨房:工具是别人造好的标准件,想怎么拼就怎么拼
关键在最后一句:工具是标准件,接口统一。今天用智谱的“切丝器”,明天换成 DeepSeek 的,接口一样、改个名字就行,业务代码几乎不动。
📖 概念讲解
Section titled “📖 概念讲解”1. 为什么需要框架?裸写不行吗?
Section titled “1. 为什么需要框架?裸写不行吗?”行,但项目稍微大一点就乱。三个真实场景,裸写都头疼:
- 换模型:老板说“智谱太贵了换 DeepSeek”。裸写你得满代码搜
glm-4-flash改;框架?改一个变量。 - 加记忆:你想让机器人记得用户名字。裸写你得自己维护 history 列表、自己拼 messages(模块 1 干过了,累);框架给你一个现成的“会员卡”,挂上去就行。
- 多组件协作:让模型先查文档、再回答、再翻译。裸写三段调用三段拼接;框架一根“管子”串起来。
一句话:框架不是“功能更强”,而是“约定更整齐”。大家都按同一套接口写,你换零件不疼、别人接手就懂。这是工程化的第一课。
2. 五大组件:开一家 AI 小店的类比
Section titled “2. 五大组件:开一家 AI 小店的类比”LangChain 有五大核心组件。别记表格,想象你要开一家 AI 小餐馆:
| 组件 | 小店里的角色 | 没有它会怎样 |
|---|---|---|
| Model(模型) | 厨师——真正做菜的人 | 没厨师店开不了,核心中的核心 |
| Prompt(提示模板) | 菜单——顾客点啥、厨师按啥规矩做 | 没菜单,顾客每次都得现编怎么点 |
| Memory(记忆) | 会员卡——记住老顾客叫啥、上次点了啥 | 没会员卡,每次去都被问“您贵姓?” |
| Tool(工具) | 外卖电话/计算器——能联系外部、能算账 | 没工具,只能靠嘴说,算账算错、查不了实时信息 |
| Retriever(检索器) | 菜谱本——祖传秘方小本子,做菜前翻一翻 | 没菜谱本,模型凭脑子做菜容易胡说八道 |
本节只动用前三个(厨师 + 菜单 + 会员卡)。Tool 和 Retriever 后面专门讲,现在只要知道“开店还有这两样宝贝”。
3. LCEL:把组件像“接水管”一样连起来
Section titled “3. LCEL:把组件像“接水管”一样连起来”LCEL(LangChain Expression Language,你不用记全称)核心就一个符号:管道符 |。
不懂“管道符”?把它想成接水管。厨房里:水管 A 出水 → 一根管子 | → 水管 B 过滤 → 又一根 | → 水龙头出水。水从一头进,顺着管子一路流到另一头。
LangChain 里也一样:
chain = prompt | model读作:“把 prompt 的输出,接到 model 的输入上”。prompt 把顾客的话加工成“标准订单”,| 把订单顺水推到 model 那里,model 炒完递回来。一根管子,一气呵成。
比裸写好在哪?每个组件都是标准水管,接口统一:.invoke(...) 进,结果出。想中间加个“翻译组件”?直接 prompt | translator | model,管子接长一点,原代码不动。
🛠️ 动手实操(分 4 小步,逐步叠加)
Section titled “🛠️ 动手实操(分 4 小步,逐步叠加)”我们不一上来 import 一堆。先 1 个组件,再加 1 个——每一步都能跑,每一步都看得见进步。
Step 1:装依赖 + 只调一个 Model(请个厨师)
Section titled “Step 1:装依赖 + 只调一个 Model(请个厨师)”pip install langchain langchain-openai langchain-community新建 langchain_step1.py:
import osfrom dotenv import load_dotenvfrom langchain_openai import ChatOpenAI # "请厨师"的工具
load_dotenv()
# 这就是厨师本人(模块1用过的智谱 glm-4-flash)model = ChatOpenAI( model="glm-4-flash", api_key=os.getenv("GLM_API_KEY"), # 你的密码,从 .env 读 base_url="https://open.bigmodel.cn/api/paas/v4/" # 智谱的门牌号)
# 直接让厨师回答一句话print(model.invoke("用一句话告诉我:什么是 LangChain?").content)跑 python langchain_step1.py,看到一句话回答。这一步和模块 1 没本质区别,只是换了套工具请厨师。
Step 2:加 Prompt 模板(给厨师一份菜单)
Section titled “Step 2:加 Prompt 模板(给厨师一份菜单)”光有厨师不行,每次问题都得自己拼“人设 + 问题”。做个菜单模板,以后填空就行。在 Step 1 代码基础上加:
from langchain_core.prompts import ChatPromptTemplate # "做菜单"的工具
# 一份菜单:固定人设 + 一个"顾客问题"的空位 {question}prompt = ChatPromptTemplate.from_messages([ ("system", "你是 FDE 学习助手,用一句话、像跟老奶奶讲话那样回答"), ("human", "{question}") # {question} 是空位,等会儿填])
# 填空看看菜单长啥样(还没请厨师)print(prompt.invoke({"question": "什么是 API?"}))这一步还没调用模型,只是“把菜单准备好”。
Step 3:用 LCEL 把 Prompt 和 Model 接起来(接水管!)
Section titled “Step 3:用 LCEL 把 Prompt 和 Model 接起来(接水管!)”现在请主角——管道符 |——把“菜单”和“厨师”接成一根管子:
# 👇 重点这一行:菜单 | 厨师。订单从菜单流到厨师chain = prompt | model
# 整根管子一气呵成,只管往里灌问题print(chain.invoke({"question": "什么是 API?"}).content)看懂 prompt | model 了吗?它就是“接水管”。以后想加翻译?prompt | translator | model。想加输出格式化?后面再接一段。这是 LangChain 全部魔法的核心。
Step 4:加 Memory(发张会员卡,记得老顾客)
Section titled “Step 4:加 Memory(发张会员卡,记得老顾客)”模块 1 说过模型“无状态”——三句之前你说啥它都忘。现在给它治病:挂个记忆组件。新文件 langchain_step4.py:
import osfrom dotenv import load_dotenvfrom langchain_openai import ChatOpenAIfrom langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholderfrom langchain_community.chat_message_histories import ChatMessageHistoryfrom langchain_core.runnables.history import RunnableWithMessageHistory
load_dotenv()model = ChatOpenAI( model="glm-4-flash", api_key=os.getenv("GLM_API_KEY"), base_url="https://open.bigmodel.cn/api/paas/v4/")
# 会员卡:在内存里存对话(生产环境换成 Redis/数据库)history = ChatMessageHistory()
# 菜单多留个空位 {history}:专门放"以前聊过啥"prompt = ChatPromptTemplate.from_messages([ ("system", "你是 FDE 学习助手,简洁、友好"), MessagesPlaceholder(variable_name="history"), # ← 历史对话塞这里 ("human", "{input}")])
chain = prompt | model # 还是那根管子
# 给管子"挂上"会员卡:每次对话自动读写 historychain_with_memory = RunnableWithMessageHistory( chain, lambda _: history, # 用哪张会员卡(这里固定一张) input_messages_key="input", # 用户输入对应 {input} history_messages_key="history" # 历史记录对应 {history})
# 同一会话用同一个 session_id,这样才知道是同一个顾客config = {"configurable": {"session_id": "user1"}}
print(chain_with_memory.invoke({"input": "我叫小明"}, config).content)print(chain_with_memory.invoke({"input": "我叫什么?"}, config).content) # 应答出"小明"✅ 验收:第二轮答出“小明”,说明会员卡生效——模型“记得”你是谁了。把
session_id换成"user2"再试,它会“装作不认识你”,因为换了张卡。
⚠️ 常见错误
Section titled “⚠️ 常见错误”| 报错 / 现象 | 大白话原因 | 怎么解决 |
|---|---|---|
NotFoundError / 模型不认识 |
base_url 没填或写错 | 国产模型必须填 base_url="https://open.bigmodel.cn/api/paas/v4/" |
| 第二轮不记得第一轮的话 | session_id 不一致,或没传 config | 每次调用都传同一个 config,session_id 别变 |
ImportError: ... MessagesPlaceholder |
langchain 版本太旧 | pip install -U langchain langchain-core langchain-community |
LCEL 写 prompt + model 报错 |
用错符号,不是 + 是 | |
永远是管道符 |,想象“接水管” |
AuthenticationError: 401 |
API Key 没填或多了空格 | 检查 .env 里 GLM_API_KEY= 后面无空格 |
1. 用"开小店"的类比,说清楚 Memory 解决什么问题?没它会怎样?
Memory 就像店里的会员卡,记录老顾客上次聊过啥、叫什么。没它,模型因为“无状态”——每次调用都像第一次见面——你三句之前说的名字它就忘了,得每次重新自我介绍。FDE 做客服机器人时 Memory 是必备组件,否则体验极差。
2. `chain = prompt | model` 里的 `|` 是什么意思?为什么不用 `+` 或 `,`?
| 是 LCEL 的管道符,读作“把左边的输出接到右边的输入”,就像厨房接水管——左边管子流出的水自动流进右边管子。不用 + 或 , 因为这不是“加法”或“并列”,而是有方向的数据流:prompt 加工出的“订单”必须顺着管子流到 model 才能被处理。统一用 | 还有个好处:想加组件就再接一段 | new_component,原代码不动。
🚀 实战小项目:三家分店的会员卡
Section titled “🚀 实战小项目:三家分店的会员卡”把 Step 4 改成同时服务 3 个用户(user1/2/3),每人有自己的记忆。提示:把 lambda _: history 改成“根据 session_id 返回不同的 ChatMessageHistory”,用一个字典 {"user1": ChatMessageHistory(), "user2": ...} 存。
验收:
- user1 说“我叫小明”,user2 说“我叫小红”,互不串扰
- 问 user1“我叫什么?“答”小明“;问 user2 同样问题答“小红”
- 你能直观感受到:session_id 就是“哪张会员卡”的钥匙
做完你就懂了 ChatGPT“多用户会话隔离”的底层逻辑——每个会话窗口一张独立的记忆卡。
📚 总结 & 下一节
Section titled “📚 总结 & 下一节”3 句话回顾:
- LangChain = AI 应用的厨房工具套装,标准件、接口统一,换模型/加组件都不疼
- 五大组件用“开小店”记:Model 厨师、Prompt 菜单、Memory 会员卡、Tool 外卖电话、Retriever 菜谱本
- LCEL 用
|接水管:prompt | model,想加啥再接一段,业务代码不动
下一节:当流程需要“循环、分支、人工审批”——比如模型回答完让人审核、不过关打回重写——LangChain 这根直管子就不够用了。那时换上 LangGraph(带岔路的管子网络)。
🏋️ 配套自练
Section titled “🏋️ 配套自练”- LangChain 官方教程 — 跟着官方 5 个 tutorial 跑一遍,每个都是可运行 notebook(免费)
- LangChain Academy — 官方免费课程,从基础到 LangGraph(免费、英文)
- 把本节的
chat()函数改成“带记忆版本”,测试连续对话
🔗 延伸阅读
Section titled “🔗 延伸阅读”← 上一节:Dify 平台 | 下一节:LangGraph 工作流 →