news 2026/10/31 10:11:10

从工具调用到代码生成:AI Agent范式转变与工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从工具调用到代码生成:AI Agent范式转变与工程实践

1. 被"工具调用"框住的那两年,我到底在做什么

2023年那会儿,我接的第一个Agent项目是给一家做工业质检的团队搭一套自动巡检流程。需求听起来很朴素:让模型读日志、判断异常、调接口触发告警。我当时的第一反应就是——这不就是"LLM + Function Calling"吗?把工具描述写成JSON Schema,塞进system prompt,模型输出一个tool_call,我解析出来执行,把结果再喂回去,循环几轮,完事。

那套东西我写了大概两周,跑通了,demo演示的时候效果还不错。但接下来半年,我几乎所有的Agent项目都长一个样:一个ReAct循环,一堆工具定义,一个while循环判断要不要继续。客户提新需求,我的第一反应永远是"这个能不能做成一个工具让模型调"。做不出来,我就觉得是模型能力不够,或者工具描述写得不够清楚。

直到有一次,一个做服装检测的客户问我:"你们的AI能不能自己决定今天用哪套检测标准?"我愣了半天。因为在我的范式里,标准是写死在代码里的,模型只能"调用"我预设好的东西,它没有权力去"决定"什么。那一刻我才意识到,Agent这个词被我理解窄了。我把它当成了一种技术架构,而不是一种设计思路。工具调用只是Agent的一种表现形式,甚至可能是最受限的那一种。

这篇东西不是教程,也不是框架对比。我想聊的是:当我们说"Agent范式"的时候,我们到底被什么限制住了,以及我这两年踩过的坑、换过的思路,哪些是真的有用。

2. 工具调用不是Agent的全部,它只是最容易被实现的那部分

2.1 为什么大家一上来就做Function Calling

先说个现象。你去搜"AI Agent怎么搭",十篇里有八篇在讲怎么定义tools、怎么解析tool_call、怎么用LangGraph或者扣子搭一个能查天气的助手。这不是偶然。

Function Calling是OpenAI在2023年6月正式推出来的能力,它把"模型输出结构化指令"这件事标准化了。在此之前,你要让模型稳定输出一个JSON,得靠prompt engineering反复调,还得写正则兜底。Function Calling出来之后,这件事变得极其简单:你给模型一个工具列表,它要么回文本,要么回一个结构化的调用请求。开发者只需要处理这两种情况。

从工程角度看,这是巨大的进步。但从认知角度看,它带来了一个副作用:大家把"Agent"等同于"会调工具的模型"。我见过不少团队,做Agent的第一件事就是列工具清单,仿佛工具越多,Agent越强。结果做出来的东西,本质上是一个带自然语言入口的if-else。

我自己的教训是:2023年底做一个运维助手,我给它定义了二十多个工具,查CPU、查内存、查磁盘、重启服务、拉日志……结果模型经常在"该查CPU还是该查内存"之间反复横跳,一轮对话调了七八次工具,最后给出的结论还不如直接写个脚本。问题不在于模型笨,而在于我把一个本该由代码逻辑决定的事情,交给了模型去"选择"。

2.2 工具调用的三个隐性天花板

我后来总结了一下,纯工具调用范式有三个绕不过去的限制。

第一,工具是离散的,但现实是连续的。你定义了一个"查询订单状态"的工具,但用户问的是"我上周买的东西怎么还没到,是不是因为下雨延误了"。这个问题需要查订单、查物流、查天气,还要做因果推断。你可以把这三个都做成工具,但模型怎么知道要按这个顺序调?它只能靠猜。而现实中的因果关系,往往不是几个离散工具能覆盖的。

第二,工具的描述能力有限。一个工具的JSON Schema能描述参数类型、必填项、枚举值,但它描述不了"什么时候该用这个工具"的微妙判断。你写"当用户询问订单状态时使用",但用户可能是在投诉、在咨询、在闲聊中顺带提了一句。模型只能靠语义相似度去猜,猜错的概率不低。

