LLM不是万能药:为什么我们需要编排框架?
作者:Weisian
发布时间:2026年3月

直击痛点:
“以为调用OpenAI API就能搞定大模型应用?这就像拿着一块乐高积木,却想直接拼出城堡!裸写LLM API的日子里,你是否每天都在重复造轮子:手动拼接Prompt、管理对话历史、处理API异常、整合外部工具……LLM只是‘智能砖块’,而LangChain才是搭建AI应用的‘底板、连接件和说明书’。”
当ChatGPT掀起AI应用开发热潮时,无数开发者兴冲冲地调用OpenAI/智谱/文心一言的API,却很快陷入困境:
- 写几百行代码才勉强实现“问答+记忆”的基础功能;
- 换个模型(如从GPT-3.5换到Claude)就要重写一半代码;
- 想调用搜索引擎/数据库,却要手动处理工具调用逻辑;
- 上线后发现对话上下文混乱、幻觉频发,却无从调试。
这就是大模型应用开发的“最后一公里”难题:LLM本身只是单点智能,而实际应用需要一套完整的“编排体系”。
LangChain的诞生,正是为了解决这个核心痛点——它不是替代LLM,而是为LLM装上“骨架”和“手脚”,让开发者用最少的代码,快速搭建出可扩展、可维护、生产级的AI应用。
本文将从痛点剖析切入,结合生活类比、核心设计、代码实战,彻底讲透LangChain的设计哲学和最佳实践:
✅ 拆解裸写LLM API的5大致命痛点(附反例代码);
✅ 用“乐高积木”类比LangChain的核心价值(一看就懂);
✅ 剖析LangChain的四大支柱(Models/Prompts/Chains/Agents);
✅ 图解LangChain核心架构:数据如何在组件间流动;
✅ 手把手教环境搭建+Hello World(避坑版);
✅ 重点解析v0.1+版本重构:为什么旧代码全失效?
✅ 实战对比:裸写API vs LangChain(代码量减少80%);
✅ 揭秘LangChain生态:LangSmith(调试)、LangServe(部署)、LangGraph(复杂流程);
✅ 避坑指南:版本兼容、密钥配置、幻觉治理的核心原则。
📌 核心一句话:
LLM是“智能大脑”,但缺乏“记忆”“手脚”“规划能力”;LangChain通过组件化编排,为LLM补上这些能力,实现“大脑+记忆+工具+流程”的完整闭环,是大模型应用开发的“操作系统”。
📌 记忆金句先记牢:
- LangChain核心哲学:组合优于继承,所有功能通过组件拼接实现,而非复杂继承;
- 四大核心组件:Models(模型)、Prompts(提示词)、Chains(链)、Agents(智能体),对应“大脑+话术+流程+手脚”;
- v0.1+是重大重构:旧版langchain包拆分为langchain-core/langchain-community等,API完全不兼容;
- LangSmith不是开发工具,而是调试/监控/评估平台,解决大模型应用“不可调试”的痛点;
- LangChain不解决幻觉,但提供检索增强生成(RAG) 组件,大幅降低幻觉概率;
- Agents是LangChain的终极形态:让LLM自主决策调用哪些工具,完成复杂任务。
一、痛点剖析:LLM 不是万能药,它只是“超级实习生”
在深入 LangChain 之前,我们必须清醒认识 LLM 的局限性。很多初学者误以为调用一下 API 就能解决所有问题,结果在实际开发中处处碰壁。
想象你第一次拿到ChatGPT的API,满心欢喜地写了个最简单的问答程序:
import openai
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": "什么是Java中的反射?"}]
)
print(response.choices[0].message.content)
看起来很美,对吧?但当你真正要做成一个生产级应用时,噩梦才刚刚开始。
1.1 缺陷一:幻觉——模型擅长“一本正经地胡说八道”
场景:你做了一个客服问答机器人,想让它基于公司产品文档回答问题。
# 噩梦:模型会自由发挥,编造不存在的产品功能
# 用户问:"你们的保险支持宠物医疗保险吗?"
# 模型答:"是的,我们的至尊版保险支持宠物医疗保险,包括猫狗等常见宠物。"
# 实际上:公司根本没有宠物医疗险!
生活类比:这就像你问朋友“老张今天为什么没来上班”,朋友脑补了一出“他可能生病了、可能堵车、可能请假了”的大戏,然后笃定地说“他肯定是因为昨晚喝酒喝多了”。模型和这个朋友一样,极度渴望给你答案,哪怕它根本不知道真相。
传统解决方案:绞尽脑汁写Prompt,加各种“如果你不确定,就说不知道”,但效果有限。
1.2 缺陷二:上下文限制——鱼的记忆只有7秒,LLM的记忆只有几K Token
场景:你做了一个长篇小说写作助手,需要模型记住前文的伏笔和人物关系。
# 噩梦:每次对话都是全新的开始
messages = []
while True:
user_input = input("你:")
messages.append({"role": "user", "content": user_input})
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=messages # 每次都要把整个历史传进去
)
assistant_reply = response.choices[0].message.content
messages.append({"role": "assistant", "content": assistant_reply})
# 问题:token数会无限增长,很快超过模型限制(16k/32k/128k)
# 即使没超限,成本也会爆炸,响应速度越来越慢
生活类比:你和一个人聊天,每次对话前都要把从出生到现在所有的对话历史重新复述一遍,否则他就忘了之前说过什么。聊到最后,复述历史的时间比真正聊天的时间还长。
传统解决方案:手动管理滑动窗口,删除最早的消息,但“删哪些”是个技术活——删了关键信息,模型就失忆;留着,token爆表。
1.3 缺陷三:无状态——每次请求都是“陌生人”
场景:你做了一个智能客服,用户已经完成了身份验证(提供了订单号、会员等级),接下来想咨询具体问题。
# 噩梦:每次请求都是独立的路人甲
# 请求1:用户提供了订单号“ORD-2025-001”,模型确认了订单信息
# 请求2:用户问“这个订单什么时候发货”,模型回复“请提供您的订单号”
# 用户崩溃:我刚才不是说了吗?!
生活类比:你去银行办事,已经给柜员看了身份证,转个身到另一个窗口,又要重新出示身份证。银行的系统没有状态,每个窗口都独立记忆。
传统解决方案:每次请求都把“上下文”(订单号、用户信息)塞到Prompt里,或者用数据库存储会话状态,但需要手动维护会话ID和状态映射。
1.4 缺陷四:知识滞后——模型活在2024年
场景:你想做一个“实时股票分析助手”,让模型分析今天的股市行情。
# 噩梦版:模型的知识截止到训练数据的时间点
def analyze_stock(ticker):
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": f"请分析{ticker}今天的走势"}]
)
# 模型回复:“截至我的知识截止日期(2024年10月),该股票表现良好…”
# 现实:今天是2026年3月,股票可能已经跌了50%!
生活类比:你拿着2024年的地图导航2026年的道路,地图上显示“前方直行”,实际上那里已经是个大坑。
传统解决方案:集成搜索功能,把搜索结果塞到Prompt里。但手动实现“搜索→解析→格式化→塞入”流程,代码很快就变成一团乱麻。
1.5 LLM的四大原生缺陷(生活化类比)
想象你招聘了一位智商极高但失忆、且从不查资料的“超级实习生”(这就是 LLM):
| 无状态 (Stateless) | 每次对话都是新的开始,记不住上文 | 实习生每回答一个问题就失忆一次,你必须把前文重新复述一遍 | 多轮对话需手动管理历史,Token 消耗巨大 |
| 幻觉 (Hallucination) | 一本正经地胡说八道 | 实习生为了面子,不懂装懂,编造事实 | 金融、医疗等严谨场景不可用,需校验机制 |
| 知识滞后 (Knowledge Cutoff) | 训练数据截止后的事一概不知 | 实习生是 2023 年毕业的,不知道 2026 年的新闻 | 无法回答实时性问题,需外挂知识库 |
| 上下文限制 (Context Limit) | 输入长度有限制 | 实习生记忆力有限,书太厚读不完,读到后面忘了前面 | 长文档处理需切片、摘要,不能一次性塞入 |

