乐于分享
好东西不私藏

AI编程的最小原理——知道边界在哪里

AI编程的最小原理——知道边界在哪里

各位好,今天想和大家聊一个我自己想了很久的问题——

CodeX或者说AI编程工具,它的边界到底在哪里?

这个问题其实一直戳在我心里。说实话,我自己用CodeX也有一段时间了,从一开始的"哇这也太强了"到后来的"等等,这个bug哪来的",中间踩过的坑可能比写过的代码还多。

后来我慢慢意识到一个道理:AI编程工具的强大,是有边界的。知道这个边界在哪,比知道它能做什么更重要。

今天我读完《Codex快速入门:Harness工程落地》这本书有了深刻的感想,就是把我自己这段时间的思考和踩过的坑,完完整整地聊聊。可能有点碎碎念,还请见谅!!!

一、大模型为什么能处理代码?

在聊边界之前,我们可以先搞清楚一件事:大模型为什么能帮我们写代码?

很多人可能觉得"因为它懂代码"。但说实话,这个说法可能不太准确。

更准确的说法是:大模型本质上是一个超级强大的"模式匹配器"。

它见过的代码太多了——GitHub上几十亿行的代码、Stack Overflow上无数的问答、无数的教程文档。这些代码经过海量训练之后,模型学会的不是"编程的原理",而是"代码长什么样"。

所以当你让CodeX写一个登录函数的时候,它并不是真的理解"什么是认证"、"为什么要用JWT"、"session和token有什么区别"。

它只是在匹配模式:当你输入"登录函数"的时候,它知道在这个语境下,应该生成一段包含"username"、"password"、"login"这些关键词的代码。

听起来好像挺low的对不对?但架不住它见过的代码太多了,多到足以cover大部分常见场景。

这就像你问一个看过无数小说的人:"主角和反派吵架了,接下来会怎么发展?"——他可能说不出具体原理,但他能给你编出一个看起来很合理的故事。

这就是为什么CodeX在处理"标准问题"的时候特别强——因为这些问题的代码模式已经被训练得很充分了。

但一旦遇到"非标准问题",尤其是和你的具体项目深度绑定的需求,它就开始力不从心了。

比如说,你们公司有一个祖传的支付模块,逻辑绕得跟山路十八弯似的。这种代码,全世界可能就你们公司在用,模型根本没见过的这种情况下,CodeX写出来的东西大概率是一塌糊涂。

所以,总结一句话:大模型会写代码,是因为它见过太多代码,而不是因为它真的懂编程。

CodeX的工作机制——上下文与闭环

二、CodeX完成任务时,到底依赖什么?

好了,现在我们进入正题。

我自己在踩坑的过程中,慢慢总结出了CodeX完成任务的四个核心依赖。这四个依赖,就好像是CodeX的四条腿,缺了任何一条,它都走不稳。

上下文——决定此刻CodeX"看到"什么

这是最最关键的一点。

CodeX不是全知的。它只能看到你当前给它的上下文。

你可能会说:"不对啊,我把整个项目都放进去了,它应该能看到所有文件才对。"

但实际情况是:放进去了 ≠ 它真的看到了

每个模型都有自己的上下文窗口限制。你可以理解为,CodeX的"视野"是有限的,就那么大一块地方。当你的项目文件很多、很大的时候,CodeX不可能在一次对话里看到所有内容。

它只能看到:

  • 你当前打开的文件
  • 你最近几次对话的内容
  • 它自己记住的一些"工作记忆"

所以你给它的上下文质量,直接决定了它输出的质量。

怎么说呢,这就像你和一个人聊天:

如果你只说"帮我改改这个功能",对方肯定一脸懵。但如果你是这么说的:

"这个功能在 src/pages/user.tsx 里,是用来处理用户登录的,登录逻辑在 src/utils/auth.ts 中,用的是JWT token……"

你看,换成是你,后者你也更容易理解对不对?

CodeX也一样。你描述得越清楚,它理解得越准确。

我有一个特别形象的比喻:CodeX就像是一个有着严重"短时记忆障碍"的同事。你跟他说的事儿,他只能记住最近的几句,之前的对话内容他很快就忘了。

所以每次开始新任务之前,我都习惯性地先把背景交代清楚,而不是假设他什么都记得。

文件读取和检索——帮CodeX补足项目背景

既然上下文这么重要,那我们怎么让CodeX"看到"更多呢?

主要有两种方式:

方式一:让它自己读

你可以直接让CodeX去读取某个文件:

"帮我读一下 src/utils/auth.ts,然后告诉我它提供了哪些方法。"

这样CodeX就会把那个文件的内容加载到当前上下文中,后续的对话就能基于这些内容展开了。

方式二:让它去找