第三,工具调用是单轮的。大部分实现里,模型调一次工具,拿到结果,再决定下一步。但真实的决策往往是并行的、嵌套的、需要中途改变计划的。比如一个做数据分析的Agent,它可能需要先抽样看看数据长什么样,再决定用哪种统计方法,而不是一开始就定好"调A工具再调B工具"。

这三个限制不是模型能力问题,是范式问题。你把Agent设计成"模型在预设工具集里做选择",那它的上限就是工具集的上限。

2.3 一个反直觉的观察:工具越少,Agent越稳

我后来做项目有个习惯:能不用工具就不用工具。听起来很反直觉,但实测下来,工具数量从20个降到5个以内,Agent的成功率反而上升。

原因很简单。工具多了,模型的注意力被分散,它要在更多的选项里做判断,出错概率自然上升。而且工具之间的边界往往模糊,模型很容易选错。我做过一个对比测试,同一个任务,5个工具时成功率78%,20个工具时掉到52%。这不是模型不行,是我给它出了太多选择题。

所以我现在设计Agent,第一步不是列工具,而是问:这件事真的需要模型来决定吗?如果答案是"其实用代码判断就行",那我就不做成工具。模型只负责它真正擅长的那部分——理解模糊意图、处理非结构化信息、在开放场景下做权衡。

3. 跳出工具调用之后,我试过的几种"非典型"Agent形态

3.1 把Agent当成"会写代码的同事",而不是"会调工具的助手"

这是我转变最大的一次。2024年初做一个数据处理项目,需求是:给一堆杂乱的Excel,自动清洗、合并、生成报表。按老思路,我得定义"读取Excel""去重""合并""生成图表"一堆工具。但我试了另一条路:让模型直接写Python代码,我执行代码,把结果返回给它。

这个思路的核心区别在于:工具调用是"模型选一个我预设的动作",代码生成是"模型自己创造一个动作"。前者受限于我的想象力,后者受限于模型的编程能力。而现在的模型,编程能力已经相当可观了。

我当时的实现很简单:给模型一个Python执行环境(沙箱),告诉它"你可以写代码来解决这个问题,执行结果会返回给你"。然后它自己写了pandas的清洗逻辑,自己处理了日期格式,自己画了图。整个过程我只提供了数据和一个执行器,没有定义任何"工具"。

这个范式的好处是显而易见的:我不需要预判所有可能的情况。用户的数据有奇怪的编码、有合并单元格、有隐藏列,这些我事先想不到,但模型在写代码的时候能根据实际报错去调整。这比我在工具里写一堆if-else要灵活得多。

当然,代价是安全性和可控性。代码执行需要沙箱,需要限制网络访问和文件系统权限。但这是工程问题,不是范式问题。

3.2 让Agent"规划"而不是"反应"

ReAct循环的本质是反应式的:观察→思考→行动→观察。它没有全局规划,走一步看一步。这在简单任务上没问题,但复杂任务上容易迷路。

我后来试了一种"先规划再执行"的结构:让模型先输出一个完整的计划(比如"第一步做什么,第二步做什么,每步的预期结果是什么"),然后我再逐步执行,每执行一步把结果反馈回去,让模型决定是否调整计划。

这个思路不是我的原创,LangGraph里的plan-and-execute模式就是这个。但我想说的是,规划和反应的区别,不是技术区别,是设计哲学的区别。反应式Agent把决策权完全交给模型,每一步都重新判断;规划式Agent让模型先想清楚再动手,执行过程中只在必要时调整。

实测下来,规划式在步骤超过5步的任务上明显更稳。因为模型有了全局视角,不会在第3步的时候忘了第1步的目标。但规划式也有问题:如果第一步的实际结果和预期差很远,整个计划可能就废了,需要重新规划。所以我现在一般是混合用:简单任务用反应式,复杂任务先规划,执行中允许局部重规划。

