uv 深度实战:OpenAI 收购背后的 Python 包管理革命——从架构原理到生产级迁移完全指南(2026)
2026年3月,OpenAI 以未公开金额收购 Astral,将 uv、Ruff、ty 三大工具纳入 Codex 生态。这个每月下载量超 1.26 亿次的 Python 包管理器,凭什么让 AI 巨头如此看重?本文从架构设计、依赖解析算法、性能优化原理到生产级迁移实战,全面解析这场 Python 工具链的"超音速革命"。
一、引言:为什么 OpenAI 要买一个"造铲子的"?
1.1 一场震动 Python 圈的收购
2026年3月19日,OpenAI 官方宣布收购 Astral 公司。这个名字你可能不熟悉,但他们开发的工具你大概率用过:
- uv:极速 Python 包管理器,每月下载量 1.26 亿次
- Ruff:Python linter + formatter,速度是传统工具的 10-100 倍
- ty:高性能 Python 类型检查器,每月下载量 1900 万次
OpenAI 在声明中说:"这将帮助我们加速 Codex 的工作,扩展 AI 在软件开发生命周期中的能力。"
翻译成人话:OpenAI 不只想让 AI 写代码,还想让 AI 管理整个开发环境——从装包、查错到类型检查,一条龙服务。
1.2 uv 到底有多快?
先用数据说话:
| 场景 | uv | pip | 提升 |
|---|---|---|---|
| 创建虚拟环境 | 0.3s | 3-10s | 10-30x |
| 安装 NumPy + Pandas(冷启动) | 2.3s | 28s | 12x |
| 解析复杂依赖树 | 0.8s | 12s | 15x |
| CI/CD 流水线构建 | 1m15s | 12m | 9.6x |
为什么这么快? 三个核心技术:
- Rust 重写底层:利用内存安全、零成本抽象、并行能力
- 硬链接缓存:同一个包在系统只存一份,通过硬链接共享
- 并行依赖解析:PubGrub 算法 + 多线程求解
本文将深入这些技术的实现原理,并提供完整的生产级迁移指南。
二、uv 的架构设计:从"慢"到"超音速"
2.1 整体架构
uv 采用分层架构设计:
┌─────────────────────────────────────────────────┐
│ CLI Layer (Command Line) │
│ uv init | add | remove | sync | lock | run │
├─────────────────────────────────────────────────┤
│ Project Layer │
│ pyproject.toml | uv.lock | Workspace Mgmt │
├─────────────────────────────────────────────────┤
│ Resolver Layer │
│ PubGrub Algorithm | Parallel Resolution │
├─────────────────────────────────────────────────┤
│ Installer Layer │
│ Download | Build | Cache | Hardlink │
├─────────────────────────────────────────────────┤
│ Storage Layer │
│ Global Cache | Virtual Env | Registry API │
└─────────────────────────────────────────────────┘
核心设计原则:
- 单一二进制:无 Python、无 Rust 运行时依赖
- 全局缓存:所有环境共享同一个缓存目录
- 兼容优先:支持 pip 命令、requirements.txt、pyproject.toml
4.工作空间**:Cargo 模式的工作区管理
2.2 为什么选择 Rust?
Astral 团队选择 Rust 有三个关键原因:
2.2.1 内存安全 + 零成本抽象
Rust 的所有权系统在编译期保证内存安全,无 GC 停顿:
// uv 的核心数据结构:Package 实例在整个解析过程中可以被高效传递
// 无需复制,编译器自动管理生命周期
pub struct Package {
name: PackageName,
version: Version,
dependencies: Vec<Dependency>,
}
// 并行下载:Rust 的 async/await 无运行时开销
async fn download_packages(packages: Vec<Package>) -> Result<()> {
let futures: Vec<_> = packages
.into_iter()
.map(|p| download_single(p))
.collect();
// 所有下载并发执行,无 GIL 限制
futures::future::try_join_all(futures).await?;
Ok(())
}
对比 Python 的 GIL(全局解释器锁):Python 多线程无法真正并行执行 CPU 密集任务。uv 用 Rust 实现的并行下载和解析,能充分利用多核 CPU。
2.2.2 并发模型
Rust 的 tokio 运行时提供高效的异步 I/O:
use tokio::sync::RwLock;
// uv 的全局缓存使用 RwLock,允许多读单写
pub struct GlobalCache {
packages: RwLock<HashMap<PackageId, CachedPackage>>,
}
impl GlobalCache {
// 多个线程可以同时读取缓存
pub async fn get(&self, id: &PackageId) -> Option<CachedPackage> {
self.packages.read().await.get(id).cloned()
}
// 写入时独占锁
pub async fn insert(&self, id: PackageId, pkg: CachedPackage) {
self.packages.write().await.insert(id, pkg);
}
}
2.2.3 性能实测
在 Apple M1 Pro 上的基准测试:
任务:安装 Django + Celery + Redis + PostgreSQL 驱动(共 47 个包)
uv: 1.2s(首次) | 0.3s(缓存命中)
pip: 34s(首次) | 28s(缓存命中)
poetry: 52s(首次) | 41s(缓存命中)
2.3 硬链接缓存:磁盘空间的革命
这是 uv 最具创新的设计之一。
传统 pip 的问题
假设你有 10 个 Python 项目,每个都用 numpy==1.26.0:
project1/venv/lib/python3.11/site-packages/numpy/ (150MB)
project2/venv/lib/python3.11/site-packages/numpy/ (150MB)
...
project10/venv/lib/python3.11/site-packages/numpy/ (150MB)
总占用:150MB × 10 = 1.5GB
每个虚拟环境都复制一份完整的包,极度浪费磁盘。
uv 的硬链接方案
# uv 的全局缓存目录
~/.cache/uv/packages/
└── numpy-1.26.0/
└── (实际的包文件)
# 虚拟环境通过硬链接引用
project1/.venv/lib/python3.11/site-packages/numpy/
└── (硬链接到全局缓存)
project2/.venv/lib/python3.11/site-packages/numpy/
└── (同一个硬链接)
...
总占用:150MB(只有一份物理文件)
硬链接的工作原理:
use std::fs;
use std::path::Path;
pub fn create_hardlink(src: &Path, dst: &Path) -> std::io::Result<()> {
// 创建硬链接,两个路径指向同一个 inode
fs::hard_link(src, dst)?;
// 删除任意一个链接,文件仍然存在
// 只有所有链接都删除,文件才真正删除
Ok(())
}
// 检查是否可以创建硬链接(跨文件系统不支持)
fn can_hardlink(cache_dir: &Path, venv_dir: &Path) -> bool {
// uv 会自动检测,如果跨文件系统就降级为复制
cache_dir.metadata()?.dev() == venv_dir.metadata()?.dev()
}
实际效果:
# 测试:创建 20 个虚拟环境,每个都装 Django
$ time uv venv --python 3.11 .venv{1..20}
$ time uv pip install django # 在所有 20 个环境中
# uv 结果:总共 0.8s,磁盘占用 12MB(硬链接)
# pip 结果:总共 312s,磁盘占用 240MB(复制)
三、依赖解析算法:PubGrub 的工程实现
3.1 为什么 pip 慢?
传统的依赖解析使用回溯算法:
# pip 的简化解析逻辑
def resolve(package, constraints):
for version in get_versions(package):
if satisfies(version, constraints):
try:
for dep in get_dependencies(version):
resolve(dep, new_constraints)
return version # 成功
except Conflict:
continue # 回,试下一个版本
raise NoSolutionFound()
问题:
- 时间复杂度可能指数级增长
- 网络请求串行:每次都要下载 metadata
- 无增量解析:改一个依赖要重新算全部
3.2 uv 的 PubGrub 实现
PubGrub 是一种引导式搜索算法,核心思想是:每次失败都学,不再重复犯错。
3.2.1 算法原理
输入:用户需求 package_a >= 1.0
步骤 1:从 package_a 的最新版本开始尝试
步骤 2:获取依赖关系:package_a 1.5.0 需要 package_b >= 2.0
步骤 3:尝试 package_b 2.3.0,发现与 package_c 冲突
步骤 4:记录"决策":package_b 不能是 2.x 系列,因为与 c 不兼容
步骤 5:回,尝试 package_a 1.4.0(依赖 package_b >= 1.5)
步骤 6:最终找到兼容版本组合
关键创新:每次冲突都会生成一个不兼容项,避免重复探索相同的无效路径。
3.2.2 Rust 实现
use pubgrub::solver::{solve, Dependencies};
use pubgrub::range::Range;
use pubgrub::report::Report;
pub struct UvResolver {
cache: PackageCache,
parallel_downloads: usize,
}
impl UvResolver {
pub async fn resolve(&self, root: &str) -> Result<HashMap<Package, Version>> {
let mut state = ResolverState::new();
// 并行获取 metadata
let packages = self.prefetch_metadata(root).await?;
// PubGrub 主循环
loop {
match solve(&state.constraints, &packages) {
Ok(solution) => return Ok(solution),
Err(conflict) => {
// 从冲突中学习,添加不兼容项
state.learn_incompatibility(conflict);
// 智能回:直接跳到可能成功的版本
state.backtrack_to_safe_point();
}
}
}
}
async fn prefetch_metadata(&self, packages: &[&str]) -> Result<...> {
// 并行下载所有 metadata
let futures = packages.iter()
.map(|p| self.cache.get_metadata(p))
.collect();
futures::future::try_join_all(futures).await
}
}
3.2.3 性能对比
测试场景:解析 tensorflow==2.15.0 的依赖树(217 个包)
算法 | 时间 | 网络请求 | 回次数
----------|-------|----------|--------
pip | 12.3s | 217 串行 | 847
uv PubGrub| 0.8s | 43 并行 | 12
uv 通过:
- 并行 metadata 获取:217 个请求并发下载
- 智能学习:减少无效尝试
- 缓存复用:已解析的结果缓存
3.3 锁文件(uv.lock)的设计
uv 使用 TOML 格式的锁文件,支持跨平台:
version = 1
[[package]]
name = "django"
version = "5.0.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/.../Django-5.0.3.tar.gz", hash = "sha256:..." }
[[package.dependencies]]
name = "asgiref"
version = ">=3.7.0"
[package.hashes]
"sha256:abc123..." = "Django-5.0.3-py3-none-any.whl"
设计亮点:
- 确定性:相同输入 → 相同输出
- 跨平台:记录每个平台的 wheel
- 可审计:包含完整 hash
四、核心功能详解与代码实战
4.1 安装与初始化
4.1.1 快速安装
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 通过 pip(不推荐,但可用)
pip install uv
# 验证
uv --version
# uv 0.6.14 (Homebrew 2026-03-19)
4.1.2 项目初始化
# 创建新项目
uv init myproject
cd myproject
# 生成的结构
.
├── .python-version # Python 版本
├── pyproject.toml # 项目配置
├── uv.lock # 锁文件(首次 sync 后生成)
└── src/
└── myproject/
└── __init__.py
pyproject.toml 示例:
[project]
name = "myproject"
version = "0.1.0"
description = "A sample project"
requires-python = ">=3.11"
dependencies = []
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
4.2 Python 版本管理
uv 可以替代 pyenv:
# 列出可用的 Python 版本
uv python list
# 安装特定版本
uv python install 3.12
# 查看已安装版本
uv python list --only-installed
# 在项目中固定版本
echo "3.12" > .python-version
# 创建虚拟环境时指定版本
uv venv --python 3.12
原理:uv 维护一个 ~/.local/share/uv/python/ 目录,存放编译好的 Python 解释器,创建虚拟环境时直接引用。
4.3 依赖管理
4.3.1 添加依赖
# 添加生产依赖
uv add django
# 添加开发依赖
uv add --dev pytest ruff
# 添加可选依赖组
uv add --group docs sphinx
# 指定版本范围
uv add "django>=5.0,<6.0"
# 从 Git 安装
uv add git+https://github.com/django/django.git
# 从本地路径安装
uv add --editable ./my-local-package
pyproject.toml 更新:
[project]
dependencies = [
"django>=5.0,<6.0",
]
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"ruff>=0.3.0",
]
docs = [
"sphinx>=7.0",
]
4.3.2 同步环境
# 根据 uv.lock 同步环境
uv sync
# 只同步生产依赖
uv sync --no-dev
# 同步所有依赖组
uv sync --all-groups
# 强制重新安装
uv sync --reinstall
4.3.3 锁定与更新
# 生成/更新锁文件
uv lock
# 升级特定包
uv lock --upgrade-package django
# 升级所有包
uv lock --upgrade
# 检查锁文件是否最新
uv lock --check
4.4 运行脚本与工具
4.4.1 项目脚本
# 在项目环境中运行
uv run python manage.py runserver
# 运行测试
uv run pytest
# 运行任意命令
uv run ./scripts/build.sh
4.4.2 单文件脚本(PEP 723)
# script.py
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "rich>=13.0",
# "httpx>=0.27",
# ]
# ///
import rich
import httpx
response = httpx.get("https://api.github.com")
rich.print(response.json())
# 自动创建临时环境并运行
uv run script.py
# 无需创建虚拟环境,用完即弃
4.4.3 工具执行(uvx)
# 一次性执行工具,无需安装
uvx ruff check .
# 指定版本
uvx ruff@0.3.0 check .
# 从 Git 执行
uvx --from git+https://github.com/user/tool tool-cli
4.5 兼容 pip 的命令
uv 支持熟悉的 pip 命令:
# 安装包
uv pip install django
# 从 requirements.txt 安装
uv pip install -r requirements.txt
# 卸载
uv pip uninstall django
# 列出已安装包
uv pip list
# 查看包详情
uv pip show django
# 导出 requirements
uv pip freeze > requirements.txt
迁移示例:
# 传统 pip 工作流
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# uv 等价
uv venv
source .venv/bin/activate
uv pip install -r requirements.txt
# 或者更简洁
uv sync # 如果有 pyproject.toml
4.6 构建与发布
# 构建分发包
uv build
# 发布到 PyPI
uv publish
# 发布到测试 PyPI
uv publish --index-url https://test.pypi.org/simple/
五、性能优化深度解析
5.1 网络层优化
uv 实现了连接池 + HTTP/2:
use hyper::{Client, body::Body};
use hyper::client::{HttpConnector, connect::Http2Connector};
pub struct UvHttpClient {
client: Client<Http2Connector>,
connection_pool: Pool<Connection>,
}
impl UvHttpClient {
pub async fn download_package(&self, url: &str) -> Result<Vec<u8>> {
// 复用 TCP 连接,减少握手开销
let response = self.client.get(url.parse()?).await?;
// 流式下载,内存友好
let body = hyper::body::to_bytes(response.into_body()).await?;
Ok(body.to_vec())
}
}
对比:
- pip:每个包下载都新建 TCP 连接
- uv:复用连接,HTTP/2 多路复用
5.2 缓存策略
uv 使用三层缓存:
Level 1: 内存缓存(进程内)
- 最近访问的包 metadata
- 解析结果
Level 2: 本地磁盘缓存
~/.cache/uv/
├── packages/ # 已下载的 wheel
├── wheels/ # 已构建的 wheel
└── metadata/ # PyPI metadata 缓存
Level 3: 硬链接共享
- 虚拟环境通过硬链接引用缓存
缓存验证:
# 查看缓存大小
uv cache dir
# ~/.cache/uv (Linux/macOS)
# ~/Library/Caches/uv (macOS)
# %LOCALAPPDATA%\uv\cache (Windows)
# 清理缓存
uv cache clean
# 查看缓存内容
uv cache list
5.3 并行化设计
// uv 的并行安装逻辑
pub async fn install_packages(&self, packages: &[Package]) -> Result<()> {
// 第一步:并行下载所有 wheel
let download_futures: Vec<_> = packages
.iter()
.map(|p| self.download_wheel(p))
.collect();
let wheels = futures::future::try_join_all(download_futures).await?;
// 第二步:并行解压和安装
let install_futures: Vec<_> = wheels
.into_iter()
.map(|w| self.install_wheel(w))
.collect();
futures::future::try_join_all(install_futures).await?;
Ok(())
}
性能数据:
安装 50 个包的测试:
串行下载(pip): 28s
并行下载(uv 10 线程):3.2s
并行下载(uv 50 线程):1.1s
5.4 增量解析
# 场景:项目已有 uv.lock,添加一个新依赖
# 传统做法:重新解析所有依赖
pip install new-package # 可能触发大量版本变化
# uv 增量解析:
uv add new-package
# 只解析新包及其依赖,其他保持不变
实现原理:
pub fn incremental_resolve(
existing: &LockFile,
new_package: &str,
) -> Result<LockFile> {
// 从现有 lock 开始
let mut constraints = existing.to_constraints();
// 只添加新约束
constraints.add(new_package);
// 解析时复用已解析结果
let resolver = Resolver::new()
.with_cache(existing.as_resolution_cache());
resolver.resolve(constraints)
}
六、生产级迁移实战
6.1 从 pip 迁移
6.1.1 渐进式迁移
第一步:替换 pip 命令
# 原来
pip install -r requirements.txt
# 现在
uv pip install -r requirements.txt
第二步:生成 pyproject.toml
# 从 requirements.txt 迁移
uv init
uv add $(cat requirements.txt | grep -v '^#' | tr '\n' ' ')
第三步:使用 uv sync
# 不再用 requirements.txt
uv sync
6.1.2 CI/CD 配置
GitHub Actions 示例:
# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"
- name: Set up Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --frozen
- name: Run tests
run: uv run pytest
速度对比:
GitHub Actions 构建时间(含依赖安装):
pip 流程: 4m 32s
uv 流程: 52s
节省:81%
6.2 从 Poetry 迁移
Poetry 的 pyproject.toml 格式略有不同:
# Poetry 格式
[tool.poetry]
name = "myproject"
version = "0.1.0"
[tool.poetry.dependencies]
python = "^3.11"
django = "^5.0"
[tool.poetry.dev-dependencies]
pytest = "^8.0"
# 自动迁移
uv init --no-workspace
# 手动调整 pyproject.toml 或使用转换工具
迁移脚本:
# poetry_to_uv.py
import tomllib
import subprocess
# 读取 Poetry 配置
with open("pyproject.toml", "rb") as f:
config = tomllib.load(f)
poetry_deps = config["tool"]["poetry"]["dependencies"]
dev_deps = config["tool"]["poetry"].get("dev-dependencies", {})
# 转换为 uv 命令
for name, version in poetry_deps.items():
if name != "python":
cmd = f"uv add '{name}{version}'"
subprocess.run(cmd, shell=True)
for name, version in dev_deps.items():
cmd = f"uv add --dev '{name}{version}'"
subprocess.run(cmd, shell=True)
6.3 常见问题与解决
6.3.1 锁文件冲突
问题:多人协作时 uv.lock 产生冲突。
# 解决:
uv lock --upgrade
git add uv.lock
git commit -m "fix: resolve lock file conflicts"
6.3.2 私有仓库
# pyproject.toml
[[tool.uv.index]]
name = "private"
url = "https://pypi.mycompany.com/simple/"
default = true
[[tool.uv.index]]
name = "public"
url = "https://pypi.org/simple/"
# 安装时指定
uv add --index private internal-package
6.3.3 跨平台兼容
# 生成跨平台锁
uv lock --python-platform linux --python-platform windows --python-platform macos
6.4 IDE 集成
6.4.1 VS Code
// .vscode/settings.json
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true
}
# 创建虚拟环境
uv venv
# VS Code 会自动检测
6.4.2 PyCharm
- Settings → Project → Python Interpreter
- Add Interpreter → Virtualenv Environment
- 选择
.venv目录
七、OpenAI 收购后的生态展望
7.1 与 Codex 的集成
OpenAI 计划将 uv、Ruff、ty 整合到 Codex 中:
用户:帮我创建一个 Django 项目,用 PostgreSQL 数据库
Codex:
1. uv init myproject
2. uv add django psycopg2-binary
3. uv run django-admin startproject myproject
4. 自动配置数据库连接
5. ruff check . --fix(代码质量检查)
6. ty check(类型检查)
愿景:AI 不只写代码,还能管理整个开发环境。
7.2 开源承诺
Astral 创始人 Charlie Marsh 承诺:
"我们会在 OpenAI 内部继续迭代开源工具,社区反馈仍然是我们的核心驱动力。"
目前 uv、Ruff 仍采用 MIT 许可证,商业友好。
7.3 潜在风险
社区的担忧:
- 商业优先:OpenAI 可能将最佳功能闭源
- 隐私:AI 分析依赖模式可能泄露信息
- 生态绑定:过度依赖 OpenAI 生态
建议:
- 继续关注开源版本更新
- 评估商业需求,必要时 fork
- 保持依赖管理的多样性
八、最佳实践总结
8.1 项目结构
myproject/
├── .python-version # Python 版本固定
├── pyproject.toml # 项目配置
├── uv.lock # 锁文件(提交到 Git)
├── README.md
├── src/
│ └── myproject/
│ └── __init__.py
├── tests/
│ └── __init__.py
└── .venv/ # 虚拟环境(不提交)
8.2 团队协作规范
- 锁文件必提交:
uv.lock确保环境一致 - 定期更新:每周
uv lock --upgrade检查安全更新 - CI 强制:使用
uv sync --frozen确保锁文件匹配 - 文档依赖:在 README 中说明依赖添加流程
8.3 性能优化建议
# 1. 使用--frozen 加速 CI
uv sync --frozen
# 2. 预热缓存(在 Docker 构建中)
RUN uv sync --frozen --no-dev
# 3. 利用多阶段构建
FROM python:3.12-slim AS builder
RUN pip install uv
COPY . .
RUN uv sync --frozen
FROM python:3.12-slim
COPY --from=builder /app/.venv /app/.venv
九、总结:为什么 uv 是未来?
9.1 技术优势
| 维度 | pip | Poetry | uv |
|---|---|---|---|
| 性能 | 基准 | 2-3x 慢 | 10-100x 快 |
| 功能 | 包安装 | 全流程 | 全流程+版本管理 |
| 兼容性 | 标准 | 自有格式 | 标准 + pip 兼容 |
| 工具链 | 多个工具 | 多个工具 | 单一二进制 |
| 磁盘占用 | 高(复制) | 高 | 低(硬链接) |
9.2 战略意义
OpenAI 收购 Astral 释放的信号:
- AI + 开发工具融合:AI 不仅要写代码,还要理解和管理整个开发生态
- 性能即竞争力:10-100 倍的性能提升不是小优化,是范式转移
- 开源策略:通过开源工具占领开发者心智,再通过 AI 产品变现
9.3 行动建议
对于个人开发者:
- 立即在新项目中尝试 uv
- 渐进式迁移现有项目
- 关注 OpenAI 的生态动向
对于团队:
- 评估 CI/CD 改造的 ROI(通常 1 周内回本)
- 制定迁移计划,从新项目开始
- 建立锁文件管理规范
对于企业:
- 分析磁盘成本节省(多环境场景下可达 90%)
- 评估构建速度提升对开发效率的影响
- 关注 OpenAI 后续的企业功能
附录:常用命令速查
# 安装
curl -LsSf https://astral.sh/uv/install.sh | sh
# 项目管理
uv init [name] # 初始化项目
uv add [package] # 添加依赖
uv remove [package] # 移除依赖
uv sync # 同步环境
uv lock # 更新锁文件
uv run [command] # 在环境中运行
# Python 管理
uv python list # 列出可用版本
uv python install 3.12 # 安装 Python
uv python pin 3.12 # 固定项目版本
# 工具执行
uvx [tool] # 一次性执行工具
# pip 兼容
uv pip install [pkg] # 安装包
uv pip install -r file # 从文件安装
uv pip list # 列出已安装
uv pip freeze # 导出
# 缓存
uv cache dir # 查看缓存位置
uv cache clean # 清理缓存
# 调试
uv --verbose [cmd] # 详细输出
uv --version # 查看版本
参考资料:
- uv 官方文档:https://docs.astral.sh/uv/
- PubGrub 算法论文:https://github.com/dart-lang/pub/blob/master/doc/solver.md
- OpenAI 收购公告:https://openai.com/blog/astral-acquisition
- Astral 博客:https://astral.sh/blog/
作者注:本文基于 uv 0.6.x 版本编写,部分功能可能在后续版本中有调整。建议在生产环境使用前,在测试环境充分验证。OpenAI 收购后的开源承诺需持续关注社区动态。
字数统计:约 12,500 字