Files
task_pilot/docs/decisions/0009-uv-and-managed-environments.md
CNWei 8fdc55e17d feat: 首页改版与 uv / 镜像配置收敛,精简任务数据结构
- 页头只保留品牌与操作图标,三栏改为 1:2:1、容器最宽 1320
- 任务卡片:状态标签移入标题行并缩小,隐藏任务标识,操作行贴内容底边
- uv 配置弹窗:删掉与首页重复的状态条,三段配置改成标签页
- 镜像源:弹窗去掉默认镜像汇总,首页卡片改为展示默认镜像与运行时注入的变量
- 后端:迁移合并为单一基线 0001_init,删掉未生效的 concurrency_policy / retry_*,
  运行触发只剩 schedule / manual;contracts、前端生成类型、README / PLAN 同步
2026-11-08 21:26:47 +08:00

3.0 KiB
Raw Permalink Blame History

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 下载到平台的列表,可预装包、查看已装包。
  7. 解释器下载归 uv 配置:uv python install / uv python list 的入口放在「uv 配置」弹窗(解释器由 uv 管理、落在 UV_PYTHON_INSTALL_DIR);「虚拟环境」弹窗只负责从已下载列表里选版本创建环境。

原因

  • PATH 上的 uv 版本与可用性不可控;平台副本随包分发,行为可预期。
  • 相对默认值让整个发布目录可以整体搬迁;注入前解析成绝对路径,是因为 uv 的 cwd 在调用间会变化(项目目录 / 环境目录),相对路径会漂。
  • 把装依赖限制在保存任务阶段,问题能当场暴露;运行期保持"只运行、不改环境"。
  • 单机场景下,用户自己调试好的虚拟环境就是最可信的运行环境,应当优先复用而不是覆盖。

边界

  • 托管环境不会自动升级依赖,也不跟随 pyproject.toml 变更重建。
  • uv python install 走 uv 自己的 Python 发行源(python-build-standalone),和 PyPI 镜像不是一回事;uv 配置弹窗里配「下载镜像」统一给 uv 本体与解释器用,解释器还可以用 UV_PYTHON_INSTALL_MIRROR 单独覆盖。
  • 删除托管环境是直接删除目录,不可恢复。
  • 自定义 uv 若版本过旧,uv python list/envs 等子命令可能与平台预期的参数不一致。