二、传统开发的困境:从“噩梦代码”到“面条式代码”
面对上述问题,传统开发者(包括我自己)的第一反应是:手动解决!

于是代码开始野蛮生长:
# 手动管理一切的“面条式代码”示例
import openai
import json
import requests
from typing import List, Dict
class ManualLLMApp:
def __init__(self, api_key: str):
self.api_key = api_key
self.conversation_history: List[Dict] = []
self.max_history_tokens = 4000 # 手动管理窗口
self.tools = {
"search": self.search_web,
"calculator": self.calculate,
"database": self.query_db
}
def ask(self, user_input: str) –> str:
# 1. 手动管理历史(删除旧消息)
self.conversation_history.append({"role": "user", "content": user_input})
self._trim_history()
# 2. 判断是否需要调用工具(关键词匹配,极其脆弱)
if "搜索" in user_input or "查一下" in user_input:
search_result = self.search_web(user_input)
user_input = f"{user_input}\\n\\n搜索结果:{search_result}"
# 3. 处理计算需求
if "计算" in user_input:
# 手动解析表达式…
pass
# 4. 构造Prompt,防止幻觉(写各种限制)
prompt = self._build_safety_prompt(user_input)
# 5. 调用API
try:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=self.conversation_history + [{"role": "user", "content": prompt}],
timeout=30
)
except Exception as e:
return f"出错啦:{str(e)}"
# 6. 处理响应
reply = response.choices[0].message.content
self.conversation_history.append({"role": "assistant", "content": reply})
# 7. 检查是否包含幻觉(手动正则匹配关键词)
if self._detect_hallucination(reply):
return "抱歉,我可能提供了不确定的信息,请稍后再试。"
return reply
def _trim_history(self):
"""手动计算token,删除旧消息"""
# 实现复杂,容易出错
pass
def _build_safety_prompt(self, input_text):
"""手动加Prompt工程"""
return f"""
请基于事实回答,不要编造信息。
如果不知道就说不知道。
用户输入:{input_text}
"""
def _detect_hallucination(self, text):
"""用关键词检测幻觉(效果极差)"""
suspicious_keywords = ["绝对", "肯定", "毫无疑问"]
return any(kw in text for kw in suspicious_keywords)
# 工具方法
def search_web(self, query):
# 调用搜索引擎API…
return "搜索结果…"
def calculate(self, expr):
# 调用计算器…
return "计算结果…"
def query_db(self, sql):
# 查询数据库…
return "查询结果…"
这段代码的问题显而易见:
- 维护噩梦:添加一个新功能(比如调用天气API)要修改多个地方;
- 脆弱性:关键词匹配工具调用,用户说“帮我查查”和“帮我搜索”就得写两个规则;
- 重复造轮子:每个LLM项目都要重写一遍历史管理、错误处理、Prompt模板;
- 难以测试:逻辑混合在一起,单元测试无从下手;
- 扩展性差:想换模型(从GPT到Claude)要重写核心逻辑。
生活类比:这就像自己动手装修房子,今天砌墙、明天铺电线、后天刷油漆,每个步骤都是现学现卖,没有设计图纸、没有标准流程。结果房子勉强能住,但墙上到处是裂缝,电线经常短路,想加个插座就得拆墙。
三、LangChain设计哲学:乐高积木的搭建艺术
LangChain的诞生,就是为了终结这种“面条式代码”的噩梦。LangChain 的名字本身就揭示了它的核心理念:Language + Chain。它不生产模型,它只是模型的搬运工和组装师。
3.1 核心哲学:组合优于继承(Composition over Inheritance)
在传统面向对象编程中,我们喜欢通过继承来扩展功能。但在 AI 应用中,场景千变万化,继承树会变得极其复杂。
LangChain 采用了组件化设计:
- 每个功能模块(如模型、存储、工具)都是独立的标准组件;
- 通过接口(Interface) 进行连接,而非硬编码依赖;
- 用户可以像搭乐高一样,随意替换某个组件(例如:把“向量数据库”从 Chroma 换成 Pinecone,只需改一行配置)。
类比:
传统开发像是在雕刻石头,改一个细节可能要推倒重来;
LangChain 像是在搭乐高,想换个颜色的窗户?直接拔下来换一块,底板和其他部分不受影响。

