ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

大模型不等于Agent:能力边界、工程选型与落地避坑

大模型不等于Agent:能力边界、工程选型与落地避坑

上周有人在群里问了一句:“我们那个工单系统,接个大模型接口是不是就等于上了 Agent?”底下七八条回复,一半说是一半说不是,还有人干脆说这俩就是一回事,只是叫法不同。这种对话我这两年听过太多遍,每次听到都会想起一个特别顺手的比喻:大模型是装在一个罐子里的大脑,Agent 是给这个大脑装上眼睛、手和一本记事本的机器人。大脑本身很聪明,能读会写会推理,但它看不见你的数据库,按不了你的按钮,也记不住上一轮到底试过什么。机器人笨一点、慢一点,但它能出门、能试错、能把一件事从头到尾办完。

这个区别听起来像文字游戏,落到工程上却是两套完全不同的东西——不同的架构、不同的成本模型、不同的失败方式,甚至连测试方法都不一样。分不清这两者的人,常见的结局有两种:一种是把大模型当 Agent 使,指望它自己“想办法”把任务办完,最后拿到一段读起来很顺、但根本没法执行的话;另一种是反过来,把 Agent 当大模型用,堆了一堆工具和循环,结果发现八成的请求压根不需要走那么多步,纯属给自己增加延迟和账单。

这篇不讲教科书式的定义,讲的是我在实际项目里怎么区分这两者、怎么判断该用哪个、以及把 Agent 真正搭起来的时候会在哪些地方翻车。如果你正在纠结“我要不要上 Agent”,或者已经上了一半发现效果不如预期,下面这些内容应该能对上你的问题。

1. 先把“大脑”和“机器人”这两件事拆开看

1.1 大模型的能力边界:它是概率续写器,不是执行器

很多人对大模型的误解,根源在于把它当成了一个“程序”。程序的特点是确定性输入输出加上副作用——你给它一个参数,它去改一个文件、发一个请求、写一条数据库记录。大模型完全不是这个路子。它做的事情本质上是:给定前文,预测下一个最合理的词,一个接一个往下续。这个机制决定了它输出的是“文本”,而不是“动作”。

文本可以描述动作,但文本本身不产生动作。你说“请帮我查一下昨天订单表里退款率最高的三个商品”,模型能给你一段非常漂亮的查询语句,甚至能给你分析思路、注意事项、边界条件,但它查不了。数据库不会因为它写得好就自动执行。这就是最核心的一条边界:大模型的产出是建议,不是结果。

第二条边界更隐蔽一点:它没有状态。每次调用都是一次全新的开始,上一轮对话里你说过的话,要么被拼进这次的输入里,要么就彻底丢了。它不会“记得”昨天有个客户投诉过物流,除非你把这段信息重新喂进去。很多人第一次做多轮任务时会觉得“它怎么忘了”,其实它从来没记住过,只是前几轮你把上下文一起传过去了,看起来像记得。

第三条边界是关于可靠性的。大模型在单次生成任务上表现可以很稳,但一旦任务需要多步连续操作,误差会累积。第一步理解偏了一点,第二步就在偏的基础上继续,到第五步已经离题很远,而它自己通常不会察觉。这不是模型“笨”,是这类系统本身缺少纠错回路——没人告诉它“你上一步错了”。

把这三条边界记住,后面所有的判断都会顺很多。能用一次生成解决的问题,交给大模型;需要查数据、需要动手、需要根据中间结果调整方向的问题,光有大模型不够。

1.2 Agent 到底多了什么:一个循环、一双手、一本记事本

Agent 这个词被用得很泛,有说“能自主规划的就是 Agent”,有说“多轮对话就是 Agent”。我给团队内部的定义比较土,就看三样东西在不在:循环、工具、状态。三样齐了算 Agent,缺一样都只能算大模型的增强用法。

循环是指它能“想一步、做一步、看结果、再想下一步”,而不是一次性把答案吐完就结束。这个循环是 Agent 和普通调用的分水岭。没有循环,模型再强也只能在脑子里推演,推演错了也没有机会补救。有了循环,它可以在第一步查错了表之后,看到返回是空的,自己换个条件再查一次。

