第二章 不是所有问题都需要Agent——什么场景该用/不该用

133 阅读9分钟

你刚学完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个层级:

image.png

第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的底线

典型场景:数据分析先查数据→分析→生成图表→解读、复杂搜索先理解需求→拆解关键词→多源检索→整合结果、故障排查先看日志→定位问题→查文档→给出方案

这类任务的特征:

  1. 步骤不确定:同样的输入,可能需要不同的执行路径
  2. 依赖中间结果:下一步做什么取决于上一步的结果
  3. 需要工具:不只是LLM"想",还需要调用外部工具"做"
# 需要Agent——步骤不确定,依赖中间结果
async def analyze_data(query: str):
    # Agent自主决定:先查哪张表?要不要join?要不要聚合?
    # 第1步可能发现数据不够,自主决定去查另一张表
    # 第2步可能发现异常值,自主决定做进一步分析
    # 这些决策不可能提前写死
    result = await agent.run(query)
    return result

关键判断标准:如果你能提前画出完整的执行流程图哪怕有分支,那就不需要Agent。只有当执行流程本身需要LLM在运行时决定时,才需要Agent。

第4层:开放探索——Agent的真正主场

典型场景:自动化研究多源信息收集+交叉验证+综合分析、复杂编程任务理解需求→设计方案→写代码→测试→调试→迭代、长期运营任务监控+决策+执行+反馈循环

这类任务的特征:

  1. 目标模糊:用户说不清具体要什么,需要Agent主动探索和确认
  2. 环境动态:外部条件在变,Agent需要持续感知和适应
  3. 试错不可避免:不可能一次做对,需要根据反馈迭代
  4. 长周期:不是一次对话能搞定的,可能跨天跨周

这是Agent最能发挥价值的场景,也是最能烧钱、最难调试的场景。


过度Agent化的3个信号

你可能在过度Agent化,如果:

信号1:你的Agent只有一条路径

打开你的Agent执行日志,看100条trace。如果95条走的是同一条路径——第一步调A工具,第二步调B工具,第三步返回结果——那你根本不需要Agent。

这条路径可以被编码成一个固定pipeline,更快、更便宜、更可控。

真实案例:某电商客服Agent,设计时考虑了退换货、投诉、咨询等多种路径。上线后数据分析发现,87%的请求走的是同一条路:查订单→返回物流信息。这条路径被抽成独立服务后,响应延迟从2.3秒降到0.4秒,成本降了90%。

fig1-over-agentization-signals.png

信号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。

fig2-cs-architecture-evolution.png

用户 → 规则引擎(关键词/正则) → 命中 → 直接调工具 → 返回
     → 未命中 → 意图分类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的复杂度。


一个快速判断框架

当你面对一个需求,按这个顺序问:

  1. 能不能用规则搞定? 关键词匹配、正则、状态机、决策表。能→不需要LLM,不需要Agent。
  2. 能不能用单次LLM调用搞定? 加上prompt engineering、few-shot、结构化输出。能→需要LLM,不需要Agent。
  3. 能不能用固定pipeline搞定? 多步LLM调用,但步骤是预先确定的。能→需要多步LLM,不需要Agent。
  4. 步骤是否必须由LLM在运行时决定? 只有"是"才需要Agent。

如果走到第4步答案是"是",恭喜,你找到了一个真正需要Agent的场景。

但别急着上Agent——先问第5个问题:

  1. Agent的错误可接受吗? Agent可能走错路径、调错工具、产生幻觉。这些错误的代价是什么?用户能容忍吗?有没有人工兜底?

如果错误代价高、没有兜底,你要考虑的不是"要不要用Agent",而是"怎么加护栏"——后面的文章展开。