你执行了升级,命令没有报错,LangChain 却仍停在 1.4.x。
你改成指定 langchain==1.5.0,又收到:
ERROR: No matching distribution found for langchain==1.5.0
第一反应是换一个国内源,第二反应是清缓存。
但这一次,真正的线索可能就在前面那句 Requires-Python 里。
LangChain 1.5.0 已于 2026 年 11 月 11 日发布,最低 Python 版本提高到 3.11,依赖的 langchain-core 下限提高到 1.8.0。
这两项变化见 LangChain 官方发布说明。
本文用真实 pip 实验复现“找不到新版”和“成功选到旧版”,再给出从定位到迁移、验证、回滚的完整操作路径。
你不用 API Key,也不用付费模型。
图 1:同一个版本目标,在不同 Python 约束下会产生不同结果;安装成功只是验证的第一层。
核验日期:2026-11-12。
下载实验在 Linux、Python 3.12.3、pip 24.0 上执行,通过--python-version指定目标解释器版本。
这不是在真实 Python 3.10 / 3.11 进程中运行 LangChain;实际安装与离线运行验证使用 Python 3.12.3。
一、先分清三种现象,别让一条报错带偏方向
| 现象 | 优先核对 | 为什么 |
|---|---|---|
| 升级命令成功,版本仍是 1.4.x | 当前 Python、版本范围、锁文件 | 新版可能不属于当前环境的兼容候选 |
| 指定 1.5.0,提示没有匹配版本 | 前面的 Requires-Python 提示、目标源是否提供该版本 | 同一句末尾错误可能有不同原因 |
| 装好了,但项目启动失败 | 实际解释器、provider 包、旧 API 与项目约束 | 下载和安装并没有执行你的业务路径 |
pip 需要同时满足版本要求、Python 要求和相关依赖约束。
“最新可安装版本”并不总是“这个项目发布的最新版本”。
本次核对的 PyPI 1.5.0 元数据声明 Python 范围为 <4.0.0,>=3.11.0。
1.4.10 的元数据则仍允许 Python 3.10;core 1.8.0 同样要求 Python 3.11 起步。
因此,不要把“LangChain 已经发了新版”理解成“任何解释器都能装新版”。
二、第一步:确认运行代码的 Python,和安装包的是同一个
在你真正启动项目的终端里执行:
python -c "import sys; print(sys.executable); print(sys.version)"
python -m pip --version
python -m pip show langchain langchain-core langgraph
看两个位置:sys.executable 指向哪里,pip --version 的路径属于哪个环境。
这里统一使用 python -m pip,让安装命令明确绑定到这一条 Python 解释器。
如果你在 Notebook 中遇到“终端已经升级、单元格还是旧版”,先在单元格执行:
import sys
from importlib.metadata import version
print(sys.executable)
print(sys.version)
for name in ("langchain", "langchain-core", "langgraph"):
print(name, version(name))
包未安装时,version() 会抛出 PackageNotFoundError;这也是“当前内核不是预期环境”的线索。
应让 Notebook 内核指向新环境,并在安装后重启内核,避免已加载模块仍驻留内存。
仅修改终端的 PATH,不能证明已启动的内核也换了解释器。
容器和服务同理:应在实际运行的容器或服务环境内检查,不能用宿主机的 Python 版本代替。
本次只做本地环境实验,没有更改论坛服务器或生产依赖。
图 2:建议按解释器、Python 兼容范围、包源候选、整组依赖的顺序缩小问题。
三、真实复现:不安装旧 Python,也能看到候选怎样被筛掉
pip download 官方文档支持为目标解释器下载分发包。
我们利用这个能力检查候选筛选,不修改当前环境中的 LangChain。
下面命令只下载顶层 wheel,不下载依赖。
--isolated 用来忽略环境变量与用户配置,减少这轮实验受到额外配置的影响;显式指定官方源便于复现本次证据,网络受限时应使用可访问且可信的源。
实验 A:目标 Python 3.10,强制要求 1.5.0
python -m pip --isolated download --index-url https://pypi.org/simple --no-deps --only-binary=:all: --python-version 3.10 --dest wheels310-pinned "langchain==1.5.0"
本地实际退出码为 1。
日志节选如下,省略了冗长的历史版本列表:
ERROR: Ignored the following versions that require a different python version: 1.5.0 Requires-Python <4.0.0,>=3.11.0
ERROR: No matching distribution found for langchain==1.5.0
关键证据是第一行:候选存在,但被 Python 版本约束排除了。
此时仅仅更换镜像,并不会改变 1.5.0 的 Python 要求。
如果你的实际日志没有这条提示,仍需继续核对索引可达性、版本是否存在,以及其他兼容条件,不能直接套用本例根因。
实验 B:仍是 Python 3.10,但允许 1.4 到 1.5 系列
python -m pip --isolated download --index-url https://pypi.org/simple --no-deps --only-binary=:all: --python-version 3.10 --dest wheels310-range "langchain>=1.4,<1.6"
本次快照实际退出码为 0,下载文件是:
langchain-1.4.10-py3-none-any.whl
这正是“命令成功,却没拿到期待的新版”的机制:要求允许旧版本,而旧版本仍满足当前 Python 约束。
本例没有真实执行 Python 3.10 环境下的 pip install -U,也没有声称所有项目都会选择 1.4.10。
未来的 1.4.x 补丁、你自己的约束和其他依赖,都可能改变具体选择。
实验 C:把目标提高到 Python 3.11
python -m pip --isolated download --index-url https://pypi.org/simple --no-deps --only-binary=:all: --python-version 3.11 --dest wheels311-pinned "langchain==1.5.0"
本地实际退出码为 0,下载文件为:
langchain-1.5.0-py3-none-any.whl
注意这里的证明边界:--no-deps 让实验聚焦顶层包,不能证明全部依赖在 Python 3.11 和你的操作系统上可安装。
完整的跨平台下载还涉及平台、ABI、实现及依赖分发包;本文没有把这三条命令当作部署打包方案。
四、真正迁移:建立新环境,不在旧环境里反复拆装
建议先保留旧环境、锁文件和原始启动方式,再用明确的 Python 路径建立新环境。
以下是 Linux / macOS 操作示例,前提是已经安装 Python 3.12:
python3.12 -m venv .venv-lc15
.venv-lc15/bin/python -m pip install "langchain==1.5.0"
.venv-lc15/bin/python -m pip check
Windows 可以使用:
py -3.12 -m venv .venv-lc15
.venv-lc15\Scripts\python.exe -m pip install "langchain==1.5.0"
.venv-lc15\Scripts\python.exe -m pip check
Windows 命令为路径适配说明,本次未在 Windows 执行。
缺少对应解释器时,先完成解释器安装;不要把 pip install python 当作升级 Python 运行时的办法。
我们在全新 Python 3.12.3 虚拟环境中实际安装了 1.5.0,并执行 pip check,结果为:
No broken requirements found.
这个结果表示已安装分发包之间的声明依赖未发现冲突,不表示旧 API、模型权限、网络调用或业务语义全部兼容。
本次环境只包含基础 LangChain 安装及其解析依赖,没有你的项目依赖,也没有额外安装模型 provider。
项目还固定 core 1.7.x,怎么办?
1.5.0 要求 langchain-core>=1.8.0,<2.0.0。
如果你又在 constraints 或锁文件中固定 core 1.7.x,这两个条件没有交集。
此时应检查整组依赖的可用兼容版本,不能靠反复单独升级顶层包解决。
先在新环境恢复原项目的依赖约束,并检查 provider 包、LangGraph、持久化组件和测试工具。
逐项确认冲突来源,再有意识地更新版本组合。
不要删掉所有版本约束后,将一次碰巧成功的解析视为迁移完成。
本例下载实验使用 --no-deps 是为了隔离观察变量;迁移项目时不要照搬它来跳过依赖冲突。
同样,不建议用 --ignore-requires-python 把不支持的解释器硬塞进运行环境。
包能被强行放进去,与项目能正确运行,是两回事。
五、别止步于 import:跑一个真正的离线 Agent 冒烟
下面代码会执行真实 create_agent 流程,但用官方核心包中的假聊天模型返回固定消息。
它还直接调用一个本地工具,检查工具输入校验与执行路径。
保存为 smoke.py,在新虚拟环境执行:
.venv-lc15/bin/python smoke.py
"""Offline smoke test: real LangChain agent with a fake model, no network."""
import json
import sys
from importlib.metadata import version
from langchain.agents import create_agent
from langchain_core.language_models.fake_chat_models import FakeMessagesListChatModel
from langchain_core.messages import AIMessage
from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
"""Add two integers locally."""
return a + b
model = FakeMessagesListChatModel(responses=[AIMessage(content='offline-ok')])
agent = create_agent(model=model, tools=[])
result = agent.invoke({'messages': [{'role': 'user', 'content': 'health check'}]})
assert result['messages'][-1].content == 'offline-ok'
assert add.invoke({'a': 2, 'b': 3}) == 5
print(json.dumps({
'python': sys.version.split()[0],
'langchain': version('langchain'),
'langchain-core': version('langchain-core'),
'langgraph': version('langgraph'),
'agent_reply': result['messages'][-1].content,
'tool_direct_result': add.invoke({'a': 2, 'b': 3}),
'live_model_called': False,
}, ensure_ascii=False, indent=2))
本地实际输出:
{
"python": "3.12.3",
"langchain": "1.5.0",
"langchain-core": "1.8.0",
"langgraph": "1.2.20",
"agent_reply": "offline-ok",
"tool_direct_result": 5,
"live_model_called": false
}
这里最容易误读的是工具那一行。
Agent 的 tools=[],所以 tool_direct_result=5 来自代码对 add.invoke() 的直接调用,不是模型自行选择工具。
agent_reply=offline-ok 说明真实 Agent 编排路径在这个最小场景中跑通,模型输出则是我们预先指定的。
这组检查不覆盖真实模型 SDK、流式输出、模型选择工具、认证、检索和数据库持久化。
你仍需在项目里增加最小业务回归,而不是把假模型冒烟当成上线评测。
图 3:三次目标版本下载实验与一次真实隔离安装验证,各自证明不同的事情。
六、还有三类高频坑,升级前顺手排掉
1. 镜像确实不同步,但别靠猜
先看同一版本的官方发布记录与 PyPI 元数据,确认该版本真的存在,再检查当前源是否可访问、是否提供对应候选。
如果相同解释器在官方源能找到,在镜像找不到,才有理由继续调查镜像同步、索引配置和网络链路。
不要在公开求助中粘贴带用户名、令牌或内部地址的完整索引配置。
通常提供去敏后的错误片段、Python 版本、包版本要求和源类型,就能开始定位。
2. lock 文件固定了旧版,升级命令与项目工具不在一套流程
如果项目由 uv、Poetry 或其他锁文件管理,先确认实际部署使用的锁文件和 Python 约束。
在旁边运行一次 pip,不能自动更新项目的锁定结果;手工编辑版本号也不等于重新完成依赖解析。
本文没有逐个验证这些工具的升级子命令,因此不提供猜测式通用命令。
迁移原则是:用项目原本采用的工具更新、重建环境,并保留可回退的锁文件版本。
3. 旧代码接口报错,和 Python 兼容性是两层问题
如果你从更早的 LangChain 0.x 跨到 1.5,可能同时遇到 API 迁移。
“换成 Python 3.12”只解决运行时要求,不会自动把旧导入路径和业务代码改成新接口。
应把安装失败、import 失败、模型调用失败、业务行为退化分开记录。
每一步保留实际报错和最小复现,避免一个错误还没定位就同时改包版本、模型、检索器和提示词。
七、从“装上了”走到“可以切换”,需要四层证据
| 层次 | 本文是否验证 | 你接入项目后还要补什么 |
|---|---|---|
| 顶层包与目标 Python 的候选匹配 | 已验证三组下载结果 | 目标操作系统、完整依赖的安装 |
| 新环境声明依赖一致 | 已执行 pip check | 原项目全套依赖与 provider |
| 最小 Agent 与本地工具路径 | 已用假模型和直接工具调用验证 | 真模型、工具选择、流式和错误处理 |
| 旧业务能力保留 | 本文未验证 | 固定样本、逐条对比、生产前回归 |
如果要回滚,优先切回保留的旧环境或旧镜像、旧锁文件与原启动方式。
不要在已经反复升级的新环境里盲目降级几个顶层包,再假设它等于迁移前状态。
涉及数据库或持久化格式变化时,还应有单独的备份和回滚设计;本次未测试这类迁移。
固定样本的回归方法可参考昨日发布的Agent 逐条评测与退化排障;如果项目带中断恢复和写操作,还可以接着检查重复执行与业务幂等。
一手来源与复现边界
- LangChain 1.5.0 官方发布说明:2026-11-11 发布;本篇聚焦运行时和依赖要求,不展开新中间件功能。
- PyPI:langchain 1.5.0 与 langchain 1.4.10:核对 Requires-Python 与实际发布版本。
- PyPI:langchain-core 1.8.0:核对核心包的 Python 要求。
- pip download 文档:目标解释器下载的机制与限制。
本文所有依赖解析与安装结果均为 2026-11-12 的本地快照;不是所有机器、源和项目的兼容性承诺。
三张图为原创工程图解,未用模拟日志冒充真实错误,未调用付费模型或修改生产环境。
遇到升级问题时,可以贴出脱敏后的 Python 版本、实际解释器路径、目标包版本与最早出现的错误片段。
先判断“新版没有成为候选”,还是“已经装上但业务不兼容”,往往比继续换源更快找到下一步。