工具是指它能真正对外部世界产生作用或者获取信息——读文件、查数据库、调内部接口、发消息、跑一段计算。工具是 Agent 的“手”,也是它跟大模型最直观的区别。同样一句“帮我看看这个月哪几天服务器负载最高”,大模型只能告诉你“你应该去看监控系统”;Agent 会真的去调监控接口,把数据拉回来,再算给你看。

状态是指它能保存和复用中间信息。最简单的状态就是对话历史,稍微复杂一点是任务清单、已经确认过的约束、已经排除过的错误路径。记事本这个东西看着不起眼,但它是 Agent 能不能跑长任务的关键。任务一长,上下文必然装不下所有细节,必须有一个地方把“已经搞清楚的结论”沉淀下来,而不是每次都在原始输入里重新翻。

这三样东西凑齐以后,系统的复杂度会有一次跃升——不是线性的,是台阶式的。你会突然多出很多新的失败模式:工具调用错了、循环停不下来、状态污染、成本失控。所以每次有人问我要不要上 Agent,我第一反应都是:先确认只用大模型到底卡在哪一步,卡的那一步是不是真的需要这三样东西。

2. 同一件事做两遍:纯大模型和 Agent 的现场对比

2.1 任务设定:把一堆杂乱的会议记录整理成可执行清单

为了把区别讲清楚,我拿一个特别常见、也特别有代表性的任务做对比:给定一份几十分钟的会议速记,产出一份带负责人和截止时间的待办清单,并且要跟公司现有的项目管理系统里的任务做去重。

先看这个任务的构成:需要理解非结构化的口语文本(大模型擅长)、需要抽取待办事项和责任人(大模型擅长)、需要去系统里查已有任务做比对(大模型做不到)、需要在发现重复时决定是合并还是新建(需要判断,但也需要知道已有任务的字段结构)。这个任务的设计意图很明显:它有一半是纯文本理解,另一半必须碰外部系统。

现实里大部分所谓“AI 落地需求”都长这个样子——不是纯粹的文本任务,也不是纯粹的系统操作,而是两者搅在一起。这种任务最容易让人误判,因为前半段跑得很顺,会让人产生“剩下的也能搞定”的错觉,直到需要真去查系统的那一刻才发现卡死了。

2.2 纯大模型版本:一次性生成,错了也只能错到底

纯大模型的做法很简单:把会议记录整段塞进提示里,附上格式要求和几个示例,让它输出一份 JSON 清单,然后由人来手动去重。这个方案我见过不少团队在用,也确实能跑,效果取决于会议记录的清晰度和提示写得好不好。

它的优点很实在:链路短、延迟低、没有运维负担、出错时好定位——反正是模型输出的,看一眼就知道哪里不对。对于“会议记录本来就比较规整、待办事项不多、去重靠人工看一眼”的场景,这个方案的性价比高得离谱,硬要上 Agent 反而是浪费。

但它的天花板也很清楚。第一,它不知道系统里已经有哪些任务,所以去重这一步必须交给人。第二,如果会议记录里出现了它没见过的项目代号,它会猜,而且猜得很自信——它会给你一个看起来很像的负责人名字,但你没法确认是不是真的。第三,格式偶尔会崩,尤其是记录特别长、待办特别多的时候,JSON 少个括号、多个逗号是常事,得加一层解析容错。

我印象比较深的一次是,一个团队用这个方案跑了两个月,准确率一直还行,直到有一次会议里提到“那个老项目”,模型把它理解成了另一个名字相近的在研项目,产出的清单被直接导进了系统,后来花了半天时间清理。问题不在模型,在于这个方案里根本没有“确认”这个环节——它只能一次成型,没有机会回头问一句“你说的老项目是指哪个”。

2.3 Agent 版本:先看、再试、再改的三轮循环

