AI 编程:追不完的工具,理得清的问题

古早时候学编程,常听一句话:知其然,更要知其所以然。

这句话听着有些老派。可多年以后再看,在喧嚣繁杂的技术潮水里,真正让人立得住的,还真就是这个道理。学网络编程,如果只记住 epollselect 快,遇到高并发的连接超时依然会心虚;学面向对象,如果只背下那几个设计模式,写出来的也可能仍然是套着类外壳的过程式面条代码。工具和概念当然要学,但工具为什么出现,它到底在解决什么问题,这背后的来龙去脉如果想不清楚,学得越多,反而越容易迷失方向。

AI 编程这几年,尤其容易让人有这种迷茫。

一开始大家卷 prompt engineering,后来热议 Agent,再后来是 MCP、Skill、上下文工程、工作流,各种新词一波一波地涌出来。基础模型在变,模型之上的工程基础设施也在变。今天刚觉得某个工具形态是未来的标准,下一轮模型升级或产品改版之后,它的生态位可能就消失了。于是业界有一句自嘲:AI 时代不用学得太快,学得慢一点,有些技术就不用学了。

这话有几分戏谑,也有几分真切。许多概念出来时声势大,过一阵子就被新的封装直接吞掉。也有一些看似极小的项目,只是把某种使用经验包了一层,开源后却能拿到上万个 star。眼红之后,我真正关心的不是它为什么拿了这么多 star,而是它到底补了哪块空缺。如果不去探究这背后的逻辑,今天追这个,明天换那个,到头来除了在电脑里装了一堆很快会过期的插件,什么也没留下。软件行业里的工具大都不是凭空冒出来的。一个东西突然被反复提及,通常是旧的方案已经露出了缺口,才有人拿着新方案去补。

我也是在这个折腾的过程中,慢慢意识到:只学会把 AI 当作提效工具是不够的。最开始我也追工具,哪个插件响应快,哪个 Agent 能自己跑,哪个工作流看起来更顺手,都会忍不住试一试。可试得越多,心里反而越不踏实。因为每个工具都在标榜自己解决了什么问题,却很少有人把这个问题背后的演进脉络从头讲清楚。模型为什么需要工具?工具为什么一定要套进循环?循环为什么又会带来更隐蔽的失败?MCP、Skill、上下文管理这些东西到底是在给谁收拾烂摊子?

这些问题一路深究,让我意识到,仅仅在碎片化的工具技巧里打转是无解的。我们必须回到最底层的逻辑,也就是 AI 编程的第一性原理。这也成为了后来我决定把这些思考和工程实践系统性沉淀下来,写成一本书的契机。

概率生成与工程事实的天然鸿沟

AI Coding 最容易让人看走眼的地方,是模型写出来的代码确实像那么回事。

在一个有着相似命名、相似错误处理的项目里,模型顺着上下文补一段实现,经常能写得像模像样。很多重复性的胶水代码、样板逻辑、测试补全,交给它处理,确实能省下不少时间。这个能力没必要贬低,也贬低不了。用过的人都知道,它确实好用。

可这份好用,是有隐形前提的。

大模型写代码,并不是因为它像一个人类工程师一样,真正理解了这个项目的历史、边界、以及它在线上运行时的责任。它只是在你给定的上下文里,顺着已有的文本脉络往下做概率推测。代码对它来说是一种结构极强的文本,项目风格、函数签名、调用关系,都是它借以推导的模式。材料足够时,它写得很好;材料缺失时,它也不会停下来反思。

这和人写代码有着本质的差别。一个工程师在项目里待久了,会拥有一种近乎直觉的警觉:他知道有些接口看起来别扭,但因为有着兼容逻辑绝不能动;有些目录看起来已经废弃,但却是线上某个边缘业务的命门。这些经验不一定写在文档里,很多时候只是长期维护形成的肌肉记忆。

模型没有这种天然的警觉。你没有把事实放进上下文,它就不会自动拥有;你没有把禁区告诉它,它也不会因为不确定而停笔。它只会用极其自信的语气,写出一段看似优雅但可能埋着致命隐患的代码。所以 AI 编程的第一个问题,不是怎么让模型拥有更强大的生成能力,而是怎样让模型接触到足够多的工程事实。只要这点没有想清楚,后面对 Agent、MCP 的讨论就容易停留在概念上。因为所有这些概念,最初都在处理同一个矛盾:模型有强大的生成能力,却没有天然的项目现场。

