Windows 安装 Codex CLI 入门级教程

在 Windows 上用 Codex 写代码,安装软件只是开头。真正让新手困惑的,往往是接下来的几件事:命令在哪个窗口输入,Key 应该交给谁,配置文件放在哪里,以及为什么版本号已经出来了,发送任务还是报错。
这篇教程把安装和 API 接入连成一条完整路线,以 Crazyrouter 作为第三方服务的配置示例。从准备 PowerShell、安装 Node.js 开始,到填写 provider、确认模型和生成一个网页,每一步都说明操作位置、预期结果和失败后要检查的地方。
如果你想继续使用 Codex 的本地编程方式,同时把请求交给自己选定的 API 服务,重点就是把客户端和服务端之间的四项信息对齐:地址、模型、凭证、协议。本文围绕这四项展开,不要求你先学会复杂的项目部署。
采用的路线是 Windows 原生 PowerShell 加 npm。已经安装好的部分不必重复;已有项目也不要拿来当首次配置的试验场。先建一个空目录,完成小任务后再逐渐增加操作范围。
一、把工具和服务的职责分清楚
Codex CLI 是本地运行的命令行工具;Crazyrouter 是本例选用的第三方 API 服务。前者负责与你交互、读取项目和执行获准的操作,后者对应请求地址、可用模型以及服务商凭证。它们不是同一个账户体系。
| 名称 | 在这个流程中负责什么 | 需要准备什么 |
|---|---|---|
| PowerShell | 接收 Windows 命令 | 一个普通终端窗口 |
| Node.js | 提供 npm 安装路线所需环境 | Windows 对应的 LTS 安装包 |
| npm | 下载和管理 Codex 包 | 随 Node.js 安装并能正常调用 |
| Codex CLI | 根据任务处理本地项目 | 正确的工作目录与访问权限 |
| Crazyrouter | 本文示例中的 API 接入服务 | 自己账户的 Key、地址及模型信息 |
| config.toml | 告诉 Codex 使用哪个 provider | 用户级配置文件 |
| 环境变量 | 向程序提供本次进程需要的参数 | 名称与配置字段对应 |
CLI 的意思是命令行界面,因此没有桌面图标也正常。装好后从终端调用它,不是到网页上找一个"运行本地文件"的按钮。
账户也要对应起来。ChatGPT 订阅、OpenAI API 账户与 Crazyrouter 账户分别管理自己的权限或费用。不能因为浏览器已经登录了某个网站,就认为另一个 API 服务也获得了认证。
你不必一次记住全部概念。遇到问题时先问:现在是 Windows 找不到程序,还是 Codex 找不到凭证,又或者服务端拒绝了请求?这个判断比不断重装更有用。
二、先学会在 PowerShell 里执行命令
打开正确的窗口
在开始菜单输入 PowerShell,打开"Windows PowerShell";使用 Windows Terminal 的话,选择 PowerShell 标签页。先用普通用户窗口,等安装程序或沙箱明确提出需要时,再处理对应权限。
窗口里的提示符通常类似这样:
text
PS C:\Users\你的用户名>
它表示目前的目录与输入位置,不是你需要输入的命令。复制文章代码时只取代码框内容,不要把提示符、解释句子和上一条执行结果一起贴进去。
看一次结果,再执行下一条
先运行 node --version,收到结果后再执行 npm.cmd --version。两个命令分别检查 Node.js 和 npm,不要把它们粘成没有换行的一长串。
多数终端支持 Ctrl + V,也可以尝试右键或 Ctrl + Shift + V。当窗口重新显示 PS ...>,通常表示上一条命令已经结束。如果出现 >>,可能是引号或括号没有结束;按 Ctrl + C 取消,再重新输入完整命令。
本文后面也有包含多行的完整脚本块,例如备份配置。这类代码应保持换行和括号,可以整块粘贴;不能只复制 if 的第一行就把后面当成另一个独立命令。
为什么特意写 .cmd
PowerShell 可能找到同名的 .ps1 启动脚本,而执行策略又不允许它运行。本文指定 npm.cmd、codex.cmd,是直接调用 Windows 命令文件,减少这个常见岔路。
这不是让你关闭执行策略,也不是把所有权限问题都绕过去。公司设备若受管理,仍要遵守设备原有要求。我们只是让启动文件的选择更明确。
三、安装 Node.js,并检查终端是否更新
先确认是否已经有环境
powershell
node --version
npm.cmd --version
两条命令均能返回版本,就无需再下载一份。本文准备过程中看到的 Node.js v24.21.0、npm 11.19.0 仅是环境记录,不是要求每位读者锁定这些数字。
如果系统提示找不到 node,常见原因是尚未安装,或者终端仍继承安装前的 Path。这个阶段还没有访问 Crazyrouter,修改 API Key 和模型名不会解决本地程序缺失。