换成 Agent 之后,流程会变成一个有来回的过程。第一步不是直接产出清单,而是先把会议记录里出现的项目名、人名抽出来,去系统里做一次模糊匹配,确认哪些是已有实体、哪些是新的。匹配不上的,它会在最终输出里标注“待确认”,而不是自己瞎猜一个。

第二步才是抽取待办。这时候它已经知道项目的准确名称和负责人的准确工号了,抽取的准确率会明显高出一截。第三步是去重,把每条待办拿去跟系统里已有任务比对,判断是新建、合并还是跳过。第四步生成最终结果,附带一份“我做了什么、哪些地方拿不准”的说明。

这四步听起来比“一次生成”复杂得多,但每一步都对应一个具体的、可验证的动作。这就是 Agent 的本质价值:把一个大而模糊的任务,拆成若干个小的、可以检查对错的步骤。拆开以后,出问题时你能定位到具体哪一步,而不是面对一个整体跑偏的结果干瞪眼。

代价也很直接。四步意味着至少四次模型调用,加上几次工具调用,延迟从秒级变成十几秒甚至几十秒;成本大概是纯大模型方案的几倍;而且多出了工具接口的维护工作。所以这个方案不是“更高级所以更好”,而是“任务里确实有几步是大模型干不了的,才值得付这个代价”。

3. Agent 的四块零件,少一块都会出问题

3.1 规划:把“做完这件事”拆成可验证的小步

规划这块最容易走过场。很多人写 Agent 的提示时会写“请一步步思考并完成任务”,然后就指望模型自己拆步骤。实际跑下来会发现,模型拆出来的步骤质量极不稳定——有时候拆得很细,有时候一句话带过,有时候拆出来的步骤顺序是反的。

我的做法是不让它自由发挥,而是给它一个固定的骨架,只在骨架里填内容。比如上面那个会议记录任务,骨架就是“实体确认 → 待办抽取 → 去重比对 → 结果汇总”四步,每一步的输入输出格式都定死,模型只负责在每一步里做判断。这样做的好处是流程可控、好调试、好加日志;坏处是遇到骨架覆盖不了的异常情况会卡住,需要留一个“无法处理,转人工”的出口。

固定骨架和自由规划的取舍,本质上是在可控性和覆盖面之间做选择。任务边界清楚、异常情况可以枚举的,用固定骨架;任务开放、每次情况都不一样的,才考虑让模型自由规划。我在实际项目里九成以上用的是固定骨架,因为自由规划的调试成本太高了——你不知道它这次为什么会选这条路,也就没法复现和改进。

还有一个细节值得说:每一步的产出最好是结构化的,不要是一段自然语言。自然语言的中间结果没法程序化检查,也没法直接喂给下一步的工具调用。让它输出 JSON,哪怕多花一点提示工程,后面省的事情远不止一点。

3.2 工具:接口描述写不好,模型再强也调不对

工具这块是翻车重灾区,而且翻车原因往往特别无聊——不是模型不行,是工具描述写得含糊。模型选工具的唯一依据就是你给它的描述文本,描述写得像产品文档,它就很难判断什么时候该用。

举个真实的对照。同样一个查询订单的工具,两种写法:

写法A(含糊): query_order - 查询订单信息 参数:order_id 写法B(明确): query_order - 根据订单号查询单笔订单的详情,返回商品、金额、状态、创建时间。 仅在用户明确提供了订单号时使用;如果用户只给了商品名或手机号, 请改用 search_orders 接口。 参数:order_id(字符串,必填,格式为 12 位数字)

写法 A 跑起来,模型经常在只拿到手机号的时候硬调这个接口,然后拿到一堆报错。写法 B 把“什么时候用、什么时候不用、参数长什么样”都写进去了,误调用率会降下来一大截。这件事的投入产出比高得惊人,但很多人就是不愿意花那二十分钟把描述写清楚。

