pip install 不能保证完全确定性,因其按宽松约束(如requests>=2.25.0)选择最新兼容版本,不同时间或机器可能安装不同版本,且间接依赖未显式声明、易漂移;pip-compile通过解析requirements.in生成含精确版本与哈希的requirements.txt,确保可重现安装。

为什么 pip install 不能保证完全确定性?
直接用 pip install -r requirements.txt 安装时,如果 requirements.txt 里写的是 requests>=2.25.0 这类宽松约束,pip 会选满足条件的最新兼容版本——不同时间、不同机器跑,可能装上 requests==2.31.0 或 requests==2.32.0,哪怕它们都符合 >=2.25.0。更麻烦的是,间接依赖(比如 requests 依赖的 urllib3)完全不显式声明,版本漂移风险更大。
pip-compile 怎么生成真正锁定的 requirements.txt?
pip-compile 的核心作用是把宽松的 requirements.in(你手写的“需求意图”)转换成带完整版本号和哈希值的 requirements.txt(精确的“安装指令”)。它会递归解析所有依赖树,固定每个包及其子依赖的精确版本。
inference.sh 的 Python SDK:运行 AI 应用、构建智能体,并集成 150 多个模型。包名:inferencesh (pip install inferencesh)。支持同步/异步……
- 先写
requirements.in,只写你直接需要的包,比如:django>=4.2<br>requests~=2.31.0
- 运行
pip-compile --generate-hashes requirements.in,生成带--hash校验的requirements.txt - 安装时用
pip install --require-hashes -r requirements.txt,pip 会校验每个包的 SHA256 值,防止篡改或 CDN 缓存污染 - 如果想让
pip-compile自动忽略某些包(比如本地开发包),加--no-deps或在requirements.in里用-e ./src/mypackage
如何处理多环境(dev / prod)的依赖差异?
常见做法是拆两个输入文件:requirements.in(生产依赖)和 requirements-dev.in(开发依赖),再分别编译:
-
pip-compile requirements.in→ 生成requirements.txt -
pip-compile requirements-dev.in→ 生成requirements-dev.txt,里面应包含-r requirements.txt行,确保 dev 环境也包含全部生产依赖 - 注意:如果
requirements-dev.in里写了和requirements.in冲突的版本(比如django==4.1.0vsdjango>=4.2),pip-compile会报错,必须手动协调 - CI 中建议始终用
--upgrade重新编译,避免人为忘记更新requirements.txt
容易被忽略的三个坑
很多人跑通一次就以为万事大吉,但实际落地时这几个点常导致锁定失效:
-
pip-tools默认不锁定 Python 版本,如果项目要求python >=3.9,,得在 <code>pyproject.toml的[project.requires-python]里声明,并在 CI 中校验python --version,否则pip-compile可能为不同 Python 版本生成不同依赖(比如typing-extensions在 3.8 和 3.10 下行为不同) - 使用
--pre参数编译时,会引入预发布版,但这类包通常没哈希值,--generate-hashes会失败;要么去掉--pre,要么手动补哈希(不推荐) - 如果团队多人维护,
requirements.txt必须提交进 Git,且每次修改requirements.in后必须重新pip-compile并提交新requirements.txt,否则别人pip install -r就不是你测试过的那套组合
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