3.2 乐高类比:从“散落积木”到“标准组件”
想象一下真正的乐高:
| 基础积木块 | LLM模型(GPT-4、Claude、Llama) |
| 特殊零件(轮子、窗户) | 工具(搜索、计算器、数据库) |
| 底板 | Chains(组件连接器) |
| 说明书 | Prompts(模板) |
| 动力系统 | Agents(自主决策) |
| 成品模型 | 完整的AI应用 |
没有乐高底板和说明书时,你用散落的积木也能搭东西,但:
- 搭出来的东西不稳定,一碰就散(代码难维护)
- 想搭复杂模型(比如城堡)几乎不可能(扩展性差)
- 换个颜色就要重搭(换模型成本高)
有了底板和说明书后:
- 组件标准化:每个积木都知道怎么和其他积木连接
- 可复用:城堡的塔楼模块可以直接用在太空飞船上
- 可扩展:想加个炮台?插上去就行
LangChain做的就是这件事:为LLM应用开发提供了标准化的组件和连接方式。

3.3 LangChain的核心价值
价值一:组件化(Componentization)
将LLM应用拆解为独立、可复用的组件:
- Models:各种LLM的标准化接口
- Prompts:模板化管理,支持变量注入
- Chains:将多个组件串联成流水线
- Agents:让LLM自主选择工具
- Memory:统一的状态管理
- Document Loaders:各种格式文档的加载器
价值二:标准化(Standardization)
定义了统一的接口规范:
- 任何LLM都通过相同的invoke()方法调用
- 任何工具的输入输出都遵循统一格式
- 任何Memory的实现都有标准接口
价值三:生态整合(Ecosystem Integration)
内置了上百种集成:
- 模型层:OpenAI、Anthropic、Google、HuggingFace…
- 向量库:Pinecone、Chroma、FAISS…
- 工具:Google Search、Wikipedia、ArXiv…
- 数据源:PDF、CSV、HTML、Notion…
四、核心架构:LangChain的四大支柱(Models/Prompts/Chains/Agents)
LangChain的核心功能围绕四大组件展开,形成完整的“智能应用闭环”:
#mermaid-svg-5kQiMGF4cftssygw{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5kQiMGF4cftssygw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5kQiMGF4cftssygw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5kQiMGF4cftssygw .error-icon{fill:#552222;}#mermaid-svg-5kQiMGF4cftssygw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5kQiMGF4cftssygw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5kQiMGF4cftssygw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5kQiMGF4cftssygw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5kQiMGF4cftssygw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5kQiMGF4cftssygw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5kQiMGF4cftssygw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5kQiMGF4cftssygw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5kQiMGF4cftssygw .marker.cross{stroke:#333333;}#mermaid-svg-5kQiMGF4cftssygw svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5kQiMGF4cftssygw p{margin:0;}#mermaid-svg-5kQiMGF4cftssygw .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5kQiMGF4cftssygw .cluster-label text{fill:#333;}#mermaid-svg-5kQiMGF4cftssygw .cluster-label span{color:#333;}#mermaid-svg-5kQiMGF4cftssygw .cluster-label span p{background-color:transparent;}#mermaid-svg-5kQiMGF4cftssygw .label text,#mermaid-svg-5kQiMGF4cftssygw span{fill:#333;color:#333;}#mermaid-svg-5kQiMGF4cftssygw .node rect,#mermaid-svg-5kQiMGF4cftssygw .node circle,#mermaid-svg-5kQiMGF4cftssygw .node ellipse,#mermaid-svg-5kQiMGF4cftssygw .node polygon,#mermaid-svg-5kQiMGF4cftssygw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5kQiMGF4cftssygw .rough-node .label text,#mermaid-svg-5kQiMGF4cftssygw .node .label text,#mermaid-svg-5kQiMGF4cftssygw .image-shape .label,#mermaid-svg-5kQiMGF4cftssygw .icon-shape .label{text-anchor:middle;}#mermaid-svg-5kQiMGF4cftssygw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5kQiMGF4cftssygw .rough-node .label,#mermaid-svg-5kQiMGF4cftssygw .node .label,#mermaid-svg-5kQiMGF4cftssygw .image-shape .label,#mermaid-svg-5kQiMGF4cftssygw .icon-shape .label{text-align:center;}#mermaid-svg-5kQiMGF4cftssygw .node.clickable{cursor:pointer;}#mermaid-svg-5kQiMGF4cftssygw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5kQiMGF4cftssygw .arrowheadPath{fill:#333333;}#mermaid-svg-5kQiMGF4cftssygw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5kQiMGF4cftssygw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5kQiMGF4cftssygw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5kQiMGF4cftssygw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5kQiMGF4cftssygw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5kQiMGF4cftssygw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5kQiMGF4cftssygw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5kQiMGF4cftssygw .cluster text{fill:#333;}#mermaid-svg-5kQiMGF4cftssygw .cluster span{color:#333;}#mermaid-svg-5kQiMGF4cftssygw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5kQiMGF4cftssygw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5kQiMGF4cftssygw rect.text{fill:none;stroke-width:0;}#mermaid-svg-5kQiMGF4cftssygw .icon-shape,#mermaid-svg-5kQiMGF4cftssygw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5kQiMGF4cftssygw .icon-shape p,#mermaid-svg-5kQiMGF4cftssygw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5kQiMGF4cftssygw .icon-shape rect,#mermaid-svg-5kQiMGF4cftssygw .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5kQiMGF4cftssygw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5kQiMGF4cftssygw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5kQiMGF4cftssygw :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
Models(模型:大脑)
Prompts(提示词:话术)
Chains(链:流程)
Agents(智能体:手脚)
Tools(工具:数据库/搜索引擎)
Memory(记忆:对话历史)

安装依赖(v0.1+版本需安装特定包)
pip install langchain-core langchain-openai
4.1 支柱一:Models(模型)——抽象一切的LLM接口
Model负责核心的推理和生成。LangChain 将其分为三类:
- LLM (Large Language Model):输入文本,输出文本(如 gpt-4)。
- Chat Model (聊天模型):输入消息列表(System/User/AI),输出消息(现代应用主流)。
- Text Embedding Model (嵌入模型):将文本转换为向量,用于检索(RAG 的核心)。
类比:Models 是发动机。你可以选法拉利引擎(GPT-4),也可以选丰田引擎(Llama 3),LangChain 提供的方向盘(接口)是一样的。
问题来了:不同模型的API千差万别,OpenAI用ChatCompletion.create(),Claude用messages.create(),切换模型要重写大量代码。

