核心概念层——深入理解 Agent 是什么

作者:想打游戏的程序猿日期:2026/3/28

1 Agent vs ChatBot:从根本上理解区别

1.1 一个直观的例子

假设你对 AI 说:"帮我分析一下我们公司上周的销售数据,找出表现最好的产品,并给团队发一封总结邮件"。

ChatBot 的反应

1ChatBot: "要分析销售数据,你可以按以下步骤操作:
21. 打开数据库,执行 SQL 查询获取上周的销售记录
32. 使用 Excel  Python 进行数据汇总
43. 找出销售额最高的产品
54. 撰写邮件总结发送给团队
6
7你需要我帮你写 SQL 查询语句吗?"
8
9 ChatBot 只能"说",不能"做"。它给你建议,但执行全靠你自己。
10

Agent 的反应

1Agent 思考: 用户想要三件事: ①分析销售数据 ②找最佳产品 ③发邮件
2
3Step 1: 调用 query_database 工具
4   执行 SQL 查询上周销售数据
5   结果: 获得 500 条销售记录
6
7Step 2: 调用 data_analysis 工具
8   分析数据,按产品分组统计
9   结果: 产品 A 销售额最高($125,000),增长 23%
10
11Step 3: 调用 send_email 工具
12   撰写邮件: "团队好,上周销售总结如下..."
13   发送给团队成员列表
14
15Agent: "已完成分析并发送邮件!上周表现最好的产品是 A,
16        销售额 $125,000,环比增长 23%。详细总结已发送到团队邮箱。"
17
18 Agent 不仅"说",还能"做"。它自主规划、执行、汇报。
19

1.2 本质区别的三个维度

1维度一: 自主性 (Autonomy)
2──────────────────────────────────────────→
3ChatBot                                Agent
4被动响应                              主动行动
5一问一答                              自主循环
6用户驱动每一步                         用户只给目标
7
8
9维度二: 能力边界 (Capability)
10──────────────────────────────────────────→
11ChatBot                                Agent
12只能生成文本                           能执行动作
13无法访问外部系统                        连接各种工具和API
14知识受限于训练数据                      可以实时获取信息
15
16
17维度三: 状态管理 (State)
18──────────────────────────────────────────→
19ChatBot                                Agent
20无状态/简单上下文                       完整的状态管理
21不记住跨会话信息                        长期记忆
22没有目标追踪                           目标导向,跟踪进度
23

1.3 Agent 的定义

综合来说,Agent = LLM + 自主循环 + 工具调用 + 记忆

1// 伪代码展示 Agent 的核心循环
2public class Agent {
3    private final LLM llm;           // 大脑
4    private final List<Tool> tools;  // 工具箱
5    private final Memory memory;     // 记忆
6
7    public Agent(LLM llm, List<Tool> tools, Memory memory) {
8        this.llm = llm;
9        this.tools = tools;
10        this.memory = memory;
11    }
12
13    public String run(String userGoal) {
14        // Agent 的核心运行循环
15
16        // 把用户目标加入工作上下文
17        var context = memory.getRelevant(userGoal);
18
19        while (true) {  //  关键: 自主循环,不是一问一答
20
21            // 1. 思考: 分析当前状态,决定下一步
22            var thought = llm.think(userGoal, context, tools);
23
24            // 2. 判断: 目标完成了吗?
25            if (thought.isGoalComplete()) {
26                return thought.finalAnswer();
27            }
28
29            // 3. 行动: 调用工具执行
30            var toolResult = executeTool(
31                thought.chosenTool(),
32                thought.toolParams()
33            );
34
35            // 4. 观察: 把工具结果加入上下文
36            context.add(toolResult);
37
38            // 5. 记忆: 存储有用的信息
39            memory.save(thought, toolResult);
40
41            // 循环继续,直到目标完成或超过最大步数
42        }
43    }
44}
45

2 Agent 四大组成部分——深入理解

2.1 大脑(LLM):Agent 的决策中心

LLM 在 Agent 中扮演"指挥官"的角色:

1LLM  Agent 中的职责:
2
3┌─────────────────────────────────────────────┐
4                 LLM (大脑)                    
5                                              
6   理解意图: 用户到底想要什么?                  
7     "帮我查下订单"  意图=查询, 实体=订单        
8                                              
9   制定计划: 需要几步?先做什么?                
10     步骤1: 查订单  步骤2: 分析状态  步骤3: 回答 
11                                              
12   选择工具: 这一步该用什么工具?                
13     "查订单"  使用 query_orders 工具           
14                                              
15   生成参数: 工具需要什么输入?                  
16     query_orders(order_id="12345")           
17                                              
18   分析结果: 工具返回了什么?达到目标了吗?       
19     结果显示订单已发货  可以回答用户了           
20                                              
21   生成回答: 组织语言回复用户                   
22     "您的订单 12345 已发货,预计明天送达"         
23└─────────────────────────────────────────────┘
24

