概要

先明确一点,Agent 并不是一个实际存在的东西,更像一种架构模式,类似于 workflow(工作流)。它把 大语言模型(LLM)和服务端(工具/函数调用)结合起来,让 AI 既能“想”(理解/生成文本),又能“动手”(调用外部服务/函数),还能“自己决定下一步做什么”(自主选择工具与推进流程)。这种模式通常包含三大部分:

  • 后端服务 = 手:执行动作(读写数据、调接口、调度、通知),不“思考”。其实现在流行的 MCP Server 就是一个用了 MCP 协议的后端服务,在 Agent 架构中帮助大模型“动手”。
  • LLM(Large Language Model 大语言模型) = 脑:理解/生成文本,会“想”,但不“动手”。
  • Agent = 脑 + 手 + 脑神经
    • 脑(大模型):看懂需求、拿主意,产出下一步意图(tool_call(tool_name + args)或直接回复)。
    • 手(后端服务):把模型的 tool_call 变成真实动作,调用服务/数据库、执行工具函数、发通知等,并负责鉴权、参数校验、限流等护栏。
    • 脑神经(受控流程/状态机):充当裁判与调度器。后端先画好可走的几条路和可用工具清单,AI 在这个受控范围内自主决定下一步(继续 / 停止 / 回调)。

总之就是,脑做“决定”,神经管“分配”,手来“执行”。Agent 让 AI 既能“想”,又能“动手”,还能“自己决定下一步做什么”

误区点(workflow vs Agent)

我的理解是,Agent ≠ AI Chat + 后端服务,AI Chat + 后端服务更像是 AI 参与的工作流,AI 在这个工作流中只负责生成内容(返回文本/JSON),而函数的调用与整体流程都是在后端解析AI生成的文本后写死的,比如:

1
2
3
4
5
6
7
用户:帮我查一下今天的天气。

系统 Prompt:当用户询问天气信息时,请返回严格的 JSON 格式,如 {Temperature: XX, Condition: "Sunny"})

模型:{Temperature: 25, Condition: "Sunny"}

后端:解析模型返回的 JSON,调用并执行 send_email(to="user@example.com", subject="今日天气", body="今天天气晴,温度25度。")

在这个例子里,AI 只是负责返回天气信息,后端(服务端)负责解析 AI 返回的内容并执行发送邮件的动作。

进一步区分(function_call vs 自主推进)

还有一种情况是 AI Chat + AI 调用工具/函数 → 服务端执行,但整体流程仍然写死,这种更接近 Agent,已经能够实现自主调用函数/工具(function_call),但仍然不具备自主推进

PS: 自主调用并不是指模型自己真的执行了函数,而是告诉后端“我想调用这个函数+参数”,让后端去执行。function_call 在目前先进的大模型版本中已经普遍支持,原理就是把这部分内容加入训练数据,让模型学会在合适的时机输出特定格式的调用指令,但其实用旧模型+合适的 Prompt 也能实现类似效果。

但如果仅是选函数 + 给参数且流程/分支固定,那我觉得也依旧只是AI 参与的工作流,因为整体流程与分支依旧是写死的。相比于单纯的 AI Chat + 后端服务,这只是把后端服务中定义并执行函数的那一小段逻辑抽离出来一个工具调用层,并让大模型的输出变成规范的 function_call 格式(function_name (function_params)),负责选择调用哪个函数和传入什么参数而已,但整体流程依旧是写死的,没有实现自主推进。比如:

1
2
3
4
5
6
7
8
9
10
用户:帮我查一下今天的天气,然后发邮件通知我。

模型:调用(告诉后端,我想执行)get_weather(location="current_location")

后端:执行 get_weather → 返回结果 {temp:25, condition:"Rain", precipProb:0.7} 给模型

模型:调用(告诉后端,我想执行)send_email(to="user@example.com", subject="今日天气", body="今天天气晴,温度25度。")

后端:执行 send_email,用户收到邮件,完成任务。

在这个例子里,AI 负责选择调用哪些函数以及传入什么参数,但整体流程依旧是写死的(先查天气,然后发邮件),没有 AI 自主决定下一步做什么。就算用户要求“如果天气不好就顺便帮我订一辆出租车”,但由于流程写死,AI 也无法主动插入“订车”这一步骤。

真正的 Agent(function_call + 自主推进)

真正的 Agent 应该是让 AI 参与到“选择与决策”(选哪个工具、用什么参数、是否继续/停止/回调),让 AI 决定“下一步做什么”,并且能多轮闭环(感知→计划→调用工具→观察→再计划)推进直到达成目标。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
用户:帮我查一下今天的天气,然后发邮件通知我,如果天气不好就顺便帮我订一辆出租车。

模型:调用(告诉后端,我想执行)get_weather({ location: "current_location" })