LangChain解决方案:统一的模型接口。
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage
# 统一调用方式:invoke()
gpt4 = ChatOpenAI(model="gpt-4")
claude = ChatAnthropic(model="claude-3-opus")
# 相同的调用方式,不同的模型
message = HumanMessage(content="介绍一下Java的反射机制")
response1 = gpt4.invoke([message])
response2 = claude.invoke([message])
# 换模型?改一行配置就行
# from langchain_google_vertexai import ChatVertexAI
生活类比:就像国际标准插座接口——无论你从哪个国家买的电器,只要插头符合标准,就能在任何国家的插座上使用。Models层就是LLM界的“标准插座”。
4.2 支柱二:Prompts(提示词)——模板化、结构化
问题:每次都要手动拼接Prompt,重复代码多,变量注入容易出错。
LangChain解决方案:PromptTemplate + Message模板。
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 定义模板(支持变量注入)
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个{role}专家,请基于以下知识回答问题:{knowledge}"),
MessagesPlaceholder(variable_name="history"), # 对话历史占位符
("human", "{input}")
])
# 使用模板(像填表格一样)
messages = prompt.invoke({
"role": "Java",
"knowledge": "Java 8引入了Lambda表达式,Java 9推出了模块系统…",
"history": [], # 空历史
"input": "什么是Java的反射?"
})
# messages现在是格式化好的消息列表,可以直接传给模型
生活类比:就像快递单模板——地址、收件人、电话的位置都是固定的,每次寄件只需填具体内容,不用重新设计单子格式。

4.3 支柱三:Chains(链)——组装流水线
问题:复杂任务需要多个步骤,比如“搜索→总结→翻译”,手动串联每一步很繁琐。
LangChain解决方案:Chain将多个组件串联成流水线。
from langchain.chains import LLMChain, SimpleSequentialChain
from langchain_openai import ChatOpenAI
# 创建模型
llm = ChatOpenAI()
# 链1:总结新闻
summary_prompt = ChatPromptTemplate.from_template("请用一句话总结以下新闻:{news}")
summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
# 链2:翻译成英文
translate_prompt = ChatPromptTemplate.from_template("将以下内容翻译成英文:{text}")
translate_chain = LLMChain(llm=llm, prompt=translate_prompt)
# 串联两条链
pipeline = SimpleSequentialChain(
chains=[summary_chain, translate_chain],
verbose=True
)
# 执行流水线(一步完成:总结→翻译)
result = pipeline.run("昨天,OpenAI发布了GPT-4.5,性能提升了30%…")
print(result) # 输出:Yesterday, OpenAI released GPT-4.5 with a 30% performance improvement…
生活类比:就像汽车生产线——零件从一端进去,经过焊接→喷漆→组装→检测,另一端开出来就是完整的汽车。Chain定义了每个工位做什么,以及零件如何在工位间流转。
langchain将多个组件串联起来,形成不同的业务逻辑。如:
- 简单链:Prompt -> Model -> Output。
- 复杂链:检索文档 -> 填充 Prompt -> 调用模型 -> 解析输出 -> 存入数据库。

4.4 支柱四:Agents(代理)——自主决策
问题:什么时候调用工具?调用哪个工具?传统方式只能硬编码规则。
LangChain解决方案:Agent让LLM自己决定调用哪些工具、按什么顺序调用。
from langchain.agents import create_react_agent, Tool
from langchain.tools import tool
from langchain_openai import ChatOpenAI
# 定义工具(装饰器方式)
@tool
def search_web(query: str) –> str:
"""搜索网络信息,当需要实时数据或最新消息时使用"""
# 这里调用真实的搜索API
return f"搜索结果:{query}的相关信息…"
@tool
def calculate(expression: str) –> str:
"""执行数学计算,当用户需要计算时使用"""
try:
result = eval(expression)
return f"计算结果:{result}"
except:
return "计算失败,请检查表达式"
# 创建Agent
llm = ChatOpenAI(model="gpt-4")
tools = [search_web, calculate]
agent = create_react_agent(llm, tools)
# 用户提问(包含搜索和计算需求)
response = agent.invoke({
"input": "搜索最新的GPT-4价格,并计算如果每天调用100次,月费用是多少?"
})
# Agent会自动:
# 1. 调用search_web获取最新价格
# 2. 调用calculate计算月费用
# 3. 组合结果返回
这是 LangChain 最强大的部分。Agent 允许 LLM 自主选择工具来完成任务。
- 核心逻辑:LLM 接收任务 -> 思考需要什么工具 -> 调用工具 -> 观察结果 -> 决定下一步。
- 适用场景:需要多步推理、调用外部 API(搜索、计算、数据库)的场景。
生活类比:Agent就像一个智能管家——你告诉它“帮我订一张下周去北京的机票”,它会自己决定:
- 先查你的行程安排(日历工具)
- 再查机票价格(搜索工具)
- 然后计算最优时间(计算工具)
- 最后下单(预订工具)
整个过程无需你指挥具体步骤。

五、环境搭建与Hello World
5.1 环境准备(关键:版本选择)
第一步:Python版本要求
- LangChain v0.1+要求Python 3.8+(推荐3.10+);
- 避免使用Python 3.7及以下版本(兼容性问题)。
第二步:安装依赖(区分核心包和社区包)
LangChain v0.1+进行了重大重构,将包拆分为多个独立模块:
# 1. 创建虚拟环境(Python 3.9+)
python -m venv langchain-env
# source langchain-env/bin/activate # Mac/Linux
langchain-env\\Scripts\\activate # Windows
# 2. 安装核心包(必须安装)
pip install langchain-core
# 模型集成包(按需安装)
pip install langchain-openai # OpenAI
pip install langchain-community # 智谱、文心一言等社区模型
pip install langchain-anthropic # Claude
# 工具集成包(按需安装)
pip install langchain-mysql # MySQL数据库
pip install langchain-google-search # 谷歌搜索
# 调试/部署包
pip install langsmith # 调试监控
pip install langserve # 部署
第三步:API Key配置(安全第一!)
错误做法:硬编码API Key(代码泄露=密钥泄露)
openai.api_key = "sk-xxxxxxxxxxxx" # 严禁!
正确做法1:环境变量(本地开发)
# Linux/Mac
export OPENAI_API_KEY="sk-xxxxxxxxxxxx"
# Windows
set OPENAI_API_KEY="sk-xxxxxxxxxxxx"
正确做法2:.env文件(推荐)
ZHIPU_API_KEY=xxxxxxxxxxxx
load_dotenv() # 自动加载.env文件中的环境变量
4.2 Hello World:第一个完整的LangChain应用
第一步:.env文件(配置核心)
# ==================== 模型密钥(可选,用于切换) ====================
# OpenAI(GPT-3.5/4)
OPENAI_API_KEY=sk–xxxxxxxxxxxx
# 智谱清言
ZHIPU_API_KEY=xxxxxxxxxxxx
# Anthropic(Claude)
ANTHROPIC_API_KEY=sk–ant–xxxxxxxxxxxx
# 阿里云通义千问(核心新增)
DASHSCOPE_API_KEY=sk–*******9 # 替换为你的真实API Key
DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatible–mode/v1 # 阿里云兼容OpenAI的地址
DASHSCOPE_DEFAULT_MODEL=qwen3.5–flash # 可选:qwen-plus / qwen-max
# ==================== 本地Ollama配置 ====================
# Ollama服务地址(默认本地:http://localhost:11434,无需修改)
OLLAMA_BASE_URL=http://localhost:11434
# 默认使用的Ollama模型
OLLAMA_DEFAULT_MODEL=qwen2–7b–q5_k_m:latest
# OLLAMA_DEFAULT_MODEL=DeepSeek-Coder-V2-Lite-Instruct-Q5_K:latest
# 可选:DeepSeek-Coder模型(代码相关问答用)
OLLAMA_CODER_MODEL=DeepSeek–Coder–V2–Lite–Instruct–Q5_K:latest