选择合适的 LLM 作为大脑

1不同任务对"大脑"的要求:
2
3简单任务(意图分类、格式转换):
4   小模型即可 (Haiku / GPT-4o-mini)
5   快速、便宜
6
7中等任务(文档问答、代码修改):
8   中等模型 (Sonnet / GPT-4o)
9   平衡速度和质量
10
11复杂任务(多步推理、架构设计):
12   强力模型 (Opus / GPT-4o with reasoning)
13   准确性最重要
14
15实际做法: 一个 Agent 内部可以用多个模型!
16  - 路由层: 小模型(判断用户意图)
17  - 执行层: 中等模型(执行具体任务)
18  - 难题: 大模型(处理复杂推理)
19

2.2 规划(Planning):Agent 的策略中心

规划能力是 Agent 区别于 ChatBot 的关键能力。

任务分解(Task Decomposition)

1用户: "帮我搭建一个博客网站"
2
3Agent 的任务分解:
4├── 1. 技术选型
5   ├── 1.1 确定前端框架 (React/Vue/Next.js)
6   ├── 1.2 确定后端方案 (Node.js/Python)
7   └── 1.3 确定数据库 (PostgreSQL/MongoDB)
8├── 2. 项目初始化
9   ├── 2.1 创建项目目录结构
10   ├── 2.2 初始化包管理
11   └── 2.3 配置开发环境
12├── 3. 核心功能开发
13   ├── 3.1 文章 CRUD API
14   ├── 3.2 用户认证
15   └── 3.3 前端页面
16├── 4. 测试与部署
17   ├── 4.1 单元测试
18   ├── 4.2 Docker 容器化
19   └── 4.3 部署上线
20

计划调整(Re-planning)

好的 Agent 会根据执行结果动态调整计划:

1原计划: 使用 MySQL 作为数据库
2
3执行步骤 2.1 时发现: 服务器只有 512MB 内存
4
5Agent 反思: "MySQL 对内存要求较高,512MB 可能不够。
6            应该改用 SQLite 或使用云数据库。"
7
8调整后的计划: 改用 SQLite(轻量级,适合小型博客)
9
10 这就是 Re-planning,Agent 能根据实际情况灵活调整
11

2.3 记忆(Memory):Agent 的信息中心

三种记忆的详细解释

