Windows 下为 Codex 构建跨盘、跨会话的独立 Python 工具环境
Windows 下为 Codex 构建跨盘、跨会话的独立 Python 工具环境
一次真实的环境治理记录:将 Python 虚拟环境、桌面自动化工具和 Playwright 浏览器放到非系统盘,同时为 Codex 提供固定、可发现、可回退的入口。
摘要
在 Windows 上使用 Codex 执行 Photoshop 自动化、浏览器验证、PDF 处理等任务时,一个常见问题是:工具包散落在 Conda、全局 Python 和不同项目的 .venv 中。当前会话可能能够运行,重启 Codex 或换一个终端后却找不到解释器;Playwright 还会默认把数百 MB 的浏览器文件下载到 C 盘。

本文记录一套经过真实验证的解决方案:
- 在非系统盘创建独立的 Python 3.11 虚拟环境;
- 使用绝对路径调用,不依赖 Conda 或终端激活状态;
- 将 Playwright 浏览器缓存迁移到非系统盘;
- 使用 Windows Directory Junction 提供稳定入口;
- 分别验证 Python、依赖、Playwright Chromium 与 Photoshop Flue 桥接;
- 保持工具环境与项目环境隔离。
最终结构如下:
C:\Users\<User>\.codex\runtimes\python311
└── Junction → F:\Codex\.venv
F:\Codex\
├── .venv\
└── playwright-browsers\
这不是把项目虚拟环境搬走,而是建立一个专门供 Codex 调用的“工具运行时”。
一、为什么不直接使用/共用现有的项目 .venv
项目环境和工具环境承担的职责不同:
| 环境 | 主要职责 | 典型依赖 |
|---|---|---|
现有项目 .venv |
运行、测试和发布具体项目 | Web 框架、数据库驱动、项目 SDK |
| Codex 工具环境 | 操作桌面软件、解析文档、浏览器验证 | Flue、Playwright、Pillow、PDF 工具 |
| EPGF 基础环境 | 提供 Python 版本与通用管理能力 | Conda 自身及公共基础包 |
如果把 Flue、Playwright、PDF 渲染库和图像工具全部装入现有项目 .venv,会带来几个问题:
- 项目锁文件被无关依赖污染;
- 升级桌面自动化工具可能破坏项目依赖;
- 不同项目重复安装体积较大的工具;
- Codex 离开该项目目录后难以发现工具;
- 删除或重建项目环境时,自动化能力一并消失。
因此,独立工具环境是更清晰的边界。
二、为什么选择 Python 3.11 与传统 venv
本次基础 Python 管理由 Conda/EPGF 提供,但工具环境使用标准库 venv 创建:
F:
cd \Codex
conda activate py311
python -m venv --copies .venv
随后激活并退出 Conda:
.venv\Scripts\activate.bat
conda deactivate
where python
预期输出首项应是:
F:\Codex\.venv\Scripts\python.exe
Python 官方 venv 文档列出了 --copies 与 --symlinks 两种创建策略。这里显式使用 --copies,目的是让虚拟环境的启动文件不依赖源环境中的符号链接行为。Python venv 官方文档
选择 Python 3.11 的主要理由不是“版本越旧越好”,而是桌面自动化、pywin32、文档处理和浏览器工具在这一版本上具有成熟的 Windows wheel 生态。实际项目仍可使用其他 Python 版本。

三、不要依赖“激活”,而要依赖绝对路径
激活虚拟环境本质上主要是修改当前终端的 PATH。换一个 CMD、PowerShell、Codex 会话或后台进程后,激活状态不会自动继承。
因此,自动化命令统一使用绝对路径:
F:\Codex\.venv\Scripts\python.exe -V
F:\Codex\.venv\Scripts\python.exe -m pip --version
这种写法虽然略长,却能消除三类歧义:
- 当前是否激活了 Conda;
- 当前 PATH 中哪个
python.exe排在最前; - CMD 与 PowerShell 是否加载了相同的启动脚本。
四、安装基础工具包
先升级 pip,再安装桌面自动化基础能力:
F:\Codex\.venv\Scripts\python.exe -m pip install --upgrade pip
F:\Codex\.venv\Scripts\python.exe -m pip install flue pillow requests psutil rich
本次实测基线:
Python 3.11.13
pip 26.1.2
flue 1.0.31
pywin32 312
根据任务按需安装,而不是复制全局环境中的全部包:
REM PDF
F:\Codex\.venv\Scripts\python.exe -m pip install pypdf pdfplumber reportlab
REM Word 与 Excel
F:\Codex\.venv\Scripts\python.exe -m pip install python-docx openpyxl
REM HTML、XML、SVG 与字体
F:\Codex\.venv\Scripts\python.exe -m pip install lxml fonttools beautifulsoup4
REM 浏览器自动化
F:\Codex\.venv\Scripts\python.exe -m pip install playwright
REM 开发验证
F:\Codex\.venv\Scripts\python.exe -m pip install pytest ruff
安装完成后检查依赖一致性:
F:\Codex\.venv\Scripts\python.exe -m pip check
本次真实输出:
No broken requirements found.