3.3 多Agent协作:不是越多越好,是要有"分工的边界"

多Agent是这两年被炒得很热的概念。我试过几种形态:一个主Agent调度多个子Agent、多个Agent平级协作、Agent之间互相审查。

踩过的坑是:Agent数量一多,通信成本就爆炸。你让三个Agent讨论一个问题,它们会来回传递消息,每一轮都要消耗token,而且很容易陷入"你说得对,但我觉得"这种无效循环。

我后来总结出一个原则:只有当子任务之间真的需要不同的上下文、不同的工具集、不同的角色设定时,才拆多Agent。比如一个做代码审查的场景,一个Agent负责读代码找问题,一个Agent负责验证问题是否真实存在,这两个角色的关注点完全不同,拆开是有意义的。但如果只是"一个Agent做前半段,一个Agent做后半段",那不如一个Agent串行做,省得通信开销。

还有一个细节:多Agent之间的消息格式要严格定义。我见过太多项目,Agent之间传的是自然语言,结果下游Agent理解错了上游的意思,整个流程跑偏。我现在会让Agent之间传结构化数据(JSON),只在需要解释的时候才用自然语言。

4. 那些被忽略的工程细节,才是Agent能不能落地的关键

4.1 并发问题:Agent不是无状态的函数

热词里有个"ai agent 怎么扛并发",这个问题很实在。很多人把Agent当成一个API来设计,以为请求进来、处理、返回就完事了。但Agent是有状态的,它可能跑几十秒甚至几分钟,中间要调多次模型、多次工具。

我做过一个客服Agent,高峰期同时有几百个会话。最初的实现是每个会话一个独立的Agent实例,结果内存直接爆了。后来改成会话状态存在Redis里,Agent本身是无状态的,每次请求从Redis加载状态、处理、写回。这样虽然多了一次序列化开销,但并发能力上了一个数量级。

还有一个坑是模型调用的限流。Agent一次任务可能调十几次模型,如果并发上来,很容易触发API的rate limit。我的做法是在Agent和模型之间加一层队列,控制并发数,超出的请求排队。听起来简单,但不做的话,高峰期会大量失败。

4.2 状态管理:Agent的"记忆"到底该存什么

Agent的状态管理是个容易被低估的问题。我见过两种极端:一种是什么都不存,每次请求都是全新的;另一种是什么都存,把每一轮对话、每一次工具调用结果都塞进上下文。

前者的问题是Agent没有连续性,用户说"刚才那个订单",它不知道是哪个。后者的问题是上下文爆炸,token消耗巨大,而且模型在超长上下文里容易迷失。

我现在的做法是分层存储:短期记忆(当前任务的中间结果)放在上下文里,长期记忆(用户偏好、历史交互摘要)放在外部存储,需要的时候检索回来。关键是"摘要"这一步——不是把原始对话存下来,而是让模型定期把对话压缩成要点。这样既保留了关键信息,又控制了上下文长度。

4.3 错误处理:Agent失败的时候,怎么优雅地退场

Agent一定会失败。模型会幻觉、工具会超时、外部API会挂。问题是失败之后怎么办。

我早期的实现是:出错就抛异常,整个任务失败。用户体验很差,因为跑了半天什么都没得到。后来改成分级降级:如果模型调用失败,重试;如果工具调用失败,把错误信息返回给模型,让它决定是换工具还是放弃;如果整个任务无法完成,返回已完成的部分结果,并说明哪一步卡住了。

这个改动看起来小,但用户满意度提升很明显。因为用户能知道"做到哪一步了",而不是面对一个冷冰冰的"系统错误"。

一个经验:Agent的错误信息不要直接抛给用户,要让模型把它翻译成人话。比如"HTTP 503"翻译成"订单服务暂时不可用,我稍后再试"。

5. 从"能跑"到"能用",我踩过的三个认知坑

5.1 坑一:以为模型越强,Agent就越好

