前面几篇文章分别了解了 Agentic Coding、Context Engineering、MCP 和 MCP Tool Design。
把这些内容放在一起,就会出现一个更核心的问题:
AI Agent 到底是怎么“行动”的?
我们经常看到这样的描述:
用户:
“帮我分析一下这个项目的问题,并修复它。”
Agent:
读取代码
→ 分析问题
→ 修改代码
→ 运行测试
→ 发现错误
→ 再次修改
→ 重新测试
→ 完成任务
看起来像是 AI 在「自主工作」。
但从工程角度看,它并不是一个神秘的黑盒。
Agent 的核心其实可以抽象成一个不断循环的过程:
理解任务
↓
观察当前环境
↓
决定下一步行动
↓
调用 Tool
↓
获得结果
↓
更新 Context
↓
再次判断
↓
……
↓
任务完成
也就是说:
Agent 最核心的能力,不是一次生成一个答案,而是能够根据环境反馈持续决定下一步应该做什么。
1. 从一次 LLM 调用开始
最简单的 LLM 应用其实非常直接:
User
↓
Prompt
↓
LLM
↓
Response
例如:
用户:
解释一下 MySQL 的索引。
↓
LLM:
MySQL 索引是一种……
整个过程只有一次决策。
可以抽象成:
Input → Model → Output
这种模式非常适合:
文本生成
翻译
摘要
分类
问答
代码解释
但它有一个明显限制:
模型只能输出信息,不能真正改变外部世界。
例如用户说:
“帮我查询一下订单 10086 的状态。”
如果 LLM 没有数据库、API 或 Tool,它只能告诉用户:
“我无法访问你的订单系统。”
于是,我们需要给模型增加外部能力。
这就是 Tool Calling 出现的原因。
2. Tool Calling:让模型从“回答”变成“行动”
假设我们提供一个 Tool:
get_order
输入:
{
"order_id": 10086
}
模型收到用户请求:
“帮我查询订单 10086 的状态。”
它不一定直接生成自然语言答案,而可能先生成:
{
"tool": "get_order",
"arguments": {
"order_id": 10086
}
}
应用程序发现这是一个 Tool Call,于是:
LLM
↓
Tool Call
↓
Application
↓
get_order()
↓
Order Service
↓
返回结果
例如:
{
"order_id": 10086,
"status": "shipped",
"tracking_number": "SF123456789"
}
然后这个结果重新进入模型上下文:
用户请求
+
Tool Call
+
Tool Result
↓
LLM
↓
最终回答
最终模型才能回答:
订单 10086 已经发货,物流单号是 SF123456789。
这里有一个非常重要的变化:
传统 LLM:
Input → LLM → Output
Tool Calling:
Input
↓
LLM
↓
Tool Call
↓
Environment
↓
Tool Result
↓
LLM
↓
Output
模型第一次输出的已经不一定是「最终答案」,而可能是下一步行动。
这就是 Agent 的基础。
3. Tool Calling 和 Agent 之间还差一个“循环”
仅仅能够调用 Tool,还不能称为完整的 Agent。
真正关键的是:
Tool 调用完成以后,模型还能不能继续决定下一步?
例如:
用户:
帮我检查一下项目有没有测试失败的问题。
Agent 可能首先调用:
run_tests
得到:
Tests: 3 failed
这时候任务显然没有完成。
模型可能进一步调用:
get_test_failure
得到:
testUserLogin failed
Expected: 200
Actual: 500
然后继续:
search_code
找到:
AuthService.php
接下来:
edit_file
修改代码。
然后:
run_tests
再次测试。
如果:
Tests: passed
Agent 才结束任务。
因此,Agent 最核心的结构实际上非常简单:
while (!done) {
observation = get_context();
action = model(observation);
result = execute(action);
update_context(result);
}
这就是所谓的 Agent Loop。
OpenAI 当前的 Agent 指南也将这种持续运行直到满足退出条件的循环视为 Agent 的核心机制之一;退出条件可以是最终输出、Tool Call 结束、错误或者达到最大执行轮次等。
Anthropic 对 Agent 的定义也非常接近这个模型:Agent 会由模型动态决定自己的过程和 Tool 使用方式,而不是完全按照预先写死的执行路径运行。
4. Agent Loop 到底在循环什么?
把 Agent Loop 展开,可以得到一个非常典型的运行过程:
┌──────────────┐
│ User Task │
└──────┬───────┘
↓
┌──────────────┐
│ Build Context│
└──────┬───────┘
↓
┌──────────────┐
│ LLM │
└──────┬───────┘
↓
┌──────────────┐
│ Next Action? │
└───┬──────┬───┘
│ │
Tool Call Final
↓ ↓
┌──────────┐ End
│ Tool │
└────┬─────┘
↓
Tool Result
↓
Update Context
│
└──────────→ LLM
每一次循环,模型实际上都在回答一个问题:
“基于目前已经知道的信息,我下一步应该做什么?”
这也是 Agent 和普通 Chatbot 最大的区别之一。
普通 Chatbot 更像:
Question → Answer
Agent 更像:
Goal
↓
Observe
↓
Think
↓
Act
↓
Observe
↓
Think
↓
Act
↓
...
↓
Goal Completed
当然,这里的「Think」并不意味着模型必须暴露或输出一段完整的内部推理过程。
从系统实现角度看,我们真正关心的是:
Context
→ Model Decision
→ Action
→ Observation
而不是模型内部的隐藏推理过程。
5. Context 是 Agent 的“工作记忆”
Agent 能够连续执行任务,一个重要原因就是:
每次 Tool 调用之后,环境产生的新信息会重新进入 Context。
例如:
用户:
修复登录接口的问题。
第一次:
Context:
用户要求修复登录接口
模型决定:
Action:
search_code("login")
Tool 返回:
Observation:
AuthController.php
AuthService.php
LoginRequest.php
Context 更新:
用户任务
+
搜索结果
模型继续判断:
Action:
read_file("AuthService.php")
Tool 返回:
Observation:
发现 token 校验逻辑存在问题
Context 再次更新:
用户任务
+
搜索结果
+
文件内容
+
问题分析
然后:
Action:
edit_file(...)
再:
Action:
run_tests(...)
于是 Agent 的 Context 实际上是在动态变化的。
这正是上一篇 Context Engineering 的意义。
可以把 Agent 理解成:
Agent
=
LLM
+
Context
+
Tools
+
Loop
+
Runtime
其中:
LLM
↓
负责决策
Context
↓
提供当前状态
Tools
↓
改变或观察外部世界
Loop
↓
让任务持续推进
Runtime
↓
负责执行、权限、超时、重试等工程控制
6. Agent 和 Workflow 到底有什么区别?
这是理解 Agent 时非常容易混淆的一点。
假设我们要生成一篇文章。
可以设计成固定 Workflow:
用户输入主题
↓
生成大纲
↓
生成正文
↓
检查文章
↓
优化文章
↓
输出
代码可能就是:
outline()
→ write()
→ review()
→ optimize()
每一步都已经提前确定。
这属于:
Workflow。
而 Agent 的方式可能是:
用户:
帮我研究一下这个技术,并写一篇文章。
Agent 自己决定:
搜索资料
→ 阅读官方文档
→ 搜索 GitHub
→ 整理信息
→ 发现资料不足
→ 继续搜索
→ 生成草稿
→ 检查事实
→ 修改
→ 输出
执行路径不是完全固定的。
因此可以简单理解:
Workflow:
人决定路径
LLM 执行步骤
Agent:
人定义目标
LLM 决定路径
Anthropic 对两者的区分也是类似的:Workflow 主要由预先定义的代码路径控制,而 Agent 则由模型动态决定过程和 Tool 使用。
为什么不是什么都使用 Agent?
因为 Agent 并不总是更好。
如果任务非常确定:
上传 PDF
↓
解析 PDF
↓
切分文本
↓
Embedding
↓
写入向量数据库
完全可以使用 Workflow。
没有必要让 Agent 每次都决定:
“我现在应该解析 PDF 吗?”
“还是应该先切分?”
“还是应该先 Embedding?”
这反而会增加:
Token 消耗
延迟
不确定性
调试难度
错误概率
所以一个很重要的工程原则是:
能用确定性 Workflow 解决的问题,不要为了“Agent”而 Agent 化。
Agent 真正适合的是:
步骤无法完全预先确定
+
需要根据环境动态调整
+
任务具有一定开放性
7. 一个真正的 Agent Runtime 应该负责什么?
很多 Agent Demo 看起来只有:
while (...) {
call_llm();
call_tool();
}
但生产环境远远不止这些。
真正的 Agent Runtime 通常需要负责:
Agent Runtime
├── Context Management
├── Tool Registry
├── Tool Execution
├── Permission
├── Timeout
├── Retry
├── Error Handling
├── State
├── Observability
├── Token Budget
├── Max Turns
└── Termination
例如:
最大执行轮次
不能允许:
Tool
→ LLM
→ Tool
→ LLM
→ Tool
→ LLM
→ ...
无限运行。
通常需要:
max_turns = 20
达到上限以后强制停止。
Tool Timeout
某个 Tool 如果执行:
60 秒
Agent 不能一直等待。
应该有:
timeout = 10s
超时以后:
Tool Error
→ Agent 判断
→ Retry / Alternative Tool / Stop
Retry
网络问题:
HTTP 502
Connection timeout
Rate limit
并不一定意味着任务失败。
Runtime 可以进行有限次数重试。
但业务错误:
Permission denied
Invalid order
Resource not found
就不应该简单无限重试。
Permission
例如:
read_file
可以自动执行。
但是:
delete_database
refund_order
send_email
deploy_production
可能需要:
Human Confirmation
MCP 官方 Tool 规范也明确强调了工具调用中的信任与安全问题,并建议应用为用户提供工具暴露情况和调用状态的清晰反馈,以及对敏感操作提供确认机制。
因此:
Agent 的“自主”不应该意味着“无限制”。
真正成熟的 Agent 是:
自主决策
+
明确边界
+
可观察
+
可停止
+
可恢复
8. 从 Tool Calling 到多步骤任务
现在可以把一个完整任务串起来。
假设用户说:
“分析一下这个 GitHub 项目,找到性能问题,
修改代码,然后运行测试。”
Agent 可能执行:
1. search_repository
↓
2. read_file
↓
3. search_code
↓
4. analyze_problem
↓
5. edit_file
↓
6. run_tests
↓
7. test failed
↓
8. read_error
↓
9. edit_file
↓
10. run_tests
↓
11. test passed
↓
12. final response
注意这里最重要的一点:
Agent 并不是提前知道完整的 12 步。
它可能只知道:
Goal:
分析项目 → 修复问题 → 测试通过
然后根据每一次 Observation 决定下一步。
这就是 Agent 的核心能力:
目标固定
+
路径动态
而传统 Workflow 更接近:
目标固定
+
路径固定
9. 当 Tool 越来越多,Agent 又会遇到什么问题?
如果只有:
5 个 Tool
模型通常比较容易选择。
但如果系统拥有:
500 个 Tool
问题马上出现。
例如一个企业 Agent 同时连接:
GitHub
Slack
Jira
Google Drive
Notion
Database
Kubernetes
AWS
Sentry
Grafana
CRM
ERP
每个系统可能拥有几十个 Tool。
如果把所有 Tool 的完整:
name
description
inputSchema
全部塞进 Context:
Tool definitions
+
User prompt
+
Memory
+
RAG
+
Conversation
+
Tool results
Context 很快就会膨胀。
这也是 MCP Tool Design 与 Context Engineering 最终会汇合的地方。
Anthropic 在 2025 年推出的 Advanced Tool Use 中专门讨论了这个问题,并提供了 Tool Search、Programmatic Tool Calling、Tool Use Examples 等机制。其中 Tool Search 的目标就是让 Agent 不需要一开始把整个 Tool Library 全部放进 Context,而是根据任务动态发现和加载需要的 Tool。
因此 Agent 的演进路线实际上很清晰:
少量 Tool
↓
直接 Tool Calling
↓
大量 Tool
↓
Tool Discovery
↓
Tool Search
↓
动态加载
↓
复杂任务编排
这也是下一阶段 Agent Runtime 非常重要的问题。
10. 最终理解:Agent 不是一个模型,而是一套运行系统
到这里,大概可以理解它们的关系:
AI Agent
│
┌──────────────┼──────────────┐
↓ ↓ ↓
Model Context Tools
│ │ │
│ ├─ Memory ├─ API
│ ├─ RAG ├─ Database
│ ├─ History ├─ MCP
│ └─ State └─ Code
│
↓
Decision
│
↓
Agent Loop
│
↓
Tool Execution
│
↓
Environment
│
↓
Observation
│
└──────────────→ Context
所以:
AI Agent
≠
一个更聪明的 Chatbot
更准确地说:
AI Agent
=
Model
+
Context
+
Tools
+
Loop
+
Runtime
+
State
+
Guardrails
其中:
Model 负责理解和决策;
Context 提供当前任务所需的信息;
Tools 让 Agent 能够观察和改变外部世界;
Loop 让 Agent 可以持续执行多个步骤;
Runtime 负责权限、超时、重试、状态和终止;
State 保存长期或跨步骤的任务状态;
Guardrails 限制 Agent 的行为边界。
因此,真正的 Agent Engineering 并不是简单地:
接入一个大模型
+
加几个 Function Calling
而是围绕:
目标
↓
Context
↓
Decision
↓
Action
↓
Observation
↓
Verification
↓
Next Action
建立一个可靠的闭环。
这也是为什么前面的几个概念最终会汇聚到一起:
01 Agentic Coding
↓
让 AI 开始执行软件工程任务
02 Context Engineering
↓
解决 Agent 应该知道什么
03 MCP
↓
解决 Agent 如何连接外部能力
04 MCP Tool Design
↓
解决 Agent 如何正确使用这些能力
05 Agent Loop
↓
解决 Agent 如何持续行动并完成任务