五、处理 pip 多索引与 SSL 重试
安装过程中曾出现以下信息:
Could not fetch URL https://pypi.ngc.nvidia.com/...
SSLError: NOT_ENOUGH_DATA
但随后主索引下载成功:
Successfully installed ...
这说明失败的是附加索引,而不是整个安装。pip 官方文档说明:--index-url 指定基础索引,--extra-index-url 会增加额外索引;环境变量 PIP_INDEX_URL 和 PIP_EXTRA_INDEX_URL 也可能影响行为。pip install 官方文档
先检查配置来源:
F:\Codex\.venv\Scripts\python.exe -m pip config debug
如果只想让该虚拟环境使用指定镜像,可以使用 site 级配置,而不要修改整台机器:
F:\Codex\.venv\Scripts\python.exe -m pip config --site set global.index-url https://mirrors.aliyun.com/pypi/simple/
pip 官方的 pip config 文档区分了 --global、--user 和 --site;其中 --site 对应当前虚拟环境。pip config 官方文档
不建议用关闭 TLS 校验的方式“解决”证书问题。
六、把 Playwright 浏览器移出 C 盘
Playwright Python 包本身安装在 F 盘虚拟环境中,并不意味着浏览器也在 F 盘。Windows 默认缓存目录是:
%USERPROFILE%\AppData\Local\ms-playwright
Playwright 官方说明,可以使用 PLAYWRIGHT_BROWSERS_PATH 改变浏览器安装和查找位置。Playwright 浏览器管理文档
在当前 CMD 中设置路径并安装 Chromium:
set PLAYWRIGHT_BROWSERS_PATH=F:\Codex\playwright-browsers
F:\Codex\.venv\Scripts\python.exe -m playwright install chromium
真实安装输出节选:
Chrome for Testing 149.0.7827.55 downloaded to
F:\Codex\playwright-browsers\chromium-1228
FFmpeg downloaded to
F:\Codex\playwright-browsers\ffmpeg-1011
Chrome Headless Shell downloaded to
F:\Codex\playwright-browsers\chromium_headless_shell-1228
注意,下面的命令是错误的:
python -m playwright install chromium -i https://mirrors.example/simple/
错误输出:
error: unknown option '-i'
原因是 -i 属于 pip,不属于 Playwright CLI。Python 包索引和浏览器二进制下载是两套机制;Playwright 浏览器默认从其 CDN 下载,代理或自定义下载主机应按官方文档使用 HTTPS_PROXY 或 PLAYWRIGHT_DOWNLOAD_HOST。
为了让新终端和重启后的 Codex 自动继承路径,写入 Windows 用户环境变量:
setx PLAYWRIGHT_BROWSERS_PATH "F:\Codex\playwright-browsers"
setx 只影响之后新启动的进程;当前 CMD 仍需保留前面的 set,或重新打开终端。

七、实际启动 Chromium,而不是只看安装日志
“安装命令没有报错”不等于浏览器一定可以启动。使用以下脚本做端到端验证:
F:\Codex\.venv\Scripts\python.exe -c "from playwright.sync_api import sync_playwright; p=sync_playwright().start(); b=p.chromium.launch(headless=True); print('version='+b.version); print('executable='+p.chromium.executable_path); b.close(); p.stop()"
重启 Codex 后的真实输出:
version=149.0.7827.55
executable=F:\Codex\playwright-browsers\chromium-1228\chrome-win64\chrome.exe
这同时证明:
- 用户环境变量已被新进程继承;
- Playwright 找到了指定版本;
- Chromium 能够实际启动;
- 浏览器确实从 F 盘运行。
八、使用 Junction 创建跨会话稳定入口
仅记录 F:\Codex\.venv 已经可以工作,但对任意 Codex 会话而言,一个位于固定用户配置目录中的入口更容易发现。最终增加如下 Directory Junction:
C:\Users\<User>\.codex\runtimes\python311
→ F:\Codex\.venv
CMD 创建命令:
mkdir C:\Users\<User>\.codex\runtimes
mklink /J C:\Users\<User>\.codex\runtimes\python311 F:\Codex\.venv
Microsoft 官方文档说明,mklink /J <link> <target> 用于创建 Directory Junction。Microsoft mklink 文档
之后统一使用稳定入口:
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -V
真实验证输出:
Python 3.11.13
Junction 与普通快捷方式不同,文件系统 API 会把它当作目录解析;Python、pip 和 Flue 无需知道目标位于另一个盘符。
为什么入口仍在 C 盘
C 盘只保存一个很小的联接点,不保存 Python 包和浏览器数据。这样既保留了 Codex 用户目录中的固定发现位置,又把实际存储放在 F 盘。
为什么不把入口命名为 .venv
推荐使用:
.codex\runtimes\python311
而不是:
.codex\.venv
后者容易被误解为 Codex 客户端自身的内部环境;runtimes\python311 能表达版本与用途。
九、验证 Flue 与 Photoshop 桥接
Flue 是一个通过本地脚本桥接专业桌面软件的开源工具。本次安装版本为 1.0.31,可从其项目资料了解适配器设计与支持范围:Flue GitHub、Flue PyPI。
先验证版本与安装位置:
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m flue.cli version
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m flue.cli where
输出示例:
1.0.31
C:\Users\<User>\.codex\runtimes\python311\Lib\site-packages
Flue 1.0.31 的 CLI 没有 context 子命令,因此按安装包自带适配器直接运行 Photoshop 只读上下文脚本:
type C:\Users\<User>\.codex\runtimes\python311\Lib\site-packages\adapters\photoshop_adapter\examples\context.jsx | C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe C:\Users\<User>\.codex\runtimes\python311\Lib\site-packages\adapters\photoshop_adapter\photoshop_bridge.py --stdin
真实返回:
{
"ok": true,
"result": {
"app": "Adobe Photoshop",
"version": "26.6.0",
"documents": 0,
"doc": null,
"activeLayer": null,
"hasSelection": false
}
}
这证明跨盘 Junction 不仅能运行 Python,也能加载 site-packages 中的桥接脚本、调用 pywin32,并连接正在运行的 Photoshop。
十、最终验收清单
可以使用以下清单复核环境:
REM 1. 联接入口
dir C:\Users\<User>\.codex\runtimes
REM 2. Python
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -V
REM 3. 依赖一致性
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m pip check
REM 4. Flue
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m flue.cli version
REM 5. Playwright 路径
echo %PLAYWRIGHT_BROWSERS_PATH%
REM 6. 已安装浏览器
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m playwright install --list
预期关键结果:
Python 3.11.x
No broken requirements found.
Flue 1.0.x
PLAYWRIGHT_BROWSERS_PATH=F:\Codex\playwright-browsers

