先看结论
如果你想在原生 Windows 上让 AI 代理长期写代码、改模板、处理 JSON、发内容,最该先解决的通常不是模型,也不是提示词,而是命令行栈。
这次我最后定下来的组合很简单:Git Bash 负责日常 shell,rg 负责搜索,sd 负责普通文本替换,jq 负责 JSON,yq 负责 YAML 和 front matter,ast-grep 负责结构化代码改写,winget 负责安装和升级。
这套东西装完以后,最直接的变化有三个。第一,中文文本处理的错误率明显下降。第二,批量替换和结构化改写不再依赖长串 PowerShell 字符串拼接。第三,很多原本要靠临时 Python 脚本救场的动作,现在都能在命令行里直接完成。
这次到底卡在什么地方
问题不是抽象的Windows不适合开发。这次遇到的麻烦很具体,基本都落在四层。第一层是 shell。PowerShell 很强,但它更像对象管道环境,不是纯文本导向的 shell。第二层是文本。只要命令稍微一长,尤其同时带上中文、引号、正则和模板片段,PowerShell 的转义负担就会上升。第三层是格式。文章发布流里同时有 Markdown、JSON、YAML、模板和 HTML。第四层是环境。PATH、命令别名、UTF-8、Git 中文显示、执行策略,这些基础项一旦没配好,再好的 CLI 也会出现明明装了结果当前 shell 找不到的假故障。
这四层叠在一起,最后就会表现成一种很典型的拖慢方式:明明任务不复杂,时间却都花在 shell 适配、引号修补和编码回查上。
为什么这次明确不装 WSL
如果只追求省事,最常见的建议当然是直接上 WSL。那样很多命令行问题会瞬间消失,Linux 工具链也几乎原样可用。
但这次的约束很清楚:不要 WSL,只做原生 Windows。这个约束很实用。因为一旦工作环境的主体还是 Windows,最后你总要面对这些现实:Git、编辑器、浏览器和发布目录都在 Windows 文件系统上,文章、模板和部署脚本都跑在 Windows 用户态里,路径、权限、命令别名和终端行为都要回到 Windows 自己的规则。
在这种前提下,再多加一层 WSL,当然能解决一批问题,但也会带来新的路径和环境分叉。对这次任务来说,先把原生栈收拾干净,收益更直接。
选型标准其实不复杂
这次选工具时,我只看四个标准。第一,职责要单一。一个工具最好只做一件事。第二,CLI 语义要清楚,最好能少做转义补丁。第三,Windows 要是一等公民。第四,和自动化兼容,能稳定进入脚本。按这个标准筛下来,最后留下来的就是现在这套栈。
为什么 Git Bash、rg 和 sd 应该放在第一层
第一步不是换搜索器,而是先把 shell 换掉。Git for Windows 的官方描述很直白:它提供了一套轻量、原生的 Windows 工具,并且带有 Git Bash;这个 Bash 模拟环境的行为会让 Unix 和 Linux 用户觉得熟悉。对今天这种大量依赖文本流的工作来说,这一点非常关键。
PowerShell 并没有错,但它不适合继续当默认文本 shell。Git Bash 更接近我们熟悉的那类命令行语义:管道就是管道,stdout 就是 stdout,配合 rg 和 sd 这类工具时几乎不需要再重学一遍表达方式。
ripgrep 的位置也没有悬念。官方 README 直接写明,它是 line-oriented search tool,会递归搜索目录,默认尊重 .gitignore,并且在 Windows、macOS、Linux 上都有一等支持和二进制发布。对仓库检索来说,这已经覆盖了绝大多数日常需求。
sd 解决的是另一个更烦的小问题:普通替换到底该交给谁。它官方把自己定义成 intuitive find and replace CLI,核心优势就是命令短、正则语义更接近 JavaScript 和 Python、也更少掉进 sed 和 PowerShell 的转义泥潭。对代理来说,越短、越直接、越少转义的命令,出错面越小。
为什么 JSON、YAML 和代码结构必须分开处理
过去一个高频错误,是拿字符串替换去碰结构化数据。这在 JSON 和 YAML 上尤其危险。不是说做不到,而是太脆。一旦字段顺序、缩进或引号稍微变化,纯文本替换就会开始误伤。
所以这次的处理很干脆。JSON 全部交给 jq。jq 官方下载页写得很清楚:它是用 C 写的,没有运行时依赖,并且 Windows 提供预编译可执行文件,也支持用 winget 安装。YAML 和 front matter 交给 yq。官方文档把它定义为 lightweight and portable command-line YAML, JSON, INI and XML processor,同时支持原地修改。对既有 front matter 又有配置文件的内容站来说,这种能力是刚需。
代码级批量改写再交给 ast-grep。它官方首页的定义也很直接:这是一个做 code structural search、lint 和 rewrite 的工具。改函数调用、改模板条件、改 import 形式这类动作,本来就不该继续靠纯文本替换硬做。
为什么安装入口也必须收口到 winget
如果前面这些工具都装好了,但安装方式还是各自乱飞,后面仍然会乱。这次安装入口我最后统一收到了 winget。Microsoft Learn 的文档写得很清楚:WinGet 是 Windows Package Manager 的命令行客户端,支持 search、install、upgrade 等动作;它作为 App Installer 的一部分提供,也适合非交互脚本。
这次本机环境里就出现了一个很典型的问题:系统里明明已经有 winget,当前 shell 却找不到。真正的做法不是怀疑系统里没有,而是先确认 App Installer 包体还在,再用绝对路径把 winget.exe 调起来,把工具装齐。这件事提醒了我一点:基础设施问题经常比工具本体更拖时间。
真正决定稳定性的,是编码和 PATH
工具装好以后,还差最后一步:把环境本身收口。这次我补的主要是三项。第一项是 UTF-8。终端编码、Python I/O 编码和文件读写编码如果不统一,中文内容迟早会出问题。第二项是 Git 的中文显示。我补了 core.quotepath=false、i18n.commitEncoding=utf-8 和 i18n.logOutputEncoding=utf-8。第三项是 shell 入口。Git Bash 要能直接调用,ast-grep 的 sg 也要能在新开的 shell 里直接找到。很多所谓Windows命令行不稳定,最后都不是某个工具失灵,而是 PATH、编码和别名没真正固定下来。
这套工具链装完以后,分工终于清楚了
现在这套栈最有价值的地方,不是工具更多了,而是每个动作该找谁已经清楚了。查仓库交给 rg,普通替换交给 sd,改 JSON 交给 jq,改 YAML 和 front matter 交给 yq,改代码结构交给 sg,复杂文本管道交给 Git Bash,真正复杂的逻辑和发布脚本再交给 Python。这个分工一旦明确,代理行为也会更稳。因为它不再需要每次现场决定这次到底该拿哪种工具来改一段文本,而是先按数据类型和任务类型分流,再选工具。
我的结论
如果今天让我给原生 Windows 下的 AI 编程环境只留一套默认组合,我会直接留这套:Git Bash + rg + sd + jq + yq + ast-grep + winget。
这不是为了追求工具数量,而是为了把命令行重新变得可预测。做完这轮之后,真正的变化很简单:中文文本处理开始稳定,批量替换不再像拆炸弹,JSON 和 YAML 不再靠字符串硬改,代码级批量修改也终于有了合适的结构化入口。到这一步,原生 Windows 才算真正适合继续承接后面的 AI 自动化工作。
还没有评论,你可以写下第一条。