一个常被混淆的问题

"我让 GPT 调用了一个查天气的 API,这算不算 Agent?"

这是我被问得最多的问题之一。答案是:不完全算。 会调用工具,只是 Agent 的起点,远不是终点。

很多人以为"工具调用 = Agent",于是接了个 Function Calling 就觉得自己做出了智能体。但真正的自主 Agent 和"会调工具的模型"之间,隔着好几级台阶。

这篇我想把这几级台阶讲清楚:从最基础的工具调用,一步步走到能自己规划、自己决策、自己纠错的自主 Agent,中间到底发生了什么。


一、第一级:工具调用——让模型「能动手」

最基础的一级,是让模型能调用外部工具。

模型本身只会生成文本,它不会查数据库、不会发邮件、不会跑代码。工具调用解决的就是"动手"问题——你给模型一份工具清单,它根据需要决定调哪个、传什么参数。

tools = [{
    "name": "get_weather",
    "description": "查询指定城市的天气",
    "parameters": {"city": "string"}
}]

# 模型决定调用
response = llm.chat(query="北京今天天气怎么样", tools=tools)
# 返回: {"tool": "get_weather", "args": {"city": "北京"}}

这一级的关键词是单次、被动:用户问一句,模型调一次工具,返回结果,结束。它没有"下一步"的概念。

这就是为什么我说它只是起点——它能动手,但还不会"自己想接下来干什么"。


二、第二级:多步循环——让模型「连续干」

往上一级,是让模型能连续地调用工具,直到任务完成。这就是经典的 ReAct 循环:想一步、做一步、看结果、再想下一步。

Thought(我该查什么)
   → Action(调用工具)
   → Observation(看返回)
   → Thought(根据结果,下一步干什么)
   → ……循环直到完成

到这一级,Agent 开始有了"过程"。它能把一个需要好几步的任务拆开来一步步做,比如"帮我查北京和上海的天气,然后告诉我哪个更适合户外活动"——它会先查北京、再查上海、最后综合判断。

但它的"规划"还是临时的、走一步看一步的,没有全局视野。任务一复杂,就容易跑偏。


三、第三级:任务规划——让模型「先想清楚再动手」

这一级的跃迁很关键:Agent 不再走一步看一步,而是先把整个任务拆成计划,再按计划执行

def plan_and_execute(goal):
    # 1. 先规划:把大目标拆成有序的子任务
    plan = llm.plan(goal)
    # plan = ["查北京天气", "查上海天气", "对比并给建议"]

    results = []
    # 2. 再执行:按计划逐步推进
    for step in plan:
        result = execute_step(step, context=results)
        results.append(result)
        # 3. 关键:每步后检查计划是否还成立
        if need_replan(result):
            plan = llm.replan(goal, results)  # 动态调整
    return summarize(results)

注意第 3 步——动态重规划。计划不是定死的,执行中发现情况变了(某个工具失败、查到的信息推翻了原假设),Agent 能回头修改计划。这是它和"死板执行脚本"的本质区别。

有了规划能力,Agent 才算有了"全局视野",能应对真正复杂的多步任务。


四、第四级:自主决策与纠错——让模型「自己兜底」

最高的一级,是 Agent 能自己判断对错、自己从错误里恢复,而不是一遇到问题就卡死或向你求救。

这一级有两个核心能力:

1. 自我反思(Reflection)

Agent 做完一步后,回头审视自己的产出:"这个结果合理吗?有没有更好的做法?"

def execute_with_reflection(task):
    result = execute(task)
    # 让模型批判自己的产出
    critique = llm.reflect(task, result)
    if critique.has_problem:
        # 根据自我批评,重做一次
        result = execute(task, feedback=critique.suggestion)
    return result

2. 错误恢复(Error Recovery)

工具调用失败是常态——超时、限流、返回格式不对。成熟的 Agent 不会因为一次失败就崩溃,而是有兜底策略:重试、换工具、降级方案。

def robust_call(tool, args, max_retry=3):
    for attempt in range(max_retry):
        try:
            return tool.run(args)
        except ToolError as e:
            if attempt == max_retry - 1:
                return fallback(tool, args)  # 最后兜底
            args = llm.fix_args(args, error=e)  # 让模型修正参数再试

走到这一级,Agent 才真正配得上"自主"二字——它能独立完成任务,遇到坑能自己爬出来,不用你全程盯着。


五、四级能力对照

把这四级摆在一起看,跃迁的脉络就很清楚了:

级别 能力 关键词 能干什么
一级 工具调用 单次、被动 查个天气、调个 API
二级 多步循环 连续、ReAct 拆几步完成一个小任务
三级 任务规划 全局、可重规划 处理复杂多步任务
四级 自主决策 反思、自纠错 独立兜底,无需盯防

每一级都建立在前一级之上,是叠加而非替代。


六、我踩过的三个坑

从工具调用做到自主 Agent,我交过的学费,挑三个最值的分享:

坑一:工具给太多,模型反而选不对。 一开始我恨不得把几十个工具全塞给模型,结果它经常选错。后来才明白——工具列表越短,模型选择越准。按任务动态裁剪工具集,比一股脑全给强得多。

坑二:没有步数上限,Agent 会无限循环。 自主 Agent 有时会陷入"调用-失败-重试-再失败"的死循环,把 token 烧光。一定要设 max_steps 硬上限,到顶就强制收尾。

坑三:自主≠放任。 高危操作(删数据、付钱、对外发送)即便 Agent 能自主决策,也必须留一道人工确认。自主是为了省心,不是为了失控。


写在最后

回头看这条路:工具调用 → 多步循环 → 任务规划 → 自主决策,本质是一个"把人从循环里逐步解放出来"的过程。

会调工具的,只是个听话的执行器;能自己规划、自己纠错的,才是真正的 Agent。

但也别盲目追最高级。任务简单,一级工具调用就够了,上自主 Agent 纯属过度设计。选对级别,比堆能力更重要。