这是我最早犯的错。2023年的时候,我总觉得Agent效果不好是因为模型不够强,所以一有新模型就换,GPT-4出来换GPT-4,Claude出来换Claude。但换了一圈发现,效果提升有限。

后来我想明白了:Agent的效果 = 模型能力 × 架构设计 × 工程实现。模型只是其中一个因子。如果你的架构是错的(比如工具定义混乱),工程是糙的(比如没有错误处理),那模型再强也救不回来。

我做过一个对比:同一个任务,用GPT-4加糟糕的架构,成功率60%;用当时较弱的模型加精心设计的架构,成功率75%。这个差距说明,架构和工程的重要性不亚于模型本身。

5.2 坑二:以为Prompt写得越详细越好

Prompt engineering是Agent开发里最玄学的部分。我早期写system prompt,恨不得把所有的规则、示例、边界情况都写进去,结果prompt长达几千字。效果呢?模型经常忽略其中的某些部分,或者被过多的规则搞晕。

后来我学乖了:prompt要分层。核心指令放最前面,简短明确;示例和边界情况放在后面,用结构化的方式组织;能写成代码规则的,就不要写在prompt里。比如"如果用户输入包含敏感词,拒绝回答",这种用代码过滤比写在prompt里可靠得多。

还有一个技巧:把prompt当成代码来管理。版本控制、A/B测试、回归测试,一样都不能少。我现在的项目里,prompt是存在配置文件里的,每次修改都要跑一遍测试用例,确保没有回归。

5.3 坑三:以为Agent能处理一切

这是最危险的认知。我见过太多项目,把Agent当成万能药,什么需求都想用Agent解决。结果做出来的东西又慢又贵又不稳定,还不如传统的规则引擎。

我现在判断一个需求适不适合用Agent,会问三个问题:第一,这个任务的输入是不是高度非结构化?如果是结构化的,用规则就行。第二,这个任务的路径是不是不确定?如果步骤是固定的,用工作流就行。第三,这个任务对错误的容忍度是不是较高?如果是金融交易这种零容忍的场景,Agent目前还不适合。

三个问题都是"是",才考虑用Agent。否则,老老实实用传统方法。

6. 如果重新开始,我会怎么设计一个Agent

6.1 先画任务流程图,再决定哪里放模型

我现在做Agent项目,第一步不是写代码,是画流程图。把整个任务的步骤画出来,标注每一步的输入、输出、判断条件。然后问:哪一步是真正需要模型来判断的?

大部分任务里,真正需要模型的只有一两步。比如一个合同审核Agent,读取合同、提取条款、比对模板、生成报告,这些步骤里,只有"提取条款"和"比对模板"需要模型,其他都可以用代码做。把模型放在关键位置,而不是让模型驱动整个流程,这样既稳定又省钱。

6.2 给Agent设计"退出条件",而不是让它无限循环

Agent最容易出的问题是死循环。模型调一个工具,结果不对,再调,还不对,再调……token烧完了,任务也没完成。

我的做法是给Agent设三个退出条件:最大步数(比如10步)、最大token消耗(比如5万token)、最大时间(比如60秒)。任何一个触发,就强制退出,返回当前结果。同时,在prompt里明确告诉模型"如果连续两次尝试都失败,就停止并报告问题"。

这个机制看起来简单,但能避免大量的资源浪费。我见过一个项目,因为没有退出条件,一个失败的请求跑了20分钟,烧了几十万token。

6.3 把"可观测性"当成一等公民

Agent是个黑盒,模型在想什么、为什么做这个决定,你很难知道。所以可观测性特别重要。

我现在每个Agent都会记录:每一轮的输入输出、模型的思考过程(如果有)、工具调用的参数和结果、每一步的耗时和token消耗。这些数据存在日志里,出问题的时候可以回溯。

更进一步,我会做一个"回放"功能:把一次失败的执行过程完整回放出来,看看是哪一步出了问题。这个功能在调试的时候极其有用,比看日志高效得多。

7. 关于Agent范式,我现在的几个判断