工具数量也是个大坑。我试过一个给模型挂二十多个工具的场景,选择准确率明显下滑,而且下滑不是均匀的——名字相近的那几个工具错得最厉害。后来的做法是按场景分组,每次只暴露当前步骤真正可能用到的五六个工具,其余的通过一个“查找工具”的元工具按需拿。这个改动对准确率的提升,比换个更强的模型还明显。

3.3 记忆:短期上下文和长期沉淀必须分开管

记忆这个词听着高级,拆开就两件事:这次任务里的临时信息,和跨任务沉淀下来的经验。这两件事必须分开处理,混在一起会出大问题。

临时信息就是当前任务进行到哪一步、已经确认了什么、排除了什么。这部分放在上下文里就行,任务结束就丢。它的问题是容量有限,任务一长就装不下,所以要有取舍——只保留结论,丢掉中间过程。比如查了五次数据库,前四次都是空结果,那上下文里只需要留一句“已确认 A、B、C 三种条件均无匹配”,不需要把四次返回的原始数据都塞着。

跨任务的沉淀就更要小心了。有些团队会把历史对话全存下来,每次按相似度检索最近几条塞进上下文,听起来很合理,实际效果经常很糟——检索出来的东西跟当前任务只是字面相似,语义上完全不搭,反而干扰判断。我的经验是,沉淀下来的应该是结构化的事实,比如“这个项目的负责人是 X”“这类问题的标准处理流程是 Y”,而不是原始对话文本。事实可以精确匹配,原始文本只能模糊匹配,前者的可控性高一个数量级。

还有一条容易被忽略的:记忆必须能失效。三个月前确认的信息现在可能已经不对了,如果记忆系统没有过期机制,Agent 会拿着旧信息一本正经地做错事,而且错得毫无征兆。

3.4 回路控制:什么时候停,比什么时候开始更重要

Agent 跑起来之后最常见的事故不是答错,是停不下来。它调一个接口失败,重试;再失败,换个参数重试;再失败,换个工具重试……如果没有硬性的停止条件,它可以一直转到把额度烧完。

我现在搭任何 Agent 都会先定三条硬线:最大轮次、单轮超时、连续失败阈值。最大轮次是防止无限循环,一般设 8 到 15 轮,看任务复杂度;单轮超时是防止某个工具卡住把整个流程拖死;连续失败阈值是连续三次同类操作失败就直接中止,返回“我卡在哪一步、试过什么、需要什么信息”。

除了硬线,还要给模型一个“主动放弃”的出口。提示里明确写清楚:如果你连续两次尝试都无法获得需要的信息,请停止并说明缺少什么,不要继续猜测。这句话看着简单,但非常有用——默认情况下模型有一种“必须给出答案”的倾向,会硬编一个看起来合理的结论,明确允许它放弃之后,这种行为会少很多。

4. 哪些场景真的需要 Agent,哪些纯属给自己找麻烦

4.1 判断标准:任务是否可验证、环境是否可交互、错误是否可回滚

判断该不该上 Agent,我一般用三个问题过一遍,全都是肯定回答才往下走。

第一个问题:这个任务的中间结果能不能被验证?如果每一步的产出都没法用程序检查对错,那 Agent 的多步循环就失去了意义——它错了你也看不出来,只能看到最后结果不对,跟一次生成没区别。能被验证的例子:查数据库是否返回了非空结果、生成的代码能不能跑通、抽取的字段是不是符合格式。不能被验证的例子:写一段营销文案、给一个方案打分。

第二个问题:环境是否允许它真的去操作?有些场景理论上很适合 Agent,但实际操作权限根本给不了——比如要动生产库、要给客户直接发消息。这种情况下要么做只读版本的 Agent(能查不能改,改的部分交给人),要么就别做。

第三个问题:错了能不能回滚?查询类操作错了顶多重查一次,成本几乎为零;写操作错了可能要清理半天数据。对写操作,我一般要求 Agent 的输出必须经过一次人工确认,或者至少要有完整的操作日志能反向撤销。没有回滚能力的场景,宁可让 Agent 只出建议。

这三个问题过完,能刷掉一大半“看起来很适合做 Agent”的需求。剩下的才是真需要做的。

