系列定位:本系列面向已经熟悉大模型 API 调用、做过智能体开发的工程师,帮助你快速理解 LangChain 1.0 的核心价值,并平滑迁移到这套生态。 本篇目标:建立对 LangChain 的整体认知,搞清楚它解决了什么问题、1.0 版本有哪些重大变化,并写出你的第一个 LangChain 程序。
系列定位:本系列面向已经熟悉大模型 API 调用、做过智能体开发的工程师,帮助你快速理解 LangChain 1.0 的核心价值,并平滑迁移到这套生态。
本篇目标:建立对 LangChain 的整体认知,搞清楚它解决了什么问题、1.0 版本有哪些重大变化,并写出你的第一个 LangChain 程序。
如果你已经做过大模型开发,你的代码大概长这样:
import os import json import requests def call_llm(user_message: str, system_prompt: str = "你是一个有用的助手") -> str: """直接调用 OpenAI 兼容接口""" headers = { "Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}", "Content-Type": "application/json" } payload = { "model": "gpt-4o", "messages": [ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_message} ], "temperature": 0.7 } response = requests.post( "https://api.openai.com/v1/chat/completions", headers=headers, json=payload ) return response.json()["choices"][0]["message"]["content"] # 调用 result = call_llm("用 Python 写一个快速排序") print(result)
这段代码能跑,也没什么问题。但当你的项目复杂度上来之后,你会遇到一系列"工程问题":
messages
每个项目都从零开始造轮子,这就是 LangChain 要解决的核心痛点。
LangChain 是一个专为大模型应用开发设计的开源框架,它的核心价值是:
把大模型应用开发中高度重复的"胶水代码",抽象成可组合的标准组件。
换一种说法:LangChain 不是让模型变得更聪明,而是让你写的代码更少、更易维护、更容易复用。
把它和几个常见概念做个类比,方便你快速定位:
\|
它不是魔法,底层依然是那些 HTTP 请求和 JSON 解析,只是帮你封装好了。
理解这六个概念,你就掌握了 LangChain 的骨架。
统一不同厂商的大模型调用接口。无论是 OpenAI、Claude、DeepSeek、Qwen,都用同一套接口调用,切换模型只需改一行初始化代码。
ChatOpenAI / ChatAnthropic / ChatDeepSeek / ... ↓ 统一抽象 BaseChatModel.invoke(messages) → AIMessage
把提示词从硬编码的字符串,变成可复用的模板组件。支持变量注入、消息列表组装、Few-shot 示例管理等。
ChatPromptTemplate + 变量 → 格式化后的消息列表
把多个组件串联起来,形成一个处理管道。LangChain 1.0 引入了 LCEL(LangChain Expression Language),用 | 管道符优雅地组合组件。
|
prompt | llm | output_parser
把任意 Python 函数包装成模型可以调用的工具,对应大模型的 Function Call 能力。
@tool 装饰器 → 带 Schema 描述的可调用工具
管理多轮对话的上下文历史,解决"模型没有记忆"的问题。支持内存存储、Redis、数据库等多种后端。
用户输入 + 历史消息 → 带上下文的完整请求
让模型自主决策"应该调用哪个工具、调用几次、什么时候停止",实现 ReAct 循环。
用户目标 → [思考 → 调用工具 → 观察结果] × N → 最终回答
如果你看过一些老教程,会发现代码和现在的写法差别很大。这是因为 LangChain 在 1.0 版本做了几项重要的架构调整,搞清楚这些变化能帮你避免很多坑。
最重要的变化。 原来所有东西都在 langchain 这一个包里,1.0 之后按职责拆分成多个独立包:
langchain
langchain-core
pip install langchain
langchain-openai
pip install langchain-openai
langchain-anthropic
pip install langchain-anthropic
langchain-community
pip install langchain-community
langgraph
pip install langgraph
实际影响: 原来的 from langchain.chat_models import ChatOpenAI 现在要改成 from langchain_openai import ChatOpenAI。
from langchain.chat_models import ChatOpenAI
from langchain_openai import ChatOpenAI
# ❌ 旧写法(已废弃) from langchain.chat_models import ChatOpenAI from langchain.schema import HumanMessage # ✅ 新写法(1.0) from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage
这是 LangChain 1.0 在架构上最核心的创新。原来用 LLMChain、SequentialChain 等类来组合组件,现在用 | 管道符直接串联,代码更直观:
LLMChain
SequentialChain
# ❌ 旧写法 from langchain.chains import LLMChain chain = LLMChain(llm=llm, prompt=prompt) result = chain.run(input="你好") # ✅ 新写法(LCEL) chain = prompt | llm | StrOutputParser() result = chain.invoke({"input": "你好"})
LCEL 背后的每个组件都实现了统一的 Runnable 接口,支持 invoke(同步)、ainvoke(异步)、stream(流式)三种调用方式,而且这些特性可以自动在整条链上传递。
Runnable
invoke
ainvoke
stream
以下是最常见的废弃写法,遇到老代码时需要注意迁移:
prompt \| llm \| parser
initialize_agent()
create_tool_calling_agent()
AgentExecutor
ConversationBufferMemory
RunnableWithMessageHistory
chain.run()
chain.invoke()
langchain.chat_models.*
langchain_openai.*
langchain_anthropic.*
根据你要使用的模型,按需安装:
# 核心包(必装) pip install langchain langchain-core # 按需选择模型包 pip install langchain-openai # OpenAI / 兼容 OpenAI 接口的模型(DeepSeek、Qwen 等) pip install langchain-anthropic # Anthropic Claude # 如果需要社区集成(VectorStore、Loader 等) pip install langchain-community
验证安装:
python -c "import langchain; print(langchain.__version__)" # 应输出 0.3.x 或更高版本
推荐用 .env 文件管理密钥,配合 python-dotenv:
.env
python-dotenv
pip install python-dotenv
在项目根目录创建 .env 文件(记得加入 .gitignore):
.gitignore
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxx ANTHROPIC_API_KEY=sk-ant-xxxxxxxx
在代码入口处加载:
from dotenv import load_dotenv load_dotenv() # 自动读取 .env 文件中的环境变量
现在用 LangChain 来重写本文开头那段原生调用代码,感受一下差别。
from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage, SystemMessage load_dotenv() # 初始化模型 llm = ChatOpenAI(model="gpt-4o", temperature=0.7) # 构建消息 messages = [ SystemMessage(content="你是一个有用的助手"), HumanMessage(content="用 Python 写一个快速排序"), ] # 调用(invoke 返回 AIMessage 对象) response = llm.invoke(messages) print(response.content)
输出类型是 AIMessage,不需要手动解析 choices[0]["message"]["content"] 了。
AIMessage
choices[0]["message"]["content"]
对于支持 OpenAI 兼容接口的国产模型,直接用 langchain_openai 包,改两个参数即可:
langchain_openai
from langchain_openai import ChatOpenAI # DeepSeek llm = ChatOpenAI( model="deepseek-chat", openai_api_key="your-deepseek-key", # 或从环境变量读取 openai_api_base="https://api.deepseek.com", ) # 通义千问 Qwen llm = ChatOpenAI( model="qwen-plus", openai_api_key="your-qwen-key", openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1", ) # 调用方式完全相同 response = llm.invoke("你好,介绍一下你自己") print(response.content)
这就是统一接口的价值所在:切换模型不需要改任何业务逻辑。
from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser llm = ChatOpenAI(model="gpt-4o") # 定义带变量的提示词模板 prompt = ChatPromptTemplate.from_messages([ ("system", "你是一位擅长 {language} 语言的编程专家,请给出简洁、专业的代码示例。"), ("human", "{task}"), ]) # 用 LCEL 管道符串联组件 chain = prompt | llm | StrOutputParser() # 调用链 result = chain.invoke({ "language": "Python", "task": "实现一个 LRU 缓存" }) print(result)
注意 StrOutputParser() 的作用:它把 AIMessage 对象自动转成纯字符串,省去了手动 .content 的步骤。
StrOutputParser()
.content
只需把 invoke 换成 stream,其他代码不变:
# 流式输出 for chunk in chain.stream({"language": "Python", "task": "实现一个二叉搜索树"}): print(chunk, end="", flush=True)
对比原生实现,你需要自己处理 SSE 的 data: 前缀解析、[DONE] 结束标志、异常中断处理等。LangChain 把这些全部封装了。
data:
[DONE]
import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser load_dotenv() def create_qa_chain(model_provider: str = "openai"): """根据供应商创建问答链,展示统一接口的价值""" if model_provider == "openai": llm = ChatOpenAI(model="gpt-4o") elif model_provider == "deepseek": llm = ChatOpenAI( model="deepseek-chat", openai_api_key=os.getenv("DEEPSEEK_API_KEY"), openai_api_base="https://api.deepseek.com", ) else: raise ValueError(f"不支持的模型供应商: {model_provider}") prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个专业的技术助手,回答请简洁准确。"), ("human", "{question}"), ]) # 链的结构完全相同,只有 llm 不同 return prompt | llm | StrOutputParser() # 使用不同模型,链的调用方式完全一致 chain = create_qa_chain("deepseek") answer = chain.invoke({"question": "什么是向量数据库?"}) print(answer)
回顾一下本篇涵盖的内容:
你现在应该能做到: - 用 langchain_openai 调通任意 OpenAI 兼容接口的模型 - 用 ChatPromptTemplate 定义带变量的提示词模板 - 用 LCEL 的 | 管道符串联 prompt | llm | parser - 用 stream() 实现流式输出
ChatPromptTemplate
prompt | llm | parser
stream()
《统一模型接口——ChatModel 与 LLM 的使用》
将深入介绍模型接口的各种用法,包括: - invoke / stream / batch / ainvoke 四种调用方式的区别和使用场景 - 如何用 with_structured_output() 让模型直接返回 Pydantic 对象 - 模型参数配置:temperature、max_tokens、timeout 等 - 如何在一套代码里对比多个模型的输出效果
batch
with_structured_output()
temperature
max_tokens
timeout
代码仓库:本系列所有可运行代码示例统一维护在 GitHub,每篇文章对应一个独立目录,可直接克隆运行。 系列导航:[第一篇(当前)] → 第二篇 → 第三篇 → ...
代码仓库:本系列所有可运行代码示例统一维护在 GitHub,每篇文章对应一个独立目录,可直接克隆运行。
系列导航:[第一篇(当前)] → 第二篇 → 第三篇 → ...
还没有评论,来抢沙发吧!
博客管理员
40 篇文章
还没有评论,来抢沙发吧!