图 1:先把本地环境补齐,再继续配置远端服务。
下载 Windows 安装程序
前往 Node.js 官方下载页,选择 LTS、Windows,以及与你电脑匹配的 x64 或 ARM64 架构。Windows 设置中的"系统信息/关于"可以查看系统类型。
需要的是后缀 .msi 的安装包。页面如果同时出现 Docker 命令,那是另一种环境部署方式,不要一边装 Windows 程序一边复制容器里的命令。本教程不需要 Docker。
双击安装包,阅读向导,保留 npm 和添加到 PATH 的组件。默认安装位置通常够用;原生模块编译工具属于另外的开发需求,不是这篇入门教程必须额外安装的部分。
重开窗口,再验收
安装完成后关闭原来的 PowerShell。若使用 Windows Terminal,退出整个应用后重新打开;若在编辑器里执行,必要时重启编辑器,让新进程获得更新后的环境。
重新运行前面的两个版本命令。不要用旧窗口中仍然存在的错误判断刚才安装一定失败。

图 2:重点是命令能运行,数字不需要与图片相同。npm 仍需单独验证。
如果重启终端后依然识别不了,再检查安装目录与 Path。不要同时换下载源、改登录和重写配置,否则很难知道究竟是哪一步产生了影响。
四、安装 Codex CLI,确认入口与路径
执行安装与版本检查
powershell
npm.cmd install -g @openai/codex@latest
powershell
codex.cmd --version
codex.cmd --help
先等待安装结束,再运行版本和帮助命令。install 是安装动作,-g 表示作为 npm 全局工具提供,@openai/codex 是包名,latest 是发布标签。全局安装不等于必须给整个流程管理员权限。
看到 codex-cli 加版本号,说明入口能启动。准备时本机显示过 0.158.0,但你应以自己实际返回为准,而不是为了对齐截图反复降级。
安装输出中的 notice 与 WARN 需要结合正文看,并非每一行英文都是失败。遇到 ERR!、网络超时或权限错误时,把完整信息留下,再确认最后是否能执行版本命令。
安装结束却找不到命令
先打开新窗口,再检查:
powershell
Get-Command codex.cmd -ErrorAction SilentlyContinue
npm.cmd config get prefix
Get-Command 有结果时可以看到启动文件的位置;npm config get prefix 则提供全局工具目录。用文件资源管理器打开该目录,找一下是否有 codex.cmd。
有文件却搜不到命令,通常应检查用户 Path 是否包含这个文件夹;没有文件,应回到安装日志确认包是否真正安装完成。在环境变量编辑器中添加目录时,保留原有条目,不能把整条 Path 覆盖成一个路径。
修改后必须重新打开终端。已有多个安装来源时,后面还要确认真正启动的是哪一份,以免更新了 A,运行的仍是 B。
五、给第一次接入准备独立工作目录
为了看清文件变化,先建一个只用于练习的文件夹:
powershell
$projectDir = Join-Path $env:USERPROFILE 'CodexProjects\crazyrouter-demo'
New-Item -ItemType Directory -Path $projectDir -Force | Out-Null
Set-Location -LiteralPath $projectDir
Get-Location
$env:USERPROFILE 会展开为当前 Windows 用户目录。New-Item 创建文件夹,Set-Location 进入它,Get-Location 用来核对结果。路径里的 crazyrouter-demo 只是项目名称,不会自动配置任何服务。
暂时不要把真实公司的代码、配置和私人文件放进去。等认证和简单生成都通过,再决定工具需要接触哪些正式项目。
终端默认可能位于整个用户目录。工作路径没选对就启动,后续即使命令能运行,也容易把文件生成到你没想到的位置。每次换项目,先确认路径是一个值得养成的习惯。
本教程接下来还会在同一个 PowerShell 窗口设置临时环境变量,因此先保留窗口。后续启动 Codex 也从这里进行,避免在新窗口中丢失刚才输入的 Key。
六、选择认证路线,并接入 Crazyrouter
三种账户不要混着用
| 路线 | 凭证来自哪里 | 接下来怎么做 |
|---|---|---|
| ChatGPT 登录 | ChatGPT 账户及工作区 | 使用官方浏览器认证 |
| OpenAI API | 官方 API 账户 | 使用对应的 API Key |
| Crazyrouter | 自己的 Crazyrouter 账户 | 配置自定义 provider 与环境变量 |
使用 ChatGPT 可以在 PowerShell 执行 codex.cmd login,状态查看用 codex.cmd login status。设备码方式 codex.cmd login --device-auth 需要账户或工作区允许,它不是解决服务地区限制的通用按钮。
本文的接入示例走第三条。这样安排的目的,是把命令行编程工具保留下来,同时让请求使用你选定的服务配置;是否满足具体模型与任务要求,仍要由真实响应确认。
准备自己账户的 Key
在 Crazyrouter 的控制台创建供自己使用的 API Key,并查看账户可调用的模型与相关权限。入口和接口说明可以从 Crazyrouter 文档查阅。不要把截图里的字符串或其他人的 Key 当作通用配置。
下面使用 CRAZYROUTER_API_KEY 这个明确的变量名,减少与官方 Key 混淆。执行后在提示位置输入密钥,屏幕不会直接显示明文:
powershell
$crazySecret = Read-Host 'Crazyrouter API Key' -AsSecureString
$env:CRAZYROUTER_API_KEY = [System.Net.NetworkCredential]::new('', $crazySecret).Password
$crazySecret.Dispose()
Remove-Variable crazySecret
[bool]$env:CRAZYROUTER_API_KEY
最后的 True 仅说明当前进程里有值,不表示密钥有效,也不表示账户有余额。这个示例没有永久写入用户环境;关闭窗口后,新窗口不会自动继承这次设置,需要重新输入。
先确认模型,再填配置
本例固定使用一个 API 基础地址,后续列表与请求都沿用它:
powershell
$crazyBase = 'https://api.crazyrouter.com/v1'
$crazyHeaders = @{ Authorization = "Bearer $env:CRAZYROUTER_API_KEY" }
$crazyModels = Invoke-RestMethod -Method Get -Uri "$crazyBase/models" -Headers $crazyHeaders
$crazyModels.data | Select-Object -ExpandProperty id
powershell
$crazyModel = Read-Host 'Model ID'
在返回的列表中选择适用于 Codex 接入、且具有所需 Responses 能力的模型标识,再输入到 Model ID 提示处。列表中出现一个名称,仅说明可见,不能代替一次成功请求,也不能假设图像或语音模型都适合编程代理。
打开用户配置并留下备份:
powershell
$codexConfigDir = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $env:USERPROFILE '.codex' }
New-Item -ItemType Directory -Path $codexConfigDir -Force | Out-Null
$codexConfigFile = Join-Path $codexConfigDir 'config.toml'
if (Test-Path -LiteralPath $codexConfigFile) {
$backupFile = $codexConfigFile + '.' + (Get-Date -Format 'yyyyMMdd-HHmmss') + '.bak'
Copy-Item -LiteralPath $codexConfigFile -Destination $backupFile
}
notepad.exe $codexConfigFile
第一次没有该文件时,记事本可能询问是否创建。已有配置时保留原内容,只调整相关项;不要把全文当作无关模板直接覆盖。
把下面的设置合并到文件里,将 MODEL_ID_FROM_YOUR_ACCOUNT 换成刚才确认的模型 ID。它是必须替换的说明文字,不是有效模型名:
toml
model = "MODEL_ID_FROM_YOUR_ACCOUNT"
model_provider = "crazyrouter"
[model_providers.crazyrouter]
name = "Crazyrouter"
base_url = "https://api.crazyrouter.com/v1"
env_key = "CRAZYROUTER_API_KEY"
wire_api = "responses"
requires_openai_auth = false
model 与 model_provider 要位于 TOML 顶层,放在各个 [表名] 前面。已有同名项应修改,而不是再追加一套;[model_providers.crazyrouter] 也不能重复声明。API 地址中不要加 UTM,不要在这里写成网站首页。
保存为 config.toml,确认没有变成 config.toml.txt。现在可以从原来的 PowerShell 启动 codex.cmd。如果已经开着旧会话,先正常退出,再重新启动以读取改动。
七、看清目录信任与沙箱权限
第一次启动可能要求信任当前项目或初始化 Windows 沙箱。先看屏幕上的目录是否就是 crazyrouter-demo,再阅读要开放哪些操作。配置远端服务与授予本地文件权限是两件事,不要把它们一起视为"随便点确认"。