4.2 三类典型适合与三类典型不适合

场景特征典型例子判断原因
需要跨多个系统取数并汇总把工单、监控、发布记录三边的信息拼成一份故障复盘适合每步结果可验证,全是只读操作
有明确对错标准的重复操作批量检查配置文件是否符合规范并自动修正格式适合校验规则可以程序化,改错了能重跑
需要根据中间结果调整策略排查一个报错,先看日志再决定下一步查什么适合下一步动作依赖上一步结果,天然需要循环
纯文本创作写周报、写文案、写总结不适合中间结果无法验证,循环没有意义
一次性简单问答解释一个概念、翻译一段话不适合一次调用就能解决,加循环纯属浪费
高风险写操作直接改生产配置、批量发通知谨慎回滚困难,必须加人工确认环节

这张表最右边的“原因”列比“判断”列更值得看。很多选型失误不是因为不知道适不适合,而是知道了但觉得“加点防护应该没事”。实际经验是:防护成本往往比换个方案更高。

5. 我在实际搭建中踩过的几个坑

5.1 工具数量一多,选择准确率断崖式下跌

这个坑前面提过,但值得单独说,因为它的表现特别有迷惑性。最开始给模型挂了七八个工具,跑得挺好;后来业务扩展,工具加到十五个,开始出现“该调 A 却调了 B”的情况;加到二十多个之后,连本来很稳的那几个基础工具也开始调错。

一开始我以为是模型能力不够,换了个更强的模型,确实好了一点,但没解决问题。后来把调用日志拉出来一条条看,发现规律:错的那些工具,描述里都有重叠的关键词。比如“查询订单”和“查询物流”,描述里都出现了“订单号”,模型就分不清该用哪个。

解决办法有两个层次。浅层是把描述改得更互斥——明确写“如果你要查的是配送状态,请用另一个”。深层是做工具分组,每次只暴露当前步骤相关的子集。这两个动作做完之后,准确率恢复到能接受的水平,而且换回原来那个较弱的模型也基本够用。

这件事给我的教训是:工具不是越多越好,工具集的边界清晰度比工具数量重要得多。设计工具的时候,与其想着“我要覆盖多少功能”,不如想着“我要让每个工具在什么情况下该被调用变得毫无歧义”。

5.2 上下文越滚越大,成本和延迟双爆

第二个坑是上下文膨胀。Agent 跑多轮之后,每一轮都要把之前所有的工具返回结果一起带上,几轮下来上下文能涨到几万 token。表现出来就是:越到后面越慢、越贵,而且准确率反而下降——因为关键信息被淹没在一堆无关的中间结果里了。

我做过一次统计,一个跑了 8 轮的 Agent 任务,如果全量保留历史,最后一轮的输入是第 1 轮的 6 倍多,而实际有用的信息可能只多了 30%。剩下的都是已经处理完的原始数据,模型根本不需要再看一遍。

处理办法是把上下文分成两层:一层是“工作区”,只放当前这一步需要的东西;另一层是“结论区”,放已经确认的事实和已完成步骤的摘要。每完成一步,就把这一步的原始结果压缩成一句结论写进结论区,工作区清空。这个改动之后,长任务的成本和延迟都降了下来,而且因为上下文更干净,判断准确率也有提升。

这里有个细节:压缩结论的时候要保留“为什么”,不能只留“是什么”。比如不要只写“已确认订单 A 存在”,要写“已确认订单 A 存在(通过订单号精确匹配)”。后者在后续需要判断可信度的时候能派上用场。

5.3 评测缺失:改了一行提示,整体效果悄悄退化

第三个坑最隐蔽,也最伤。因为没有评测集,每次调提示、换工具描述、换模型,都只能靠手动试几个例子看看。看着没问题就上线了,结果过几天发现某个边缘场景坏了,而这时候已经不知道是哪次改动引入的。

