你刚学完ReAct循环,看完LangChain的官方示例,热血沸腾:我要把所有业务都Agent化!
客服?加Agent!推荐?加Agent!搜索?加Agent!连个表单校验都想让Agent来"智能判断"。
停下来。
Agent不是银弹。大多数时候,你需要的只是一个if-else,一个规则引擎,或者一个加了RAG的LLM调用——根本不需要Agent。
这篇文章给你一把尺子。
先搞清楚:Agent到底多做了什么
一句话:Agent = LLM + 自主决策循环。
关键在"自主决策循环"——LLM不是被调一次就完事,而是根据上一步的结果自己决定下一步做什么。
这意味着:
- 多次LLM调用:不是一问一答,可能是5次、10次、50次
- 动态工具选择:不是预先定好调哪个API,而是LLM当场决定
- 状态持续:每一步的结果要传给下一步,上下文越来越长
- 不确定的执行路径:同样的输入,可能走出不同的执行路径
每多一个"自主决策循环",你就多付一份成本:token、延迟、不可预测性、调试难度。
所以问题是:你愿意为"自主决策"付多少成本?值不值?
决策树:4个层级
不是所有任务都在同一个难度线上。按"需不需要Agent"来分,任务可以分成4个层级:
第1层:简单映射——不需要LLM,更不需要Agent
典型场景:FAQ查询、表单校验、状态查询、规则匹配
这类任务的特征:输入和输出之间有确定的映射关系。
# 不需要Agent,甚至不需要LLM
def get_order_status(order_id: str) -> str:
order = db.query(order_id)
if order.status == "shipped":
return f"已发货,快递单号:{order.tracking_no}"
elif order.status == "processing":
return "处理中,预计2天内发货"
...
什么时候你会误判:FAQ场景。很多人觉得"用户问法千变万化,得用LLM理解意图"。没错,意图理解可能需要LLM,但理解完意图后直接查知识库返回结果就够了——不需要Agent循环。一个intent classification + knowledge retrieval的pipeline就搞定。
第2层:结构化生成——需要LLM,不需要Agent
典型场景:文本摘要、翻译、内容生成、信息抽取
这类任务的特征:单次LLM调用就能完成。
# 需要LLM,不需要Agent
async def summarize_meeting(transcript: str) -> str:
response = await llm.complete([
{"role": "system", "content": "你是会议纪要助手,提取关键决策和行动项"},
{"role": "user", "content": transcript}
])
return response.content
什么时候你会误判:内容生成场景。有人觉得"先生成大纲→再逐段生成→再润色"需要Agent。其实这是一个可以预先确定的多步pipeline,不需要LLM自主决策——你提前写好pipeline就行。
# 不是Agent,是固定pipeline
async def generate_article(topic: str) -> str:
outline = await llm.complete(f"生成{topic}的大纲")
sections = []
for section in outline.sections:
content = await llm.complete(f"根据大纲写{section}")
sections.append(content)
full_text = "\n".join(sections)
polished = await llm.complete(f"润色:{full_text}")
return polished
这个pipeline是确定性的——每一步做什么、调用几次LLM,都是你提前写好的。LLM不参与决策,只参与生成。这是"多步LLM调用",不是"Agent"。
第3层:多步推理——需要Agent的底线
典型场景:数据分析先查数据→分析→生成图表→解读、复杂搜索先理解需求→拆解关键词→多源检索→整合结果、故障排查先看日志→定位问题→查文档→给出方案
这类任务的特征:
- 步骤不确定:同样的输入,可能需要不同的执行路径
- 依赖中间结果:下一步做什么取决于上一步的结果
- 需要工具:不只是LLM"想",还需要调用外部工具"做"
# 需要Agent——步骤不确定,依赖中间结果
async def analyze_data(query: str):
# Agent自主决定:先查哪张表?要不要join?要不要聚合?
# 第1步可能发现数据不够,自主决定去查另一张表
# 第2步可能发现异常值,自主决定做进一步分析
# 这些决策不可能提前写死
result = await agent.run(query)
return result
关键判断标准:如果你能提前画出完整的执行流程图哪怕有分支,那就不需要Agent。只有当执行流程本身需要LLM在运行时决定时,才需要Agent。
第4层:开放探索——Agent的真正主场
典型场景:自动化研究多源信息收集+交叉验证+综合分析、复杂编程任务理解需求→设计方案→写代码→测试→调试→迭代、长期运营任务监控+决策+执行+反馈循环
这类任务的特征:
- 目标模糊:用户说不清具体要什么,需要Agent主动探索和确认
- 环境动态:外部条件在变,Agent需要持续感知和适应
- 试错不可避免:不可能一次做对,需要根据反馈迭代
- 长周期:不是一次对话能搞定的,可能跨天跨周
这是Agent最能发挥价值的场景,也是最能烧钱、最难调试的场景。
过度Agent化的3个信号
你可能在过度Agent化,如果:
信号1:你的Agent只有一条路径
打开你的Agent执行日志,看100条trace。如果95条走的是同一条路径——第一步调A工具,第二步调B工具,第三步返回结果——那你根本不需要Agent。
这条路径可以被编码成一个固定pipeline,更快、更便宜、更可控。
真实案例:某电商客服Agent,设计时考虑了退换货、投诉、咨询等多种路径。上线后数据分析发现,87%的请求走的是同一条路:查订单→返回物流信息。这条路径被抽成独立服务后,响应延迟从2.3秒降到0.4秒,成本降了90%。
信号2:你的"工具"其实只是if-else
看看你给Agent注册的工具列表。如果工具的实现长这样:
async def check_inventory(product_id: str) -> dict:
"""检查商品库存"""
stock = db.get_stock(product_id)
if stock > 0:
return {"available": True, "quantity": stock}
else:
return {"available": False, "restock_date": "3天后"}
这个"工具"不需要LLM来决定调不调。它就是一个查询函数,可以在规则引擎里直接调用。
判断方法:如果你的工具列表里,每个工具的调用条件都是确定的比如"用户问库存就调check_inventory",那工具选择不需要LLM的"自主判断",一个意图分类+路由就够了。
信号3:你在用prompt弥补架构缺陷
最隐蔽的过度Agent化:Agent的自主决策其实没起作用,你只是在用越来越长的prompt来约束LLM的行为。
SYSTEM_PROMPT = """你是一个客服Agent。
当用户询问订单状态时,先调用get_order_status工具。
当用户要求退货时,先调用check_return_policy工具。
当用户投诉时,先调用create_ticket工具。
不要调用不相关的工具。
不要重复调用同一个工具。
不要在调用工具前就给出答案。
不要...又追加了20条规则
"""
这个prompt里每加一条"不要",就是在承认:LLM的自主决策不可靠,你在用规则修补它。
当你发现prompt超过1000字、大部分是"不要做什么"时,问自己一个问题:这些规则能不能直接写进代码里?
实战:客服系统从"全Agent"到"Agent+规则引擎"的架构演进
这是一个真实的架构演进案例。名字和细节做了脱敏,但问题模式是普遍的。
V1:全Agent架构
最初的设计:所有用户请求进入Agent,Agent自主决定调什么工具。
用户 → Agent → [查订单|查库存|查物流|退货|投诉|转人工]
问题:
- 平均每个请求4.2次LLM调用3次是"思考"该调哪个工具
- 延迟3-5秒用户:我只是查个快递号啊
- 成本:每天$150的API费用
- 偶尔"幻觉"调错工具用户问物流,Agent调了退货接口
V2:意图分类 + Agent
改进:先用一次LLM调用做意图分类,简单意图直接路由到工具,复杂意图才进Agent。
用户 → 意图分类LLM → 简单意图 → 直接调工具 → 返回
→ 复杂意图 → Agent → [多步推理] → 返回
效果:
- 70%的请求走直接路由,1次LLM调用
- 平均延迟降到1.2秒
- 成本降了60%
- 幻觉问题基本消失简单场景不走Agent了
V3:规则引擎 + 意图分类 + Agent
进一步改进:高频、模式固定的意图用规则引擎处理,不走LLM。
用户 → 规则引擎(关键词/正则) → 命中 → 直接调工具 → 返回
→ 未命中 → 意图分类LLM → 简单意图 → 直接调工具 → 返回
→ 复杂意图 → Agent → [多步推理] → 返回
最终效果:
- 40%请求走规则引擎0次LLM调用,<50ms响应
- 30%走意图分类+直接路由1次LLM调用,<500ms
- 30%走Agent3-5次LLM调用,1-3秒
- 总成本降了85%
- 用户满意度反而提高了简单问题秒回,不用等Agent"思考"
教训
不是"能用Agent就用Agent",而是"能用规则就不用LLM,能用LLM就不用Agent"。
这不是偷懒,是工程成熟度。每一层你放弃的"智能",换来了确定性和低成本。只有在规则和简单LLM调用都搞不定的场景,才值得承受Agent的复杂度。
一个快速判断框架
当你面对一个需求,按这个顺序问:
- 能不能用规则搞定? 关键词匹配、正则、状态机、决策表。能→不需要LLM,不需要Agent。
- 能不能用单次LLM调用搞定? 加上prompt engineering、few-shot、结构化输出。能→需要LLM,不需要Agent。
- 能不能用固定pipeline搞定? 多步LLM调用,但步骤是预先确定的。能→需要多步LLM,不需要Agent。
- 步骤是否必须由LLM在运行时决定? 只有"是"才需要Agent。
如果走到第4步答案是"是",恭喜,你找到了一个真正需要Agent的场景。
但别急着上Agent——先问第5个问题:
- Agent的错误可接受吗? Agent可能走错路径、调错工具、产生幻觉。这些错误的代价是什么?用户能容忍吗?有没有人工兜底?
如果错误代价高、没有兜底,你要考虑的不是"要不要用Agent",而是"怎么加护栏"——后面的文章展开。