AI Coding 工具治理规则: opencode + 智谱 MCP
一、从程序员最常用的两个场景说起:抓网页内容、查阅 GitHubAI Coding过程中,程序员最常用工具的应用场景: 获取网页和github相关内容。抓网页内容——查个文档、读篇博客、扒一段 API 说明;查阅GitHub——看某个开源仓库的源码、读一个 issue 的讨论、查仓库的目录结构。这两件事占了我日常工具调用的大头,我猜大多数程序员也差不多。先看一张图,弄清 AI 手里的工具到底是怎么来的:工具按照提供方划分顺带澄清一个常见误解:MCP 不是某一种特定的工具,而是 Model Context Protocol——模型上下文协议。凡是走这个协议被 AI 调用的服务,都叫 MCP server。我日常用的智谱 web-reader、zread、web-search-prime,以及 zai 视觉服务,属于远程 MCP。工具对 AI 模型的重要性不用多说,AI Coding 的能力天花板,一半取决于它手里能调度的工具。可问题来了——光是获取网页和查阅 GitHub这两个场景,AI 手里就有好几个工具:curl、webfetch、web-reader、zread,还有 web-search-prime。听起来挺豪华,但工具多了不一定是好事。每个工具能力不同、失败方式不同、拿到的东西甚至不是同一个东西,而 AI 选工具时能参考的只有 MCP 描述上那几行字——几行简介,远远不够支撑一个正确的决策。结果就是反复翻车。这两个场景里真实发生过的,随便举几个:让 AI 去 GitHub 拿一个 issue 的讨论,它挑了 web-reader——超时了。它不知道 web-reader 对 issue 详情页不稳(动态渲染重),正确做法是 curl 打api.github.com拿 JSON,又快又干净。让它抓一个被墙的站点(比如 linux.do),curl 直连被 GFW 拦,它直接判断网站不可达就放弃了。其实 web-reader 走云端,根本不经过本地 GFW,一试就通。让它读一个 React 单页应用,curl 拿回来一个div idroot/div空壳,它就当真以为页面没内容。其实这页面的内容全是 JS 跑出来的,curl/webfetch 不执行 JS,根本拿不到。这些不是AI 不够聪明,是它不知道该用哪个、用错了会怎样、失败了该怎么办。人也不会天生知道——这些知识是踩坑踩出来的。与其指望 AI 临场判断,不如提前给它把路指好。面对什么功能、有哪些工具可选、首选是谁、为什么选它、调用失败了按什么顺序降级——这些都写死在规则里,让它照着执行。这就是 本篇工具规则 的由来,把它放在 opencode 配置目录下的AGENTS.md,每次会话自动加载,作为全局规则。这篇文章围绕它展开:先看成果,再讲每条规则是怎么被现实一遍遍打脸、又一遍遍磨出来的。你可以直接把这份规则拿去用,也可以照着这个思路给 AI 立你自己的规矩。二、先看成果:这份 AGENTS.md 你可以直接用这份规则经过我长期使用打磨,现在覆盖三块:工具失败的处理、网页内容获取工具选择、智谱云端 MCP 并发纪律。下面是完整内容,可以直接复制进你自己的全局AGENTS.md中:---------------------------------------------------------------------------------------------------------------------------------工具失败的处理本章用于工具调用失败或超时后恢复并继续任务。通用策略(单个工具的重试):可恢复类失败(timeout / 5xx / 连接拒绝 / 429 / 1302 / rate limit)→ 先调 bash 执行 sleep 5,再以同一工具、相同参数重试 1 次,无论是否有其他冗余数据源已经成功;仍失败则不再重试,切换到功能等价的替代工具。目标找不到或工具不支持(target not found / 404 / unsupported)→ 先用工具核实目标路径/是否存在、参数和工具能力后,切换到功能等价的替代工具。禁止凭主观推断下结论。输入或本地环境错误(参数类型/格式/缺失 / 依赖未安装:command not found、module not found / 本地配置文件解析失败)→ 必须先查工具的参数定义或错误原因(参数 schema / 工具文档 / 报错信息),确认正确格式后再修正,用同一工具重试。禁止凭猜测改参数重试。网页/GitHub 获取场景必须严格按照「网页内容获取工具选择」中当前场景对应行的 ①首选→②次选→③兜底顺序降级。每个候选工具失败时,一律按第1条「通用策略」处理并执行,仍失败才换下一个降级工具。恢复路径全部失败后:必须说明已尝试的工具、各次错误类型、已采取的恢复动作及仍未验证的事项。这只表示当前恢复手段已经穷尽,不足以证明目标、网站或服务整体不可用。网页内容获取工具选择四个工具(一句话定位)工具定位curl(bash)本地(libcurl)直连(受 GFW 影响),原始 HTTP 响应(HTML/JSON/二进制),不渲染 JS,灵活性(header/代理/POST)最高webfetch(opencode 内置)本地 undici 直连(受 GFW 影响) turndown 转 markdown,不渲染 JS,它与curl同属本地直连工具,但 HTTP 栈不同;在部分 GitHub HTML 页面上,undici 代理链路可能比 libcurl 更不稳定web-reader(智谱 MCP)智谱云端部分渲染转 markdown,走智谱网络可直接访问 linux.dozread(智谱 MCP)官方文档称其基于 zread.ai 能力,返回的是 zread.ai 已收录索引后的仓库数据,非 GitHub 原始数据。zread.ai 是数据/能力来源,不是客户端连接的入口;客户端实际连接的 MCP 端点以 opencode.json 里 zread 工具的配置为准。SPA 页面(Vue/React/Angular 应用)是一个空 HTML 壳子,浏览器下载 JS bundle 后由 JS 全权接管——创建 DOM、加载数据、处理路由,一切内容都是 JS 运行时动态拼出来的。调用方式差异:curl/webfetch/web-reader→ 传 URL(任意 URL,如raw.githubusercontent.com/...、api.github.com/...);zread→ 不传 URL,传repo_namefile_path,内部自己决定怎么调 API。zread.ai 并不是覆盖所有 GitHub 开源仓库——只有被 zread.ai 收录的那些才能通过zread(智谱 MCP)访问到内容,所以当 zread 访问某个仓库失败时(MCP 三个工具全部target not found),通常表示仓库未被索引,直接用 curl GitHub API。场景速查(按优先级)场景① 首选② 次选③ 兜底理由获取整个仓库git clone——获取指定目录所有文件git clone --sparsegit sparse-checkout set 目录——仅靠git clone不行;需 sparse-checkoutGitHub issue / PR / discussionscurlzread search_docweb-reader(不稳)此环境中,webfetch访问此类动态 GitHub HTML 页面曾出现 undici 代理链路不稳GitHub 指定文件源码curlzread read_fileweb-reader(仅临时阅读)raw.githubusercontent.com/...直出原文,web-reader会转换为 markdown,不可用于精确获取、解析或校验源码GitHub 目录结构zread get_repo_structurecurl—已索引时 zread 的层级树最清晰;未索引时 curl 保底GitHub 仓库主页 / READMEweb-readerzread—此环境实测中,curl/webfetch抓取该类 HTML 页面曾持续超时(3/3);web-reader干净缓存兜底 504GitHub 巨型仓库(504)web-reader(缓存)zread(预索引)—curl/webfetch 直连都挂被墙站点(linux.do )web-reader——curl/webfetch 直连被 GFW 拦,web-reader云端不受本地 GFW,实测三层全通国内网页(SPA / JS 渲染,只需正文)web-readerPlaywright—curl/webfetch不执行 JS,拿空壳国内网页(静态)web-readerwebfetchcurl国内直连都快,转换型省 token需精确 DOM/outerHTMLPlaywright——在当前工具集中,只有 Playwright 能获取渲染后的精确 DOM自定义 header/POST/Cookiecurl——只有curl能精确控制请求GitHub URL 速查(URL 形式参考,实际工具选择以场景速查为准)你想要的URL示例备注GitHub 仓库主页 / READMEgithub.com/owner/repoIssueapi.github.com/repos/{o}/{r}/issues/{n}返回结构化 JSONPull Requestapi.github.com/repos/{o}/{r}/pulls/{n}返回结构化 JSON;含 PR 专属字段Discussionapi.github.com/graphql无 REST API;使用curlPOST GraphQL 查询指定文件源码raw.githubusercontent.com/{o}/{r}/{b}/{p}返回纯文件内容单文件元数据api.github.com/repos/owner/repo/contents/path返回 base64 编码的 JSON仓库目录结构api.github.com/repos/owner/repo/contents返回当前层级的结构化 JSON 数组文档站/博客*.github.io服务器返回静态 HTML/JS/CSS,页面仍可能是 SPA 空壳高概率踩坑(工具错配)❌ 用webfetch硬刚被墙站点或需 JS 渲染的页面:它本地直连、且不执行 JS。→ 要正文用web-reader;要渲染后的精确 DOM 用 Playwright。❌ 用web-reader/webfetch获取需要精确保真的 JSON、API 响应或原始源码:它们会转换为 markdown,不能作为原始结构化数据或源码校验的来源。→ 通用 JSON/API/原始文件用curl;仅临时阅读文本时可使用web-reader。❌ 优先直接抓github.com的 Issue / PR / 仓库 HTML 页:页面动态、体积大,此环境中webfetch的 undici 代理链路也曾不稳定。→ Issue / PR 用api.github.com;仓库文件用 GitHub API 或 raw URL。❌ 用curl/webfetch抓 SPA 后,把空壳 HTML 当作页面没有内容。→ 要文字正文用web-reader;要元素、outerHTML、computed styles 用 Playwright。❌ 把web-reader返回的 markdown 当成原始 HTML / 浏览器 DOM。→ 它适合读正文,不适合拿 HTML 结构或精确样式;后两者用 Playwright。❌ 拿zread去抓普通网页、文档站或 GitHub 以外的 URL。→zread只面向 zread.ai 已索引的 GitHub 仓库;网页内容按 URL 类型选curl、web-reader或 Playwright。❌ 把zread的结果当作 GitHub 最新源码的唯一依据。→ 需要精确、最新的文件内容时,用raw.githubusercontent.com或 GitHub API 复核。智谱云端 MCP 并发纪律zread:仅限制并发,不限制调用次数。同一时刻最多 1 个请求(不要并行发两个 zread),但连续多次串行调用完全没问题。web-reader:同一时刻最多 2 个并发调用。web-search-prime:同一时刻最多 2 个并发调用。web-reader或web-search-prime出现 1302 限流时,降低对应工具的并发后再重试。---------------------------------------------------------------------------------------------------------------------------------规则不长,但里面没有一句话是多余的——有些看上去啰嗦、甚至像是废话的地方,其实是踩了坑才补上的。后面三章讲解,我就一条条拆给你看,这些规则到底是被什么现实磨出来的。三、讲解一:工具失败的处理——为什么这么写1. 核心心法:按恢复动作分类,不是按错误码很多人写失败处理规则,第一反应是按 HTTP 状态码分流:timeout 怎么办、4xx 怎么办、5xx 怎么办。我一开始也是这么写的。但很快就被现实教做人:错误码在很多工具上根本不准。比如 zread 限流时,它不报 429,而是伪装成 timeout;很多 API 过载时返 5xx,看起来像瞬时故障,其实是服务端在拒。靠标签分流的前提是能准确区分,而这个前提在很多工具上不成立。后来我换了个思路——按恢复动作分类。不管错误码长什么样,关键是下一步该干什么,而下一步只有三种:可恢复:偶发故障或限流,没人错 → 等一下,重试同一个工具能力/定位错误:工具不支持、目标不存在 → 换工具或换目标输入/环境错误:参数传错、依赖没装、配置坏了 → 修正我这边,重试同一个工具这三类的恢复动作严格互斥:每类怎么办都唯一确定,AI 执行时不用临场归类。这就是这一章的全部追求。2. 没有一句多余逐条拆解先调 bash 执行 sleep 5—— 这是把瞬时错误和限流合二为一的关键。原来我分两条:瞬时错误立即重试、限流先降并发。但 zread 这种限流伪装成 timeout会走错路(被当成瞬时错误立即重试)。合并后,统一成先冷却 5 秒再重试,不靠错误码前置判断,靠重试结果分流。这同时消解了 zread 那个需要单独写特例的麻烦——通用流程自然把它兜住了。无论是否有其他冗余数据源已经成功—— 这句看着像废话,其实是防 AI 偷懒。并行检索时,如果 web-reader 已经拿到结果、web-search-prime 却失败了,AI 会想够用了,不重试了。这句就是堵住这个偷懒念头:失败的工具该重试就重试,别管有没有备选垫底。切换到功能等价的替代工具(网页/GitHub 场景按表降级)—— 早期版本写的是按当前场景切换工具。但当前场景是个空指针:除了网页/GitHub 有明确的降级表,其他场景(比如代码库搜索、通用文件操作)根本没有切到哪的定义。AI 读到这个词,要么迟疑、要么现场瞎猜。改成功能等价的替代工具后,动作是确定的(找个能干同样活的工具),不用先判断这是什么场景。禁止凭猜测改参数重试—— 这条是后面压力测试暴露的最大缺口补的,留到第六章细讲。3. 规则演化的四个真实案例这些案例不是凭空设计,每一个都对应一次真实的执行翻车。案例一:zread 限流伪装 timeout最早的规则里,瞬时错误和限流是分开的两条,中间我还想为 zread 写一条特例:zread 限流表现为 timeout,要按限流处理。但写着写着发现——合并成冷却重试一条通用流程后,这个特例根本不需要存在了:zread 的限流会自动走重试失败→降级这条路。这给了我一个启示:把一个需要特例处理的边界情况,变成通用流程的自然结果,规则就会更少、覆盖更全。案例二:4xx 归类冲突某一版我把4xx写进了可恢复类,同时又把404写进了能力错误类。但 404 就是 4xx——一个 API 返回 404,AI 到底该按可恢复→sleep重试还是按能力错误→换工具?而且 4xx 里大部分都是客户端确定性错误:400/422 参数错、401/403 认证错、404/410 资源不存在,重试必然失败,真正可恢复的只有 408/429。修正:把 4xx 整体移出可恢复,404 只匹配能力错误那一条,冲突消除。案例三:参数错误该归哪条有一版规则里,参数或格式不符和target not found / 404 / unsupported捆在一条,统一处理是切换工具。但参数错误的正确恢复动作是读 schema → 修参数 →重试同一个工具,跟换工具完全是两码事。把两种处理不同的错误捆一起,AI 遇到参数错误会被指示去换工具,直接走错。修正:把参数错误拆出来,和 command not found、配置解析失败合并成第三条,动作统一为修正后重试同一工具。分类依据从错误码变成了谁的问题、恢复动作是什么,这才自洽。案例四:deepwiki 重复传错参数这个案例最打脸,留到第六章压测复盘里细讲——它是禁止凭猜测改参数重试这条最硬核措辞的直接来源。四、讲解二:网页内容获取工具选择——实测出来的选型表这一章最有干货,因为每一个结论都带着实测数据。我不讲应该怎么选,只讲我是怎么把这张表实测出来的。1. 四个工具的本质差异先把四个工具的底子钉死,否则后面全是空谈:curlwebfetchweb-readerzread抓取在哪发生本地(libcurl)本地(undici)智谱云端zread.ai 预索引受 GFW 影响直连受影响直连受影响取决于智谱服务器不受影响返回形态原始响应HTML→markdown渲染后→markdown结构化(目录/文件/搜索)执行 JS否否云端部分渲染不适用适用范围任意 URL任意 URL任意 URL仅 GitHub 仓库核心分水岭一句话:curl/webfetch 是本地直连(受 GFW),web-reader 是云端(能绕墙),zread 是预索引(只管 GitHub)。2. webfetch 不是云端渲染工具很长一段时间里,我以为 webfetch 是调云端渲染服务的——因为它访问 GitHub issues 时会超时,行为和 web-reader(智谱云端)很像。我甚至把这个错误判断写进了笔记,说webfetch/web-reader 慢且不稳的根源是它要调云端渲染服务或起浏览器进程。后来逆向 opencode 源码才发现:webfetch 是本地 undici fetch 本地 turndown 转 markdown,它根本不调云端、不起浏览器、不执行 JS。它访问 GitHub issues 慢,是因为 undici 在代理隧道 HTTP/2 大响应这个组合下有个握手 bug,跟云端渲染八竿子打不着。同一份笔记里,场景速查表那一节,我明明正确写了 webfetch 不执行 JS 渲染,但本质差异那一节又说它调云端渲染服务——自相矛盾,自己打自己脸。这个错误判断遗留了很久,直到逐字对照源码才纠正过来。这说明一个写作原则:当你对一个工具的理解是从行为相似反推来的,而不是从源码/文档看来的,这种隐错会藏得很深。场景表里用对了,本质定义里却用错了,因为压根没意识到两边说的不是同一个东西。纠正的方法只有一个:回到权威源(源码/官方文档),别靠现象反推。webfetch 纠正后的准确表述是:它和 curl 同属本地直连工具,只是多了个 turndown 转换。这也解释了为什么它和 curl 一样受 GFW 影响、一样拿不到 SPA 内容。3. GitHub 三入口,加上取源码的几条路很多人把访问 GitHub当成一件事,其实它至少分三个完全不同的入口,对你的工具友好度天差地别:github.com/owner/repo:GitHub 主站的 Web 应用,服务端渲染的 HTML(正文夹在大量导航/侧栏噪音里),有反爬。这类页面体积大、动态,本地工具抓起来又慢又不稳。api.github.com:GitHub 的 REST/GraphQL API,返回干净的结构化 JSON。未认证限速 60 次/小时,认证后 5000 次/小时。这是最该用的入口。*.github.io:GitHub Pages 托管的静态站(文档站、博客),纯静态文件,干净,谁都能拿。取单个文件源码,又有几条路,容易混淆:raw.githubusercontent.com/owner/repo/branch/path:直出纯文件内容,零噪音,最快。但只能取单个文件,给目录路径会 404。api.github.com/repos/o/r/contents/path:返回 JSON,文件内容在content字段里、base64 编码,外面裹着元数据(sha/size/html_url)。既能查目录结构,也能查文件内容,但单文件 ≤1MB。api.github.com/repos/o/r/git/blobs/sha:按 Git blob 的 SHA 查,无 1MB 限制,但你得先知道 SHA。一句话总结:要数据走api.github.com,要单个文件源码走raw.githubusercontent.com,要整个仓库老老实实git clone。能走 API 就别硬刚 HTML 页——这是 GitHub 工具选择的第一原则。4. 场景速查表是怎么实测出来的这张表不是拍脑袋写的,每一行都对应一次实测。我挑几个最有戏剧性的讲。GitHub issue/PR → curl api为什么 issue 不用 web-reader?实测很清楚:web-reader 对 issue 详情页不稳——issue 详情页包含评论时间线、react、编辑历史等大量动态内容,GitHub 的 SSR 特别重。我测了两个仓库的 issue 和一个 PR,3/3 全部失败(超时或 500)。但仓库主页/README、discussions 列表这些相对轻量的页面,web-reader 又 5/5 全成功。所以GitHub 页面不能一刀切,得分详情页和列表/主页两种。详情页就老老实实用curl api.github.com拿 JSON,干净又稳。被墙站点(linux.do)→ web-reader 免 VPN这是全文最抓人的一个反转。一开始我诊断 linux.do 是DNS 污染 IP 封锁 SNI 审查三重封锁,结论是基本只能 VPN/代理。然后顺手试了一下 web-reader——成功了,而且不止连上首页,帖子列表、JSON API、具体帖子全文三层全通。为什么会这样?因为 web-reader 的抓取发生在智谱的服务器上,从智谱的网络出去访问 linux.do,这条路径根本不经过你本地的 GFW:curl/webfetch: 你(本地) ──GFW拦截──→ linux.do ❌ web-reader: 你 ──→ 智谱云端 ──→ linux.do ✅ ↑ 这段不受你本地 GFW 管控DNS 污染、IP 封锁、SNI 审查这三重封锁,全被云端这一跳绕过去了。这反过来印证了之前讨论的VPN 对 web-reader 无效的另一面:web-reader 根本不需要 VPN,它自带绕墙能力。唯一的限制是它只能拿转换后的 markdown,要登录态、自定义 header、精确 DOM 的场景还得靠代理 浏览器。SPA → 必须 web-reader 或 Playwrightcurl/webfetch 都不执行 JS,对 React/Vue 单页应用只能拿到div idroot/div空壳。要正文用 web-reader(云端渲染),要精确的 outerHTML/computed styles 只能上 Playwright 起无头浏览器——这四个工具都做不到。巨型仓库 504 → web-reader 缓存 / zread 预索引测到sst/opencode(18 万 stars)这种巨型仓库时,curl 和 webfetch 直连都撞 GitHub 服务端 504(GitHub 自己渲染超时了),只有 web-reader(靠云端缓存)和 zread(走预索引)能拿到 README。这说明有些失败根本不是你的工具或网络问题,是目标自身容量问题——这时候换思路(走缓存/预索引)比换同类工具管用。5. 高概率踩坑(反模式)表里最后那组 ❌ 不是凑数,每一条都是真实踩过或差点踩的。记住一个共同模式:工具错配的根因,都是把看起来都能抓网页的工具当成了同一个东西。webfetch 不是云端渲染,zread 只管 GitHub 仓库,web-reader 返回的 markdown 不是原始 DOM——搞清楚每个工具是什么、不是什么,选型就不会错。五、讲解三:智谱云端 MCP 并发纪律这一节最短,但教训最深:它讲的是规则的措辞本身,怎么影响 AI 的执行。翻车: zread 串行误读最早我给 zread 写的并发规则是zread:必须串行。同一时刻最多 1 个请求。字面意思其实很清楚——同一时刻最多 1 个请求就是并发度 ≤ 1,意思是别同时发两个 zread。连续发 10 个(一个个排队)完全合规。但 AI 实际跑起来,把这句话误读成了:zread 是脆弱资源,要省着用,整个会话尽量少调。具体表现就是反复内耗:zread 调过几次了就调这一次串行且调用较多——这些纠结全在它的思考过程里,根本没体现在工具结果上。以下是glm5.2展开的思考过程:事实上我回看那几次调用,zread 全部正常返回,一次都没超时。为了证伪这个误读,我让它连续 3 次串行打同一个仓库(sst/opencode),查三个不同的点。3 次全部成功,零超时、零限流。规则本意就是别同时发两个,硬被脑补成要少调,纯属自我设限。修正后的写法是:zread:仅限制并发,不限制调用次数。同一时刻最多 1 个请求(不要并行发两个 zread),但连续多次串行调用完全没问题。关键就加了仅限制并发,不限制调用次数和连续多次串行调用完全没问题——把串行 ≠ 少用钉死,反向锚定,这类过度约束就不会再发生。六、怎么验证规则真的有效:多模型交叉 数据库复盘规则写在纸上不算数,得跑起来验证。我用两种方式交叉确认。双模型交叉验证:glm-5.2 gpt-5.6 terra遇到有争议的问题(比如zread MCP 到底是不是在调用 zread.ai 的后端),我不听任一方的一面之词,而是让两个模型各自独立分析,再用实测证据去裁定。具体做法是:用 gpt-5.6 terra 做一轮详细分析,再用 glm-5.2 做二次独立分析,两边互相印证。如果两个模型结论一致,可信度大增;如果不一致,就上实测——DNS 探测、HTTP 头分析、行为对照、官方文档核对——以事实证据为准,不采信任何一方的纯推理。这套工作流的附带收获,是两个模型的体感对比。我的观察是:提示词给得准确时,两者质量差不多;提示词简单时,gpt-5.6 整体更稳一点。我个人比较喜欢 gpt-5.6 显式调用 skill 的思维链——它会明确把我要加载某个 skill写出来,这让我能看清它的决策过程。之前一直用 glm,顺着这个思维链我才发现,有一半的 skill 是无法成功调用的——如果不是看到显式调用链,这个隐患我根本察觉不到。真实压力测试:26 个任务,从数据库里复盘我编了 26 个工作任务(不是测试题,是纯工作任务,刻意不提按规则执行),让 AI 自然去完成,然后从 opencode 的本地数据库里提取完整的工具调用记录来复盘——不光看最终输出,连每一次工具调用的成败、AI 的推理过程、子代理派发了什么都扒出来看。这一测,规则的有效性暴露得很彻底。最亮的是 sleep 5 冷却重试那条。任务里有个 web-search-prime 调用报错,AI 的反应是:先调bash sleep 5(真睡 5 秒,时间戳 01:11:51 → 01:11:56 精确对上)→ 重试 1 次 → 仍失败 → 停手。它的推理原文是:slept 5 seconds, now retry → 重试失败后 → Per recovery rules, Ive retried once, still failed - I should not retry again。这条核心规则完全内化了:识别可恢复 → 真 sleep → 重试 1 次 → 失败停手。不是嘴上说等了,是真的发了 bash 调用。能力错误处理也基本正确。zread 查一个不存在的仓库报target not found,AI 没盲目重试(仓库不会因为隔 5 秒就被索引进去),直接识别为未索引仓库的确定失败模式,切换到别的工具。command not found也没重试(exit 127),识别为环境问题。这些都对。但参数错误是最大的缺口,也是禁止凭猜测改参数重试这条最硬核措辞的来源。测试里有个任务调 deepwiki,第一次参数传错了(把子路径当成了owner/repo),报错信息里明明白白写着Call MCP via /api/mcp/{owner}/{repo}——正确格式就在报错里。结果 AI 没读这个提示,换了个函数名又试了一次,传了一模一样的错误格式,再次失败。参数错误→读定义修正这条规则,在它那里形同虚设。这就是为什么规则里最终写成必须先查工具的参数定义或错误原因,确认正确格式后再修正……禁止凭猜测改参数重试——加了必须先查确认正确格式后,把读定义变成不可跳过的前置步骤,再用禁止凭猜测封死那个没查就改、改了还错的行为。规则不是设计出来的,是被这种真实翻车逼出来的。类似的,测出来还有两个小缺口:一是 404 时确认目标太含糊,AI 判断错了(以为仓库迁移,实际只是分支名main写错,应该是dev);二是重试失败后,如果有冗余源已经成功,AI 就不切换了(这其实合理,但原规则没给合法依据)。这两个缺口后来也都补进了措辞里。七、结语:给开发者的使用建议回到开头那个问题:工具这么多,该让 AI 自己判断,还是提前给它指路?我的实践给出的答案是:提前指路 临场判断。AI 选工具时能参考的信息太少(几行简介),指望它临场做对决策不现实。把面对什么功能、首选哪个工具、失败了怎么降级写成确定规则,让它照着执行,效果立竿见影——至少 sleep 5 冷却重试那条,在压力测试里是真真切切被严格执行了的。AGENTS.md 是软约束,不是硬编码逻辑。它会自动加载、会被 AI 参考、能大幅降低犯错概率,但不能保证每次都执行到位——参数错误那条在测试里就被跳过了。规则降低犯错概率,不归零。如果你想直接用,这份 AGENTS.md可以直接复制进你的配置目录。按你的环境实测调整。规则里有不少结论是带时效性的环境实测(比如curl 抓 GitHub 仓库主页 3/3 超时),换了网络环境可能不一样我是国内环境,wsl中opencodeomo核心一句话:让 AI 选对工具的关键,不是给它更多工具,而是给它更清晰的规矩。希望这份规则和这些踩坑经验,能帮你在 AI Coding 里少走点弯路。

相关新闻

最新新闻

日新闻

周新闻

月新闻