第一个判断:工具调用会长期存在,但它不会是Agent的主流形态。就像汇编语言还存在,但没人用它写业务系统一样。工具调用适合简单、确定的场景,复杂场景需要更灵活的范式。

第二个判断:代码生成会成为Agent的核心能力之一。当模型能写代码、执行代码、根据结果调整代码的时候,它的能力边界就从"我预设的工具"扩展到了"任何可以用代码表达的操作"。这个想象空间大得多。

第三个判断:Agent的竞争会从"模型能力"转向"工程能力"。模型大家都能用,但怎么设计架构、怎么管理状态、怎么处理错误、怎么保证可观测性,这些工程细节才是拉开差距的地方。

第四个判断:不要为了Agent而Agent。我见过太多项目,明明用规则引擎就能解决,非要上Agent,结果又慢又贵。技术选型要看场景,不是看热度。

最后说个我自己的体会。做Agent这两年,最大的收获不是学会了某个框架或者某个技巧,而是学会了区分"模型该做的事"和"代码该做的事"。模型擅长处理模糊、开放、非结构化的问题,代码擅长处理确定、重复、需要精确控制的问题。把这两者放在合适的位置,Agent才能真正发挥作用。

工具调用只是Agent的一种实现方式,不是Agent的定义。当我们把Agent从"会调工具的模型"这个框里解放出来,会发现能做的事情多得多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 10:09:46

OpenRig:本地AI开发的轻量级服务编排工具链

1. OpenRig 是什么:一个被严重误读的开源工具链真相 OpenRig 这个名字最近在开发者社区里频繁刷屏,但绝大多数人点进去后都愣住了——它既不是显卡挖矿软件,也不是AI训练框架,更不是某个新出的LLM推理平台。我第一次看到这个词是在…

作者头像 李华
网站建设 2026/10/31 10:07:47

LibTomCrypt F8模式实现详解:从CFB痛点到3GPP加密实战

分组密码这东西,算法本身只解决了“怎么把一块数据搅乱”的问题,真正落到工程里,麻烦的从来都是“怎么把一长串数据切成块、每块怎么串起来、出错会不会传染、能不能并行”。我最早接触 F8 模式是在啃 LibTomCrypt 源码的时候,翻到…

作者头像 李华
网站建设 2026/10/31 10:04:53

轮滑电商平台开发:技术架构与核心功能实现

1. 项目概述 "基于轮滑网站《无与轮比》购物网任务书"这个项目标题透露了几个关键信息点:这是一个专注于轮滑领域的电子商务网站开发项目,核心功能围绕在线购物展开,并且很可能包含任务管理或任务发布系统。作为一位有10年全栈开发…

作者头像 李华
网站建设 2026/10/31 10:04:53

轮滑装备电商平台技术架构与实现

1. 项目概述:轮滑装备垂直电商平台构建轮滑运动作为一项兼具竞技性与休闲性的户外活动,近年来在国内持续升温。根据体育用品行业协会数据,2022年轮滑装备市场规模已达37亿元,年增长率保持在15%以上。《无与轮比》购物网正是瞄准这…

作者头像 李华
网站建设 2026/10/31 10:01:29

企业内外协同数据互通实战:从语义对齐到可靠链路搭建

1. 企业内外协同的真实痛点:数据不通,协同就是空谈做过企业协同项目的人都有一个共同感受:系统上线了一大堆,流程图画得漂漂亮亮,真到跨部门、跨组织跑业务的时候,卡住的地方永远不是审批节点,而…

作者头像 李华
网站建设 2026/10/31 10:00:28

马尾怎么扎才好看?从脸型匹配到发圈选择的完整指南

马尾这件事,看着简单,扎起来全凭运气。早上洗完头顺手一绑是它,通勤挤完地铁散了半截也是它。出门前照镜子觉得自己挺精神,下午开会一摸后脑勺,好家伙,那一坨又扁又歪,活像头顶挂了块拖把。 “…

作者头像 李华