欢迎光临
我们一直在努力

进阶篇-LangChain篇-1--LLM不是万能药:为什么我们需要编排框架?

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 乐高类比:从“散落积木”到“标准组件”

想象一下真正的乐高:

乐高世界LangChain世界
基础积木块 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文件(推荐)

  • 安装python-dotenv:pip install python-dotenv
  • 创建.env文件:OPENAI_API_KEY=sk-xxxxxxxxxxxx
    ZHIPU_API_KEY=xxxxxxxxxxxx

  • 加载.env文件:from dotenv import load_dotenv
    load_dotenv() # 自动加载.env文件中的环境变量

  • 4.2 Hello World:第一个完整的LangChain应用

    第一步:.env文件(配置核心)

    # ==================== 模型密钥(可选,用于切换) ====================
    # OpenAI(GPT-3.5/4)
    OPENAI_API_KEY=skxxxxxxxxxxxx
    # 智谱清言
    ZHIPU_API_KEY=xxxxxxxxxxxx
    # Anthropic(Claude)
    ANTHROPIC_API_KEY=skantxxxxxxxxxxxx
    # 阿里云通义千问(核心新增)
    DASHSCOPE_API_KEY=sk*******9 # 替换为你的真实API Key
    DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/compatiblemode/v1 # 阿里云兼容OpenAI的地址
    DASHSCOPE_DEFAULT_MODEL=qwen3.5flash # 可选:qwen-plus / qwen-max

    # ==================== 本地Ollama配置 ====================
    # Ollama服务地址(默认本地:http://localhost:11434,无需修改)
    OLLAMA_BASE_URL=http://localhost:11434
    # 默认使用的Ollama模型
    OLLAMA_DEFAULT_MODEL=qwen27bq5_k_m:latest
    # OLLAMA_DEFAULT_MODEL=DeepSeek-Coder-V2-Lite-Instruct-Q5_K:latest
    # 可选:DeepSeek-Coder模型(代码相关问答用)
    OLLAMA_CODER_MODEL=DeepSeekCoderV2LiteInstructQ5_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核心知识点)

  • 核心思想:LangChain是"组件化"的大模型开发框架,将Prompt、模型、解析器、记忆等功能拆分为独立组件,通过"链"串联实现复杂功能。
  • 开发流程:环境配置 → 模型初始化 → 构建处理链 → 实现交互 → 前置检查,五步即可完成基础的对话机器人。
  • 关键技巧:
    • 用环境变量管理密钥,避免硬编码
    • 封装统一的模型初始化函数,便于切换
    • 合理设计Prompt模板,控制模型行为
    • 做好异常处理和前置检查,提升稳定性
  • 扩展方向:
    • 记忆层:将InMemoryChatMessageHistory替换为数据库(如Redis、SQL)
    • 功能扩展:添加工具调用、文档检索、多模态等能力
    • 部署优化:封装为API服务、添加日志、监控等

  • 六、LangChain生态系统:LangSmith、LangServe、LangGraph

    LangChain不只是一个库,而是一套完整的生态系统,覆盖“开发→调试→部署→监控”全流程。

    在这里插入图片描述

    6.1 LangSmith:大模型应用的“调试器+监控台”

    核心作用:解决大模型应用“不可调试”的痛点,支持:

    • 查看每一步的Prompt、模型输出、工具调用;
    • 评估模型回答的质量(准确性、相关性);
    • 监控生产环境的调用情况(成功率、响应时间);
    • 标注数据,用于微调或优化Prompt。

    使用步骤:

  • 注册LangSmith账号(https://smith.langchain.com/);
  • 获取API Key,配置环境变量:export LANGSMITH_API_KEY=ls_xxxxxxxxxxxx
    export LANGSMITH_TRACING=true # 开启追踪

  • 运行代码,即可在LangSmith控制台看到完整的调用链路。
  • 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,升级时需要:

  • 重新安装:pip install langchain-openai langchain-core
  • 修改导入路径:从langchain.xxx改为对应的子包
  • 改用invoke():所有模型统一用invoke(),不再有__call__
  • 检查文档日期:看教程时确认发布时间在2024年之后
  • 重要建议:学习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. 核心要点回顾

  • LangChain的核心价值:为LLM补上记忆、工具调用、流程编排能力,解决大模型应用落地的“最后一公里”问题;
  • 四大核心组件:Models(标准化模型调用)、Prompts(可复用提示词模板)、Chains(流程编排)、Agents(自主工具调用);
  • 版本重构:v0.1+拆分包结构,API从run()改为invoke(),需注意迁移适配;
  • 生态系统:LangSmith(调试)、LangServe(部署)、LangGraph(复杂流程)构成完整开发生态;
  • 避坑核心:版本兼容、密钥安全、合理使用RAG降低幻觉、避免过度使用Agents。
  • 3. 实战建议

    • 新手入门:从Chains开始,掌握Prompt模板和记忆管理;
    • 进阶提升:学习RAG组件,解决幻觉问题;
    • 高级应用:使用Agents实现自主工具调用,用LangGraph编排复杂流程;
    • 生产部署:结合LangSmith调试、LangServe部署,保证应用稳定性。

    在这里插入图片描述


    写在最后

    从裸写LLM API到使用LangChain,本质上是从“面向过程编程”到“面向组件编程”的转变。LangChain没有创造新的技术,而是将大模型应用开发中重复的、通用的逻辑抽象成标准化组件,让开发者聚焦于业务逻辑,而非底层细节。

    记住:LangChain不是银弹,它不能解决LLM的所有问题(如幻觉、成本),但它能让你用最少的代码、最快的速度、最高的可维护性,将LLM的能力落地为实际应用。

    大模型应用开发的核心不是“如何调用API”,而是“如何让LLM更好地解决业务问题”——而LangChain,正是实现这一目标的最佳工具。

    如果觉得有帮助,欢迎点赞、收藏、转发!

    赞(0)
    未经允许不得转载:171主机测评 » 进阶篇-LangChain篇-1--LLM不是万能药:为什么我们需要编排框架?
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址