CodeX还有一些内置的检索能力,可以帮你找到和某个概念相关的代码。

比如你可以说:

"帮我找到所有和用户认证相关的代码"

它会尝试理解你的意图,去搜索相关的文件。

但这里有个坑我踩过:检索的质量取决于你问的方式。

你问"用户认证",它可能找不到。但你问"login相关的代码",它可能就找到了。

所以怎么说呢,学会怎么问问题,其实也是用好CodeX的一门学问。这不是CodeX的问题,是你的描述方式的问题。

执行反馈——让生成进入工程闭环

CodeX写出来的代码,到底对不对?

光靠"看起来对"是不够的,必须跑起来才知道。

这就是执行反馈的价值。

当你让CodeX写完代码之后,你应该:

  1. 运行测试
  2. 跑一下构建
  3. 实际用一用

如果报错了,把错误信息贴给CodeX,让它修复。

这个过程,其实就是让CodeX进入工程闭环

它的生成 → 你的执行 → 报错反馈 → 它的修复 → 你的验证

这个闭环越紧密,CodeX的输出质量就越高。

我自己的习惯是:每次让CodeX写完代码,第一件事就是跑测试。如果测试过了,我才放心往下走。如果测试没过,我直接把错误信息粘给它,让它根据真实反馈来修复。

这个感觉就像是,你让一个新来的实习生写了一份报告,不能光看他的自我感觉良好,得实际看看有没有错别字、格式对不对、内容通不通顺。

能力再强,也不能替代正确的上下文

这一条是我踩了无数坑之后才意识到的。

CodeX的能力再强,也弥补不了上下文的缺失。

你不能指望CodeX"凭感觉"去猜你的项目结构、你的编码规范、你的业务逻辑。

它不是读心者。你不告诉它,它就不知道。

这听起来好像是一句废话,但我见过太多人用CodeX的时候,完全不注重上下文的构建,然后抱怨CodeX不够智能。

不是CodeX不够智能,是你没给它足够的上下文。

怎么说呢,这就好像你让一个天才去翻译一篇文章,你把原文藏起来不让他看,你指望他能翻译准确?不可能的。


三、信息永远不完整——CodeX的"盲区"

说完了依赖,我们再来说说CodeX的"盲区"。

我自己的总结是:信息永远不完整,这是CodeX最大的挑战。

具体来说,有三种情况最容易出现信息缺失:

代码没有明示的关系

很多代码里的隐含依赖,CodeX是看不到的。

比如说:

// userService.tsexportfunctioncreateUser(name: string{return db.query('INSERT INTO users VALUES (?)', [name]);}

这里有个隐含的依赖:db对象。这个db是从哪来的?可能在文件顶部import了,可能是个全局变量,也可能是在测试mock里注入的。

CodeX在生成新代码的时候,可能根本不知道这个db的存在方式。

它可能生成这样的代码:

// userService.test.tstest('createUser'async () => {const result = await createUser('John');// 假设这里要mock数据库// 但CodeX可能不知道应该mock哪个db实例});

你说这种情况常见不常见?真的太常见了。

我之前就踩过这个坑。CodeX帮我写了一个测试用例,运行时才发现它根本不知道我的数据库是mock的,每次测试都在实际操作真实的数据库。

后来我学乖了:让CodeX写代码之前,先让它了解相关的依赖关系,而不是假设它什么都知道。

信息会在长任务中变形

当一个任务很长、跨越很多轮对话的时候,CodeX对项目整体的理解会逐渐"失真"。

一开始它可能还记得你的项目结构。但随着对话轮数增加,上下文窗口被新内容填满,早期的信息就会被"挤出"。

这就像你和一个新同事合作,第一天他什么都记得清清楚楚,但到了第十天,他可能连你姓什么都开始搞混了。

不是因为它变笨了,而是因为早期的上下文信息已经被后来的内容覆盖了。

我有一个特别好的比喻:上下文窗口就像是一张桌子,桌上的东西越来越多,早期放上去的东西就会被挤掉。

怎么解决这个问题?我的经验是:

  1. 每个大任务开始之前,重新交代一遍项目背景
  2. 不要让对话持续太长,感觉CodeX"开始犯迷糊"了就重新开始
  3. 重要的上下文信息,用文件的形式固定下来,而不是只靠对话传递

项目结构决定上下文质量

这个可能是最关键的一点。

如果你的项目结构混乱,CodeX的上下文质量就不会好。

比如说你的文件命名不规范,这个文件叫util.js,那个叫helper.ts,还有一个叫tools.ts,CodeX根本不知道它们之间的关系。

又比如说你的代码没有清晰的层次,所有逻辑都堆在一个大文件里,CodeX也不知道该从哪里切入。