工具调用:从场外建议到介入真实环境

早期使用大模型写代码,很像身边多了一个只会说话的场外军师。你贴一段报错,它解释;你让它写个函数,它给你一段 markdown。这个阶段已经很有价值,但对实际开发来说,它始终隔着一层聊天窗口。

真正的软件开发从不在聊天框里。代码在文件系统里,测试在命令行里,依赖在包管理器里,项目历史在 Git 里。模型如果只能输出文本,它最多只能把建议交给人。人再充当人形搬运工,复制、粘贴、运行、观察报错、再把报错贴回去。这个过程跑个一两次还行,一旦项目复杂起来,这种人肉桥接就会显得极其笨重。

于是,工具调用(Function Calling / Tools Call)的出现变得顺理成章。

给模型一组可以调用的外部 API:读取文件、搜索代码、执行终端命令、修改某行逻辑。模型并没有长出双手,它只是生成了结构化的调用意图(比如一个 JSON 格式的指令),真正执行这个动作的是外部的框架。但这一步,让事情的性质发生了变化。大模型从一个只说不练的回答系统,开始被拖进了真实的物理环境。它可以看见文件,可以拿到真实的测试反馈,可以根据命令的返回继续调整下一步的动作。

这让我想起调试代码的过程。如果只能靠人肉看代码找 Bug,效率不可能高;一旦你打开调试器,让代码在真实环境中跑起来,配合断点和变量监控,定位问题的速度就会发生质的飞跃。工具调用就像是给模型接上了这个调试器,让环境的反馈能够实时输入到它的思考流程里。

但到这里依然不够,工程任务很少是一次动作就能搞定的。读完文件要判断是不是缺了定义,改完代码要跑测试,测试失败了要根据报错重新搜索。单次的工具调用只是让模型能摸到环境,要让它自己把任务跑完,还需要一个循环。

Agent 机制:自动化循环背后的偏航风险

Agent 这个词现在被捧得很高。很多产品一旦挂上 Agent 的名头,仿佛就拥有了某种自主心智。可如果把这层外壳剥开,它的技术骨架并不神秘:模型读取当前状态 → 决定下一步动作 → 调用工具 → 拿到环境反馈 → 将结果塞回上下文 → 继续下一轮判断。

这里它厉害的地方,也是它危险的地方。

厉害之处在于,过去需要人手动串联的许多繁琐步骤,现在可以被这个循环接管。修一个 bug,它自己去定位、修改、跑测试、补漏洞,人不再需要在聊天窗口和终端之间反复横跳。这种体验一旦习惯(也很容易习惯),就很难再退回到过去的手工时代。

危险之处在于,循环会无限放大问题。所谓失之毫厘,谬以千里。如果大模型在第一步做出了一个错误的判断(比如误判了 Bug 的根源),在单轮对话里,这个错误顶多是一句废话。但在 Agent 循环里,后面的每一次搜索、修改、解释,都会围绕这个错误前提继续展开。它会非常敬业地在这个错误的道路上狂奔。等最终结果交到你手里时,呈现在你面前的不再是一句写错的话,而是一堆被改得面目全非、却又自圆其说的代码垃圾。(比如:它会自作聪明地帮你重构了半个项目的异常捕获,顺便把线上环境最关键的监控日志全部吞掉。)

我不太喜欢把 Agent 拟人化地称为 AI 同事。它不是一个理解了业务并能承担责任的实体。准确地说,它是一个执行循环套着一台概率生成机器。循环给了它行动的腿,模型给了它看似合理的判断。这个组合足够强大,但也极其需要注意边界。

如果 AI 编程只讨论怎么让 Agent 拥有更高的自主性,讨论很容易跑偏。自主性只是表象,我们真正需要拷问的是:它每一步决策依赖的事实从哪里来?它调用的工具边界在哪?什么时候它必须停下来向人类请示?否则,执行循环越顺畅,它把错误包装成完美交付的能力就越强。

