AI 答非所问,多半是上下文给错了——我在 wescode 里的几个提问习惯

0 阅读6分钟

@TOC


同一个模型,同一个项目,我和同事问出来的结果经常差很远。

一开始我以为是提示词写得不够好,后来发现关系不大。真正的差别在于:AI 手里有哪些材料。它看到的代码不对,问题描述得再精确也没用。

这篇记一下我在 wescode 里用了一段时间总结的几个习惯,以及踩过的坑。都是很小的事,但对结果影响比改提示词大得多。


一、别让它猜要看哪个文件

最常见的浪费是这样的:

CreateOrder 这个函数有什么问题?」

项目里叫 CreateOrder 的可能不止一个,就算只有一个,AI 也得先去找。找的过程有概率出错,尤其是名字比较通用的时候。

我现在的习惯是在 wescode 的 Chat 里用 @ 明确指定:

@order_service.go 里的 CreateOrder,参数校验部分有什么问题

或者直接引用符号:

@CreateOrder 这个函数的错误处理和项目里其他地方一致吗

@ 后面可以跟文件、文件夹、符号。我用得最多的是符号引用——不用记文件在哪,打函数名就行。

这个习惯带来的差别比想象中大。以前我经常遇到 AI 分析了半天,最后发现它看的是另一个同名函数。指定之后基本不会了。


二、选中代码再按 Cmd+L

@ 更省事的办法:在编辑器里选中那段代码,然后按 Cmd+L 打开 wescode 的 Chat 面板。选中的内容会自动进上下文,不用手动引用。

这个我用来问局部逻辑特别顺手。看到一段不明白的代码,选中,Cmd+L,「这段在干什么」,比先想清楚它在哪个文件、再打 @ 快得多。

要问某几行的话,@ 还支持带行号范围:

@payment.go:120-180 这段的事务边界对吗

改 bug 时我会用这个——把可疑的那一段圈出来,而不是把整个文件扔过去。


三、一个会话只聊一件事

这条是我踩坑之后才养成的。

早期我习惯开一个 Chat 一直聊,从早上聊到下午。结果是后面的回答越来越飘——问 A 模块的事,它会扯到上午讨论过的 B 模块。

原因是上下文窗口有限。会话长到一定程度,早期内容会被压缩或丢弃,而残留的片段又会干扰当前问题。

上下文窗口里各部分的占用

现在我换了个话题就在 wescode 里按 Ctrl+Shift+L 新开会话。判断标准很简单:如果新问题和上一个问题不需要共享背景,就新开。

顺带一提,这也是省 token 的办法。长会话每次请求都要把历史带上,成本是累加的。


四、用 @git 做提交前自检

这个是我最近才用上的,效果不错。

提交之前,在 wescode 的 Chat 里引用未提交的变更:

@git:changes 帮我看下这次改动有没有遗漏的地方

它能看到 diff,也能看到这些改动涉及的调用关系。我用它抓到过两次问题:一次是改了函数签名但漏了一个通过接口调用的地方,一次是改了返回值语义但没更新注释。

这不能替代 code review——它不知道业务上对不对。但作为提交前扫一眼的工具,比自己盯着 diff 看强,尤其是改动分散在好几个文件的时候。


五、把项目约定告诉它一次

wescode 有记忆功能,可以让它记住一些项目约定,之后不用每次重复。

我存进去的大多是这类:

  • 这个项目的错误一律用 errors.Wrap,不用 fmt.Errorf
  • HTTP handler 统一 Handle 开头
  • 数据库操作必须在事务里

存了之后,它生成代码时会遵守,不用我每次在提示词里强调。

但有一点要注意:记忆是按工作区隔离的。 你在 A 项目里存的约定,切到 B 项目不会生效。

我一开始觉得这是个缺陷,后来想明白了——不同项目的约定本来就不一样,串了才是灾难。B 项目用 fmt.Errorf,A 项目的记忆跑过去反而添乱。知道这个设计,就不会奇怪为什么换了项目它「忘了」。


六、几个坑

@ 整个大文件夹

@internal/ 这种引用,在包多的项目里会塞进来一大堆无关内容,把真正相关的部分挤出上下文窗口。我试过一次,结果还不如只引用两个相关文件。

引用的范围应该刚好覆盖问题,不是越多越好。

索引没跑完时的回答要打折

刚打开项目或者刚切完分支,索引还在更新,这时候涉及调用关系的问题会答不全。等状态栏安静下来再问。

它不知道「为什么」

结构上的问题它能答,历史原因答不了。那段看起来多余的判断可能是三年前踩坑加的,答案在 git blame 里。我现在的习惯是:结构问它,历史问 git。

大文件的未保存修改看不到

超过一定体积(1MB 左右)的文件不做内容同步,改了没保存的话 AI 读到的是旧版本。正常代码文件不会这么大,但生成的数据文件要注意。


七、这些习惯什么时候没用

写全新代码的时候。 没有存量上下文要管理,直接描述需求就行,@ 引用反而多余。

问通用知识的时候。 「Go 的 context 怎么用」这种问题和你的项目无关,给不给上下文都一样。

项目很小的时候。 几个文件的项目,AI 全读一遍也不费劲,精确引用的收益不明显。

这些技巧的价值和项目规模正相关。文件越多、调用关系越复杂,「给对材料」的重要性越高。


小结

用 wescode 写了一段时间代码之后,我的感受是:大部分「AI 不好用」的情况,问题不在模型,在于给它的材料不对。

同样一句「帮我看看这个函数有什么问题」,它手里有精确的目标代码和调用关系时,给出的东西是能用的;材料不对的时候,回答听起来很专业,但基本是废话。

这几个习惯说白了就一件事:明确告诉它看哪儿,别让它猜。 花两秒钟打个 @,比事后花十分钟辨别它的回答靠不靠谱划算。

文中的 @ 引用、会话隔离和记忆分层都是 wescode 里的功能,官网是 weisyn.com。你们平时怎么给 AI 组织上下文,有什么好习惯,欢迎评论区交流。