好的项目结构,本身就是好的上下文。

这就好比你整理好你的房间,别人来你家做客的时候,才知道什么东西放在哪里。反过来,如果你家乱七八糟,找个东西都得翻半天。

我自己在实践中发现,把项目结构整理清楚,是让CodeX发挥最大价值的前提。这个功夫花得值,后面用它的时候效率能翻倍。

CodeX的三大盲区——信息不完整的三种场景

四、CodeX会犯的三类工程错误

好了,说完了信息缺失的问题,我们来说说CodeX在实际编程中最容易犯的三类错误。

这三类错误叫做:幻觉、漏改、误判

幻觉——编造不存在的API

这是最常见的一类错误。

CodeX有时候会编造一些根本不存在的API、函数名、参数。

比如说,你让它用某个第三方库写个功能,它可能会生成这样的代码:

import { someFunction } from'some-library';const result = someFunction({  mode: 'advanced',  timeout: 5000,});

但实际上,some-library里根本没有someFunction这个导出,或者它的参数根本不是这样的。

这种幻觉错误,最容易被忽视,因为代码看起来太专业了,你可能会以为库就是这个用法。

我第一次遇到这种情况的时候,完全没怀疑是CodeX在胡编,直接就开始调试为什么跑不通。结果折腾了半天,才发现是API名字都写错了。

怎么避免?我的经验是:每次用到一个新库的时候,先自己去文档里看一眼,确认一下API的名字和用法。不要完全相信CodeX说的。

不是说CodeX故意骗你,而是它真的不知道。它只是根据见过的代码模式,编了一个看起来合理的API。

漏改——该改的地方没改全

第二类错误是"漏改"。

当你让CodeX修改某个功能的时候,它可能只改了表面上的逻辑,但遗漏了相关的调用点、配置文件、测试代码。

比如说,你让它把某个函数从同步改成异步,它可能只改了函数本身的实现,但没有更新调用这个函数的地方,导致类型不匹配或者调用方式错误。

这类错误需要你仔细检查diff,确保所有相关的地方都改到位了。

我的经验是:让CodeX改完代码之后,一定要自己过一遍,尤其是看看有没有其他地方也用了这个函数或者类似的逻辑。

这种感觉就像是,你让装修队改了一下厨房的水管,结果他们只改了明面上的管子,墙里埋的那段给你漏了。等你住进去才发现,墙面渗水。

误判——对业务逻辑的理解跑偏

第三类错误是"误判"。

CodeX有时候会基于不完整的上下文,对你的业务逻辑产生误解,然后生成"看起来对但实际不对"的代码。

比如说,你有一个"用户积分"的概念,你让CodeX写一个"扣减积分"的函数。

CodeX可能基于训练数据,觉得"扣减"就是直接减。但实际上你们的产品逻辑是"扣减前要先检查积分是否足够",或者"扣减后要发送通知"。

这些业务规则,CodeX是不知道的。

它只能基于你给它的上下文去猜。上下文不够准确,它的猜测就会跑偏。

我之前遇到过一个特别奇葩的case:我们有个功能是"用户升级VIP",产品逻辑是"升级VIP的同时清零用户积分"。结果CodeX写的代码只做了升级,没有清零。因为它根本不知道还有"清零积分"这个附加逻辑。

后来我学乖了:涉及业务逻辑的地方,一定要描述得特别清楚,不能假设CodeX能猜到。


五、从边界意识到协作方法

知道了边界在哪里,我们才能真正用好CodeX。

我自己的经验总结就是:人做判断,AI执行;人定边界,AI发挥。

这句话听起来简单,但真正做到其实挺难的。

任务的核心,自己来定

用CodeX编程,第一步不是直接让它写代码。

第一步是你自己要清楚:我要做什么,我要达到什么目标。

这个"什么"不能是模糊的描述,必须是清晰的边界。

比如说,你不能说:"帮我优化一下登录功能"

你得说:"帮我优化登录功能,要求:1)使用JWT token;2)token有效期7天;3)支持refresh token;4)登录失败超过5次要锁定账户10分钟"

边界越清晰,CodeX的输出就越准确。

这就像你给设计师提需求一样。你说"帮我设计一个好看的海报",设计师肯定一头雾水。但如果你说"帮我设计一个儿童节活动海报,要活泼可爱风格,主色调是蓝色,尺寸是A4",设计师就能给你一个明确的结果。

CodeX负责执行和展开

定好边界之后,具体的实现细节可以交给CodeX。

它比你写代码快,语法比你熟练,常见模式的覆盖比你全面。

让它去拼凑、去展开、去填充细节。

但要注意,这个过程你需要随时检查,不能完全当甩手掌柜。

自己负责审查和验收

CodeX写完代码之后,必须有人来审查。