MCP 协议:破解工具爆发后的适配困局

当 Agent 还只是某个特定 IDE 插件的内部功能时,底层的接口怎么接都行。一个插件有自己的格式,一个平台有自己的私有协议,短时间里也能跑通。但工程现场的工具从来不是单一的。

Git、数据库、CI/CD 系统、浏览器、工单系统、内部文档库,都可能成为 Agent 的操作对象。每个工具都要暴露能力,每个 Agent 都要理解这些能力。如果大家都用私有协议各接各的,最先被拖垮的不是大模型的推理能力,而是开发者的适配成本。工具提供方不想为每个客户端写一遍描述文件,Agent 开发者也不想为每个工具写一套适配器。

MCP(Model Context Protocol,模型上下文协议)就是为解决这个痛点而生的。

它解决的不是模型本身聪不聪明的问题,而是工具如何被统一发现、描述和调用的问题。工具按协议声明能做什么,Agent 按协议去发现并调用。这就像是 Agent 生态里的USB 接口标准。没有它,你也能用飞线把外设接上;但一旦外设多了,接口标准就是唯一的出路。

这在软件行业里不是新鲜事,从 Web 协议的标准化,到微服务时代的 gRPC 和服务发现,再到云原生里的统一 API,背后的驱动力从来不是大家突然热爱标准,而是混乱接入的成本已经超过了标准化的成本。AI 编程走到这一步,不过是又一次重复了软件工程的老规律。

但也要看清楚,MCP 解决的只是工具的插槽,而不是任务的经验。一个工具能被调用,不等于模型懂得在什么时机、按什么顺序去用它。标准化把工具摆上了桌面,而桌面上的东西怎么用,仍然是问题。

Skill 机制:工程规范与工作流的资产化

在真实的开发中,真正拉开水平差距的,往往不是你用了什么工具,而是你做事的顺序和规范。

写代码前,先看目录结构,再看同类实现,最后动笔;做 Code Review,先理解 PR 的目的,再看 diff,最后查边界条件。这里面的读文件、搜代码都只是工具,决定结果质量的,是工具背后的组织逻辑,以及哪些判断必须先执行。

如果这些经验每次都要人在提示词里临时交代,它就无法沉淀复用。今天你叮嘱 Agent 改代码前先看项目风格,明天新建个会话,你还得再复述一遍。团队里每个人都有自己的提示词手感,看似用得热闹,但团队整体的工程质量并没有提升。

Skill 的意义就在于此,它把某类特定任务里反复出现的流程、约束、参考材料和工具调用方式,压缩成一个模型可以随时加载的能力包。一个好的 Skill,背后真正值钱的不是那几行脚本,而是一组被反复验证过的做事方式

但经验一旦被封装成资产,就会立刻带来资产所特有的烦恼:版本控制、陈旧退役、所有权维护。如果团队的规范变了,而 Skill 没有同步更新,它就会继续用旧的经验去指导新的任务。AI 编程发展到这一步,已经不再是个人如何编写 Prompt 的技巧,而是团队如何管理自身工程经验的课题。

上下文治理:拓扑检索与多 Agent 职责隔离

当工具接进来了,经验也封装好了,我们很快会撞上物理极限:上下文窗口。

虽然现在的模型上下文窗口动辄几十万甚至上百万 Token,看起来容量惊人,但实际用起来会发现,窗口变大只是把问题往后推了推,并没有从根本上解决问题。

上下文不是仓库,不能把所有东西都一股脑倒进去。

每一段材料都会占用 Token 成本,更致命的是,它会分散模型的注意力。材料太少,模型缺乏工程事实,容易胡说八道;材料太多,模型在噪声里迷路,找不到关键线索。这很像软件设计里的抽象,抽象的艺术不在于暴露所有细节,而是在最合适的位置呈现最关键的信息。

例如代码库的检索。简单的向量切块检索,在对付普通文档时还算够用,但在代码世界里往往会失效。代码库中的代码是有拓扑关系的(定义、调用、继承、提交历史)。一个函数离开它的上下文,就失去了语义。真正有效的检索,是动态的探索。模型不需要一次性背下整个项目,而是要在工具的帮助下,在任务推移的过程中,像一个真正的工程师一样去看需要看的那一小块代码。