第二步:hello.py实现(基于LLM的交互问答系统)
"""
LangChain多模型对话机器人
功能:支持本地Ollama模型、阿里云千问API、OpenAI、智谱清言、Claude模型一键切换
核心能力:多轮对话记忆、中文友好交互、异常处理、配置管理
作者:自定义
日期:2026
"""
import os
import traceback
import requests
from dotenv import load_dotenv
# ==================== LangChain核心组件导入 ====================
# 提示词模板:用于构建标准化的对话提示
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 输出解析器:将模型输出转换为字符串
from langchain_core.output_parsers import StrOutputParser
# 聊天历史:内存级对话记忆管理
from langchain_core.chat_history import InMemoryChatMessageHistory
# 带历史的链:实现多轮对话上下文管理
from langchain_core.runnables.history import RunnableWithMessageHistory
# ==================== 第一步:环境配置加载(核心基础) ====================
def load_environment():
"""
加载环境变量,统一管理密钥和配置
作用:
1. 避免硬编码密钥,提升安全性
2. 统一管理不同模型的配置,便于切换
3. 使用绝对路径加载.env,避免路径问题
返回:配置字典
"""
# 获取当前脚本所在目录,拼接.env文件绝对路径(关键:避免相对路径错误)
current_dir = os.path.dirname(os.path.abspath(__file__))
dotenv_path = os.path.join(current_dir, ".env")
# 加载.env文件,指定UTF-8编码避免中文乱码
load_dotenv(dotenv_path=dotenv_path, encoding="utf-8")
# 整理所有配置项,返回结构化字典
config = {
# Ollama本地模型配置
"ollama_base_url": os.getenv("OLLAMA_BASE_URL", "http://localhost:11434"),
"ollama_default_model": os.getenv("OLLAMA_DEFAULT_MODEL", "qwen2-7b-q5_k_m:latest"),
# 阿里云千问API配置
"dashscope_api_key": os.getenv("DASHSCOPE_API_KEY", ""),
"dashscope_base_url": os.getenv("DASHSCOPE_BASE_URL", "https://dashscope.aliyuncs.com/compatible-mode/v1"),
"dashscope_default_model": os.getenv("DASHSCOPE_DEFAULT_MODEL", "qwen3.5-flash"),
# 其他云端模型配置(备用)
"openai_api_key": os.getenv("OPENAI_API_KEY", ""),
"zhipu_api_key": os.getenv("ZHIPU_API_KEY", ""),
"anthropic_api_key": os.getenv("ANTHROPIC_API_KEY", "")
}
# 配置校验:关键参数不能为空
if config["dashscope_api_key"] and len(config["dashscope_api_key"]) < 10:
raise ValueError("阿里云千问API Key格式错误!请检查.env文件配置")
return config
# 执行环境加载
config = load_environment()
# ==================== 第二步:模型初始化(核心业务逻辑) ====================
def init_llm(model_type="ollama", config=config):
"""
初始化不同类型的大语言模型,实现一键切换
核心设计:
1. 单一入口函数,统一模型初始化逻辑
2. 适配不同模型的参数差异,保证接口一致性
3. 异常防护,明确的错误提示
参数:
– model_type: 模型类型,可选值:ollama/qwen_api/openai/zhipu/anthropic
– config: 环境配置字典
返回:初始化后的LangChain ChatModel实例
"""
# 1. 本地Ollama模型初始化
if model_type == "ollama":
from langchain_ollama import ChatOllama
llm = ChatOllama(
base_url=config["ollama_base_url"], # Ollama服务地址
model=config["ollama_default_model"],# 本地模型名称
temperature=0.7, # 随机性:0(严谨)-1(创意)
num_ctx=4096, # 上下文窗口大小
max_tokens=1024 # 最大输出token数
)
# 2. 阿里云千问API初始化(核心适配)
elif model_type == "qwen_api":
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
# 双写model/model_name兼容不同LangChain版本
model=config["dashscope_default_model"],
model_name=config["dashscope_default_model"],
temperature=0.7, # 回答随机性
# 双写api_key/openai_api_key兼容版本差异
api_key=config["dashscope_api_key"],
openai_api_key=config["dashscope_api_key"],
# 双写base_url/openai_api_base兼容版本差异
base_url=config["dashscope_base_url"],
openai_api_base=config["dashscope_base_url"],
max_tokens=1024, # 最大输出长度
timeout=30 # 超时时间,适配云端接口
)
# 3. OpenAI模型初始化(备用)
elif model_type == "openai":
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-3.5-turbo",
temperature=0.7,
api_key=config["openai_api_key"]
)
# 4. 智谱清言模型初始化(备用)
elif model_type == "zhipu":
from langchain_zhipuai import ChatZhipuAI
llm = ChatZhipuAI(
model="glm-4",
temperature=0.7,
api_key=config["zhipu_api_key"]
)
# 5. Claude模型初始化(备用)
elif model_type == "anthropic":
from langchain_anthropic import ChatAnthropic
llm = ChatAnthropic(
model="claude-3-sonnet-20240229",
temperature=0.7,
api_key=config["anthropic_api_key"]
)
# 不支持的模型类型
else:
raise ValueError(f"不支持的模型类型:{model_type},可选值:ollama/qwen_api/openai/zhipu/anthropic")
return llm
# 选择要使用的模型(一键切换核心)
# 可选值:"ollama"(本地) / "qwen_api"(阿里云千问)
# SELECTED_MODEL_TYPE = "qwen_api"
SELECTED_MODEL_TYPE = "ollama"
# 初始化模型实例
llm = init_llm(model_type=SELECTED_MODEL_TYPE, config=config)
# ==================== 第三步:构建对话链(LangChain核心流程) ====================
def build_chat_chain(llm):
"""
构建完整的对话处理链
LangChain核心流程:Prompt模板 → 模型调用 → 输出解析 → 历史管理
每一步职责清晰,可插拔替换
参数:llm – 初始化后的模型实例
返回:带历史记忆的对话链
"""
# 1. 定义Prompt模板(对话的"规则")
# 结构:系统指令 + 历史消息 + 用户输入
prompt = ChatPromptTemplate.from_messages([
# 系统角色定义:设定助手的行为模式
("system", "你是一个友好的中文聊天助手,会记住之前的对话内容,回答简洁、亲切。"),
# 历史消息占位符:动态填充多轮对话历史
MessagesPlaceholder(variable_name="chat_history"),
# 用户输入占位符:接收实时用户输入
("user", "{input}")
])
# 2. 构建基础处理链:Prompt → 模型 → 输出解析
# | 是LangChain的链式调用运算符,按顺序执行
base_chain = prompt | llm | StrOutputParser()
# 3. 初始化内存级对话历史(重启后丢失,生产环境可替换为数据库)
chat_history = InMemoryChatMessageHistory()
# 4. 包装为带历史记忆的对话链
history_chain = RunnableWithMessageHistory(
runnable=base_chain, # 基础处理链
get_session_history=lambda sid: chat_history, # 按会话ID获取历史
input_messages_key="input", # 用户输入字段名
history_messages_key="chat_history", # 历史消息字段名
output_messages_key="output" # 输出字段名(兼容配置)
)
return history_chain, chat_history
# 构建对话链
chat_chain, chat_history = build_chat_chain(llm)
# ==================== 第四步:交互逻辑实现(用户界面) ====================
def run_chat_interface():
"""
运行交互式聊天界面
功能:
1. 接收用户输入
2. 调用对话链处理
3. 处理特殊指令(退出/清空历史)
4. 异常捕获与友好提示
"""
# 显示欢迎信息,明确当前使用的模型
if SELECTED_MODEL_TYPE == "ollama":
model_info = f"{config['ollama_default_model']}(本地Ollama)"
elif SELECTED_MODEL_TYPE == "qwen_api":
model_info = f"{config['dashscope_default_model']}(阿里云千问API)"
else:
model_info = SELECTED_MODEL_TYPE
print("="*60)
print(f"LangChain多模型聊天机器人(v1.0)")
print(f"当前使用模型:{model_info}")
print("操作说明:")
print(" – 输入任意内容进行聊天")
print(" – 输入 'exit' 退出程序")
print(" – 输入 'clear' 清空对话历史")
print("="*60)
# 主交互循环
while True:
# 获取用户输入
user_input = input("\\n你:").strip()
# 1. 退出指令
if user_input.lower() == "exit":
print("机器人:再见!👋")
break
# 2. 清空历史指令
if user_input.lower() == "clear":
chat_history.clear()
print("机器人:已清空所有对话历史!🧹")
continue
# 3. 空输入处理
if not user_input:
print("机器人:你还没输入内容哦~😯")
continue
# 4. 调用对话链处理
try:
# 调用带历史的对话链
response = chat_chain.invoke(
input={"input": user_input}, # 用户输入数据
config={
"configurable": {"session_id": "user001"}, # 会话ID
"timeout": 30 # 超时配置
}
)
# 输出回答
print(f"机器人:{response}")
# 异常处理:捕获所有可能的错误并友好提示
except Exception as e:
print(f"\\n机器人:抱歉,处理请求时出错了!❌")
print(f"错误详情:{str(e)}")
# 打印详细异常栈(调试用)
traceback.print_exc()
# 分模型给出排查建议
if SELECTED_MODEL_TYPE == "qwen_api":
print("\\n【千问API排查建议】:")
print("1. 确认API Key正确且有余额(Java能调用则Key无问题)")
print("2. 检查网络是否能访问阿里云接口")
print("3. 升级依赖:pip install –upgrade langchain-openai openai")
elif SELECTED_MODEL_TYPE == "ollama":
print("\\n【Ollama排查建议】:")
print("1. 确认Ollama服务已启动(执行ollama serve)")
print("2. 确认模型名称正确(执行ollama list查看)")
# ==================== 第五步:前置检查与程序启动 ====================
def pre_check():
"""
程序启动前的前置检查,提前发现问题
"""
if SELECTED_MODEL_TYPE == "ollama":
# 检查Ollama服务是否可达
try:
resp = requests.get(f"{config['ollama_base_url']}/api/tags", timeout=5)
if resp.status_code != 200:
print("⚠️ 警告:Ollama服务响应异常,但继续尝试运行…")
except requests.exceptions.ConnectionError:
print("⚠️ 警告:无法连接到Ollama服务!")
print("请先执行 'ollama serve' 启动服务,或确认服务地址正确")
elif SELECTED_MODEL_TYPE == "qwen_api":
# 检查千问API Key是否配置
if len(config["dashscope_api_key"]) < 10:
print("⚠️ 致命错误:千问API Key未正确配置!")
exit(1)
# 可选:测试阿里云接口连通性
try:
resp = requests.get(
f"{config['dashscope_base_url']}/models",
headers={"Authorization": f"Bearer {config['dashscope_api_key']}"},
timeout=10
)
print(f"✅ 千问API连通性测试成功,状态码:{resp.status_code}")
except:
print("⚠️ 千问API连通性测试失败,但继续尝试运行…")
# 程序主入口
if __name__ == "__main__":
# 执行前置检查
pre_check()
# 启动聊天界面
run_chat_interface()
运行效果:
1、阿里百炼大模型基于OPENAI API调用

