在上一篇文章中,我们通过LangChain框架介绍了AI Agent,也提到了对LLM的调用,那么对LLM的调用和AI Agent之间究竟有什么区别?本文则继续基于LangChain详细介绍两者的本质区别以及相应的使用场景。
一、普通大模型调用解决的是一次推理任务
先看最简单的大模型程序。
用户输入
↓
构造 Prompt / Messages
↓
调用 LLM
↓
获得 Response
↓
程序继续执行
例如:
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-5.4")
response = model.invoke(
"请解释 Python 中 list 和 tuple 的主要区别。"
)
print(response.content)
运行结果
模型生成内容具有随机性,下面展示一次典型结果:
list 和 tuple 都用于保存有序数据。
主要区别是 list 可以修改,而 tuple 通常作为不可变序列使用。
list 使用 [],tuple 通常使用 ()。
这里有两个角色。
LLM 负责:
输入 → 推理 → 输出
应用程序负责:
什么时候调用 LLM
↓
给 LLM 什么数据
↓
拿到结果之后做什么
也就是说,模型拥有内容生成权,但没有程序流程的控制权。
它完成的是一次推理任务。
翻译、摘要、分类、信息抽取、文本改写、生成 SQL 等大量场景,本质上都可以采用这种模式。LangChain 当前也把 Model 作为可以独立调用的基础组件,同时说明模型也可以作为 Agent 的推理引擎。
二、Tool Calling 仍然不等于 Agent
这里有一个特别容易混淆的问题:
模型可以自己选择工具,是不是就已经成为 Agent 了?
不一定。
现代模型普遍支持工具调用(Tool Calling / Function Calling)。开发者先告诉模型有哪些工具以及每个工具的参数结构,模型可以返回一个结构化的工具调用请求。
例如:
from langchain.chat_models import init_chat_model
from langchain.tools import tool
@tool
def get_order_status(order_id: str) -> str:
"""查询订单当前状态。"""
return f"订单 {order_id} 已发货"
model = init_chat_model("openai:gpt-5.4")
model_with_tools = model.bind_tools([get_order_status])
response = model_with_tools.invoke(
"查询订单 A1024 的状态"
)
print(response.tool_calls)
示例输出
[
{
"name": "get_order_status",
"args": {"order_id": "A1024"},
...
}
]
模型确实已经做出了一个决定:
应该调用 get_order_status
参数是 A1024
但这里需要注意,模型只是提出了调用请求,并没有真正执行 Python 函数。
在独立使用 Model 时,LangChain 官方文档明确说明:模型返回 Tool Call 之后,需要应用程序执行工具,再把 Tool Result 放回消息历史,然后再次调用模型。
完整过程实际上是:
LLM
↓
我要调用 get_order_status
↓
你的 Python 程序执行工具
↓
得到工具结果
↓
你的程序重新调用 LLM
↓
LLM 生成最终答案
因此:
Tool Calling 是模型的一种能力,而 Agent 是围绕这种能力构建出来的一种执行系统。
这是理解 Agent 非常重要的一层边界。
三、Agent改变的是程序的控制方式
普通 LLM 调用与 Agent 最根本的区别,可以从“控制流”来理解。
传统程序通常是:
result_a = step_a()
if result_a:
result_b = step_b()
result_c = model.invoke(...)
下一步做什么,由开发者提前写进代码。
即使中间使用了 LLM,程序整体仍然是:
开发者定义流程
↓
程序按照流程执行
↓
LLM只是其中一个节点
Agent 则引入了一种不同的运行方式:
目标
↓
LLM判断
↓
选择Action
↓
环境执行
↓
获得Observation
↓
重新判断
↓
选择下一步Action
↓
……
↓
完成任务
LangChain 当前的 create_agent 正是围绕这个循环运行:调用模型,让模型选择工具,执行工具,然后把结果重新送入模型;当模型不再请求工具时结束。
所以,更准确地说:
普通 LLM 调用把模型放在流程里面;Agent 则让模型参与决定流程本身。
变化的不是“调用次数”,而是决策权的位置。
四、从一次调用到 Agent Loop
假设用户提出一个稍微复杂的任务:
查询订单 A1024。如果已经发货,查询物流状态;如果物流异常,再查询售后处理规则,然后告诉我应该怎么办。
传统 Workflow 可以直接写:
查询订单
↓
判断是否发货
↓
查询物流
↓
判断是否异常
↓
查询售后规则
↓
调用 LLM 生成回答
这个方案没有任何问题。
甚至从工程角度看,这种流程往往更加可靠。
因为每一步都是开发者预先确定的:
条件 A → 执行 B
条件 C → 执行 D
但如果任务变成:
帮我调查为什么订单 A1024 还没有收到,并给出处理建议。
事情就变得不同。
完成这个目标可能需要:
查订单?
查物流?
查仓库?
查天气?
查客服记录?
查退款政策?
而且查询物流之后得到的信息,可能决定下一步是否还需要查询其他系统。
这时很难提前写出一棵完整的 if/else 决策树。
Agent 更适合处理这种情况。
它可能第一次执行:
get_order_status("A1024")
得到:
已发货
然后决定:
继续查询物流
得到:
包裹停留在上海中转站 3 天
模型发现仍然不能解释原因,于是继续:
get_logistics_exception(...)
最后才生成回答。
这就是 Agent Loop 的意义:
下一步不是只由最初的问题决定,也由前一步执行结果决定。
LangChain 官方把 Agent 描述为动态定义自身过程和工具使用方式的系统,而 Workflow 则具有预先确定的代码路径。
五、Agent不是“LLM + Tools”,而是一个闭环系统
如果继续向下拆,Agent 至少包含几个相互配合的部分。
Model:判断下一步
Model 是推理引擎。
它读取当前上下文,然后决定:
直接回答
还是
调用工具
如果调用工具,还要决定:
调用哪个工具
使用什么参数
工具返回以后,模型还要再次判断:
信息够了吗?
还需要做什么?
是否应该结束?
因此 Model 提供的是决策能力,但 Model 本身并不是 Agent。LangChain 官方也明确把模型描述为 Agent 的 reasoning engine。
Tool:改变或观察外部世界
LLM 本身主要处理上下文中的信息。
Tool 则把模型连接到外部系统,例如:
数据库
搜索引擎
文件系统
浏览器
Python
GitHub
企业 API
邮件系统
日历
工具既可以读取信息,也可能产生真实副作用,例如:
发送邮件
创建订单
修改数据库
提交代码
因此工具不是“给模型补充知识”这么简单,它实际上提供了 Agent 观察环境和作用于环境的接口。LangChain 的 Tool 也是具有明确输入、输出和描述的可调用函数。
State:保存当前执行现场
一次普通 LLM 调用通常只关心:
Input → Output
但 Agent 需要知道自己已经执行到了哪里。
例如:
用户原始任务
历史消息
已经调用过哪些工具
工具返回了什么
当前有哪些中间结果
任务是否已经完成
这些信息共同形成执行过程中的状态(State)。
如果没有状态,每次模型调用都会像重新开始一样,它无法根据之前的工具结果继续工作。
LangGraph 的 Graph API 将 State 定义为应用当前状态的共享数据结构;LangChain 的 Agent 又运行在 LangGraph Runtime 之上,因此状态和执行过程不是附加功能,而是 Agent 编排的重要基础。
Runtime:真正执行这个循环
Model 只负责产生决策。
Tool 只负责执行某个动作。
还需要一个 Runtime 把它们连接起来:
调用模型
↓
读取 Tool Call
↓
执行 Tool
↓
更新 State
↓
再次调用模型
↓
检查是否结束
LangChain 当前的 create_agent 底层运行在 LangGraph Runtime 上。这个 Runtime 还可以承载上下文、Store、执行信息以及流式输出等能力。
因此一个更完整的 Agent 可以理解为:
Agent
=
Model
+
Tools
+
State
+
Agent Loop
+
Runtime
+
控制规则
而不是简单的:
Agent = LLM + Tools
后者适合作为入门记忆,前者才更接近工程实现。
六、Agent与Workflow的边界尤其重要
理解 Agent 时,最容易犯的另一个错误,是把所有多步骤 LLM 程序都叫作 Agent。
例如:
用户问题
↓
分类器
↓
搜索
↓
RAG
↓
LLM总结
↓
返回
这可能是一个非常完整的 AI 应用,但它并不一定是 Agent。
判断标准不是:
有没有 LLM?
有没有 Tool?
步骤多不多?
而是:
执行路径主要由谁决定?
LangGraph 官方给出的区分非常直接:Workflow 的代码路径是预先确定的,而 Agent 的过程和工具使用是动态的。
因此可以形成三个层级。
普通 LLM 调用
开发者决定:什么时候调用模型
模型决定:生成什么
Workflow
开发者决定:整个执行路径
模型负责:某些节点中的推理
Agent
开发者决定:目标、工具、规则和边界
模型决定:运行过程中下一步采取什么行动
这个区别比“Agent 可以调用工具”更加准确。
七、Agent获得自主性的同时,也失去了一部分确定性
把控制权交给模型之后,会产生一个很直接的结果:
系统的执行路径变得不完全确定。
对于传统 Workflow:
A → B → C → D
开发者通常知道下一步一定是什么。
对于 Agent:
A
↓
LLM
├─→ B
├─→ C
└─→ D
进入 B 以后,模型还可能继续选择:
B
├─→ E
└─→ F
于是一次任务可能执行:
A → B → E → Response
另一次相似任务可能执行:
A → C → F → B → Response
这就是 Agent 可以处理开放问题的原因,也是 Agent 更难工程化的原因。
两者实际上是在做一种交换:
| 维度 | 普通调用 / Workflow | Agent |
|---|---|---|
| 控制流 | 开发者预先定义 | 运行时动态决定 |
| 模型角色 | 内容生成或局部判断 | 持续参与决策 |
| 执行路径 | 相对固定 | 可能变化 |
| 工具使用 | 程序决定 | 模型可动态选择 |
| 中间状态 | 通常较简单 | 通常更重要 |
| 可预测性 | 高 | 相对低 |
| 测试难度 | 较低 | 较高 |
| Token / API 成本 | 较容易估计 | 与实际路径相关 |
| 适合问题 | 已知流程 | 开放式、多步骤任务 |
因此 Agent 并不是免费获得“自主性”。
它实际上完成了一次交换:
降低部分确定性
↓
换取更强的运行时适应能力
这也是为什么 Agent 系统往往需要更多的可观测、重试、限流、权限、终止条件和人工介入机制。LangChain 当前通过 Middleware 提供日志、工具选择控制、重试、提前终止、Guardrails 和 Human-in-the-loop 等控制能力。
八、Agent的“自主”实际上是受约束的自主
Agent 经常被描述成“自主执行任务的 AI”。
这个说法容易产生另一个误解,好像模型获得了完全自由的执行能力。
实际上,工程中的 Agent 更接近:
在开发者规定的行动空间中,由模型动态选择下一步动作。
开发者仍然决定:
给它什么模型
给它哪些工具
工具具有什么权限
能够访问什么上下文
最多执行多少步
什么操作需要人工确认
发生错误如何处理
什么时候强制停止
例如一个 Agent 只有:
search_web
read_file
两个工具,那么无论模型如何推理,它都不能发送邮件。
如果再增加:
send_email
它才拥有发送邮件的行动能力。
因此 Agent 的能力边界,并不只是由模型决定,而是由:
Model 能力
×
Tool 能力
×
Context
×
Runtime
×
Policy
共同决定。
这也是为什么 Agent 工程中经常会出现 Middleware、Guardrails、权限控制以及 Human-in-the-loop。它们并不是额外装饰,而是在动态执行过程中重新建立可控性。
九、什么时候用普通调用,什么时候用 Agent
实际开发中,不应该从“Agent 更先进”这个角度做选择。
更实用的判断方式,是看任务路径是否可以提前确定。
例如:
文本 → 摘要
文本 → 分类
数据 → JSON
中文 → 英文
直接调用 LLM 即可。
如果任务是:
读取用户问题
→ 查询知识库
→ 把资料交给模型
→ 生成答案
流程已经非常明确,更适合 Workflow。
即使其中调用了向量数据库、搜索 API 和 LLM,也没有必要强行做成 Agent。
但如果需求是:
调查这个项目为什么部署失败,并尽可能找到原因。
模型可能需要:
读日志
↓
判断问题
↓
查配置
↓
发现依赖异常
↓
查 package.json
↓
搜索文档
↓
再次检查日志
↓
给出结论
开发者很难提前知道需要执行哪些步骤。
这种目标明确,但解决路径不明确的问题,更适合 Agent。
可以用一句简单的判断来区分:
步骤已知 → 优先 Workflow
目标已知、步骤未知 → 考虑 Agent
当然,两者并不是互斥关系。
实际生产系统经常采用混合方式:
确定性 Workflow
↓
某个开放问题
↓
Agent
↓
返回 Workflow
↓
继续确定性处理
LangChain 的 Middleware 文档也明确支持把完整 Agent 作为节点或子图放入更大的 LangGraph 工作流中,用确定性步骤包围 Agent。
这通常比“所有事情全部交给 Agent”更加容易控制。
十、真正需要理解的是控制权的变化
回到最开始的问题。
普通大模型调用、Tool Calling、Workflow 和 Agent,并不是四个完全独立的技术。
它们更像是逐步增加模型决策范围的几种系统形态:
普通 LLM
模型决定:说什么
↓
Tool Calling
模型还可以决定:想调用什么工具
↓
Workflow
模型参与多个步骤
但整体路径仍由代码决定
↓
Agent
模型持续根据当前状态决定:
下一步做什么、用什么工具、是否继续
所以,AI Agent 与普通大模型调用之间最值得理解的差异,并不是“Agent 调用了更多次 LLM”,也不是“Agent 能联网、能搜索、能调用 API”。
它改变的是应用程序中的控制权分配。
普通调用中,模型是被程序调用的一个能力;Agent 中,模型进一步成为运行时的决策组件,而 Runtime 负责不断把模型决策、工具执行和状态更新组织成反馈循环。
本文可以最终把这个关系总结成一句话:
LLM 负责推理,Tool 负责行动,State 记录现场,Runtime 负责执行循环,而 Agent 让模型在这些能力之上持续决定“下一步做什么”。
这也是为什么学习 Agent 时,不必急着进入多 Agent、长期记忆或复杂规划。先真正理解一次 Model Call、一次 Tool Call 和一个 Agent Loop 之间发生了什么,后面的 LangChain、LangGraph 和 Deep Agents 才会自然衔接起来。
社区讨论
参与讨论
有问题或想法?欢迎继续讨论。