图 3:截图只是界面位置参考,版本、模型和选项次序可能变化,不代表该模型已成功调用。
沙箱用于约束文件、命令和网络等能力。下面的练习需要在当前目录创建一个 HTML 文件,却没有理由访问全部用户资料或关闭所有保护。
只问一个概念时不需要写文件;需要保存网页时,再确认文件名与路径。看到不认识的命令,可以让 Codex 解释修改对象、执行目的和可替代方法,然后再决定是否批准。
出现写入拒绝时也要区分:是目录不可写、沙箱范围不含该路径,还是模型请求本身没成功?服务端认证已经通过,仍可能在本地保存时失败,不能仅靠"有回复"判断全部流程结束。
八、从最小请求到第一个可打开的网页
先检查 Responses 请求
在刚才设置过变量的 PowerShell 窗口执行下面的最小请求。它会使用你的账户发起实际调用,按服务商账户规则处理用量:
powershell
$crazyPayload = @{
model = $crazyModel
input = 'Reply with OK.'
stream = $false
} | ConvertTo-Json -Depth 6
$crazyResponse = Invoke-RestMethod -Method Post -Uri "$crazyBase/responses" -Headers $crazyHeaders -ContentType 'application/json' -Body $crazyPayload
$crazyResponse | Select-Object id, status, error
$crazyResponse.output | ConvertTo-Json -Depth 8
这段代码的模型来自刚才输入的 $crazyModel,请求发往 /v1/responses。保留返回 ID、状态和输出文本作为自己核对的依据,但分享日志时要去掉凭证。
不要把没有抛出 HTTP 错误当作生成成功。检查是否有正常输出、错误字段是否为空,以及服务返回的状态;若结构与示例不同,先对照当时的文档。列表可读但请求失败,说明还需要核查模型权限或协议能力。
在 Codex 里确认连接
powershell
Set-Location -LiteralPath $projectDir
codex.cmd
进入对话后,先要求"用一句中文解释 HTML,不读取文件、不执行命令"。正常回复说明这次交互请求完成;缺变量、401、403 或余额提示都应先解决,不要马上增加复杂任务。
还要检查当前 provider 和模型是否是自己选择的配置。单独的 HTTP 请求成功,并不能自动证明 Codex 会话也使用了相同的地址和凭证。
创建单文件练习
text
请在当前项目目录创建 index.html,制作一个中文入门页面。
标题为"我的第一个 Codex 页面",正文显示"你好,Codex"。
添加"查看提示"按钮,点击后在页面上出现"页面交互正常"。
CSS 和 JavaScript 都放在此 HTML 内,不引用外部图片或框架。
不要安装依赖,不发起额外网络请求,也不要修改其他文件。
完成后报告实际保存位置,以及我应该如何检查按钮。
如果不能写文件,请直接说明原因,不要把聊天中的代码当成已保存结果。
把需求限定成一个文件,可以先排除构建工具、数据库与服务端配置。允许写入时确认对象为当前目录的 index.html。
完成后输入 /quit 或使用当前界面的退出方式,回到 PowerShell,再检查文件并打开:
powershell
Test-Path .\index.html
powershell
Start-Process .\index.html
第二条命令在第一条返回 True 后执行。浏览器应该能显示约定标题,按钮被点击后出现指定文本。只有回复、文件、页面行为都对应起来,才算这次练习验收完成。这里给的是验证步骤,不用示例截图冒充你的实际运行结果。
九、理解配置,后面换模型才不会乱
路径与备份的作用
默认文件在用户目录的 .codex\config.toml。前面的脚本先检查 CODEX_HOME,是为了兼容已经自定义位置的环境;配置目录不能仅凭别人电脑的路径猜测。
备份名加上时间,便于分辨修改前后的内容。回退时先退出会话,在备份中找到被修改的 provider、模型和认证字段恢复即可,不要为了一个报错顺手删除所有历史数据和登录文件。
每个字段到底负责什么
| 字段 | 应如何理解 | 填写时要注意 |
|---|---|---|
model |
这次请求的模型标识 | 从自己的账户信息确认,并实际调用 |
model_provider |
选择下方哪份供应商设置 | 与表名末尾的 crazyrouter 对应 |
name |
供应商显示名称 | 名称本身不决定请求去向 |
base_url |
API 基础路径 | 本例包含 /v1,不是完整 /responses 地址 |
env_key |
读取哪个环境变量 | 填变量名,不把真实 Key 放进此值 |
wire_api |
客户端请求协议 | 当前按 responses 配置 |
requires_openai_auth |
是否使用 OpenAI 认证机制 | 本例使用服务商变量,明确设置为 false |
把 requires_openai_auth 改成 true 会选择 OpenAI 认证并忽略 env_key。这就是有时"明明设置了第三方 Key,却仍然走另一套认证"的原因之一。不要混用不同教程中的两套方案。
同样,服务支持普通聊天接口并不能证明它支持 Codex 需要的 Responses 与相关工具行为。使用 Crazyrouter 时,模型名称、接口能力和账户权限仍要组合确认;官网上的一个产品名称不一定等于 API 的精确模型 ID。
为什么用了独立变量名
CRAZYROUTER_API_KEY 能帮助你区分服务来源,而不用反复猜测 OPENAI_API_KEY 里现在放的是哪家凭证。配置中的名称和终端中的名称必须逐字对应。
如果在新的窗口启动,先执行存在性检查。不要在文章截图里展示变量的实际内容,也不要把凭证放进会被 Git 提交或云盘共享的示例文件。
怎样继续使用这套配置
首次验证通过后,可以沿用同一个工作方式处理自己的项目:进入项目、准备凭证、核对 provider、提交小范围任务。需要换模型时先查当时账户可用的 ID,更新对应字段并重新启动会话。
不必因为新增一个模型就重装 Node.js。安装环境与调用参数分开管理,正是这套方法方便维护的地方。若要切回官方方式,先恢复合适的 provider,再使用相应账户认证,不要留下第三方地址却换成官方凭证。
给这次接入留一份可用记录
可以在自己的项目笔记中记录日期、CLI 版本、所选模型和这次请求的结果。记录的是配置身份,不是密钥内容。以后同一套命令出现不同表现,有了这份信息才能判断是本地版本发生变化,还是账户权限、模型渠道或远端响应发生了改变。
建议把"模型列表读取成功""最小文本请求成功""Codex 能正常回复""网页按钮有效"分别记下来。比如列表请求正常、生成请求报错,这个记录比笼统写"接口可用"准确得多,也能避免在分享经验时把未完成的环节误写成结论。
如果需要向服务方反馈,优先提供脱敏后的错误类型、请求时间、模型 ID 和返回的请求标识。不要把 Authorization 请求头、整个认证文件或包含私人业务内容的完整上下文一起发出去。排错需要足够信息,不需要把所有文件公开。
同一个项目里也不要同时切换地址、模型和 Key 后再测试。一项一项调整、重复同一个短请求,更容易比较差异。确认连接稳定后再恢复较长任务,能减少无意义的重试和排查成本。
十、常见错误应该在哪一层处理
| 表现 | 先排查的范围 | 合理的下一步 |
|---|---|---|
| 无法识别 node | Node.js 与 Path | 检查安装,再重开终端 |
| npm.ps1 或 codex.ps1 被拦截 | 启动脚本与执行策略 | 先使用本文 .cmd 形式 |
| 安装过程超时 | npm 下载网络与 registry | 读取原始报错和源地址 |
| 找不到指定环境变量 | 当前进程的凭证设置 | 核对变量名称及启动窗口 |
| 401 | 凭证、服务地址与认证机制 | 检查 Key 是否属于当前服务 |
| 403 | 返回正文与服务权限 | 分辨地区、账户或组织限制 |
| 404 或模型不存在 | URL 路径和模型 ID | 排除重复 /v1 与错误别名 |
| 429 | 用量限制或请求频率 | 根据错误说明区分余额和限流 |
| TOML 解析失败 | 引号、表名、重复键 | 从最近修改的字段开始核对 |
1. 脚本被禁止运行,一定要改策略吗
先试 npm.cmd --version 或 codex.cmd --version。如果正常,就沿用明确的启动文件形式。确实需要运行脚本时再考虑设备策略,组织管理的电脑不要自行放宽限制。
2. 下载太慢,能否直接换源
powershell
npm.cmd config get registry
先看看现有地址。企业可能有内部 registry,不应直接覆盖;普通网络问题也不要通过关闭证书验证处理。安装阶段的源与 Crazyrouter 的 API 地址没有关系,切换其中一个不会自动修好另一个。
3. 配置已经保存,为什么还说缺 Key
powershell
[bool]$env:CRAZYROUTER_API_KEY
False 表示这个 PowerShell 当前没有值;True 也只表示存在。注意你是否关掉了设置 Key 的窗口,以及 TOML 是否写了另一个名字。不要把密钥本体作为排错信息公开。
4. 403 能不能用改配置解决
先看发往哪个域名、拒绝原因是什么。错误地址可以通过配置修正,服务明确的地区或账户限制却不是改一个 TOML 字段就能消除。不要据此编造"所有 403 都能解决"的结论。
5. 为什么 CMD 教程的路径命令不能用
PowerShell 用 $env:USERPROFILE,不要照搬 CMD 的 %USERPROFILE% 与 cd /d。本文使用 Set-Location,带空格的路径保留引号。语言版本可以不同,终端语法不能混。
6. 如何更新和检查多个安装位置
powershell
npm.cmd install -g @openai/codex@latest
codex.cmd --version
Get-Command codex* -All
升级后看实际调用路径。重复安装程序不应成为每次打开终端前的动作;凭证是否存在和包是否存在分别处理。
7. 能回复却没有生成文件
检查任务是否真的要求保存、沙箱是否允许当前目录写入,以及文件是否生成在另一条路径。只有聊天里的代码,不应算成落盘成功。用 Get-Location 与 Test-Path 分别确认位置和文件。
8. 怎样描述问题才容易获得帮助
保留版本、命令、错误类型和触发步骤。分享前遮挡密钥、设备码、邮箱与无关私人路径,不要上传整个 .codex。一次只调整一项,再重复最小请求,这样才能知道改变是否有效。
十一、把安装和接入分别验收
验收时可以在本地笔记中记录每一步的实际结果,但不要把本文的检查清单直接当成已完成的测试报告。例如"版本命令正常、模型列表正常、生成请求返回鉴权错误",已经能够说明问题停在远端调用阶段;这时应检查账户和响应内容,而不是继续重装 Node.js。对新手而言,能够准确描述失败位置,也是在推进问题解决。
如果之后更换电脑,应重新检查安装环境和凭证来源;如果只是换项目,通常先确认目录和文件权限。把需要重新做的步骤与已经稳定的步骤区分开,才能避免每次开始工作都把整篇安装教程执行一遍。
- Node.js 和 npm 的版本检查已完成。
- Codex 的版本与帮助命令能运行。
- 当前工作目录是独立练习目录。
- Crazyrouter 的 Key 属于自己的账户,并已放入正确变量。
- 已查询模型列表,使用真实模型 ID 替换模板说明文字。
- 用户级配置中的地址、provider 和协议一致。
- 最小 Responses 请求返回有效状态与正常输出。
- Codex 会话使用预期的 provider,并能回答一个简单问题。
-
index.html确实存在,浏览器中的按钮按要求工作。
前半部分检查本地工具,后半部分检查服务和具体任务。通过这种分层方式,Crazyrouter 接入就成为一个可以解释、可以回退、可以重复验证的配置过程,而不是复制一段不知道含义的文本。
后续把练习换成正式需求时,也保留这个顺序:先确认账户和工作范围,再定义你能亲自检查的成果。这样即使界面升级或模型更换,也能沿着同样的思路定位问题。
技术参考:Codex 官方文档。