Python 版本与依赖分组:`requirements/` 下每个文件管什么

2026-08-10

装一个 Python 项目之前,值得先花五分钟把它的依赖声明读一遍——尤其是当它同时存在 pyproject.tomlrequirements/ 两套文件的时候。这两套东西一旦口径不一致,你按其中一份装出来的环境就和作者、CI、Docker 镜像里的不是同一个。

DeepTutor 正好是这种双轨结构。下面所有行号、条目数都对应我们采集的仓库快照:HEAD 456f9c2,采集日 2026-08-10,deeptutor/__version__.py 里的版本号是 1.5.11。你自己 clone 之后行号可能已经漂了,但文件名和 extra 的名字是稳的。

一、Python 版本区间:上限被写死在 3.14 之前

pyproject.toml:12-18 写的是 requires-python = ">=3.11,<3.14"。下限好理解,上限值得看一眼旁边那段注释:它给出的理由是 3.14 上 pip 找不到部分编译依赖(注释点名了 faiss-cpu)的 wheel,于是会退化成注定失败的源码构建,注释里引用了 issue #664。

同一个区间在 CLI-only 子包里也写了一遍:packaging/deeptutor-cli/pyproject.toml:9-12 同样是 >=3.11,<3.14

但「能装」和「作者建议你用哪个」是两回事,仓库里至少有四层口径:

位置写的是什么
pyproject.toml:12-18>=3.11,<3.14(硬约束)
README Option 1(PyPI 安装)Python 3.11–3.13,且 PATH 上要有 Node.js 20+
README Option 2(源码安装)建议 Python 3.11–3.13 + Node.js 22 LTS,理由是对齐 CI 与 Docker
.github/workflows/tests.yml矩阵 3.11 / 3.12 / 3.13;另以 experimental: truecontinue-on-error)额外跑 3.14,Node 侧用 22
Dockerfilepython-baseproduction 两个 stage 都是 python:3.11-slim

这几层不冲突,但含义各不相同:pyproject 那一条是装不装得上的闸门,CI 矩阵那一条是「被测过的组合」,Docker 那一条是「官方镜像里实际跑的那个版本」。要复现作者的环境,看 Docker 那一行最直接;要判断自己的 3.13 会不会踩坑,看 CI 矩阵;至于 3.14,CI 里它是带 continue-on-error 的实验列,pyproject 的上限也把它排除在外——这是仓库当前状态,不是对未来版本的结论。

二、反直觉的那一处:requirements/ 不是依赖的来源

按大多数 Python 项目的习惯,requirements/ 下的文件就是依赖清单本体。这个仓库明确不是。

根目录 requirements.txt 共 22 行,头部注释(requirements.txt:6-8)自己声明:单一事实来源是 pyproject.tomlrequirements/ 下的文件只是把那些 extra 镜像一份,供「还拿不到 pyproject.toml 与源码」的 Docker / CI 安装场景使用。requirements/ 下每个文件的文件头也都写着同一句话的变体:Mirrors pyproject.toml…… Keep in sync。

于是问题变成:镜像全了吗?

我们实读的数字是:pyproject.toml:80-240[project.optional-dependencies] 实际定义了 15 个 key —— cliserverpartnersparse-markitdownparse-doclingparse-pymupdf4llmparsetutorbotmatrixmatrix-e2emath-animatorgraphragrag-lightragdevall

requirements/ 下只有 7 个文件cli.txtserver.txtpartners.txtdev.txtmatrix.txtmatrix-e2e.txtmath-animator.txt

两边做个差集,有 8 个 extra 没有对应的镜像文件:三个 parse-*、聚合的 parsetutorbotgraphragrag-lightrag,以及 all。这条差集的实际后果很具体:如果你在一个只有 requirements/ 可用的环境里(比如某些只 COPY 了依赖文件的镜像构建阶段)想装文档解析或图谱检索这几块能力,pip install -r 是拿不到的,只能回到有 pyproject 的源码 checkout 用 pip install -e ".[parse]" 这类写法。