1┌───────────────────────────────────────────────────┐
2                    Agent 记忆系统                    
3                                                    
4  ┌────────────────────────────────────────────┐    
5             短期记忆 (Short-term Memory)           
6                                                   
7    本质: LLM 的上下文窗口                           
8    内容: 当前对话的 messages 列表                   
9    容量: 受上下文窗口限制 ( 128K tokens)          
10    寿命: 当前对话结束就没了                         
11                                                   
12    例:                                            
13    messages = [                                   
14      {system: "你是助手"},                          
15      {user: "你好"},                               
16      {assistant: "你好!"},                          
17      {user: "帮我查天气"},      短期记忆           
18      {assistant: "北京今天晴"},                     
19      ...                                          
20    ]                                              
21  └────────────────────────────────────────────┘    
22                                                    
23  ┌────────────────────────────────────────────┐    
24             长期记忆 (Long-term Memory)            
25                                                   
26    本质: 外部持久化存储                            
27    内容: 跨对话的知识和用户信息                     
28    容量: 理论上无限                                
29    寿命: 永久(除非主动删除)                       
30                                                   
31    存储方式:                                       
32    ├── 向量数据库: 把文档变成数字向量存储,           
33        能做"语义搜索"(详见模块五 5.2             
34    ├── 知识图谱: 用"实体→关系→实体"的网络            
35        存储知识(详见模块五 5.3                    
36    ├── Key-Value 存储: 用户偏好等简单键值对           
37    └── 关系数据库: 结构化历史数据                   
38                                                   
39    例:                                            
40    - 用户偏好: "张三喜欢 Python,用 VS Code"        
41    - 历史知识: "订单系统用的是 Spring Boot"         
42    - 对话摘要: "上次讨论了 Redis 缓存方案"          
43  └────────────────────────────────────────────┘    
44                                                    
45  ┌────────────────────────────────────────────┐    
46             工作记忆 (Working Memory)              
47                                                   
48    本质: 当前任务的中间状态                         
49    内容: 已执行的步骤、中间结果、当前计划           
50    容量: 较小,只保留关键信息                       
51    寿命: 当前任务结束就清除                         
52                                                   
53     (Agent 正在做数据分析):                       
54    working_memory = {                              
55      "current_plan": ["①查数据", "②分析", ...],    
56      "completed_steps": ["①查数据 ✓"],             
57      "intermediate_results": {                     
58         "raw_data": "500条销售记录",                
59         "top_product": "产品A"                     
60      }                                            
61    }                                              
62  └────────────────────────────────────────────┘    
63└───────────────────────────────────────────────────┘
64

上下文窗口管理策略

当对话太长,超出上下文窗口时怎么办?

1策略一: 滑动窗口
2  保留最近 N 轮对话,删除最早的
3  [对话1, 对话2, 对话3, 对话4, 对话5]
4   删除对话1
5  [对话2, 对话3, 对话4, 对话5, 对话6]
6
7  优点: 简单
8  缺点: 可能丢失重要的早期信息
9
10策略二: 摘要压缩
11   LLM 把旧对话压缩成摘要
12  [对话1-10 的摘要, 对话11, 对话12, ...]
13
14  优点: 保留了关键信息
15  缺点: 摘要本身消耗 token,可能丢失细节
16
17策略三: RAG 检索
18  把历史对话存入向量库,需要时检索
19  问到相关话题  从向量库搜索相关历史  注入上下文
20  (RAG 是什么?见模块一 1.1.4;完整实现见模块五 5.1)
21
22  优点: 不丢失信息,按需检索
23  缺点: 实现复杂,检索可能不准
24
25策略四: 混合方案(推荐)
26  最近 5   完整保留(短期记忆)
27  更早的  压缩为摘要
28  关键事实  存入长期记忆(向量库/图谱)
29

2.4 工具(Tools):Agent 的执行中心

工具的本质

1工具 = 一个函数 + 描述信息
2
3┌─────────────────────────────────┐
4  工具定义                        
5                                  
6  名称: search_web                
7  描述: "在互联网上搜索信息"          LLM 靠这个决定是否使用
8  参数:                           
9    - query (string, 必填)           LLM 生成这个参数值
10    - max_results (int, 可选)     
11  返回: 搜索结果列表               
12                                  
13  实际执行:                        
14    String searchWeb(String query)    你写的代码
15        // 调用搜索 API            
16        return results;           
17└─────────────────────────────────┘
18

常见工具类型

1Agent 工具箱:
2
3├── 信息获取类
4   ├── 网络搜索 (Google/Bing API)
5   ├── 文档检索 (RAG 向量搜索)
6   ├── 数据库查询 (SQL 执行)
7   └── API 调用 (天气/股票/新闻)
8
9├── 执行操作类
10   ├── 代码执行 (Java/Python/Shell)
11   ├── 文件操作 (//修改)
12   ├── 发送消息 (邮件/Slack/钉钉)
13   └── 系统操作 (创建任务/更新状态)
14
15├── 计算分析类
16   ├── 数学计算 (计算器)
17   ├── 数据分析 (Java Stream/Apache Commons Math)
18   └── 图表生成 (JFreeChart/ECharts)
19
20└── 交互类
21    ├── 浏览器操作 (Browser Use)
22    ├── 屏幕操作 (Computer Use)
23    └── 人工确认 (Human-in-the-loop)
24

工具设计的好与坏

1//  差的工具设计
2var badTool = """
3{
4    "name": "do_stuff",
5    "description": "执行各种操作",
6    "parameters": {
7        "type": "object",
8        "properties": {
9            "action": {"type": "string"},
10            "target": {"type": "string"},
11            "option1": {"type": "string"},
12            "option2": {"type": "string"},
13            "option3": {"type": "string"},
14            "option4": {"type": "string"}
15        }
16    }
17}
18""";
19// 问题: 名字太模糊、描述不清楚、参数含义不明、参数太多
20
21//  好的工具设计
22var goodTool = """
23{
24    "name": "search_user_orders",
25    "description": "根据用户ID查询该用户的订单列表。返回订单号、状态、金额、时间。",
26    "parameters": {
27        "type": "object",
28        "properties": {
29            "user_id": {
30                "type": "string",
31                "description": "用户的唯一标识符,如 'U12345'"
32            },
33            "status": {
34                "type": "string",
35                "enum": ["pending", "shipped", "delivered", "cancelled"],
36                "description": "按订单状态筛选(可选)"
37            },
38            "limit": {
39                "type": "integer",
40                "description": "返回结果数量上限,默认10",
41                "default": 10
42            }
43        },
44        "required": ["user_id"]
45    }
46}
47""";
48// 优点: 名称精确、描述详细、参数含义清楚、只有必要的才 required
49

3 推理策略——Agent 如何思考

3.1 ReAct 模式(深入理解)

ReAct(Reasoning + Acting)是最经典、最常用的 Agent 推理模式。

完整的 ReAct 循环

1用户: "帮我了解竞品公司 XYZ 最近的融资情况和主要产品"
2
3=====  1  =====
4Thought: 用户想了解 XYZ 公司的融资和产品信息。
5         我需要先搜索该公司的基本信息。
6Action:  search_web(query="XYZ公司 融资")
7Observation: "XYZ 公司于 2024  3 月完成 B 轮融资 5000 万美元,
8             由红杉资本领投..."
9
10=====  2  =====
11Thought: 已获得融资信息。现在需要搜索他们的产品信息。
12Action:  search_web(query="XYZ公司 主要产品")
13Observation: "XYZ 公司旗下有三款产品: ProductA(协作工具)、
14             ProductB(项目管理)、ProductC(文档工具)..."
15
16=====  3  =====
17Thought: 我已经收集到了融资和产品两方面的信息,
18         可以综合整理回答用户了。
19Action:  [无需调用工具]
20Answer:  "XYZ 公司融资情况:
21         - 2024年3月完成B轮融资5000万美元
22         - 领投方: 红杉资本
23
24         主要产品:
25         - ProductA: 协作工具
26         - ProductB: 项目管理
27         - ProductC: 文档工具"
28

ReAct 的 Prompt 模板

1var REACT_PROMPT = """
2你是一个助手,可以使用工具来回答问题。
3
4可用工具:
5%s
6
7请使用以下格式:
8
9Thought: 分析当前情况,决定下一步
10Action: 工具名称
11Action Input: 工具参数(JSON格式)
12Observation: [工具返回的结果会自动填入这里]
13
14... (可以重复 Thought/Action/Observation 多次)
15
16当你认为已经有足够的信息来回答时:
17Thought: 我已经有了足够的信息
18Final Answer: 最终回答
19
20开始!
21
22用户问题: %s
23""".formatted(toolsDescription, userQuestion);
24

Java 实现一个简单的 ReAct Agent

1import com.fasterxml.jackson.databind.ObjectMapper;
2import com.fasterxml.jackson.databind.node.ObjectNode;
3import java.util.*;
4
5// 使用模块 1 中的 ClaudeClient(已定义 chat / chatWithTools / stream 方法)
6
7// 定义工具
8var toolsMap = Map.<String, java.util.function.Function<Map<String, String>, String>>of(
9    "search_web", args -> "搜索结果: 关于'" + args.get("query") + "'的信息...",
10    "calculator", args -> {
11        // 注意: 生产环境中应使用安全的表达式引擎
12        try {
13            var engine = new javax.script.ScriptEngineManager()
14                .getEngineByName("JavaScript");
15            return String.valueOf(engine.eval(args.get("expression")));
16        } catch (Exception e) {
17            return "计算错误: " + e.getMessage();
18        }
19    }
20);
21
22var toolsSchema = """
23[
24    {
25        "name": "search_web",
26        "description": "搜索互联网获取信息",
27        "input_schema": {
28            "type": "object",
29            "properties": {
30                "query": {"type": "string", "description": "搜索关键词"}
31            },
32            "required": ["query"]
33        }
34    },
35    {
36        "name": "calculator",
37        "description": "计算数学表达式",
38        "input_schema": {
39            "type": "object",
40            "properties": {
41                "expression": {"type": "string", "description": "数学表达式"}
42            },
43            "required": ["expression"]
44        }
45    }
46]
47""";
48
49/** 一个简单的 ReAct Agent */
50String runAgent(String userMessage, int maxSteps) {
51    var objectMapper = new ObjectMapper();
52    var tools = objectMapper.readTree(toolsSchema);
53
54    var messages = new ArrayList<Message>();
55    messages.add(new Message("user", userMessage));
56
57    var system = "你是一个有用的助手,可以使用工具来回答问题。";
58
59    for (int step = 0; step < maxSteps; step++) {
60        // 1. 调用 LLM(使用 ClaudeClient  chatWithTools)
61        var response = client.chatWithTools(system, messages, tools);
62        var stopReason = response.get("stop_reason").asText();
63        var content = response.get("content");
64
65        // 2. 检查是否需要调用工具
66        if ("tool_use".equals(stopReason)) {
67            //  assistant 回复加入消息列表
68            messages.add(new Message("assistant", content.toString()));
69
70            var toolResults = new ArrayList<Map<String, Object>>();
71            for (var block : content) {
72                if ("tool_use".equals(block.get("type").asText())) {
73                    var funcName = block.get("name").asText();
74                    var funcArgs = objectMapper.convertValue(
75                        block.get("input"),
76                        new com.fasterxml.jackson.core.type.TypeReference<Map<String, String>>() {}
77                    );
78                    var toolId = block.get("id").asText();
79
80                    System.out.printf("  [Step %d] 调用工具: %s(%s)%n", step + 1, funcName, funcArgs);
81
82                    // 3. 执行工具
83                    var result = toolsMap.get(funcName).apply(funcArgs);
84                    System.out.printf("  [Step %d] 工具结果: %s%n", step + 1,
85                        result.substring(0, Math.min(100, result.length())));
86
87                    // 4. 把工具结果传回 LLM
88                    toolResults.add(Map.of(
89                        "type", "tool_result",
90                        "tool_use_id", toolId,
91                        "content", result
92                    ));
93                }
94            }
95            messages.add(new Message("user", objectMapper.writeValueAsString(toolResults)));
96        } else {
97            // LLM 没有调用工具,说明它准备直接回答
98            for (var block : content) {
99                if ("text".equals(block.get("type").asText())) {
100                    return block.get("text").asText();
101                }
102            }
103        }
104    }
105    return "Agent 达到最大步数限制";
106}
107
108// 使用
109var answer = runAgent("北京和上海的面积分别是多少?哪个更大?", 5);
110System.out.println("\n最终回答: " + answer);
111

3.2 CoT(思维链)的深入应用

Zero-shot CoT

1// 只需要在 prompt 末尾加一句话就能大幅提升推理准确率
2
3//  直接问(准确率低)
4var directPrompt = "一个书架有 3 层,每层放 8 本书。小明拿走了 5 本,又放回 2 本。现在有多少本书?";
5
6//  加上 CoT 引导(准确率大幅提升)
7var cotPrompt = """
8一个书架有 3 层,每层放 8 本书。小明拿走了 5 本,又放回 2 本。现在有多少本书?
9请一步步思考。""";
10
11// LLM 的回答:
12// 1. 书架有 3 层,每层 8 本,总共 3 × 8 = 24 
13// 2. 小明拿走 5 本: 24 - 5 = 19 
14// 3. 又放回 2 本: 19 + 2 = 21 
15// 答: 现在有 21 本书
16

CoT 在 Agent 决策中的应用

1var AGENT_SYSTEM_PROMPT = """
2你是一个智能助手。在选择工具前,请先进行推理分析。
3
4推理格式:
5<thinking>
61. 用户的核心需求是什么?
72. 需要哪些信息才能满足需求?
83. 哪个工具最适合获取这些信息?
94. 需要什么参数?
10</thinking>
11
12然后调用合适的工具。""";
13
14// 这样 Agent 的工具选择准确率会显著提高
15// 因为它在"行动"之前先"想清楚"了
16

3.3 Plan-and-Execute 策略详解

1Plan-and-Execute 的核心思想:
2把"规划"和"执行"分成两个独立阶段
3
4┌─────────────────────────────────────────┐
5            Planner(规划者)               
6                                          
7  输入: 用户目标                           
8  输出: 完整的步骤计划                     
9                                          
10  "帮我写一个 Python 爬虫"                 
11    Plan:                                
12     1. 确定目标网站和数据                  
13     2. 分析网页结构                       
14     3. 编写爬虫代码                       
15     4. 测试运行                           
16     5. 处理异常和边界情况                  
17└──────────────────┬──────────────────────┘
18                   
19                   
20┌─────────────────────────────────────────┐
21           Executor(执行者)              
22                                          
23  逐步执行计划中的每一步                    
24                                          
25  Step 1: search_web("Python 爬虫 教程")  
26  Step 2: analyze_html(url)               
27  Step 3: write_code(spec)                
28  Step 4: execute_code(code)              
29  Step 5: fix_errors(errors)              
30                                          
31  如果某步失败  通知 Planner 重新规划     
32└─────────────────────────────────────────┘
33

Plan-and-Execute vs ReAct 的选择

场景推荐策略原因
简单查询ReAct一两步就能完成,不需要提前规划
明确的多步任务Plan-and-Execute步骤可预见,先规划效率更高
探索性任务ReAct不确定需要什么信息,边做边看
复杂项目Plan-and-Execute + ReAct大计划用 P&E,每步执行用 ReAct

3.4 Reflection(反思)策略详解

1Reflection 的核心: Agent 执行后评估自己的输出,发现问题后改进
2
3┌──────────┐     ┌──────────┐     ┌──────────┐
4  Generator│ ──→   Evaluator│ ──→   Reflector│
5  (执行)          (评估)          (反思)   
6                                           
7 生成代码        跑测试          分析错误  
8 写回答          检查质量        找出原因  
9                 打分            提出改进  
10└──────────┘     └──────────┘     └─────┬────┘
11                                        
12      └──────────────────────────────────┘
13                  改进后重试
14

代码生成中的 Reflection 示例

1/** 带反思能力的代码生成 Agent */
2String codeAgentWithReflection(String task, int maxRetries) {
3    String code = null;
4    String reflection = null;
5
6    for (int attempt = 0; attempt < maxRetries; attempt++) {
7        // 1. 生成代码
8        if (attempt == 0) {
9            code = generateCode(task);
10        } else {
11            code = generateCode(task, code, reflection);
12        }
13
14        // 2. 执行代码并检查结果
15        var result = executeCode(code);
16
17        if (result.success()) {
18            return code;  // 成功了,直接返回
19        }
20
21        // 3. 反思: 分析失败原因
22        reflection = client.chat(
23            "你是一个代码审查专家。",
24            List.of(new Message("user", """
25                任务: %s
26                生成的代码: %s
27                错误信息: %s
28
29                请分析:
30                1. 代码为什么出错?
31                2. 具体哪一行有问题?
32                3. 应该如何修复?
33                """.formatted(task, code, result.error())))
34        );
35
36        System.out.printf("第 %d 次尝试失败,反思: %s%n", attempt + 1, reflection);
37    }
38
39    return null;  // 多次尝试都失败
40}
41

4 Agent 循环的完整生命周期

把所有概念串起来,一个 Agent 处理请求的完整过程:

1用户发起请求
2
3
4┌──────────────────────────────────────────────────┐
5  Phase 1: 理解与规划                               
6                                                   
7   检索长期记忆(用户历史、偏好)                    
8   LLM 理解用户意图                                
9   判断是否需要规划(简单任务直接执行)               
10   如需规划  分解为步骤列表                        
11└───────────────────────┬──────────────────────────┘
12                        
13                        
14┌──────────────────────────────────────────────────┐
15  Phase 2: 执行循环(ReAct Loop)                    
16                                                   
17  for each step in plan:                           
18     Thought: 当前步骤需要什么?用什么工具?          
19     Action:  调用选定的工具                        
20     Observation: 获取工具执行结果                   
21     更新工作记忆(记录中间结果)                    
22     判断: 是否需要调整计划?                       
23       - 如果结果不符预期  Reflection  Re-plan     
24       - 如果正常  继续下一步                       
25└───────────────────────┬──────────────────────────┘
26                        
27                        
28┌──────────────────────────────────────────────────┐
29  Phase 3: 总结与输出                               
30                                                   
31   综合所有中间结果                                
32   生成最终回答                                    
33   更新长期记忆(保存有价值的信息)                  
34   返回结果给用户                                  
35└──────────────────────────────────────────────────┘
36

5 实战练习

练习 1: 手动模拟 ReAct 循环

1/**
2 * 目标: 不用任何框架,纯用 API 实现一个 ReAct Agent
3 * 功能: 能搜索天气和做数学计算
4 */
5
6import com.fasterxml.jackson.databind.ObjectMapper;
7import com.fasterxml.jackson.databind.JsonNode;
8import java.util.*;
9import java.util.function.Function;
10
11// 使用模块 1 中的 ClaudeClient  Message
12
13public class ReactAgentDemo {
14
15    private static final ObjectMapper objectMapper = new ObjectMapper();
16
17    // 模拟工具(实际中你会调用真正的 API)
18    static String getWeather(Map<String, String> args) {
19        var city = args.get("city");
20        var weatherData = Map.of(
21            "北京", "晴,25°C,湿度30%",
22            "上海", "多云,28°C,湿度65%",
23            "广州", "雷阵雨,32°C,湿度80%"
24        );
25        return weatherData.getOrDefault(city, "未找到 " + city + " 的天气数据");
26    }
27
28    static String calculate(Map<String, String> args) {
29        try {
30            // 注意: 生产环境中不要用 ScriptEngine,这里仅为演示
31            var engine = new javax.script.ScriptEngineManager()
32                .getEngineByName("JavaScript");
33            return String.valueOf(engine.eval(args.get("expression")));
34        } catch (Exception e) {
35            return "计算错误: " + e.getMessage();
36        }
37    }
38
39    // 工具注册
40    static final Map<String, Function<Map<String, String>, String>> availableTools = Map.of(
41        "get_weather", ReactAgentDemo::getWeather,
42        "calculate", ReactAgentDemo::calculate
43    );
44
45    static final String toolsForApi = """
46    [
47        {
48            "name": "get_weather",
49            "description": "获取指定城市的实时天气信息",
50            "input_schema": {
51                "type": "object",
52                "properties": {
53                    "city": {"type": "string", "description": "城市名称"}
54                },
55                "required": ["city"]
56            }
57        },
58        {
59            "name": "calculate",
60            "description": "计算数学表达式,如 '2+3*4'  '100/7'",
61            "input_schema": {
62                "type": "object",
63                "properties": {
64                    "expression": {"type": "string", "description": "数学表达式"}
65                },
66                "required": ["expression"]
67            }
68        }
69    ]
70    """;
71
72    /** ReAct Agent 实现 */
73    static String reactAgent(ClaudeClient client, String question, int maxSteps)
74            throws Exception {
75        var tools = objectMapper.readTree(toolsForApi);
76        var messages = new ArrayList<Message>();
77        messages.add(new Message("user", question));
78
79        var system = "你是一个有用的助手。请使用提供的工具来回答用户问题。";
80
81        System.out.println("\n[思考] 问题: " + question + "\n");
82
83        for (int step = 0; step < maxSteps; step++) {
84            var response = client.chatWithTools(system, messages, tools);
85            var stopReason = response.get("stop_reason").asText();
86            var content = response.get("content");
87
88            // 如果 LLM 决定直接回答(不调用工具)
89            if (!"tool_use".equals(stopReason)) {
90                for (var block : content) {
91                    if ("text".equals(block.get("type").asText())) {
92                        var answer = block.get("text").asText();
93                        System.out.println("[完成] 最终回答: " + answer);
94                        return answer;
95                    }
96                }
97            }
98
99            // 处理工具调用
100            messages.add(new Message("assistant", content.toString()));
101
102            var toolResults = new ArrayList<Map<String, Object>>();
103            for (var block : content) {
104                if ("tool_use".equals(block.get("type").asText())) {
105                    var funcName = block.get("name").asText();
106                    var funcArgs = objectMapper.convertValue(
107                        block.get("input"),
108                        new com.fasterxml.jackson.core.type.TypeReference<Map<String, String>>() {}
109                    );
110                    var toolId = block.get("id").asText();
111
112                    System.out.printf("  [工具] Step %d: %s(%s)%n", step + 1, funcName, funcArgs);
113
114                    // 执行工具
115                    var result = availableTools.get(funcName).apply(funcArgs);
116                    System.out.printf("  [结果] %s%n", result);
117
118                    // 工具结果传回 LLM
119                    toolResults.add(Map.of(
120                        "type", "tool_result",
121                        "tool_use_id", toolId,
122                        "content", result
123                    ));
124                }
125            }
126            messages.add(new Message("user", objectMapper.writeValueAsString(toolResults)));
127        }
128
129        return "达到最大步数限制";
130    }
131
132    // 测试
133    public static void main(String[] args) throws Exception {
134        var client = new ClaudeClient();
135        reactAgent(client, "北京和上海今天哪个城市更热?温差是多少度?", 10);
136    }
137}
138

本模块学习检查清单

  • 能清晰解释 Agent 和 ChatBot 的 3 个核心区别
  • 能画出 Agent 的四大组成部分架构图
  • 理解 ReAct、CoT、Plan-and-Execute、Reflection 四种推理策略的区别和适用场景
  • 理解三种记忆(短期/长期/工作记忆)的区别
  • 理解工具调用的完整流程
  • 能手写一个简单的 ReAct Agent(使用 API + 工具调用)


核心概念层——深入理解 Agent 是什么》 是转载文章,点击查看原文


相关推荐


配置钉钉龙虾OpenClaw机器人调用OpenMetadata
光于前裕于后2026/3/20

目录 一、前言1️⃣钉钉(DingTalk)2️⃣OpenClaw3️⃣OpenMetadata4️⃣MCP(Model Context Protocol) 二、安装OpenClaw三、配置OpenClaw钉钉机器人四、调用OpenMetadata MCP 一、前言 先介绍下这四个工具/协议的定位与核心能力,本文将从零开始配置。 1️⃣钉钉(DingTalk) 阿里巴巴旗下的企业协作平台,2014年上线,是中国市场份额最大的企业即时通讯与办公套件之一。 核心能


10分钟搭建 Windows + WSL + Codex环境
Lei_official2026/3/12

并不是 AI 替代人,而是会用 AI 的人替代不会用 AI 的人。 我的大模型使用历程 从2023年秋季,我开始使用对话型的大模型,提升工作和学习的效率,以及回答一些生活上的常识问题。最开始是 ChatGPT 的免费版本,随着使用频率提高,慢慢会遇到问答超过上限的情况。随后便开通了Plus订阅直至今日。期间也曾使用过 Deepseek、Gemini、Minimax 等等,不过最主要的仍然是 ChatGPT,个人感觉它在回答的质量、速度、上下文方面体验最好。 在这段历程里,网页对话型 的 AI


MySQL中 SHOW FULL PROCESSLIST` 输出中 `State` 列的所有可能值
左Python右Java2026/3/4

SHOW FULL PROCESSLIST输出中State` 列的所有可能值,以及这些值代表的含义,这能帮你精准判断数据库连接的状态(包括锁相关、执行状态等)。 一、State 列核心分类及含义 State 列描述了当前线程正在执行的操作状态,不同状态对应不同的数据库行为,以下是最常见且实用的分类(按场景划分): 1. 锁相关状态(排查锁表核心) 这是你最关心的锁表相关状态,直接反映锁等待 / 阻塞: 状态值含义Waiting for t


326. Java Stream API - 实现自定义的 toList() 与 toSet() 收集器
yaoxin5211232026/2/23

文章目录 326. Java Stream API - 实现自定义的 `toList()` 与 `toSet()` 收集器📦 实现一个自定义 `toList()` 收集器🚀 使用我们的 `ToList` 收集器🔄 将其改造成 `toSet()` 收集器✅ 修改 1:使用 `HashSet` 作为容器✅ 修改 2:声明该收集器是无序的 🧪 `ToSet` 收集器完整实现示例🎯 总结一下关键点🧠 小贴士 326. Java Stream API - 实现自定义的 toL


Kafka 生产者与消费者配置详解
倚肆2026/2/15

Kafka 生产者与消费者配置详解 一、DefaultKafkaProducerFactory 生产者配置详解 配置项示例值作用说明调优建议ProducerConfig.BOOTSTRAP_SERVERS_CONFIG"localhost:9092"Kafka 集群地址列表,生产者通过此地址发现集群。配置多个地址(用逗号分隔)以提高可用性。ProducerConfig.KEY_SERIALIZER_CLASS_CONFIGStringSerializer.class消息键的序列化器。键用于分区


Spring IOC&DI(上)
阿武不想上早八2026/2/6

Spring IOC&DI(上) 1. Spring IOC&DI Spring 是包含了众多工具方法的 IOC 容器 1.1 容器 概念:容器时用来容纳物品的装置。 例子:List/Map -> 数据存储容器;Tomcat -> Web 容器 1.2 IOC 概念:全称:Inversion of Control(控制反转),是 Spring 的核心思想,把对象交给 Spring 管理,就是 IOC 思想。 总的来说,Spring 就是一个”控制反转“的容器。 2. I


【学习笔记】C++(1)
贺一航【Niki】2026/1/28

C++学习笔记 一、基础 1、类型表示范围 2、cout 3、char 4、string 5、逻辑运算符 6、枚举 7、随机数 8、数组 9、其他 一、基础 1、类型表示范围 类型 字节数 位宽 十进制范围(大约) 具体值范围 char 1


【AI大模型开发】-基于FAISS的语义搜索系统(实战)
Java后端的Ai之路2026/1/19

向量数据库实战:基于FAISS的语义搜索系统 一、项目概述 1.1 什么是向量数据库? 向量数据库是一种专门用于存储、索引和检索高维向量数据的数据库系统。在AI领域,向量通常是指通过预训练模型(如Transformer)将文本、图像等非结构化数据转换而成的数值表示(Embedding)。 1.2 项目背景 本项目展示了如何使用阿里云百炼Embedding API生成文本向量,并结合FAISS(Facebook AI Similarity Search)构建一个简单但功能完整的语义搜索系统。 1.


Claude Skills:Agent 能力扩展的新范式
清沫2026/1/11

为什么需要 Skills? 2025 年被称为智能体元年。各类 Agent、子 Agent、MCP 工具及自动化流水线迅速出现,让 AI 可以接手越来越多真实工作。比如 Claude Code 推出的 Agent 模块,或通过可视化平台、LangChain 开发的各种工具。 随着智能体功能增强,需要更具可组合性、可扩展性和可移植性的方法,为它们配备特定领域专业知识。这促使智能体 Skills 诞生:智能体可动态发现并加载包含指令、脚本和资源的文件夹,从而更好完成特定任务。 什么是 Skills?


2025年度总结之-如何构建 2025 专属的 GitHub AI 项目情报库
CoderJia_2026/1/3

背景 为什么做 为了更好地追踪 2025 年涌现的 AI 开源项目,我经常浏览 Github 热榜 并整理分享。但手动查阅难免会有遗漏,为此,我计划开发一套自动化工具来采集 Github 热榜数据,旨在辅助个人技术积累的同时,也为博客内容提供持续的素材来源。下文将详细介绍我的技术实现思路,若有设计不足之处,恳请各位读者指正。 如何制作 在该流程的初始阶段,核心任务是构建针对 GitHub 热榜(Trending)页面的数据采集机制。需要分别按照日(Daily)、周(Weekly)及月(M

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客