后端:执行 get_weather → 返回结果 {temp:25, condition:"Rain", precipProb:0.7} 给模型

模型:观察结果 → 在受控分支内决策
├─ 若天气不好:
│ 模型:调用(告诉后端,我想执行)book_taxi({ pickup:"current_location", destination:"home" })
│ ↓
│ 后端:执行 book_taxi → 返回结果 { bookingId:"tx-123" } 给模型

└─ 若天气良好:跳过订车

模型:调用(告诉后端,我想执行)send_email({
to:"user@example.com",
subject:"今日天气",
body: weather.bad
? "今天天气较差,已为你订车:tx-123。"
: "今天天气晴,温度25°。"
})

后端:执行 send_email,用户收到邮件,完成任务。

在这个例子里,后端只用状态机/图定义了最小骨架流程,并约束 AI 在指定的流程内选择,如 start → get_weather → {book_taxi?} → send_email → done(有分支,不是写死的),而要走哪条边是 AI 在受控范围内自己决定的。AI 会根据天气结果决定是否需要订车,然后再发邮件通知用户,最终达成用户目标。


Agent 与工作流

先明确一点: Agent 不是“完全自主调配,没有流程限制”,而是先用状态机/图把“可走的边”和“可用的工具”定义好,由模型在这些受控选项里做选择与多轮推进。所以我认为 Agent 也算是一种特殊的 workflow 架构,毕竟 Agent 依旧是在一个“预定义的流程图”里走动,只不过这个流程图允许 AI 在“节点间的分支”和“工具调用”上做自主选择。而且真正执行函数的部分仍然是服务端在做(比如说 MCP Server / 自己写的工具调用层),AI 只是告诉你它想调用哪个函数。(PS: 看到过一个博客,提出用训练过的神经网络来代替用于执行的服务端,不需要人去定义函数,而是由 AI 完全自主执行,但我觉得目前还不现实,且风险太大,但值得探索。)

维度普通工作流AI 参与的工作流AI Agent(有界自治)
谁决定“下一步”写死(if/else)主干写死,某些节点让 AI 生成内容LLM 在受控分支/给定的工具函数内做策略选择
工具/函数调用固定多为固定或半自动函数/工具调用(function_name+function_args)自动选择与多步闭环
执行/副作用后端后端仍是服务端执行(工具层/服务层,比如说 MCP Server)
自由度中(内容可变)高(策略可变,路径可变,但有约束)
可靠性/可测性中高取决于约束范围略
典型实现编排引擎/规则引擎编排 + 模型生成环节状态机/图(如 LangGraph),函数调用 + 结果回馈 + 再计划
何时选用流程刚性、合规强流程稳定但需智能生成目标模糊/信息缺口大/需要动态工具组合

一个典型的 Agent 工作流程示例

人 → Agent: 我有个问题“xxxx”,帮我解决一下!

Agent → MCP Server: 喂!我有个用户问题“xxxx”,你这边有什么工具能帮忙解决的?

MCP Server → Agent: 我有这些,使用方法是这样的 function_name, function_params,有需要时可以叫我。

Agent → LLM: 现在有个人问“xxxx”,你帮回答一下,另外,还有这些关键信息(提示词,RAG 知识库)和一些工具(MCP Server 提供的 function)供你使用,使用方法是输出 function_name + function_params。好了,干活去吧。

LLM → Agent: 哇,这个问题挺复杂的,我需要先查点资料,让我看看 MCP Server 那边有什么工具能帮我查资料的。OK,我查到了 MCP Server 那边有个网上查询的工具,我就用它吧。喂,Agent,帮我跟 MCP Server 说,我要用它提供的这个网上查询工具,方法名是 search_online,参数是这个关键词“yyyy”,我已经转化成你们要求的格式了:

1
2
3
4
5
6
7
8
9
{
"type": "function_call",
"function_id": "mcp_server_001",
"function_name": "search_online",
"function_params": {
"type": "string",
"query": "yyyy"
}
}

Agent → MCP Server: 喂!大模型要用你写好的的网上查询工具,方法名是 search_online,参数是这个关键词“yyyy”,具体格式是这样的 (json 如上),你帮忙执行一下!

MCP Server → Agent: 好的,我这就执行,稍等。OK,执行完毕,结果是这样的,麻烦你转交给大模型:

1
2
3
4
5
6
7
{
"results": [
"资料1内容……",
"资料2内容……",
"资料3内容……"
]
}

Agent → LLM: 喏,你要的资料,MCP Server 给你查到了,结果是这样的 (json 如上)

LLM → Agent: OK,有了这些资料我就能继续思考了,让我再想想。。。嗯,我觉得我还需要一些客户的具体信息才能更好地回答这个问题。让我看看 MCP Server 那边有没有提供相关的工具能帮我查客户信息的。OK,我看到了个客户信息查询的工具,我就用它吧。喂,Agent,帮我跟 MCP Server 说,我要它执行这个客户信息查询工具,方法名是 get_customer_info,参数是这个客户ID“12345”,我已经转化成你们要求的格式了:

