直接说结论:这件事完全能做,而且做完之后,你会觉得 Obsidian 从一个“本地 Markdown 笔记本”变成了“长在你自己工作流里的小型 AI 工作站”。标题里的三个关键词——Obsidian、Codex、Windows——拼在一起,本质上是三件事:本地笔记库、命令行 AI 助手、以及 Windows 上各种路径/编码/环境变量问题。我先把整套思路讲透,再给你一份可以照着抄的配置过程,最后附上我踩过的坑。
这套方案适合谁?主力系统是 Windows,用 Obsidian 管理笔记/知识库/项目文档,同时想用 Codex 对话式地写代码、改文本、复盘日志,但不想来回切窗口,更不想把对话记录随便丢到某个网页里。如果你只是偶尔想点击按钮让 AI 写一段文字,也可以装,但收益最大的其实是程序员、技术写作者、以及用 Obsidian 做知识管理的人。
1. 为什么要在 Obsidian 里调用 Codex,而不是开两个窗口
1.1 很多人的真实使用场景
大部分人在 Obsidian 里写着写着笔记,突然需要问一个问题,比如“帮我解释一下这段 SQL 的窗口函数”,或者“根据我下面这三条日志,写一个排查总结”。这时候你的本能反应是什么?切到浏览器/终端,把问题粘进去,等回复,再复制回 Obsidian,手动排版,然后在笔记最上面补一行“今天问了 AI 什么问题”。
一次两次还行,次数多了你就会发现:对话内容根本沉淀不下来。浏览器里聊完就没了,就算能导出,格式也是乱的,时间一长根本没法检索。Obsidian 的最大价值是本地 Markdown、双向链接、可检索,所以最理想的形态应该是:在笔记页面里发起对话、把回答写回笔记、对话记录自动变成知识库的一部分。这就需要一个桥。
1.2 方案选型:CLI 中转,而不是网页版或桌面版
先说一个很多人会踩的第一个坑:Obsidian 插件库里那些“接入 ChatGPT/OpenAI”的插件,大部分需要 API Key,而且你一旦把 Key 写进笔记或者插件配置里,哪天文章同步到公开仓库就麻烦了。另一部分人会用 Codex 桌面版/网页版,但那些应用默认不会暴露一个本地端口给 Obsidian 调用,你没法在模板里命令它。
所以最通用的方案是:安装 Codex CLI,让 Obsidian 的 Templater 插件去调用这条命令行指令,把结果读回来,插入到当前笔记。相当于 Obsidian 是你的前台面板,Codex CLI 是你的后台引擎。这样做有四个明确好处:不额外暴露 API Key,所有对话记录天然就是 Markdown 文件,Windows 环境变量问题可以被单独隔离调试,而且你能用模板控制每一次对话的格式。
1.3 需要准备的基础环境
既然是在 Windows 上跑,我建议你提前装好这几样东西,后面都不是多余步骤:
- Windows 10/11,不用纠结版本,只要不是被严重精简过的系统就行
- Obsidian 本体,用最新稳定版,装的时候保持默认路径
- Node.js 20 LTS 或更高版本,因为 Codex CLI 是以 npm 包分发的
- Git for Windows,非严格必需,但 Codex 在处理代码仓库上下文时会用到 git,建议顺手装上
- 一个能用的终端环境,Windows Terminal 或 PowerShell 都行
如果你之前装过 Node.js 但版本很老,建议先升级,因为新版 Codex CLI 对 Node 版本有最低要求。下面我按顺序讲配置。
2. Windows 环境准备与 Codex CLI 安装
2.1 安装 Node.js 和 Git for Windows
Node.js 的安装没什么玄学,去官方渠道下载 LTS 版本的 Windows Installer,双击运行。安装过程中有一点必须注意:在“Custom Setup”那一步,确认“Add to PATH”是启用的。很多人装完 Node 后终端里敲npm提示找不到命令,就是这一步没勾。
装完之后,重新打开一个终端窗口,输入下面两条命令验证:
node -v npm -v正常情况下会各打印一行版本号。如果提示找不到命令,说明 PATH 没生效,要么重装勾选,要么重启系统,要么手动把 Node 的安装目录加进系统环境变量。
Git for Windows 的安装同理,一路下一步。装它的意义在于:Codex CLI 生成代码改动时,如果当前目录是一个 git 仓库,它判断上下文会更准确。对 Obsidian 来说,很多人的 Vault 本身就是个 git 仓库,这正好用得上。
2.2 安装 Codex CLI 并完成登录
打开终端,直接执行全局安装:
npm install -g @openai/codex装完先验证版本:
codex --version如果报错“codex 不是内部或外部命令”,不要慌,大概率是 npm 的全局目录没在 PATH 里。用这条命令看一下全局安装路径:
npm prefix -g然后把输出的那个目录加到系统环境变量 Path 里,重新打开终端。这一步我身边至少有两个同事卡过,他们以为是安装失败,其实就是 PATH 没刷出来。
验证通过后,执行登录:
codex login按终端提示在浏览器里完成授权。登录信息会保存在本地配置目录,不需要手动记 token。这里有一点要特别说:不要把你得到的任何 token、会话信息写进 Obsidian 笔记,尤其不要写进会同步的 Vault。代码写得再安全,也防不住笔记公开分享。
2.3 先跑通一个最小的命令行对话
在配置 Obsidian 之前,务必先在终端里验证 CLI 能用:
codex exec "用一句话解释什么是局部性原理"如果能返回一段中文回答,说明 CLI 链路没问题。第一次通常会慢一些,因为可能要加载模型和初始化环境。如果你平时习惯在命令行里再加--model指定模型,这里要提醒一句:不是所有账号/版本都支持随便指定模型,后面排查章节会专门讲。
3. Obsidian 侧的桥接:Templater 脚本 + 临时文件
3.1 安装 Templater 并设置 Scripts 文件夹
Obsidian 侧的桥接主角是 Templater 插件。它支持在笔记模板里嵌入 JavaScript,还能调用系统命令,这正是我们需要的。
安装步骤:Obsidian 设置 -> 第三方插件 -> 关闭安全模式 -> 浏览 -> 搜索“Templater” -> 安装并启用。
装好后,进入 Templater 设置,找到“Script files folder”,把它指向你 Vault 里的一个固定目录。比如我习惯建一个“00-Templates/Scripts”目录。这个目录用来放 user script,Templater 会把这些脚本当函数库加载。
如果你看到模板里的tp.user相关函数怎么都调不到,先去确认这个目录设置是不是正确,然后重启一次 Obsidian。这是最容易被忽略的点。
3.2 在 Scripts 目录创建 PowerShell 中转脚本
为什么非要多一层 PowerShell 脚本?因为 Obsidian 的 user script 直接在 Node.js 环境里跑,如果你用exec直接拼 command line,一旦 prompt 里含中文引号、换行、特殊字符,Windows 的转义规则会让你痛不欲生。正确做法是:先让 JavaScript 把 prompt 写进一个临时文件,再由 PowerShell 读取这个文件、调用 Codex、把结果写到另一个临时文件,最后让 JavaScript 读回结果。
在你刚设置的 Scripts 目录旁边(或者任意固定位置),新建一个codex_run.ps1:
param( [Parameter(Mandatory = $true)][string]$InputFile, [Parameter(Mandatory = $true)][string]$OutputFile ) $ErrorActionPreference = 'Stop' $prompt = Get-Content -Raw -Encoding UTF8 $InputFile $output = codex exec $prompt 2>&1 | Out-String Set-Content -Path $OutputFile -Value $output -Encoding UTF8这段脚本做的事情很简单:读输入文件,执行codex exec,把输出写到输出文件。短问题直接用命令行参数没问题,但如果你的 prompt 可能超过几百字,文件中转方式才是稳定的。
3.3 编写 Templater user script:runCodex.js
回到 Scripts 目录,新建一个runCodex.js,内容如下:
const { execFile } = require('child_process'); const os = require('os'); const path = require('path'); const fs = require('fs'); module.exports = async function runCodex(tp, prompt) { const inputFile = path.join(os.tmpdir(), `codex_input_${Date.now()}.txt`); const outputFile = path.join(os.tmpdir(), `codex_output_${Date.now()}.md`); fs.writeFileSync(inputFile, prompt, 'utf8'); const ps1Path = path.join( tp.app.vault.adapter.getBasePath(), '00-Templates', 'Scripts', 'codex_run.ps1' ); await new Promise((resolve, reject) => { execFile( 'powershell.exe', [ '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', ps1Path, inputFile, outputFile ], { timeout: 180000, windowsHide: true }, (error) => { if (error) reject(error); else resolve(); } ); }); const result = fs.readFileSync(outputFile, 'utf8'); fs.unlinkSync(inputFile); fs.unlinkSync(outputFile); return result.trim(); };几个细节说明:tp.app.vault.adapter.getBasePath()拿的是 Vault 在磁盘上的真实路径,这样才能在 PowerShell 进程里直接访问.ps1文件;timeout设置为 180 秒,避免 Codex 思考太久导致脚本挂死;windowsHide: true是防止每次调用都弹一个黑窗口。
3.4 新建一个“Codex 对话”模板
在 Templater 模板目录里新建一个模板文件,比如Codex 对话.md,内容:
--- type: codex-conversation created: <% tp.date.now("YYYY-MM-DD HH:mm") %> tags: [codex] --- ## 我的问题 <%* const question = await tp.system.prompt("想对 Codex 说什么?"); const answer = await tp.user.runCodex(tp, question); tR += question; %> ## Codex 回复 <%* tR += answer; %>创建新笔记时,选这个模板,会弹出一个输入框,你输入一个问题,等待几十秒,回答就会插入到笔记里。这条记录天然就是 Markdown,后续可以用 Obsidian 的搜索、标签、Dataview 去聚合。
如果模板执行时报错,第一时间按Ctrl+Shift+I打开 Obsidian 开发者控制台,看红字。绝大多数情况是runCodex没有被 Templater 识别,或者 PowerShell 执行策略挡住了脚本。
4. 把 Codex 变成日常知识管理的一部分
4.1 场景一:把笔记中的代码片段直接交给 Codex 审查
只跑一个“输入问题 -> 得到回答”的模板,其实只是把网页聊天搬到了 Obsidian 里,还不够爽。更值钱的用法是:选中笔记里的代码块,直接让 Codex 审查。
思路是在模板里读取当前编辑器选中的文本,然后组装 prompt。Templater 支持通过tp.app.workspace.activeEditor.editor.getSelection()拿到选中内容。可以写一个专门的审查模板:
--- type: codex-review created: <% tp.date.now("YYYY-MM-DD HH:mm") %> tags: [codex, review] --- ## 待审查代码 <%* const editor = tp.app.workspace.activeEditor.editor; const selection = editor ? editor.getSelection() : ''; const prompt = `请审查下面这段代码,重点看:1.潜在bug 2.可读性 3.性能问题。不要泛泛而谈,要给出具体修改建议。\n\n\`\`\`\n${selection}\n\`\`\``; const answer = await tp.user.runCodex(tp, prompt); tR += selection; %> ## 审查结果 <%* tR += answer; %>这样你在阅读别人代码或者回看自己旧笔记时,可以选中一段,一键生成审查结果,后面再手动确认一遍。省去复制粘贴、来回切窗口的时间。
4.2 场景二:自动生成结构化知识点
Obsidian 用户普遍喜欢维护“永久笔记”和“知识卡片”。这类笔记对格式有要求,比如要有概念定义、例子、联系、反例。你可以在模板里预置输出格式要求:
--- type: codex-concept created: <% tp.date.now("YYYY-MM-DD HH:mm") %> tags: [codex, concept] --- ## 概念 <%* const concept = await tp.system.prompt("输入概念名称,例如:CAP 定理"); const prompt = `请用中文解释「${concept}」,要求: 1. 先用两句话给出直觉定义 2. 给出一个程序员熟悉的类比 3. 给出一个可运行的简单示例 4. 说明常见误解 全部使用 Markdown 格式,不要超过 400 字。`; const answer = await tp.user.runCodex(tp, prompt); tR += `# ${concept}`; %> ## 回答 <%* tR += answer; %>这里的关键是:把“格式偏好”写死在模板里,而不是每次都临时口头补充。人容易忘记,模板不会。你用了几次之后,可以不断调优这个格式,让它更符合自己的笔记习惯。
4.3 用 AGENTS.md 固定你的风格要求
Codex CLI 有一个特性:它会读取当前工作目录下的AGENTS.md,把它当作用户级指令。你在 Vault 根目录放一个AGENTS.md,就能全局约束 Codex 在 Obsidian 里的回答风格,这样模板里不用重复写大段要求。
举个例子,我自己的AGENTS.md里写了:
# 对我写作的约束 - 默认使用中文输出 - 使用 Markdown 格式,标题层级不要跳级 - 代码示例必须给完整可运行版本,不要写伪代码 - 回答尽量简洁,超过 500 字时先给出结论再展开 - 不要使用 emoji这个文件是纯文本,可以随时改,改完立即生效。如果你某些目录/子文件夹有特殊风格,也可以放各自的AGENTS.md,Codex 会做层级合并。这种机制比在模板里写死更优雅,也更贴近真实项目协作方式。
4.4 同步与多设备问题
聊到这里就不得不回应一个网上经常看到的说法:“Obsidian 是不是收费了?”。准确地说,Obsidian 本体和核心插件免费,收费的是官方同步服务和发布服务。如果你不想付费,可以完全用本地文件的方式,不同设备之间用 Git 仓库推送/拉取。
不过这里要提醒一句:如果你用了上面的 Codex 模板,生成出来的对话记录默认是本地文件。如果你把它加入 Git 同步,注意不要同步包含敏感信息的临时文件和缓存目录。我建议在.gitignore里排除.obsidian/workspace.json、临时文件目录、以及任何可能生成 key 的文件,只同步笔记正文。
5. 常见问题与排查实录
5.1 codex 命令找不到或无法启动
现象:在 Obsidian 模板里执行脚本后,PowerShell 报错“codex 不是内部或外部命令”,但你在终端里手动敲codex是正常的。
原因通常是 Obsidian 进程继承的环境变量和终端里不一致,尤其是你通过某些软件修改环境变量后没重启 Obsidian。解决办法:最直接的是重启 Obsidian;如果还没用,检查 npm 全局目录是否在系统 PATH 里,而不是只在用户 PATH。也可以在runCodex.js里打印一下环境变量,看PATH里是否有 npm 目录,便于定位。
5.2 本地代理环境变量冲突导致 endpoint 切换报错
如果你之前因为某些开发需要配置过HTTP_PROXY、HTTPS_PROXY这类环境变量,那么 Obsidian 调用 Codex 时,PowerShell 子进程也会继承这些变量。这时候经常会出现类似cc switch local proxy failed while handling codex endpoint /responses的报错。
排查思路:打开系统环境变量设置,看有没有HTTP_PROXY、HTTPS_PROXY、ALL_PROXY这类变量。如果业务上暂时不需要它们,可以先在“系统变量”层面删掉,再重启 Obsidian。如果这些变量是某个开发工具自动写入的,你可以在codex_run.ps1开头临时清理它们:
Remove-Item Env:HTTP_PROXY -ErrorAction SilentlyContinue Remove-Item Env:HTTPS_PROXY -ErrorAction SilentlyContinue Remove-Item Env:ALL_PROXY -ErrorAction SilentlyContinue注意,我遇到过有人把这种清理写进全局脚本后,导致其他依赖这些变量的工具失效。建议只在codex_run.ps1里做局部清理,只影响 Codex 调用链路。
5.3 模型不支持报错
有读者反馈过类似错误:the 'gpt-5.6-sol' model is not supported when using codex with a ...。这类报错基本是两种原因:一是 CLI 版本太老,默认模型已经失效;二是你手动在命令里指定了一个当前账号/当前接口不支持的模型。
解决方式:先升级 Codex CLI,再删除本地旧的配置缓存。执行npm install -g @openai/codex升级后,运行codex --help查看当前默认模型,不要自己硬写模型名。如果你确实需要某个特定模型,确认它出现在可用列表里。这个坑的自查优先级高于其他所有网络排查,因为报错信息已经把问题说得非常明白了,就是模型名不被支持,而不是网络不通。
5.4 Obsidian 输出乱码或脚本超时
乱码问题几乎全部出在编码。解决方案就是整个链路统一 UTF-8:Templater 的 user script 用fs.writeFileSync(inputFile, prompt, 'utf8')写文件,PowerShell 脚本用Get-Content -Encoding UTF8和Set-Content -Encoding UTF8,不要用默认编码。还有一个容易忽略的点:AGENTS.md和模板文件本身也要是 UTF-8,建议你在 Obsidian 设置里把“默认新文件格式”也改成 UTF-8。
脚本超时问题,我前面把timeout设成了 180 秒,如果你经常遇到的问题比较复杂,可以再放宽到 300 秒。但不要无限大,真卡死了你连中断的机会都没有。如果你频繁遇到超时,建议把问题拆小,而不是让 Codex 做太大的一次性任务。
5.5 下载慢、安装包获取不下来怎么办
这个问题在 Windows 用户里太常见了,尤其是下载 Node.js、Git、Obsidian 这类安装包。这里不谈任何绕过网络限制的手段,就说合规又实用的经验:官方渠道下载慢,很多时候是 CDN 节点负载高,你可以换时间段再试,比如早上比晚上快很多;尽量用支持断点续传的下载方式,不要用容易中断的浏览器直下;下载过程中不要同时开一堆安装包下载任务,挤占带宽。另外一个容易被忽视的问题是安装包完整性,下载到一半失败但你又强行运行,容易出现奇奇怪怪的错误,比如 Codex 安装成功后命令不完整、登录流程中断。下载完先看文件大小是否和官方页面一致,再安装。
5.6 手机端怎么更新 Obsidian 插件
手机端 Obsidian 的插件更新逻辑和桌面端不完全一样,它不是点击“检查更新”就万事大吉。你需要先确认手机和电脑访问网络都正常,然后在插件列表里找到要更新的插件,看是否有“更新”按钮。如果一直更新失败,最简单的办法是先在电脑上把插件更新到最新,再通过同步服务或手动拷贝.obsidian/plugins目录到手机。注意,移动端对本地文件系统的访问受限,所以手动拷贝路径要放在 Obsidian 能识别的 Vault 目录里,别随手放下载目录。
最后,我的实际使用习惯
这套配置已经跟了我几个月,最后分享两个我已经离不开的习惯。第一个习惯:所有 Codex 对话笔记都打上codex标签,然后用 Dataview 做一个简单的“最近问答”汇总列表,放在 Vault 首页。这样每次打开 Obsidian 都能看到过去一周问了什么、哪些问题值得整理成正式笔记,而不是让对话记录沉底。第二个习惯:凡是我觉得以后可能会复用的回答,我会在回看时给它补充一个“结论”字段,把 AI 回答里最核心的三句话摘出来,其他细节折叠到注释里。这其实是用人的二次加工弥补模型输出的信息冗余。
另外要提醒一句:Codex 生成的内容,尤其是代码,一定要自己读一遍再进正式项目。它不是幻觉免疫体。我见过它把旧 API 写成新 API、把错误的密码错位填进配置文件、把git reset --hard放在一个奇怪的执行顺序里。当成高效助手没问题,当成甩手掌柜就会出事。
如果你按上面的步骤走,顺利的话半小时内就能把“在 Obsidian 里直接和 Codex 对话”这件事跑起来。跑通之后,建议你先拿一个小项目试点一周,再看哪些模板、哪些 prompt 需要调整。工具这东西,配置只是开始,真正值钱的是你用它的那一套流程。