不是大概看一眼就完事了,是真的要:

  • 跑测试
  • 看diff
  • 读关键逻辑
  • 想业务场景

CodeX是放大器,你对的方向,它放大;你错的方向,它也放大。

人机协作方法论——从边界意识到最佳实践

六、一些我自己踩过的坑

说完了方法论,再聊聊我踩过的一些坑吧,都是些惨痛的教训😢😖。

坑一:以为它能理解我的整个项目

刚开始用CodeX的时候,我以为它能自动理解我的整个项目。我只需要说"帮我加一个功能",它就能自动知道所有相关的代码在哪里、怎么调用。

结果呢?它生成的代码完全牛头不对马嘴,因为它根本不知道我的项目是怎么组织的。

后来我学会了:每次开始新任务之前,先花几分钟让CodeX了解项目背景,然后再开始干活。

坑二:让它一次性做完整个功能

我也曾经试过让CodeX一次性做完整个功能,从数据库设计到前端页面,一股脑全交给它。

结果呢?到处都是问题,逻辑对不上,接口对不上,样式对不上,改都不知道从哪改起。

后来我学会了:把大任务拆成小任务,一个功能一个功能地做,每完成一个小功能就验证一下,确认没问题再往下走。

坑三:完全相信它的代码

还有就是太相信CodeX写的代码,觉得它既然能写出来,那肯定是对的。

但其实CodeX也会犯错,而且有些错误藏得很深,不跑一下根本发现不了。

后来我学会了:CodeX的代码必须自己过一遍,尤其是涉及业务逻辑的地方,一定要自己想清楚对不对。

坑四:以为它能记住所有的规则

有时候我会在某次对话里跟CodeX说一堆规则,比如"这里不要用var要用const"、"这个函数必须加try catch"之类的。

然后下一次对话的时候,我以为这些规则它还记得,结果它完全没遵守。

后来我学会了:重要的规则要写进项目配置文件里,而不是只靠对话说。


七、一些我自己的实战技巧

说完了坑,再分享几个我自己在用的实战技巧,都是用血泪教训换来的。

技巧一:学会"喂"上下文

不是等CodeX来猜,而是主动告诉它。

每次开始一个新任务之前,我习惯先说:

"这是一个React项目,结构如下:src/components存放组件,src/hooks存放自定义hook,使用TypeScript,编码规范是xxx。"

这样CodeX一上来就知道项目的背景,后续的输出质量会高很多。

技巧二:拆解大任务为小任务

CodeX处理小任务比处理大任务强得多。

如果你让CodeX做一个大功能,它可能会漏掉很多东西。

但如果你拆成:

  1. 先写数据层
  2. 再写业务层
  3. 再写UI层

每一步都验证通过再往下走,质量会好很多。

技巧三:让CodeX先读文件,再生成代码

不是直接让它写,而是让它先理解。

"帮我读一下 src/services/user.ts 和 src/types/user.ts,然后告诉我你理解了哪些内容。"

等它确认理解正确之后,再让它生成代码。

技巧四:用自然语言描述需求,而不是技术方案

CodeX在技术方案的选择上,其实比不过专业的你。

所以与其让它做选择,不如告诉它"我要达到什么效果",让它来决定"怎么实现"。

比如你可以说:"用户登录成功后要跳转到首页,如果失败了要显示友好的错误提示。"

你不需要告诉它用什么路由、用什么状态管理,CodeX会基于你的项目上下文来决定。

技巧五:建立项目规则,让CodeX遵守

如果你有一个长期项目,可以给CodeX建立一套"项目规则":

  • 编码规范
  • 目录结构
  • 命名约定
  • 代码风格

CodeX在了解这些规则之后,会自觉遵守,输出的一致性会好很多。


八、最后说一句真心话

可能有点"和稀泥",但确实是真心话——

CodeX本质上是一个超级助手,不是全知全能的神。

它能帮你做很多事,但它也有自己的边界和局限。知道边界在哪,比盲目相信它的强大更重要。

我自己用CodeX这段时间,最大的感受是:用得好不好,90%取决于人,不取决于工具。

同一个CodeX,不同的人用它,效果天差地别。

有的人用它一天能交付一个模块,有的人用它一天能制造一堆bug。

区别在哪?

区别在于:用得好的人,知道CodeX能做什么、不能做什么、该怎么配合。


写在最后

CodeX不是银弹,它是一个需要你去管理的超级助手。

知道边界在哪里,比知道它能做什么更重要。

把方向盘握在自己手里,让CodeX成为你的超级助理,而不是你的超级拐杖。

以上是我对"AI编程的最小原理——知道边界在哪里"的详细复盘与思考。

如果你觉得有收获,欢迎和我交流你的看法。