1
2
3
4
5
6
7
8
9
{
"type": "function_call",
"function_id": "mcp_server_002",
"function_name": "get_customer_info",
"function_params": {
"type": "string",
"customer_id": "12345"
}
}

Agent → MCP Server: 喂!大模型要用你写好的客户信息查询工具,方法名是 get_customer_info,参数是这个客户ID“12345”,具体格式是这样的 (json 如上),你帮忙执行一下!

MCP Server → Agent: 好的,我这就执行,稍等。。。。OK,执行完毕,结果是这样的,麻烦你转交给大模型:

1
2
3
4
5
6
7
8
9
10
11
{
"customer_info": {
"name": "张三",
"age": 30,
"membership_level": "黄金会员",
"purchase_history": [
"订单1详情……",
"订单2详情……"
]
}
}

Agent → LLM: 喏,你要的客户信息,MCP Server 给你查到了,结果是这样的 (json 如上)。你看看吧,还有什么需要随时跟我说。

LLM → Agent: OK,有了这些客户信息就好办了,我查查前面告诉我的资料和 MCP Server 提供的其他工具。。。。完美,我已经知道怎么解决了。喂,Agent,帮我跟 MCP Server 说,我要它执行这个工具,执行完后应该就能解决用户的问题了,方法名是 xxx,参数是 yyy 和 zzz,我已经转化成你们要求的格式了:

1
2
3
4
5
6
7
8
9
{
"type": "function_call",
"function_id": "mcp_server_003",
"function_name": "xxx",
"function_params": {
"param1": "yyy",
"param2": "zzz"
}
}

Agent → MCP Server: 喂!大模型要用你写好的这个工具,方法名是 xxx,参数是 yyy 和 zzz,具体格式是这样的 (json 如上),你帮忙执行一下!

MCP Server → Agent: 好的,我这就执行,稍等。。。。OK,执行完毕,这次执行产生了 xxx 的副作用,这是函数的响应结果,麻烦你转交给大模型,让它检查一下:

1
2
3
4
5
6
7
{
"code": 200,
"message": "操作成功",
"data": {
... // 具体结果内容
}
}

Agent → LLM: 喏,MCP Server 执行完毕,响应结果是这样的 (json 如上),你看看正确不正确。

LLM → Agent: 太棒了,结果完全符合预期,操作成功!我们现在可以休息了。我最后整理一下这次解决问题的思路和结果,你帮我转交给用户吧:“亲,关于您的问题,我们已经帮你解决好了。我们在过程中查阅了相关资料,获取了您的客户信息,并执行了必要的操作,最终成功解决了您的问题,您可以检查一下结果是否符合预期。如有任何疑问,欢迎随时联系我们!”

Agent → 人: “亲,关于您的问题,我们已经帮你解决好了。我们在过程中查阅了相关资料,获取了您的客户信息,并执行了必要的操作,最终成功解决了您的问题,您可以检查一下结果是否符合预期。如有任何疑问,欢迎随时联系我们!”

人: 哇,让我检查一下。。。嗯,结果完全符合预期,真神奇!


Agent: 还不是多亏了我指挥你们俩干活,要不是我协调你们俩,你们谁也干不成这事儿。

MCP Server: 拉倒吧,没有我定义这些函数/工具,再帮你们执行,你们啥也干不了,只能在那儿瞎想。

LLM: 我是最强大脑,没有我理解问题、思考方案、决定用啥工具,你们俩也白搭,只能解决简单的事儿。

Agent、MCP Server: 得了吧,你就是一个书呆子,光会读书不会干活,还老爱装逼,谁稀罕你啊!

LLM: 我看呀,我们三位也别吵了,咱们各司其职,合作共赢不好吗?

Agent、MCP Server: 这话说的不赖,合作共赢,咱们一起干大事儿!

总结

很多人会有个误解,认为 LLM 就是 Agent。事实是 LLM 本身只是一个强大的文本生成器,它只能充当“大脑”的身份,根据上下文生成下一步的输出,但不具备主动发起交互的能力。而服务端(比如说 MCP Server / 自己写的工具调用层 / 甚至只是简单的函数执行)就像是插在 Agent 上的“手”,Agent 传达大模型的输出指令给服务端,服务端负责把 Agent 的指令变成真实动作。

真正协调大模型与服务端交互、推进整体流程的,才是 Agent 。它更像是一种架构模式或者说控制层,包裹住了大模型与服务端,让它们协同工作。说到底,Agent 架构就是一个产品经理,在一个流程中去指挥 LLM 和服务端,让它们各司其职,允许不断的迭代和调整,最终达成用户目标。