遇到报错随手复制粘贴丢给 AI是这半年我在各种群里看到最多、也最容易被翻车的排障方式。我的态度很明确不是 AI 不行而是你丢过去的仅仅是报错文本AI 真正需要的是排障上下文——代码、环境、操作路径、期望结果、已经尝试过的方案。信息越少模型越倾向于猜一个看起来很有道理的答案而不是真的帮你定位问题。本文就用我自己实际维护项目和帮别人排障的经验把正确的排障上下文长什么样这件事彻底讲清楚。1. 报错文本是给带着背景的人看的而 AI 没有你的背景1.1 报错的本质是症状摘要不是问题本体先想一个问题报错信息是谁写的是程序运行时在执行现场打印的一段文本。它天然假设读的人了解程序逻辑、数据结构、调用链、环境配置。比如 MySQL 的 1064 报错它只告诉你语法错误在第 X 行附近至于这句 SQL 是怎么拼接出来的、表结构什么样、用的是哪个版本的 MySQL它一概不管。更极端的例子是 Android 开发里那个经典的java.lang.RuntimeException: start failed.MediaRecorder 启动失败报错就这一句话既不告诉你权限问题、编码格式问题、还是文件路径问题。你拿着这句话去问 AI它能做的只有把所有可能原因列一遍这和你 Google 搜到的结果没区别。把报错直接丢给 AI 的第一个问题就在这里你把症状摘要当成了问题本体希望 AI 从一块拼图里还原整个图景。可这块拼图本来就是给已经握着其他拼图的人看的线索你手头有项目代码、有环境信息、有操作步骤AI 一个都没有。1.2 信息不足时大模型会启动最大似然补全为什么 AI 面对残缺的信息时给出的答案经常是一堆正确的废话这要从大模型的生成机制说起。大模型本质是一个极其擅长续写的系统它根据你给出的所有历史 token去预测下一个最可能的 token。当你提供的上下文不足时它会选择置信度最高的、统计上最常见的修复路径而不是事实上的那个原因。我举一个特别直观的例子你贴一个link.exe not found给 AI它十有八九会先告诉你安装 Visual Studio Build Tools或者检查 C 环境变量。这个建议对吗对的因为大量 Windows 构建报错确实源于工具链缺失。但如果你已经装了 VS Build Tools问题还在那这个答案就让你白折腾半小时。AI 不是在骗你它只是在你没给它足够信息时启动了一个通用的模板化修复——这在数学上叫最大似然估计在实际排障里叫猜。这和医生看诊是一个道理。你只跟医生说我头疼他只能给你开点止痛药或者让你去拍个 CT。但你告诉他我头疼三天了每天下午疼左边太阳穴跳着痛最近没睡好没有恶心呕吐他就能把范围缩小到紧张性头痛还是偏头痛。报错诊断同理输入的信息密度直接决定输出的精准度。1.3 三种常见的报错搬运工你是哪一种我把平时在群里、在工位上、在技术论坛里看到的提问方式分成三类对号入座一下只贴一行党报错全文有几十行堆栈他只挑中间那一行拷出来连什么语言、什么框架都不说就问这是什么原因。AI 只能从那一行字里猜个大概回答自然泛泛而谈。整屏堆栈党把终端里几百行红色堆栈全部复制出来粘贴进去包括其他无关服务的日志、编译器的内部输出但没有任何一句说明。AI 被海量无关信息淹没反而抓不住关键的那一两行。无场景党贴了报错全文但完全不说自己在做什么操作、项目是什么类型、代码长什么样。比如贴一个 JavaScript 运行时错误但不说这是浏览器环境还是 Node 环境是点击按钮触发的还是页面加载时触发的。这三种搬运方式的核心问题都一样你把排障的现象给了 AI却把背景全都留在自己脑子里。你觉得有些背景不用说也应该知道但 AI 对你的项目一无所知。它又不好意思告诉你它不知道于是只能给一堆所有场景下都成立的车轱辘话。2. 排障上下文的三根支柱环境、动作、现象外加一个好结果2.1 AI 需要的是复现你脑子里的推理链排障这件事很多人以为难的是一开始的那一下灵光一闪但真正有经验的工程师都知道难的是把问题复现出来。你自己排障时脑子里其实有一条隐性的推理链这个报错是最近改代码之后才出现的还是很久以前就有本地没报错上了 Docker 才报错说明环境有差异。报错里提到的那张表最近有个字段被改过类型会不会是这里不匹配这些隐性知识在你的脑子里运转得很自然所以你总觉得我已经把问题说清楚了呀。但对 AI 来说它没有你的记忆它每次都是第一次见到这个项目、这份代码、这段报错。你要做的是把你脑内那条推理链用文字外化出来让它能顺着你的线索往前走。我把外化需要的内容归纳成了三个图层环境层、动作层、现象层。三个图层各管一段缺一个都可能让排查方向跑偏。2.2 环境层版本、运行方式、数据状态环境信息是排障上下文里最容易被忽略、又最常导致答非所问的部分。同样是ModuleNotFoundError: No module named requestsPython 2.7 的环境里可能涉及 pip 和系统 Python 的关系问题Python 3.11 的环境里可能是虚拟环境没激活也可能是 pyproject.toml 没配置好。你不说版本AI 只能都列一遍。具体要交代哪些环境信息我的习惯是语言运行时版本比如 Python 3.11.5、Node 18.17、Java 17。框架和依赖版本比如 Django 4.2、Vue 3.4、某个关键 npm 依赖的版本号。运行方式本地命令行、Docker 容器、K8s 集群、还是生产服务器不同运行方式的差异非常大很多报错只出现在容器里因为镜像里的底层库和你本机不一样。数据状态表里有没有数数据是正常业务数据还是测试脏数据比如你跑一个报表查询报错如果数据库里恰好是空表有些 JOIN 逻辑就会触发空指针这都是环境的一部分。尤其是生产环境报错这件事很多人只说生产上挂了但其实生产环境的镜像版本、配置参数、数据量级和本地可能天差地别。你把这些补上AI 才可能意识到哦问题可能出在数据量太大导致的超时/内存溢出而不是只盯着代码看。2.3 动作层触发路径和复现步骤动作层解决的是这个报错是怎么蹦出来的。同样一段代码你是刚启动就报还是点了一个按钮才报还是定时任务跑到凌晨三点才报背后往往是完全不同的问题。我在写排障上下文的时候会尽量写下这样的操作序列我先执行了什么命令/什么操作然后用什么数据去调用了哪个接口/页面大概在什么位置、什么输入条件下报错出现了。这里我想重点强调复现步骤的价值。很多人觉得我按流程操作就有这个报错不用写那么细但你忘了 AI 没法替你操作它只能根据你描述的操作路径去理解触发条件。举个例子你贴一个 React 报错如果你补一句这个警告只在页面第二次进入时才出现首次进入完全正常AI 立刻就会往副作用没有清理依赖数组写错这两个方向收窄如果你什么都不说它就只能把 React 生命周期讲一遍。最理想的情况是你能给出一个最小复现步骤。哪怕只是把 A 组件的 useEffect 删掉就不报错这样一句都是一个非常强力的线索。AI 做诊断本质上是在做排除法你的每一个正反实验结果都会帮它砍掉一整片错误候选区。2.4 现象层与期望结果AI 需要知道合格的定义现象层听起来简单就是报错本身但很多人在这一步栽了跟头。我强烈建议贴完整报错不要只贴最后一行或者第一行。堆栈信息里往往藏着函数调用关系比如 JavaScript 的调用栈会告诉你报错是从哪个函数传导过来的这对定位很有帮助。除了报错文字还要描述程序的实际表现。是崩溃了界面卡死接口返回超时还是没有任何响应这些行为特征有时候比报错文字更关键。说出你期望的结果。这一条被我放在最后却可能是最重要的。你期望的是这个查询应该返回 10 条记录但实际它报错了AI 就盯着报错本身修修到最后语法对了返回数量不对你才发现根本没对齐过目标。在提问里明说我期望 XX但现在的结果是 XXAI 才知道自己修的东西是否真正满足你的验收标准。我还用一个很粗鲁但有效的标准判断自己写的上下文是否合格把这段话发给一个没看过你代码的同事他能不能仅凭这段话就明白你在做什么、卡在哪、需要什么样的帮助如果不能说明某些关键背景还在你脑子里没落到文字上。3. 我一直在用的排障上下文模板字段、示例和裁剪原则3.1 一套可以直接抄走的通用模板先声明下面这个模板是我自己在踩过无数次坑之后固定下来的格式它不一定每个字段都必需但绝大多数定位型问题都够用。你可以直接复制到自己笔记软件里每次排障就照着填。## 问题现象 报错原文完整堆栈或核心报错片段不要只贴一行具体报错代码## 触发路径 1. 我先做了……如启动服务、执行某条命令、点击某个按钮 2. 然后……具体操作步骤 3. 报错出现在……哪个页面/接口/命令 ## 相关代码 贴最关键的一段代码片段控制在 50 行以内。不要把整个文件丢进来。 ## 环境信息 - 语言/框架版本如 Python 3.11.5 / FastAPI 0.100 - 关键依赖版本如 SQLAlchemy 2.0.21 - 运行方式本地 / Docker / 生产 - 数据库或其他外部服务MySQL 8.0 / Redis 7.0 ## 已经尝试过 1. 重启服务 —— 无效 2. 清理缓存 —— 无效 3. 回滚到上个版本 —— 依旧报错 ## 期望结果 vs 实际结果 - 期望这个接口应该返回正常的 JSON 数据而不是 500 - 实际接口 500报错指向某一行代码3.2 模板里每个字段为什么存在已经尝试过这一栏是我后来才加上去的加的起因是某次排障时AI 连续给了我三个我已经验证过无效的方案让我瞬间血压升高。从那以后我就明白了AI 没有你的试验记录你不说试过什么它就只能把它知识库里最常规的招数重新推荐一遍。排障是排除法的游戏你预先排掉几个方向AI 就能在剩下的方向上集中火力。相关代码一栏也有讲究不要贴整个文件。原因很简单大模型的注意力是有限的你贴 500 行代码进去报错相关的逻辑可能只占 20 行模型还得花力气在无关代码里寻找线索——它既然没有你的背景它甚至可能被无关代码带偏。我见过一个哥们儿把整个 service 类几百行全贴进去AI 分析了一整页之后说问题可能出在 XX 方法结果他一看那个方法他根本没调用过。触发路径的作用是给 AI 一个时间顺序。报错往往不是一个瞬间动作产生的而是某个执行线路走到了尽头才爆出来的。比如构建工具的报错往往不是你自己写的代码有问题而是构建步骤里某个前置任务挂了导致下一步拿到了空值。把操作顺序讲清楚AI 才能理解报错出现在整个链路的哪个环节。3.3 上下文太长怎么办先收敛再投喂有人会问我的项目很复杂代码也长我总不能把所有相关的都整理一遍吧这就是上下文工程的核心问题了。我的做法是用一句话说清楚优先级投喂的价值排序是报错原文和触发路径 关键代码切片 环境版本信息 无关服务的日志。如果上下文实在庞大你可以先只投喂报错原文 一句触发动作然后明确告诉 AI我先给你这些如果你需要更多信息请告诉我你需要什么。让模型自己来问你缺什么比你盲目贴一大堆资料高效得多。这也是反向提问技巧的一种后面第 5 节我会专门讲。4. 同样一个报错低上下文和高上下文的答案差距有多大4.1 MySQL 1064从通用检查清单到直接定位MySQL 1064 是语法错误提示也是被问得最多的一类报错。我们先看一个低上下文的问法为什么报错 ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ) at line 7这种问法AI 最可能给出的回复是检查 SQL 里的引号是否闭合。检查逗号、括号是否多写或少写。看看是不是用了 MySQL 不支持的函数。把 SQL 分段执行定位到具体片段。这些建议全是正确的但你要拿去一根根排查很可能要花上半小时。而且如果这是嵌套得很深的动态 SQL你根本不知道从哪下手。再看一个高上下文的问法执行下面这段 INSERT 时报了 MySQL 1064说第 7 行附近有语法错误。 我怀疑是 items 字段里嵌套 JSON_ARRAY 的写法不对因为同样的写法在我同事的 MySQL 5.7 上能过我这边是 MySQL 8.0。 SQL INSERT INTO orders (order_no, user_id, items, total) VALUES (NO123, 42, (SELECT JSON_ARRAY(JSON_OBJECT(sku, A1, qty, 2))), 399.00); 表结构 orders(id bigint, order_no varchar(32), user_id bigint, items json, total decimal(10,2)) 请帮我看看是不是括号层级不匹配或者 8.0 对子查询作为 JSON 类型赋值有什么限制。这个问法里包含了报错原文、SQL、表结构、环境版本、我的怀疑方向。AI 几乎会直接告诉你错误大概率在第 3 行的子查询外层多了一个右括号——SQL 里(SELECT JSON_ARRAY(...))外面本来不该再有括号MySQL 8.0 在解析赋值语句时对这种多余的括号层级处理得比 5.7 严格所以 5.7 能过、8.0 报错。这段话同时验证了版本差异、给出了正确写法。同样一个 1064低上下文是全网通用语法排查清单高上下文是直接告诉你第几行哪里错了以及为什么。差别不在 AI 的能力而在你给的上下文的质量。4.2 React Cannot update a component while rendering a different component 的两个问法再举一个 JavaScript 运行时报错的场景。这个报错看起来挺吓人实际原因是在 React 渲染过程中某个组件更新了另一个组件的状态。低上下文的问法就是直接贴这句话AI 会给你解释 React 渲染机制、state 更新时机甚至贴一段官方文档的翻译。你听完还是不知道怎么改。高上下文问法是React 项目版本 18.2。报错Cannot update a component while rendering a different component. 在 Dashboard 组件里我写了这样一段代码删减版 function Dashboard() { const [profile, setProfile] useState(null); if (!profile) { setProfile(fetchLocalProfile()); // 我在这里直接调用了 setState } return MainView profile{profile} /; } 问题我希望组件首次渲染时如果有缓存数据就直接读取并展示。触发时报这个警告。 期望应该是正常展示 profile 数据不出现更新警告。 请问正确写法是什么应该用 useState 的初始值参数、useEffect、还是 useMemo看到没有这个问法里已经把我做了什么导致报错写清楚了。AI 就能直接告诉你不该在渲染过程中调用setState正确做法是把初始数据放到useState(fetchLocalProfile())的初始化参数里或者用useEffect在挂载后设置。这个答案不用你去翻 React 文档也不用反复折腾试错。还有你让它在 useEffect、useMemo、初始化参数三个方案里选一个它给出的建议会更贴合你的具体场景。4.3 什么时候真可以直接丢报错确认型问题 vs 定位型问题那么问题来了是不是所有报错都要写一份长上下文不是。我一般会先把问题分成两类确认型问题我知道问题是什么只是想确认一下解法。比如ModuleNotFoundError: No module named requests这种一眼就能看出答案的直接丢报错没问题。AI 说pip install requests你就装呗这个场景不需要什么上下文。定位型问题我只知道报错内容但不知道根因是什么需要 AI 帮我找到问题所在。比如 Tauri 在 Windows 上报link.exe not found你可能已经装了 VS Build Tools但构建时 npm 脚本里的环境变量没有正确传递导致链接器找不到。这种情况你必须告诉 AI我已经装了 Build Tools、命令行里 cl.exe 能跑、但 tauri build 还是报错否则它永远会从建议你安装工具链开始把你逼到崩溃。判断标准很简单如果你能预判 AI 的回答就是某个固定动作比如修一下这里装一下依赖那直接丢报错没问题。如果它的正确解答高度依赖你的项目环境、运行方式、已经做过的尝试那就必须老老实实把上下文补齐。5. 上下文工程里最容易踩的四个暗坑5.1 上下文污染旧话题会让模型串味很多人忽略了上下文污染这件事。大模型对话是连续的你在这个会话里先聊了半小时无关话题比如某个 CSS 动画怎么做、某道菜怎么做然后突然贴一段报错进去模型在理解报错时它的注意力会分散到前面的历史内容里。它甚至会试图在旧话题里找关联比如把报错往你刚才说的某个插件上靠。我的习惯是排障问题一律新开一个会话。如果实在想沿用某个会话至少在最前面加一句以上对话结束下面的内容是一个独立的新问题让模型明确切换语境。这种一行字的成本几乎为零收益却很实在。5.2 低估了已经做过什么的信息价值前面提过已经尝试过字段但我觉得值得单独再说一次。做排障的时候很多人是这么描述自己的尝试的我试过重启服务了也清过缓存都没解决。就这一句话对 AI 的排障效率提升是巨大的。因为重启和清缓存恰恰是它最常用的两个建议你把这两个方向明确关闭了它就只能往更深的方向走。反过来如果你不说AI 把重启试试排在第一位你看到这答案时的心情基本等于在排障路上白跑了一个来回。我甚至见过一种高级玩法在排障前先把自己能做的实验全部做一遍比如我把 A 注释掉问题消失把 B 注释掉问题还在然后把这两个结论一起给 AI。这种正反实验数据是排障上下文里最有价值的线索比任何提示词咒语都有用。5.3 1M 上下文不是让你整库投喂现在很多大模型都在宣传超长上下文比如 1M token 的窗口听起来好像可以把整个项目丢进去。但窗口大不等于效果好这是我的亲身感受。长上下文的注意力分配是有限的你塞进去 1M token真正跟报错有关的可能只有几千 token模型想要精准定位难度反而更大。上下文工程的核心原则是在有限的信息里把高价值信息放在最显眼的位置。具体到排障就是把报错原文放最前面代码切片放其次环境信息和日志放在最后。不要觉得反正窗口够大乱塞也没关系信息的价值密度才是决定 AI 输出质量的关键。5.4 忘了让 AI 先复述问题来校验上下文最后这个技巧是我用了很久才发现特别管用的一招。发完一段排障上下文之后不要急着让它给方案而是先加一句先不要给我解决方案。你先用自己的话复述一遍我遇到的问题包括报错出现的位置、 我尝试过的方案、我的期望结果。如果你觉得信息还不够请列出你还需要什么。这一步有三个作用第一你可以快速判断 AI 有没有读懂你的上下文。如果它复述错了比如把生产环境理解成本地环境那你现在补正还来得及而不是等它给出一大篇错误方向的分析后才发现理解有偏差。第二它会在复述时自然地梳理线索很多原本潜伏在描述里的信息会自动浮现。这就像你给新同事讲了一遍问题讲着讲着你自己就能发现问题出在哪了。第三让 AI 主动索取信息比你自己猜测它需要什么信息要精准得多。有时候你觉得自己上下文给得很全了但它一复述你马上发现漏了某个版本号或者某条命令的参数。还有一个连带的好处这招能把 AI 从急于给答案的模式里拉出来。你见过 AI 在信息不足时强行给方案的样子吗它有时候会特别笃定地给一个错误猜测整个分析过程看起来天衣无缝实际上第一步就错了。让它先复述它就可能说我注意到这里信息不足从而避免硬猜。6. 养成先写上下文再求助的习惯之后排障速度反而更快了最后我想聊点真心话。一开始我也嫌麻烦报错都贴过去了还要写触发路径、环境版本、已经试过什么这不耽误事吗但坚持了一年多之后我发现这个习惯真正的价值不是让 AI 回答得更准而是让我自己的排障速度变快了。原因很有意思就是那个著名的橡皮鸭效应——你把问题用文字写清楚的过程本身就是在重新审视它。很多时候我打开模板准备填触发路径那一栏写到我执行了 A 命令然后 B然后……的时候突然就想起来了A 命令之前我改过一个配置那个配置正是这次报错的起点。问题根本不需要问 AI我自己写着写着就找到了。所以我现在的工作流变成遇到报错先花 30 秒到一分钟把上下文按模板梳理好先不着急发给 AI自己读一遍。如果还没想通再发给 AI。现在 AI 收到的是干净、完整、有条理的信息它给出的方案也几乎不用二次加工就能落地。填模板的 30 秒买回来的是一个下午的试错时间。这个账怎么算都划算。希望看完这篇的你下次再遇到报错能先把上下文准备好再去找 AI。你会发现AI 在你手里的排障能力可能直接翻了一倍。