2、基于本地Ollama部署模型调用

4.3 关键代码解释说明(LangChain入门核心)
1. LangChain开发核心流程(5个核心步骤)
| 环境配置 | load_environment() | 管理密钥和配置 | 永远不要硬编码密钥,用.env文件+环境变量管理 |
| 模型初始化 | init_llm() | 创建模型实例 | 不同模型参数不同,但LangChain封装后接口统一 |
| 构建对话链 | build_chat_chain() | 组合核心组件 | LangChain的核心是"链",将Prompt→模型→解析器串联 |
| 交互逻辑 | run_chat_interface() | 处理用户交互 | 调用链的invoke()方法执行推理,传入输入和配置 |
| 前置检查 | pre_check() | 提前发现问题 | 开发规范:启动前检查依赖/服务状态,提升用户体验 |
2. LangChain核心组件详解
(1)PromptTemplate(提示词模板)
prompt = ChatPromptTemplate.from_messages([
("system", "系统指令"),
MessagesPlaceholder(variable_name="chat_history"),
("user", "{input}")
])
- 作用:定义对话的结构和规则,是控制模型行为的核心
- 核心元素:
- system:设定模型的角色和行为准则(如"友好的中文助手")
- MessagesPlaceholder:动态填充多轮对话历史
- user:接收实时用户输入,{input}是变量占位符
- 入门要点:Prompt是影响模型回答质量的关键,好的Prompt能让模型更贴合需求
(2)ChatModel(模型实例)
llm = ChatOllama(...) # 本地模型
llm = ChatOpenAI(...) # 云端模型
- 作用:封装不同大模型的调用逻辑,提供统一接口
- 入门要点:
- 不同模型的初始化参数不同,但调用方式完全一致
- temperature:控制回答的随机性(0=严谨,1=创意)
- max_tokens:控制回答的最大长度
(3)OutputParser(输出解析器)
StrOutputParser()
- 作用:将模型返回的复杂对象转换为纯字符串
- 入门要点:LangChain模型返回的是包含元数据的对象,解析器能提取核心回答内容
(4)RunnableWithMessageHistory(带历史的链)
history_chain = RunnableWithMessageHistory(...)
- 作用:实现多轮对话的上下文记忆
- 核心参数:
- get_session_history:按会话ID获取/创建历史记录
- input_messages_key:指定用户输入的字段名
- history_messages_key:指定历史消息的字段名
- 入门要点:默认使用InMemoryChatMessageHistory(内存存储,重启丢失),生产环境可替换为数据库存储
(5)链式调用(|运算符)
base_chain = prompt | llm | StrOutputParser()
- 作用:按顺序执行组件,前一个组件的输出作为后一个的输入
- 执行流程:
- 用户输入填充Prompt模板 → 生成完整的提示词
- 提示词传入模型 → 模型生成回答
- 回答通过解析器 → 转换为纯字符串
- 入门要点:这是LangChain最核心的设计,组件化、可插拔、易扩展
3. 模型切换的核心实现
# 只需修改这一行即可切换模型
SELECTED_MODEL_TYPE = "qwen_api" # 阿里云千问
# SELECTED_MODEL_TYPE = "ollama" # 本地模型
- 设计思路:
- 所有模型初始化逻辑集中在init_llm()函数
- 通过model_type参数控制创建哪种模型
- 所有模型返回统一的ChatModel接口,后续链的逻辑无需修改
- 入门要点:面向接口编程,不同实现类(Ollama/OpenAI)遵循相同接口,便于切换
4. 异常处理的最佳实践
- 分层捕获:全局异常捕获 + 分模型针对性提示
- 信息丰富:不仅提示错误,还给出具体的排查步骤
- 调试友好:打印异常栈,方便定位问题
- 用户友好:错误提示用自然语言,避免技术术语堆砌
4.4 入门小结(LangChain核心知识点)
- 用环境变量管理密钥,避免硬编码
- 封装统一的模型初始化函数,便于切换
- 合理设计Prompt模板,控制模型行为
- 做好异常处理和前置检查,提升稳定性
- 记忆层:将InMemoryChatMessageHistory替换为数据库(如Redis、SQL)
- 功能扩展:添加工具调用、文档检索、多模态等能力
- 部署优化:封装为API服务、添加日志、监控等
六、LangChain生态系统:LangSmith、LangServe、LangGraph
LangChain不只是一个库,而是一套完整的生态系统,覆盖“开发→调试→部署→监控”全流程。