十一、环境复现与升级策略
环境稳定后生成锁定清单:
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m pip freeze > F:\Codex\requirements-lock.txt
重建时:
D:\Path\To\Python311\python.exe -m venv --copies F:\Codex\.venv
F:\Codex\.venv\Scripts\python.exe -m pip install -r F:\Codex\requirements-lock.txt
set PLAYWRIGHT_BROWSERS_PATH=F:\Codex\playwright-browsers
F:\Codex\.venv\Scripts\python.exe -m playwright install chromium
建议将包分成三类:
- 基础包:Flue、pywin32、Pillow、requests、psutil、rich;
- 能力包:Playwright、PDF、Office、SVG/字体处理;
- 重型包:NumPy、OpenCV、AI/CUDA 框架,仅按任务安装。
不要直接把 Conda 全局环境的 pip freeze 原样灌入工具环境。那会把平台相关、项目相关和历史遗留依赖全部带进来,失去隔离意义。
升级 Playwright 后应重新执行:
C:\Users\<User>\.codex\runtimes\python311\Scripts\python.exe -m playwright install chromium
Playwright 官方说明,不同 Playwright 版本依赖特定浏览器版本,升级后可能需要重新安装浏览器。Playwright 浏览器安装说明
十二、常见问题
1. 为什么不直接把 F 盘 Python 加到系统 PATH?
PATH 会影响所有终端和程序,并可能改变已有项目的解释器解析顺序。固定绝对入口更可控。
2. CMD 和 PowerShell 哪个更适合?
二者都可以。本文优先给出 CMD 命令,因为 set、setx 和 mklink 的表达直接;复杂对象查询和批量检查时,PowerShell 更方便。真正决定稳定性的不是 Shell,而是固定解释器路径。
3. Junction 删除后会删除 F 盘环境吗?
正常删除联接本身不会删除目标目录,但操作前必须确认删除对象确实是 Junction。不要对不确定的路径执行递归删除。
4. 环境变量已经设置,为什么旧终端看不到?
setx 写入后只对新进程生效。关闭并重新打开 CMD、PowerShell 或 Codex。
5. 为什么 Chromium 以前仍安装到 C 盘?
因为安装浏览器时没有设置 PLAYWRIGHT_BROWSERS_PATH,或运行脚本的进程没有继承该变量。安装阶段和运行阶段必须使用相同路径。
6. 是否还需要在 Codex 项目配置中重复设置?
通常不需要。Windows 用户环境变量适用于所有新会话;Junction 提供固定 Python 入口。项目配置更适合保存项目级行为,而不是复制操作系统级运行时路径。
结语
这套配置的关键不在于“把所有东西都搬到非 C 盘”,而在于同时解决四个问题:
- 隔离:工具依赖不污染项目;
- 发现:Codex 有固定的入口;
- 持久:重启终端和 Codex 后仍能复现;
- 验证:不以安装日志代替真实运行结果。
最终,Python 包、Playwright 浏览器和缓存主要存放在 F 盘;Codex 用户目录仅保留轻量 Junction。即使未来迁移真实环境,也只需重新指向 Junction,而不必修改每一篇脚本、文档或会话约定。
参考资料
更多推荐




所有评论(0)