后来我强制要求每个 Agent 项目先攒一个最小评测集:二三十条真实出现过的输入,覆盖常见路径和已知的边界情况,每条都标注期望的关键行为(不要求逐字匹配,但要求关键判断正确)。每改一次提示或工具,跑一遍这个集合,对比通过率。这套东西搭起来花不了两天,但省下的返工时间远不止两天。

评测集这东西的另一个好处是,它能让你在讨论“效果好不好”的时候有共同语言。没有评测集的时候,产品说“感觉变笨了”,开发说“我测了没问题”,最后只能靠吵。有了评测集,直接看通过率从 82% 掉到 76%,是哪个用例掉的,一目了然。

6. 从大模型到 Agent 的渐进路线

6.1 第一步永远是“不加 Agent”

我见过太多项目一上来就设计一个多工具、多轮循环、带记忆的复杂 Agent,最后跑不起来,不是因为 Agent 不行,是因为连最基础的那一步都没验证清楚——这个任务用一次模型调用能做到什么程度?

正确的顺序是先把最简单的版本跑通:一次调用、固定提示、人工检查输出。跑个几十条真实数据,看看到底错在哪。如果错误集中在“信息不够”或者“格式不稳”,那加提示、加示例就能解决,不需要 Agent。如果错误集中在“需要去查系统里的东西”或者“需要根据中间结果改方向”,那才是 Agent 该上场的地方。

这一步省不得。因为只有先把简单版本跑通,你才知道 Agent 里每一步的基线是什么——比如抽取这一步纯大模型能做到 90% 准确率,那 Agent 加进来之后如果掉到 80%,你就知道是流程设计出了问题,而不是任务本身太难。

6.2 加工具的优先级顺序

真要往 Agent 走,工具不是一次加满的,我一般按这个顺序往上叠:

先加只读的查询类工具。这类工具风险最低,错了重查就行,而且能立刻解决“模型不知道系统里有什么”这个最普遍的痛点。这个阶段主要验证两件事:模型能不能正确地选对工具、能不能正确地填参数。

再加计算和转换类工具。让模型把不需要它动脑的部分交出去——算数、格式转换、排序、去重。大模型做这些事又慢又容易错,交给确定性代码做又快又准。这一步的收益经常被低估,实际上它能显著减少“看起来很对但数字算错了”这类问题。

最后才考虑写操作类工具。而且第一版一般做成“生成操作建议 + 人工确认后执行”,跑一段时间确认稳定之后再考虑全自动。跳过人工确认直接上全自动的,我见过的事故不止一次。

6.3 什么时候才值得上多 Agent

多 Agent 这个概念现在被炒得很热,但我在实际项目里用得很少。多 Agent 的价值在于把不同职责拆开,让每个 Agent 有独立的提示、独立的工具集、独立的上下文——本质上是一种模块化。如果单个 Agent 的提示已经长到互相干扰、工具集已经大到选择困难,那拆开是有意义的。

但拆开也有代价:Agent 之间的通信成本、职责边界模糊导致的互相推诿、整体链路的调试难度成倍上升。我遇到过最典型的失败案例是三个 Agent 互相传话,一个说“数据不完整”,一个说“我已经给了”,一个说“我再查一遍”,来回好几轮,实际上问题出在最初那个工具的参数上。

我的判断标准比较保守:单 Agent 的提示还能读懂、工具集还在十个以内、上下文还能控制住,就不拆。真正需要拆的场景通常是职责差异非常大的,比如一个负责理解需求、一个负责执行操作、一个负责检查结果,而且每一块的提示和工具都完全不同。职责相近的拆开,只会增加沟通成本。

最后分享一个我觉得特别有用的小习惯:每次要给一个任务上 Agent 之前,先自己手动把这个流程走一遍,把每一步的输入输出都写下来。如果写的过程中发现有哪一步你自己都说不清该怎么判断,那这一步大概率就是 Agent 会翻车的地方,先在那一处加确定性规则或者加人工确认,比什么提示技巧都管用。这个习惯听起来笨,但它帮我在动手之前就砍掉了不少注定要返工的设计。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进