6.1 LangSmith:大模型应用的“调试器+监控台”
核心作用:解决大模型应用“不可调试”的痛点,支持:
- 查看每一步的Prompt、模型输出、工具调用;
- 评估模型回答的质量(准确性、相关性);
- 监控生产环境的调用情况(成功率、响应时间);
- 标注数据,用于微调或优化Prompt。
使用步骤:
export LANGSMITH_TRACING=true # 开启追踪
6.2 LangServe:一键部署LangChain应用为API服务
核心作用:将LangChain链/Agent快速部署为REST API,无需手动写FastAPI/Flask代码。
实战代码:
# 安装依赖:pip install langserve fastapi uvicorn
from langserve import add_routes
from fastapi import FastAPI
import uvicorn
# 1. 创建FastAPI应用
app = FastAPI(title="LangChain Demo API")
# 2. 把之前的chain添加为API路由
add_routes(
app,
chain,
path="/chat", # API路径
input_type=str, # 输入类型
output_type=str # 输出类型
)
# 3. 启动服务
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
调用API:
curl -X POST "http://localhost:8000/chat/invoke" -H "Content-Type: application/json" -d '{"input": "你好"}'
6.3 LangGraph:复杂流程的“可视化编排工具”
核心作用:用于构建复杂的多步骤流程(如“用户提问→查知识库→调用模型→生成答案→检查答案→返回结果”),支持:
- 可视化流程设计;
- 分支逻辑(如“答案正确则返回,错误则重新调用模型”);
- 循环逻辑(如“多次调用工具直到获取正确结果”);
- 人类介入(如“不确定答案时,转人工处理”)。
核心场景:客服机器人、智能助手、自动化工作流等复杂应用。
6.4 核心小结
| LangChain | 核心框架 | 提供构建 AI 应用的原子组件(Models, Chains, Agents) |
| LangSmith | 调试与监控 | DevOps 平台。追踪链路、评估效果、调试 Prompt,生产环境必备 |
| LangServe | 部署服务 | 将 Chain 快速发布为 REST API,无需写 Flask/FastAPI 样板代码 |
| LangGraph | 状态机编排 | 进阶版 Chains。支持循环、状态保持、多 Agent 协作,适合复杂工作流 |
建议:初学者先掌握 LangChain 核心,生产环境务必引入 LangSmith 进行监控,复杂工作流考虑 LangGraph。
七、版本变迁:从v0.0.x到v0.1+的重大重构
⚠️ 重要提示:LangChain在2024年初进行了重大重构,v0.1版本与之前的v0.0.x在API上不兼容!如果你在网上搜教程,会发现大量“已废弃”的代码。
7.1 为什么重构?
-
问题:早期版本将所有功能塞在一个包里(langchain),导致:
- 依赖臃肿(装一个包要下载一堆用不到的库)
- 版本冲突(不同组件依赖不同版本的第三方库)
- 扩展困难(想加新功能要改核心代码)
-
解决方案:模块化拆分
- langchain-core:核心接口、基类
- langchain-community:社区贡献的第三方集成
- langchain-openai:OpenAI专属集成
- langchain-anthropic:Anthropic专属集成
- …

