docs: 更新 uv 与虚拟环境文档

- README:三栏工作台与弹窗说明、uv 路径默认值(python / uv-cache)、镜像只在装包时生效、API 与数据布局、测试现状注记

- RELEASE:补 uv-cache 与 uv 目录、配置入口改为弹窗、运行时注入说明

- 新增 ADR-0009:uv 与托管 Python 环境的决策与边界

- PLAN:补记已完成的后继迭代
This commit is contained in:
2026-11-07 17:05:02 +08:00
parent 1914d38451
commit 37479f48c7
4 changed files with 97 additions and 43 deletions
+11 -5
View File
@@ -18,17 +18,23 @@
- SQLite 数据库:`data/task_pilot.db`(WAL 模式,运行中会额外出现 `-wal`/`-shm` 文件)
- 运行日志:`logs/{task_id}/{run_id}.log`
- 托管虚拟环境:`data/envs/<名称>/`(「虚拟环境」页创建,删除环境就是删掉整个目录)
- uv 下载的 Python 解释器:`python/<版本>/`(`UV_PYTHON_INSTALL_DIR` 默认指这里)
- 托管虚拟环境:`data/envs/<名称>/`(「虚拟环境」弹窗创建,删除环境就是删掉整个目录)
- uv 下载的 Python 解释器:`python/<版本>/`
- uv 缓存:`uv-cache/`(首次装包/下载 Python 后才会出现)
- 程序下载的 uv:`uv/uv.exe`
`UV_PYTHON_INSTALL_DIR` 与 `UV_CACHE_DIR` 默认是**相对本目录**的 `python` / `uv-cache`,
整个发布目录可以整体搬走;想复用机器上的全局缓存,在 uv 配置弹窗里把这两个变量改成绝对路径。
## Python 与 uv
用 uv 创建虚拟环境时,uv 的来源在「Python 环境」页切换(不读系统 PATH):
用 uv 创建虚拟环境时,uv 的来源在 uv 配置弹窗(任务调度页右栏「uv → 配置」)切换(不读系统 PATH):
- 本目录下的 `uv/uv.exe`(默认):没有 uv 时点「下载 uv」,会从科大镜像下载并校验 sha256 后放进来;也可以自己下载后放到这里
- 本目录下的 `uv/uv.exe`(默认):没有 uv 时会出现「下载 uv」,会从科大镜像下载并校验 sha256 后放进来;也可以自己下载后放到这里
- 任意位置的 `uv.exe`:选「指定路径」,保存时会先校验能运行;本机已装 uv 就把它的路径填进来
同一页还能配置 `UV_*` 环境变量(如 `UV_CACHE_DIR`、`UV_PYTHON_INSTALL_DIR`),会注入到每一次 uv 调用。
同一弹窗还能配置 `UV_*` 环境变量(如 `UV_CACHE_DIR`、`UV_PYTHON_INSTALL_DIR`),会注入到每一次 uv 调用;
任务运行时会把这些变量和默认镜像 `UV_DEFAULT_INDEX` 一并注入任务进程(任务自己的环境变量优先)。
「下载 uv」依赖 `mirrors.ustc.edu.cn` 可达;离线环境请自己准备 uv 并指定路径。
@@ -0,0 +1,31 @@
# ADR-0009:uv 与托管 Python 环境
- 状态:已接受
- 日期:2026-11-07
## 背景
Python 任务需要一个可复现的运行环境,但宿主机上的工具链状态不可控:PATH 上的 uv 版本随启动方式变化(终端 / 快捷方式 / 计划任务各不相同),也可能根本没装;pip、conda 与项目 `.venv` 的组合更是无法预设。之前的实现直接依赖 PATH 里的 uv,并要求用户先手动准备好虚拟环境,出了问题要到第一次运行时才暴露。
## 决策
1. **uv 是唯一的环境工具**:建环境、装依赖、跑预装都走 uv,不依赖 `pip.exe`。
2. **uv 来源只认平台副本或指定路径**:默认 `程序目录\uv\uv.exe`,或用户指定的 `uv.exe`;**不读系统 PATH**。缺失时从科大镜像 `mirrors.ustc.edu.cn/github-release/astral-sh/uv/LatestRelease` 下载当前架构压缩包,校验 sha256 后安装到程序目录。
3. **镜像只在装包时生效**:建环境 / 预装依赖时注入 `UV_DEFAULT_INDEX`(以及兼容的 `UV_INDEX_URL`);任务运行时不再注入 `PIP_*` 或镜像变量。
4. **路径默认值相对程序目录**:`UV_PYTHON_INSTALL_DIR` 默认 `python`、`UV_CACHE_DIR` 默认 `uv-cache`,注入前统一按可执行文件目录解析成绝对路径;用户可改成绝对路径。
5. **用户环境优先,缺失才创建**:解析顺序仍是显式 `venv` → 解释器路径推断 → 工作目录向上查找;都没有时在**保存任务**时用 uv 创建 `.venv`,运行期只校验、不再自动装依赖。
6. **托管环境**:`data/envs/<名称>` 预创建常用环境,Python 版本来自 `uv python install` 下载到平台的列表,可预装包、查看已装包。
## 原因
- PATH 上的 uv 版本与可用性不可控;平台副本随包分发,行为可预期。
- 相对默认值让整个发布目录可以整体搬迁;注入前解析成绝对路径,是因为 uv 的 cwd 在调用间会变化(项目目录 / 环境目录),相对路径会漂。
- 把装依赖限制在保存任务阶段,问题能当场暴露;运行期保持"只运行、不改环境"。
- 单机场景下,用户自己调试好的虚拟环境就是最可信的运行环境,应当优先复用而不是覆盖。
## 边界
- 托管环境不会自动升级依赖,也不跟随 `pyproject.toml` 变更重建。
- `uv python install` 走 uv 自己的 Python 发行源,不受 PyPI 镜像影响;必要时用 `UV_PYTHON_INSTALL_MIRROR`。
- 删除托管环境是直接删除目录,不可恢复。
- 自定义 uv 若版本过旧,`uv python list/envs` 等子命令可能与平台预期的参数不一致。