当任务复杂度膨胀,单个 Agent 的上下文也会显得捉襟见肘。写代码、审代码、安全审计、架构决策,各自需要的注意力和上下文完全不同。把它们塞进同一个长对话里,结果必然是越往后越混乱。多 Agent 协作的出现,本质上不是产品形态的升级,而是为了解决上下文的瓶颈,当一个上下文承受了太多的角色和历史,将它们拆分、隔离,才是唯一的控制手段。

演进主线:软件工程规律的新轮回

梳理完这条问题链,你会发现,AI 编程里那些层出不穷的新词,其实就没那么神秘了。

大模型能写代码,但它缺少项目现场,于是需要上下文和工具;单次工具调用无法完成复杂任务,于是需要 Agent 循环;工具种类变多,于是诞生了 MCP 这类标准化协议;为了让经验能复用,我们需要 Skill 封装;当工具和经验堆积,上下文管理就成了新的工程难题;任务再复杂,单个上下文承载不下,多 Agent 协作便顺理成章地出现。

这并不是一部由新词拼接成的编年史,而是软件工程走过无数次的那条老路:能力突破带来复杂度,复杂度累积迫使我们进行抽象、标准、封装和治理。网络编程如此,面向对象如此,云原生如此,AI 编程也逃不出这个规律。

在这些不断漂移的工具和热词之下,AI 编程的第一性原理其实从未改变:那就是如何在一台概率生成机器和一套确定性的软件系统之间,建立起坚固、可靠且可扩展的连接。

《AI 编程的第一性原理》这本书所讨论的内容,正是这条底层脉络,以及在真实的工程现场如何去落地这些治理方法。我已将这本书的内容以开源的形式公开在 GitHub 上:ai-programming-book

如果你在阅读过程中,觉得这些被整理出来的逻辑线对你有所启发,或者能在开发中帮上一点忙,欢迎给这个项目点个 Star。它不只是一份简单的鼓励,更是把这种往工具下面多看一眼的共识,传递给更多同行的纽带。

在写这本书的过程中,我越来越清楚地感到:如果我们只追逐工具,最后留在脑子里的,只会是一堆注定会过期的截图和旧接口说明。真正值得沉淀下来的,是工具之下的问题:模型的边界在哪里?执行循环为什么会失败?经验复用为什么困难?上下文为什么会成为工程对象?

知其然,更要知其所以然。在 AI 时代,这句老话不仅没有过时,反而变得更加要紧。变化越快,表面越热闹,越不能只跟着名字跑。今天叫 Agent,明天可能换一个说法;今天叫 Skill,明天也可能变成另一种封装。但只要模型仍然需要把概率生成转化为工程结果,这条问题链就依然会向下延伸。

工具会变,但问题不会突然消失。如果想在这场技术浪潮里保持一点独立的判断力,我们恐怕还是要忍住追逐热闹的冲动,往工具下面,多看一眼。

相关推荐
Goodwin1 小时前
手机离线跑大模型ReactNative实战
人工智能·ai编程
Necis2 小时前
半天,AI 重写了我的五年前的娃娃机
ai编程·three.js
光电的一只菜鸡3 小时前
小白从零开始学agent(四)——上下文漂移与如何约束大模型幻觉
ai编程
明月_清风3 小时前
显存即正义:不同显存容量能训多大的模型?一文说清硬件边界与训练策略
前端·后端·ai编程
constCpp3 小时前
AI 编程:追不完的工具,理得清的问题
人工智能·ai编程·ai-native
VIP_CQCRE3 小时前
用 Ace Data Cloud 接入 Codex:让 AI 编程工具配置更简单
openai·ai编程·开发工具·codex·acedatacloud
liliangcsdn4 小时前
OpenClaw如何通过js编程从浏览器提取数据
ai编程
小虎AI生活13 小时前
AI 培训现场翻车后的应急方案设计:从工具选型到教学流程的系统化思考
ai编程
犀利豆16 小时前
我和 Claude Code 一起写了一本介绍 Claude Code 原理的书
人工智能·ai编程·claude