7.2 新旧版本API对比
# ❌ 旧版本(v0.0.x,已废弃)
from langchain.llms import OpenAI # 从langchain直接导入
from langchain.chat_models import ChatOpenAI
llm = OpenAI(model_name="text-davinci-003")
# 调用方式不统一
# ✅ 新版本(v0.1+,推荐)
from langchain_openai import ChatOpenAI # 从独立包导入
from langchain_core.messages import HumanMessage
llm = ChatOpenAI(model="gpt-3.5-turbo")
response = llm.invoke([HumanMessage(content="Hello")]) # 统一使用invoke()
7.3 升级指南
如果你之前用过旧版LangChain,升级时需要:
重要建议:学习LangChain时务必查看官方文档,第三方教程很可能已经过时。
八、实战坑点:新手最容易踩的5个坑
坑点1:忽略版本兼容性
# 错误示范:照搬2023年的教程
from langchain import LLMChain # 旧版本写法
# ImportError: cannot import name 'LLMChain' from 'langchain'
# 正确做法:查看最新文档,从正确的位置导入
from langchain.chains import LLMChain # 注意导入路径变了
避坑指南:遇到报错,第一时间看官方文档的“Migration Guide”。
坑点2:环境变量配置不当导致密钥泄露
# 错误示范:硬编码密钥
llm = ChatOpenAI(api_key="sk-1234567890") # 代码上传到GitHub就泄露了
# 正确做法:使用环境变量
import os
from dotenv import load_dotenv
load_dotenv()
llm = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"))
避坑指南:
- 永远不要将密钥硬编码在代码里
- 使用.env文件管理环境变量,并添加到.gitignore
- 生产环境使用密钥管理服务(如AWS Secrets Manager)
坑点3:误以为LangChain能自动解决幻觉
# 错误期待
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run("告诉我公司2025年的营收") # 期待模型知道
# 实际:模型编造了数据
# 正确做法:结合RAG(检索增强生成)
from langchain_community.document_loaders import PDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
# 1. 加载公司财报PDF
loader = PDFLoader("财报2025.pdf")
docs = loader.load()
# 2. 分割文档
splitter = RecursiveCharacterTextSplitter(chunk_size=500)
chunks = splitter.split_documents(docs)
# 3. 存入向量库
vectorstore = Chroma.from_documents(chunks, OpenAIEmbeddings())
# 4. 检索相关文档
retriever = vectorstore.as_retriever()
relevant_docs = retriever.get_relevant_documents("2025年营收")
# 5. 将文档作为上下文传给LLM
prompt = ChatPromptTemplate.from_template("""
基于以下文档回答问题。如果文档中没有相关信息,请说不知道。
文档:{context}
问题:{question}
""")
避坑指南:LangChain是编排工具,不是魔法棒。解决幻觉要靠RAG(检索增强生成),让模型基于你提供的数据回答。
坑点4:忽略token管理导致成本失控
# 错误示范:不控制历史长度
memory = ConversationBufferMemory() # 无限增长
# 正确做法:使用限制大小的记忆
from langchain.memory import ConversationBufferWindowMemory
memory = ConversationBufferWindowMemory(k=5) # 只保留最近5轮对话
避坑指南:
- 始终使用带窗口限制的Memory
- 长对话考虑使用向量存储做长期记忆
- 监控token消耗,设置告警
坑点5:滥用Agent导致响应变慢
# 错误示范:每个问题都用Agent
agent = create_react_agent(llm, tools)
result = agent.invoke({"input": "你好,今天天气不错"})
# Agent会思考:需要调用工具吗?调用哪个?…
# 白白浪费时间和token
# 正确做法:简单对话用Chain,需要工具时用Agent
if needs_tools(user_input):
result = agent.invoke({"input": user_input})
else:
result = simple_chain.invoke({"input": user_input})
避坑指南:Agent会调用LLM多次(思考→行动→观察→…),每次调用都消耗token和耗时。只在确实需要多步决策时才用Agent。

总结
1. 核心知识点速记口诀
LLM是大脑,缺记忆手脚,
LangChain来补,组件化拼接,
Models定接口,Prompts管话术,
Chains串流程,Agents做决策,
v0.1要注意,包结构已重构,
LangSmith调BUG,LangServe一键部署。
2. 核心要点回顾
3. 实战建议
- 新手入门:从Chains开始,掌握Prompt模板和记忆管理;
- 进阶提升:学习RAG组件,解决幻觉问题;
- 高级应用:使用Agents实现自主工具调用,用LangGraph编排复杂流程;
- 生产部署:结合LangSmith调试、LangServe部署,保证应用稳定性。

写在最后
从裸写LLM API到使用LangChain,本质上是从“面向过程编程”到“面向组件编程”的转变。LangChain没有创造新的技术,而是将大模型应用开发中重复的、通用的逻辑抽象成标准化组件,让开发者聚焦于业务逻辑,而非底层细节。
记住:LangChain不是银弹,它不能解决LLM的所有问题(如幻觉、成本),但它能让你用最少的代码、最快的速度、最高的可维护性,将LLM的能力落地为实际应用。
大模型应用开发的核心不是“如何调用API”,而是“如何让LLM更好地解决业务问题”——而LangChain,正是实现这一目标的最佳工具。
如果觉得有帮助,欢迎点赞、收藏、转发!


![[LangChain RAG] 01 大模型为什么需要 RAG:四个问题与标准流程-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260825035331-6a8d11bb97bca-220x150.png)