顺带一个同源的口径差:AGENTS.md:129-137 的 “Source extras” 只列了 8 个(cli / server / partners / matrix / matrix-e2e / math-animator / dev / all),README 的安装示例只给了 5 条(.[dev].[partners].[matrix].[matrix-e2e].[math-animator]README.md:265-269),而 pyproject 里是 15 个。三处列出的数量都不一样,以我们实读的 pyproject 为准。

三、七个文件各管什么

wc -l 数行数、grep -cvE '^\s*(#|$)' 数非注释条目,结果是这样:

文件行数非注释条目
requirements/cli.txt6534
requirements/server.txt3612(含 -r cli.txt
requirements/partners.txt4119
requirements/dev.txt2511(含 -r server.txt
requirements/matrix.txt184
requirements/matrix-e2e.txt192
requirements/math-animator.txt161

这张表要横着读,别竖着读。注意两件事:

其一,条目数里有一部分是 -r 引用,不是包。 事实卡里明确标注的两处是 server.txt-r cli.txtdev.txt-r server.txt,其余文件是否也有引用行我们没有逐个核,所以下面这条 grep 值得你自己跑一遍。根 requirements.txt 那 22 行里唯一的实体内容也是一条引用——-r requirements/partners.txt,按头部注释,它对应的是完整 server 运行时(CLI + API + partners)那一档,而不是最小依赖;它与 dev / matrix / math-animator 各自覆盖什么,我们没有做逐包 diff。想搞清楚完整的引用图,最省事的动作是在仓库根目录跑一次 grep -n '^-r' requirements/*.txt,把每个文件头上的引用行捞出来自己连成一张图,比逐个文件翻要快——上面这张表里 partners.txtmatrix.txtmatrix-e2e.txt 的条目数同样可能含引用行,别当成纯包数看。

其二,条目少不等于装起来轻。 math-animator.txt 只有 1 条,就是 manim>=0.19.0pyproject.toml:193-195)。但同一处注释写明了它的系统前置:LaTeX、pkg-config、cairo、cmake、ffmpeg——这些都要在 pip 之外自己装。一个条目的文件对应五个系统级依赖,是这批文件里最容易看走眼的一个。matrix-e2e.txt 只有 2 条,这 2 条具体是什么、有没有系统前置,我们没有核。

还有一个专门的标记要留意:tutorbot 这个 extra 在 pyproject.toml:176-177 被注明为 “Legacy alias kept for one release”。原样记录,不做延伸。

四、两个 marker 背后的坑

graphragrag-lightrag 这两个 extra 在 pyproject.toml:197-215 里都带了 python_version < '3.14' 的环境 marker。旁边注释写清了不加会怎样:pip 会静默把 deeptutor 回退到最后一个没有该 extra 的版本 1.4.5。

这个坑的形态值得单独记一下:它不报错。你以为装的是当前版本,实际解析器给了你一个旧版本,然后你在旧版本上找不到新功能,从头开始怀疑人生。判断动作很简单——装完之后先看一眼真正落地的版本号,跟 deeptutor/__version__.py 里那一行对一下(我们采集时是 1.5.11);对不上,就先回去看你的 Python 版本是不是落在了 marker 之外。

这一段只陈述注释写了什么与怎么核对,marker 生效后的实际解析结果我们没有验证。

五、cli.txt 文件头上那条口径差

写这篇的时候撞上一处必须说清的不一致,位置就在 requirements/cli.txt:7:这一行写的是 “Public install: pip install deeptutor-cli”。

同一件事在仓库里有四处表述:

  • README.md:372README.md:755:CLI-only 包只能从源码 checkout 安装,“isn’t published to PyPI yet”
  • AGENTS.md:78AGENTS.md:126:把 pip install deeptutor-cli # CLI-only 写成安装方式
  • requirements/cli.txt:7:Public install: pip install deeptutor-cli
  • SKILL.md:20pip install deeptutor-cli for CLI-only

.github/workflows/pypi-release.yml:139-153 的发布校验清单里只要求并发布 deeptutor-<version>-py3-none-any.whl 一个产物,不含 deeptutor-cli。

四处口径不一致,以我们实读的仓库状态为准。要不要按某一处去装,取决于你自己的核对结果,我们不推断哪一处是对的,也不据此评价这个项目。

六、还有第四张依赖面:Dockerfile.runner

如果你只盯着 pyproject 和 requirements/,会漏掉一张独立的依赖清单。

Dockerfile.runner 共 110 行,base 镜像同为 python:3.11-slim单阶段,不 COPY 应用代码——它只 COPY 一个文件 deeptutor/services/sandbox/runner/server.py/app/server.pyDockerfile.runner:19Dockerfile.runner:98)。注释写明了这么做的目的(Dockerfile.runner:14-16):它 “must not depend on the DeepTutor package or any heavy framework”,为的是把攻击面和镜像体积压到最小。

所以它的依赖是自己 pip 装的另一套 12 个包(Dockerfile.runner:63-75):numpy、pandas、python-docx、python-pptx、openpyxl、pypdf、pdfplumber、PyMuPDF、reportlab、lxml、defusedxml、Pillow。apt 侧装的是 git、curl、ca-certificates、ripgrep、jq、build-essential、nodejs、fonts-wqy-zenhei(Dockerfile.runner:26-35);注释解释了装 nodejs 却不装 npm 的原因——CLI apps 由主容器安装,runner 只读挂载执行。

这里有必要如实说明它的性质:这个容器是用来执行程序的,跑的是从主容器传过去的命令与脚本;DeepTutor 本身也会去驱动你本机已安装的 agent CLI。要不要开这条路径,请结合自己的环境判断,不要因为它叫 sandbox 就默认它等于安全隔离——docker-compose.yml:124 的注释自己就写着 “per-command isolation is a roadmap item”。

另一处值得记的取舍:LibreOffice(soffice默认不装,理由写在 Dockerfile.runner:77-83,是体积 ~400MB+,相关 office 技能会先 command -v soffice 再优雅降级;文件里以注释形式给出了可选开启的命令。这意味着你如果需要 office 相关处理,得自己决定要不要把这段注释放开。

七、你可以照着核的五步

  1. 打开 pyproject.toml:12-18,确认 requires-python 的区间与上限那段注释的理由。
  2. pyproject.toml:80-240 里数一遍 [project.optional-dependencies] 的 key,再 ls requirements 数文件,把差集列出来——这决定了你能不能靠 pip install -r 装到某块能力。
  3. 跑一次 grep -n '^-r' requirements/*.txt,把文件之间的引用关系连成图,再决定你该 -r 哪一个。
  4. 打开 requirements/math-animator.txtpyproject.toml:193-195,把 pip 之外的五个系统前置抄下来。
  5. 打开 pyproject.toml:197-215,确认那两个 python_version < '3.14' marker 的存在;装完之后拿 deeptutor/__version__.py 的版本号对一遍,防止静默落到旧版本。

最后交代边界:本文只数了 requirements/*.txt 的行数与非注释条目数,没有把每个文件与 pyproject 对应 extra 做逐包 diff,所以「是不是真的逐条同步」我们没有验证;pyproject.toml:21-75 的核心 dependencies 我们只知道是 40 余项(含 openai / anthropic / dashscope / perplexityai / llama-index / faiss-cpu / fastapi / uvicorn / pocketbase / typer / rich 等),未逐行计数。以上出现的所有版本区间与默认配置都是仓库当前的声明,不是对安装结果的保证。


本文依据 DeepTutor 官方仓库(github.com/HKUDS/DeepTutor)的 README、AGENTS.mdpyproject.tomldeeptutor/ 下的源码整理,核对日 2026-08-10,对应仓库快照 456f9c2(版本 1.5.11)。 本文内容为仓库源码与文档口径,我们没有安装、部署或运行过该项目,也没有调用过其中任何一个模型 API, 因此不涉及生成质量、响应速度与教学效果的任何描述。 参数与默认值随版本变动,请以仓库最新代码与 --help 的实际输出为准。 安全相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。