先理解包结构,再敲 pip。 LangChain 把『稳定抽象』和『易变集成』物理隔离:
langchain-core只含 Runnable / Prompt / Message 等接口,几乎不动;具体厂商(OpenAI、Anthropic)拆成独立的langchain-openai、langchain-anthropic,各自迭代各自发版。这样某个厂商 SDK 升级不会逼着你升级整个 LangChain。你的业务代码应当依赖 core 抽象,而不是某个集成包的内部实现。
包拆分演进:0.1 / 0.2 / 0.3 到底变了什么
如果你在网上看到的教程 from langchain.chat_models import ChatOpenAI 报错,多半是它停留在旧版结构。下面这张表说明三个里程碑各自的关键变化,决定了你今天该 import 哪个路径。
| 版本 | 包结构关键变化 | ChatOpenAI 的正确 import |
|---|---|---|
| 0.1.x | langchain 单体为主,集成混在 langchain.* 下 | from langchain.chat_models import ChatOpenAI(已废弃) |
| 0.2.x | 拆出 langchain-core,集成迁往 langchain-community / langchain-openai | from langchain_openai import ChatOpenAI |
| 0.3.x | 全面 core + 集成包;Pydantic 升到 v2;community 进一步瘦身 | from langchain_openai import ChatOpenAI |
安装:装对包,锁住版本
最小可运行集合:核心抽象 langchain + 你要用的厂商集成包。下面命令同时给出 OpenAI 与 Anthropic 两个常用集成,以及加载 .env 的 python-dotenv。版本约束用 >=,< 区间,避免日后大版本跳变破坏代码。
# 1) 强烈建议先建虚拟环境(venv 内置,零额外安装)
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
# 2) 安装核心 + 厂商集成包 + dotenv
# langchain —— 高层封装(链、agent 工具等)
# langchain-core —— 抽象层,会被上面这些作为依赖自动装上
# langchain-openai —— OpenAI / 兼容 OpenAI 接口的厂商
# langchain-anthropic —— Claude 系列
pip install "langchain>=0.3,<0.4" \
"langchain-openai>=0.2,<0.3" \
"langchain-anthropic>=0.2,<0.3" \
"python-dotenv>=1.0"
# 3) 仅在用到社区集成(如某些向量库、文档加载器)时再装
# pip install "langchain-community>=0.3,<0.4"
# 4) 验证:能 import 且打印版本就算装对了
python -c "import langchain, langchain_core; print(langchain.__version__, langchain_core.__version__)"
配置 API Key:环境变量优先,.env 辅助开发
LangChain 的厂商集成会自动从环境变量读取 key:langchain-openai 读 OPENAI_API_KEY,langchain-anthropic 读 ANTHROPIC_API_KEY。所以正确姿势是把 key 放进环境变量,而不是写死在代码里。开发期用 .env 文件 + python-dotenv 加载最方便,记得把 .env 加入 .gitignore。
# .env —— 放在项目根目录,切勿提交到 git
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxx
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxx
# 如果走代理 / 自建网关(OpenAI 兼容接口),再配 base_url
OPENAI_BASE_URL=https://your-gateway.example.com/v1
import os
from dotenv import load_dotenv
# load_dotenv() 把 .env 里的键值写入 os.environ
# override=False(默认):已存在的系统环境变量优先,不被 .env 覆盖
load_dotenv(override=False)
# 验证 key 是否就位(不要打印完整 key,只看是否存在)
assert os.environ.get("OPENAI_API_KEY"), "OPENAI_API_KEY 未设置,检查 .env 是否被加载"
print("OPENAI_API_KEY loaded:", bool(os.environ.get("OPENAI_API_KEY")))
# 也可以纯代码方式注入(不依赖 .env,比如在 CI 里)
# os.environ["OPENAI_API_KEY"] = "sk-..."
Hello World:第一个可运行的 invoke
推荐用 init_chat_model 作为统一入口——它接受 "provider:model" 形式的字符串,换模型只改一行,无需改 import。下面给出 init_chat_model 和直接实例化 ChatOpenAI 两种写法,跑通后都会打印模型对你那句话的回复。
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
load_dotenv() # 读取 .env 里的 OPENAI_API_KEY / ANTHROPIC_API_KEY
# 统一入口:"provider:model" 字符串。换厂商只改这一行:
# OpenAI -> "openai:gpt-4o-mini"
# Anthropic -> "anthropic:claude-3-5-sonnet-latest"
model = init_chat_model("openai:gpt-4o-mini", temperature=0)
# invoke 接受字符串或消息列表,返回一个 AIMessage
resp = model.invoke("用一句话解释 LangChain 是什么")
print(type(resp).__name__) # AIMessage
print(resp.content) # 模型生成的文本
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage
load_dotenv()
# 直接实例化 ChatOpenAI;key 自动从环境变量 OPENAI_API_KEY 读取
# 如需走代理 / 自建网关,传 base_url(或设环境变量 OPENAI_BASE_URL)
model = ChatOpenAI(
model="gpt-4o-mini",
temperature=0,
timeout=30,
max_retries=2,
# base_url="https://your-gateway.example.com/v1", # 自建网关时取消注释
)
# 用消息列表组织 system + user,比纯字符串更可控
messages = [
SystemMessage(content="你是简洁的技术助理,回答控制在两句话内。"),
HumanMessage(content="LangChain 的 Runnable 抽象解决了什么问题?"),
]
resp = model.invoke(messages)
print(resp.content)
常见 ImportError 与环境问题排查
ImportError: cannot import ChatOpenAI from langchain.chat_models
- 典型表现
- 照旧教程写 from langchain.chat_models import ChatOpenAI 报 ImportError 或 deprecation 警告。
- 判断标准
- 确认你在用 0.2+ 的包结构。
- 解决方向
- 改成 from langchain_openai import ChatOpenAI,并 pip install langchain-openai。旧路径在 0.2 后已迁移/废弃。
ModuleNotFoundError: No module named 'langchain_openai'
- 典型表现
- import langchain_openai 时报模块不存在。
- 判断标准
- 集成包是否单独安装、是否装进了当前激活的虚拟环境。
- 解决方向
- pip install langchain-openai。若仍报错,确认 which python 指向 .venv,避免装进了全局 Python 而代码跑在 venv 里。
OPENAI_API_KEY 未生效 / AuthenticationError
- 典型表现
- 代码报缺少 key 或 401,但 .env 里明明写了。
- 判断标准
- load_dotenv() 是否在创建 model 之前调用、.env 路径是否正确。
- 解决方向
- 确保 load_dotenv() 在 import model 类之后、实例化之前执行;用 print(os.environ.get('OPENAI_API_KEY') is not None) 验证;.env 不在当前工作目录时传 load_dotenv(dotenv_path=...)。
Pydantic 相关报错(v1/v2 冲突)
- 典型表现
- 升级到 0.3 后出现 pydantic ValidationError 或 BaseModel 行为异常。
- 判断标准
- 项目里是否混用了 pydantic v1 写法。
- 解决方向
- LangChain 0.3 基于 pydantic v2。pip install -U pydantic 并把自定义模型迁到 v2 API(如 model_config 替代 class Config)。
✓推荐做法
- 用 venv 或 PDM 隔离依赖,version 用 >=,< 区间锁住大版本
- key 走环境变量 / .env,代码里只读不写死
- 优先 init_chat_model 统一入口,换模型零成本
- 代理 / 网关通过 base_url 或 OPENAI_BASE_URL 配置
✗不推荐
- 不要 pip install 全局污染系统 Python
- 不要把 api_key 硬编码进源码并提交 git
- 不要照搬 from langchain.chat_models import ... 的老教程
- 不要在 0.3 项目里混用 pydantic v1 写法
⚠常见误区
- which python 与代码运行环境不一致,导致『装了却 import 不到』
- load_dotenv() 放在实例化之后,key 没注入就建 model
- base_url 指向了非 OpenAI 兼容接口,请求格式对不上
在干净虚拟环境里 python app.py 能打印出模型回复,且源码不含任何明文 key——即视为环境配置达标。
环境就绪后,下一章进入 LangChain 真正的灵魂——Runnable 抽象与 LCEL 管道:理解为什么一个 | 就能把 prompt、模型、解析器串成可组合、可流式、可异步的链。