Преглед изворни кода

Merge branch 'datawhalechina:main' into main

jjyaoao пре 11 месеци
родитељ
комит
0d21d2881f

+ 3 - 2
README.md

@@ -110,7 +110,8 @@
 ### 核心贡献者
 - [陈思州-项目负责人](https://github.com/jjyaoao) (Datawhale成员)
 - [孙韬-项目负责人](https://github.com/fengju0213) (Datawhale成员)  
-- [姜舒凡-项目负责人](https://github.com/Tsumugii24)(Datawhale成员)
+- [姜舒凡-项目负责人](https://github.com/Tsumugii24) (Datawhale成员)
+- [Jason-Datawhale意向成员](https://github.com/HeteroCat) (第五章Coze\Dify\FastGPT内容贡献者, Agent开发工程师)
 
 ### 特别感谢
 - 感谢 [@Sm1les](https://github.com/Sm1les) 对本项目的帮助与支持
@@ -125,7 +126,7 @@
 ## Star History
 
 <div align='center'>
-    <img src="./docs/images/star-history-2025922.png" alt="Datawhale" width="90%">
+    <img src="./docs/images/star-history-2025927.png" alt="Datawhale" width="90%">
 </div>
 
 <div align="center">

+ 1 - 1
code/chapter4/Plan_and_solve.py

@@ -23,7 +23,7 @@ PLANNER_PROMPT_TEMPLATE = """
 
 问题: {question}
 
-请严格按照以下格式输出你的计划:
+请严格按照以下格式输出你的计划,```python与```作为前后缀是必要的:
 ```python
 ["步骤1", "步骤2", "步骤3", ...]
 ```

+ 188 - 16
code/chapter7/my_simple_agent.py

@@ -1,6 +1,7 @@
 # my_simple_agent.py
-from typing import Optional
+from typing import Optional, Iterator
 from hello_agents import SimpleAgent, HelloAgentsLLM, Config, Message
+import re
 
 class MySimpleAgent(SimpleAgent):
     """
@@ -13,23 +14,27 @@ class MySimpleAgent(SimpleAgent):
         name: str,
         llm: HelloAgentsLLM,
         system_prompt: Optional[str] = None,
-        config: Optional[Config] = None
+        config: Optional[Config] = None,
+        tool_registry: Optional['ToolRegistry'] = None,
+        enable_tool_calling: bool = True
     ):
         super().__init__(name, llm, system_prompt, config)
-        print(f"✅ {name} 初始化完成,基于框架基类构建")
-
-    def run(self, input_text: str, **kwargs) -> str:
+        self.tool_registry = tool_registry
+        self.enable_tool_calling = enable_tool_calling and tool_registry is not None
+        print(f"✅ {name} 初始化完成,工具调用: {'启用' if self.enable_tool_calling else '禁用'}")
+    
+    def run(self, input_text: str, max_tool_iterations: int = 3, **kwargs) -> str:
         """
-        重写的运行方法 - 实现简单对话逻辑
+        重写的运行方法 - 实现简单对话逻辑,支持可选工具调用
         """
         print(f"🤖 {self.name} 正在处理: {input_text}")
 
         # 构建消息列表
         messages = []
 
-        # 添加系统消息
-        if self.system_prompt:
-            messages.append({"role": "system", "content": self.system_prompt})
+        # 添加系统消息(可能包含工具信息)
+        enhanced_system_prompt = self._get_enhanced_system_prompt()
+        messages.append({"role": "system", "content": enhanced_system_prompt})
 
         # 添加历史消息
         for msg in self._history:
@@ -38,17 +43,157 @@ class MySimpleAgent(SimpleAgent):
         # 添加当前用户消息
         messages.append({"role": "user", "content": input_text})
 
-        # 调用LLM
-        response = self.llm.invoke(messages, **kwargs)
+        # 如果没有启用工具调用,使用简单对话逻辑
+        if not self.enable_tool_calling:
+            response = self.llm.invoke(messages, **kwargs)
+            self.add_message(Message(input_text, "user"))
+            self.add_message(Message(response, "assistant"))
+            print(f"✅ {self.name} 响应完成")
+            return response
+
+        # 支持多轮工具调用的逻辑
+        return self._run_with_tools(messages, input_text, max_tool_iterations, **kwargs)
+
+    def _get_enhanced_system_prompt(self) -> str:
+        """构建增强的系统提示词,包含工具信息"""
+        base_prompt = self.system_prompt or "你是一个有用的AI助手。"
+
+        if not self.enable_tool_calling or not self.tool_registry:
+            return base_prompt
+
+        # 获取工具描述
+        tools_description = self.tool_registry.get_tools_description()
+        if not tools_description or tools_description == "暂无可用工具":
+            return base_prompt
+
+        tools_section = "\n\n## 可用工具\n"
+        tools_section += "你可以使用以下工具来帮助回答问题:\n"
+        tools_section += tools_description + "\n"
+
+        tools_section += "\n## 工具调用格式\n"
+        tools_section += "当需要使用工具时,请使用以下格式:\n"
+        tools_section += "`[TOOL_CALL:{tool_name}:{parameters}]`\n"
+        tools_section += "例如:`[TOOL_CALL:search:Python编程]` 或 `[TOOL_CALL:memory:recall=用户信息]`\n\n"
+        tools_section += "工具调用结果会自动插入到对话中,然后你可以基于结果继续回答。\n"
+
+        return base_prompt + tools_section
+    
+    def _run_with_tools(self, messages: list, input_text: str, max_tool_iterations: int, **kwargs) -> str:
+        """支持工具调用的运行逻辑"""
+        current_iteration = 0
+        final_response = ""
+
+        while current_iteration < max_tool_iterations:
+            # 调用LLM
+            response = self.llm.invoke(messages, **kwargs)
+
+            # 检查是否有工具调用
+            tool_calls = self._parse_tool_calls(response)
+
+            if tool_calls:
+                print(f"🔧 检测到 {len(tool_calls)} 个工具调用")
+                # 执行所有工具调用并收集结果
+                tool_results = []
+                clean_response = response
+
+                for call in tool_calls:
+                    result = self._execute_tool_call(call['tool_name'], call['parameters'])
+                    tool_results.append(result)
+                    # 从响应中移除工具调用标记
+                    clean_response = clean_response.replace(call['original'], "")
+
+                # 构建包含工具结果的消息
+                messages.append({"role": "assistant", "content": clean_response})
+
+                # 添加工具结果
+                tool_results_text = "\n\n".join(tool_results)
+                messages.append({"role": "user", "content": f"工具执行结果:\n{tool_results_text}\n\n请基于这些结果给出完整的回答。"})
+
+                current_iteration += 1
+                continue
+
+            # 没有工具调用,这是最终回答
+            final_response = response
+            break
+
+        # 如果超过最大迭代次数,获取最后一次回答
+        if current_iteration >= max_tool_iterations and not final_response:
+            final_response = self.llm.invoke(messages, **kwargs)
 
         # 保存到历史记录
         self.add_message(Message(input_text, "user"))
-        self.add_message(Message(response, "assistant"))
-
+        self.add_message(Message(final_response, "assistant"))
         print(f"✅ {self.name} 响应完成")
-        return response
+
+        return final_response
+
+    def _parse_tool_calls(self, text: str) -> list:
+        """解析文本中的工具调用"""
+        pattern = r'\[TOOL_CALL:([^:]+):([^\]]+)\]'
+        matches = re.findall(pattern, text)
+
+        tool_calls = []
+        for tool_name, parameters in matches:
+            tool_calls.append({
+                'tool_name': tool_name.strip(),
+                'parameters': parameters.strip(),
+                'original': f'[TOOL_CALL:{tool_name}:{parameters}]'
+            })
+
+        return tool_calls
+
+    def _execute_tool_call(self, tool_name: str, parameters: str) -> str:
+        """执行工具调用"""
+        if not self.tool_registry:
+            return f"❌ 错误:未配置工具注册表"
+
+        try:
+            # 智能参数解析
+            if tool_name == 'calculator':
+                # 计算器工具直接传入表达式
+                result = self.tool_registry.execute_tool(tool_name, parameters)
+            else:
+                # 其他工具使用智能参数解析
+                param_dict = self._parse_tool_parameters(tool_name, parameters)
+                tool = self.tool_registry.get_tool(tool_name)
+                if not tool:
+                    return f"❌ 错误:未找到工具 '{tool_name}'"
+                result = tool.run(param_dict)
+
+            return f"🔧 工具 {tool_name} 执行结果:\n{result}"
+
+        except Exception as e:
+            return f"❌ 工具调用失败:{str(e)}"
+
+    def _parse_tool_parameters(self, tool_name: str, parameters: str) -> dict:
+        """智能解析工具参数"""
+        param_dict = {}
+
+        if '=' in parameters:
+            # 格式: key=value 或 action=search,query=Python
+            if ',' in parameters:
+                # 多个参数:action=search,query=Python,limit=3
+                pairs = parameters.split(',')
+                for pair in pairs:
+                    if '=' in pair:
+                        key, value = pair.split('=', 1)
+                        param_dict[key.strip()] = value.strip()
+            else:
+                # 单个参数:key=value
+                key, value = parameters.split('=', 1)
+                param_dict[key.strip()] = value.strip()
+        else:
+            # 直接传入参数,根据工具类型智能推断
+            if tool_name == 'search':
+                param_dict = {'query': parameters}
+            elif tool_name == 'memory':
+                param_dict = {'action': 'search', 'query': parameters}
+            else:
+                param_dict = {'input': parameters}
+
+        return param_dict
     
-    def stream_run(self, input_text: str, **kwargs):
+    def stream_run(self, input_text: str, **kwargs) -> Iterator[str]:
         """
         自定义的流式运行方法
         """
@@ -77,4 +222,31 @@ class MySimpleAgent(SimpleAgent):
         # 保存完整对话到历史记录
         self.add_message(Message(input_text, "user"))
         self.add_message(Message(full_response, "assistant"))
-        print(f"✅ {self.name} 流式响应完成")
+        print(f"✅ {self.name} 流式响应完成")
+
+    def add_tool(self, tool) -> None:
+        """添加工具到Agent(便利方法)"""
+        if not self.tool_registry:
+            from hello_agents import ToolRegistry
+            self.tool_registry = ToolRegistry()
+            self.enable_tool_calling = True
+
+        self.tool_registry.register_tool(tool)
+        print(f"🔧 工具 '{tool.name}' 已添加")
+
+    def has_tools(self) -> bool:
+        """检查是否有可用工具"""
+        return self.enable_tool_calling and self.tool_registry is not None
+    
+    def remove_tool(self, tool_name: str) -> bool:
+        """移除工具(便利方法)"""
+        if self.tool_registry:
+            self.tool_registry.unregister(tool_name)
+            return True
+        return False
+    
+    def list_tools(self) -> list:
+        """列出所有可用工具"""
+        if self.tool_registry:
+            return self.tool_registry.list_tools()
+        return []

+ 37 - 11
code/chapter7/test_simple_agent.py

@@ -1,6 +1,7 @@
 # test_simple_agent.py
 from dotenv import load_dotenv
-from hello_agents import HelloAgentsLLM
+from hello_agents import HelloAgentsLLM, ToolRegistry
+from hello_agents.tools import CalculatorTool
 from my_simple_agent import MySimpleAgent
 
 # 加载环境变量
@@ -9,21 +10,46 @@ load_dotenv()
 # 创建LLM实例
 llm = HelloAgentsLLM()
 
-# 创建自定义SimpleAgent
-agent = MySimpleAgent(
-    name="我的简单助手",
+# 测试1:基础对话Agent(无工具)
+print("=== 测试1:基础对话 ===")
+basic_agent = MySimpleAgent(
+    name="基础助手",
     llm=llm,
     system_prompt="你是一个友好的AI助手,请用简洁明了的方式回答问题。"
 )
 
-# 测试标准调用
-response1 = agent.run("你好,请介绍一下自己")
-print(f"标准响应: {response1}")
+response1 = basic_agent.run("你好,请介绍一下自己")
+print(f"基础对话响应: {response1}\n")
 
-# 测试流式调用
-print("\n流式响应:")
-for chunk in agent.stream_run("请解释什么是人工智能"):
+# 测试2:带工具的Agent
+print("=== 测试2:工具增强对话 ===")
+tool_registry = ToolRegistry()
+calculator = CalculatorTool()
+tool_registry.register_tool(calculator)
+
+enhanced_agent = MySimpleAgent(
+    name="增强助手",
+    llm=llm,
+    system_prompt="你是一个智能助手,可以使用工具来帮助用户。",
+    tool_registry=tool_registry,
+    enable_tool_calling=True
+)
+
+response2 = enhanced_agent.run("请帮我计算 15 * 8 + 32")
+print(f"工具增强响应: {response2}\n")
+
+# 测试3:流式响应
+print("=== 测试3:流式响应 ===")
+print("流式响应: ", end="")
+for chunk in basic_agent.stream_run("请解释什么是人工智能"):
     pass  # 内容已在stream_run中实时打印
 
+# 测试4:动态添加工具
+print("\n=== 测试4:动态工具管理 ===")
+print(f"添加工具前: {basic_agent.has_tools()}")
+basic_agent.add_tool(calculator)
+print(f"添加工具后: {basic_agent.has_tools()}")
+print(f"可用工具: {basic_agent.list_tools()}")
+
 # 查看对话历史
-print(f"\n对话历史: {len(agent.get_history())} 条消息")
+print(f"\n对话历史: {len(basic_agent.get_history())} 条消息")

+ 2 - 1
docs/README.md

@@ -113,6 +113,7 @@
 - [陈思州-项目负责人](https://github.com/jjyaoao) (Datawhale成员)
 - [孙韬-项目负责人](https://github.com/fengju0213) (Datawhale成员)  
 - [姜舒凡-项目负责人](https://github.com/Tsumugii24)(Datawhale成员)
+- [Jason-Datawhale意向成员](https://github.com/HeteroCat) (第五章Coze\Dify\FastGPT内容贡献者, Agent开发工程师)
 
 ### 特别感谢
 - 感谢 [@Sm1les](https://github.com/Sm1les) 对本项目的帮助与支持
@@ -127,7 +128,7 @@
 ## Star History
 
 <div align='center'>
-    <img src="./images/star-history-2025922.png" alt="Datawhale" width="90%">
+    <img src="./images/star-history-2025927.png" alt="Datawhale" width="90%">
 </div>
 
 <div align="center">

+ 1 - 1
docs/_sidebar.md

@@ -4,7 +4,7 @@
 - <strong>第一部分:智能体与语言模型基础</strong>
   - [第一章 初识智能体](./chapter1/第一章%20初识智能体.md)
   - [第二章 智能体发展史](./chapter2/第二章%20智能体发展史.md)
-  - [第三章 大语言模型基础](./chapter3/第三章%20大模型基础.md)
+  - [第三章 大语言模型基础](./chapter3/第三章%20大语言模型基础.md)
 
 - <strong>第二部分:构建你的大语言模型智能体</strong>
   - [第四章 智能体经典范式构建](./chapter4/第四章%20智能体经典范式构建.md)

+ 1 - 1
docs/chapter3/第三章 大模型基础.md → docs/chapter3/第三章 大语言模型基础.md

@@ -33,7 +33,7 @@ $$P(w_i∣w_1,…,w_{i−1})≈P(w_i∣w_{i−2},w_{i−1})$$
 
 这些概率可以通过在大型语料库中进行<strong>最大似然估计(Maximum Likelihood Estimation,MLE)</strong> 来计算。这个术语听起来很复杂,但其思想非常直观:最可能出现的,就是我们在数据中看到次数最多的。例如,对于 Bigram 模型,我们想计算在词 $w_{i−1}$ 出现后,下一个词是 $w_i$ 的概率 $P(w_i∣w_{i−1})$。根据最大似然估计,这个概率可以通过简单的计数来估算:
 
-$$P(w_i∣w_{i−1})=Count(w_{i−1})Count(w_{i−1},w_i)$$
+$$P(w_i∣w_{i−1})=\frac{Count(w_{i−1},w_i)}{Count(w_{i−1})}$$
 
 这里的 `Count()` 函数就代表“计数”:
 

+ 36 - 39
docs/chapter4/第四章 智能体经典范式构建.md

@@ -616,17 +616,20 @@ Plan-and-Solve 尤其适用于那些结构性强、可以被清晰分解的复
 
 规划阶段的目标是让大语言模型接收原始问题,并输出一个清晰、分步骤的行动计划。这个计划必须是结构化的,以便我们的代码可以轻松解析并逐一执行。因此,我们设计的提示词需要明确地告诉模型它的角色和任务,并给出一个输出格式的范例。
 
-```bash
+````python
 PLANNER_PROMPT_TEMPLATE = """
-你是一个善于规划的AI助手。你的任务是根据用户提出的问题,将其分解成一个由多个步骤组成的、可执行的计划。
-请确保每个步骤都是独立的、清晰的,并且严格按照逻辑顺序排列。
-请你只输出计划本身,不要包含其他任何解释或对话
+你是一个顶级的AI规划专家。你的任务是将用户提出的复杂问题分解成一个由多个简单步骤组成的行动计划。
+请确保计划中的每个步骤都是一个独立的、可执行的子任务,并且严格按照逻辑顺序排列。
+你的输出必须是一个Python列表,其中每个元素都是一个描述子任务的字符串
 
 问题: {question}
 
-计划:
-"""
+请严格按照以下格式输出你的计划,```python与```作为前后缀是必要的:
+```python
+["步骤1", "步骤2", "步骤3", ...]
 ```
+"""
+````
 
 这个提示词通过以下几点确保了输出的质量和稳定性:
 - <strong>角色设定</strong>: “顶级的AI规划专家”,激发模型的专业能力。
@@ -687,7 +690,7 @@ class Planner:
 - <strong>历史步骤与结果</strong>: 提供至今为止已经完成的工作,作为当前步骤的直接输入。
 - <strong>当前步骤</strong>: 明确指示模型现在需要解决哪一个具体任务。
 
-```bash
+```python
 EXECUTOR_PROMPT_TEMPLATE = """
 你是一位顶级的AI执行专家。你的任务是严格按照给定的计划,一步步地解决问题。
 你将收到原始问题、完整的计划、以及到目前为止已经完成的步骤和结果。
@@ -792,50 +795,44 @@ class PlanAndSolveAgent:
 --- 开始处理问题 ---
 问题: 一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?
 --- 正在生成计划 ---
-🧠 正在调用 xxxxxx 模型...
-✅ 计划已生成:
+🧠 正在调用 xxxx 模型...
+✅ 大语言模型响应成功:
 ```python
-["确定周一卖出的苹果数量为15个", "计算周二卖出的苹果数量,即周一数量的两倍", "计算周三卖出的苹果数量,即周二数量减去5个", "将这三天卖出的苹果数量相加得到总数"]
---- 开始处理问题 ---
-问题: 一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?
---- 正在生成计划 ---
-🧠 正在调用 xxxxxx 模型...
-✅ 计划已生成:
---- 开始处理问题 ---
-问题: 一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?
---- 正在生成计划 ---
---- 开始处理问题 ---
---- 开始处理问题 ---
---- 开始处理问题 ---
---- 开始处理问题 ---
-问题: 一个水果店周一卖出了15个苹果。周二卖出的苹果数量是周一的两倍。周三卖出的数量比周二少了5个。请问这三天总共卖出了多少个苹果?
---- 正在生成计划 ---
-🧠 正在调用 xxxxxx 模型...
+["计算周一卖出的苹果数量: 15个", "计算周二卖出的苹果数量: 周一数量 × 2 = 15 × 2 = 30个", "计算周三卖出的苹果数量: 周二数量 - 5 = 30 - 5 = 25个", "计算三天总销量: 周一 + 周二 + 周三 = 15 + 30 + 25 = 70个"]
+```
 ✅ 计划已生成:
 ```python
-["确定周一卖出的苹果数量为15个", "计算周二卖出的苹果数量,即周一数量的两倍", "计算周三卖出的苹果数量,即周二数量减去5个", "将这三天卖出的苹果数量相加得到总数"]
+["计算周一卖出的苹果数量: 15个", "计算周二卖出的苹果数量: 周一数量 × 2 = 15 × 2 = 30个", "计算周三卖出的苹果数量: 周二数量 - 5 = 30 - 5 = 25个", "计算三天总销量: 周一 + 周二 + 周三 = 15 + 30 + 25 = 70个"]
 ```
 
 --- 正在执行计划 ---
 
--> 正在执行步骤 1/4: 确定周一卖出的苹果数量为15个
-🧠 正在调用 xxxxxx 模型...
-✅ 步骤 1 已完成,结果: 15个
+-> 正在执行步骤 1/4: 计算周一卖出的苹果数量: 15个
+🧠 正在调用 xxxx 模型...
+✅ 大语言模型响应成功:
+15
+✅ 步骤 1 已完成,结果: 15
 
--> 正在执行步骤 2/4: 计算周二卖出的苹果数量,即周一数量的两倍
-🧠 正在调用 xxxxxx 模型...
-✅ 步骤 2 已完成,结果: 30个
+-> 正在执行步骤 2/4: 计算周二卖出的苹果数量: 周一数量 × 2 = 15 × 2 = 30个
+🧠 正在调用 xxxx 模型...
+✅ 大语言模型响应成功:
+30
+✅ 步骤 2 已完成,结果: 30
 
--> 正在执行步骤 3/4: 计算周三卖出的苹果数量,即周二数量减去5个
-🧠 正在调用 xxxxxx 模型...
-✅ 步骤 3 已完成,结果: 25个
+-> 正在执行步骤 3/4: 计算周三卖出的苹果数量: 周二数量 - 5 = 30 - 5 = 25个
+🧠 正在调用 xxxx 模型...
+✅ 大语言模型响应成功:
+25
+✅ 步骤 3 已完成,结果: 25
 
--> 正在执行步骤 4/4: 将这三天卖出的苹果数量相加得到总数
-🧠 正在调用 xxxxxx 模型...
-✅ 步骤 4 已完成,结果: 70个
+-> 正在执行步骤 4/4: 计算三天总销量: 周一 + 周二 + 周三 = 15 + 30 + 25 = 70个
+🧠 正在调用 xxxx 模型...
+✅ 大语言模型响应成功:
+70
+✅ 步骤 4 已完成,结果: 70
 
 --- 任务完成 ---
-最终答案: 70
+最终答案: 70
 ````
 
 从上面的输出日志中,我们可以清晰地看到 Plan-and-Solve 范式的工作流程:

+ 245 - 8
docs/chapter5/第五章 基于低代码平台的智能体搭建.md

@@ -54,20 +54,257 @@
 在接下来的小节中,我们将逐一上手体验这些平台,通过实际操作来更直观地感受它们各自的魅力。
 
 ## 5.2 平台一:Coze
+扣子(Coze)是一个超级酷的AI智能体制作工具!也是目前市面上应用最广泛的智能体平台。该平台以其直观的可视化界面和丰富的功能模块,让用户能够轻松创建各种类型的智能体应用,比如能陪你聊天的机器人、自动写故事的创作机,甚至直接帮你将故事变成电影MV!它的一大亮点在于其强大的生态集成能力。开发完成的智能体可以一键发布到微信、飞书、豆包等主流平台,实现跨平台的无缝部署。对于企业用户而言,Coze还提供了灵活的API接口,支持将智能体能力集成到现有的业务系统中,实现了"搭积木式"的AI应用构建。
+### 5.2.1 Coze 的功能模块
+(1)平台界面初览
 
-### 5.2.1 Coze 的功能模块与集成能力
+整体布局介绍:最近扣子又又更新了他的UI界面了,如图5.1所示。现在最左边的侧边栏是扣子平台主页的开发工作区,包括核心的项目开发、资源库、效果评测和空间配置。下面的区域是扣子开发的配套资料空间包括官方模板一键复制、扣子最大的优势丰富多样的插件商店、最大的智能体社区琳琅满目、api管理就是api测试用的、以及详细的教程文档和面向企业的通用管理。右边这一块有四个模板,最上面是扣子最新的更新公告告诉你扣子的最新进展方便你了解最新的工具和功能。接着下面是新手教程,点开就是新手教程文档啦,分分钟开始智能体搭建。其次是你的关注和智能体推荐,在这里你也可以关注喜欢的AI开发者,和收藏他们的智能体为自己所用。
 
-### 5.2.2 构建集成多种工具的“每日简报”智能体
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-01.png" alt="图片描述" width="90%"/>
+  <p>图 5.1 扣子智能智能体平台整体示意图</p>
+</div>
+
+(2)核心功能介绍
+
+首先我们点击左边侧栏的加号就可以看到创建智能体的入口了,这里目前有两类AI应用,一种是创建智能体,另一种叫应用。其中智能体又分为单智能体自主规划模式、单智能体对话流模式和多智能体模式。AI应用也分两种不仅能设计桌面网页端的用户界面,还能轻松搭建小程序和 H5 端的界面,如图5.2所示。
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-02.png" alt="图片描述" width="90%"/>
+  <p>图 5.2 扣子智能体创建入口</p>
+</div>
+项目空间里是你的智能体仓库,这里放着你所有开发的智能体或复制的智能体/应用,也是在扣子进行智能体开发你最经常来到的地方,如图5.3所示。
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-03.png" alt="图片描述" width="90%"/>
+  <p>图 5.3 扣子智能体项目空间</p>
+</div>
+资源库是你开发扣子智能体的核心武器库,资源库就会存放你的工作流,知识库,卡片,提示词库等等一系列开发智能体的工具。你能做出什么样的智能体,首先取决于模型的能力,但是最重要的还是要看你怎么给智能体搭配“出装和技能”。模型决定了智能体的下限,但是扣子资源库给了你智能体的能力的无穷上限,让你能够按照自己的想法,开发想象力和脑洞进行智能体的开发,如图5.4所示。
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-04.png" alt="图片描述" width="90%"/>
+  <p>图 5.4 扣子智能体资源库</p>
+</div>
+空间配置包含智能体、插件、工作流和发布渠道的一个统一的管理频道,以及模型管理就是你可以在这里看到你调用的各种大模型,如图5.5所示。
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-05.png" alt="图片描述" width="90%"/>
+  <p>图 5.5 扣子智能体发布渠道</p>
+</div>
+如果让我对扣子的智能体开发做一个简单的总结的话,我会把他比喻成一个游戏的各个组成部分,各部分配合组合出一个一个精彩的智能体像极了打“游戏”,每做完一个智能体都像是打完了一个boss并且收获满满,不管是“经验”还是“装备”。
+
+- 工作流: 关卡通关路线图
+- 对话流:NPC 对话通关
+- 插件:角色技能卡
+- 知识库:游戏百科全书
+- 卡片:快捷道具栏
+- 提示词:角色的移动键
+- 数据库:“云存档”
+- 发布管理:关卡审核员
+- 模型管理:游戏角色库或者叫捏脸系统
+- 效果评测:闯关评分系统
+
+
+
+
+### <strong>5.2.2 构建“每日AI简报”助手</strong>
+
+
+
+<strong>案例说明:</strong> 本实践案例旨在深入剖析 Coze 平台的插件集成能力,指导读者从零开始构建一个功能强大的“每日AI简报”智能体。该智能体能够自动化地从多个信息源(包括36氪、虎嗅、it之家、infoq、GitHub、arXiv)抓取当日最新的AI领域头条新闻、学术论文及开源项目动态,并将其结构化、专业化地整合成一份生动、精炼的简报。
+
+通过本案例,您将系统性地掌握以下核心技能:
+
+  * <strong>多源信息聚合:</strong> 利用 Coze 的插件生态,实现跨平台、跨类型的数据流无缝集成。
+  * <strong>智能体行为定义:</strong> 通过角色设定和提示词(Prompt)工程,精准控制智能体的任务执行与内容生成,确保输出符合预设的专业标准。
+  * <strong>自动化工作流构建:</strong> 学习如何将数据获取、内容处理与格式化输出等多个步骤串联成一个高效、自动化的工作流。
+
+
+
+<strong>步骤一:添加并配置信息源插件</strong>
+
+构建“每日AI简报”智能体的首要任务是为其接入丰富且权威的信息来源。在 Coze 平台中,这通过添加和配置相应的插件来实现。
+
+1.  <strong>插件集成:</strong> 在 Coze 的插件库中,搜索并添加所需的插件。例如,通过 <strong>RSS</strong> 插件订阅媒体平台的RSS源(如图5.6所示),通过 <strong>GitHub</strong> 插件追踪开源项目(如图5.7所示),以及通过 <strong>arXiv</strong> 插件获取最新的学术研究成果(如图5.8所示)。
+
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-06.png" alt="图片描述" width="90%"/>
+  <p>图 5.6 媒体平台的RSS源插件</p>
+</div>
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-07.png" alt="图片描述" width="90%"/>
+  <p>图 5.7 GitHub插件</p>
+</div>
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-08.png" alt="图片描述" width="90%"/>
+  <p>图 5.8 Arxiv插件</p>
+</div>
+
+2.  <strong>个性化配置:</strong> 对每一个插件进行精细化配置,以确保其能精准地获取所需数据。例如,在 RSS 插件中,输入36氪、虎嗅等网站的特定RSS订阅链接;在 GitHub 插件中,设置需监控的关键词查询数量以及最新更新设置;在 arXiv 插件中,定义感兴趣的领域关键词,如“LLM”、“AI”等,定义数量以及最新更新设置。
+
+```
+RSS链接配置
+
+- **36氪:** https://www.36kr.com/feed
+- **虎嗅:** https://rss.huxiu.com/
+- **it之家:** http://www.ithome.com/rss/
+- **infoq:** https://feed.infoq.com/ai-ml-data-eng/
+
+GitHub插件配置
+
+- q:AI
+- per_page:10
+- sort:updated
+
+Arxiv插件配置
+
+- count:5
+- search_query:AI
+- sort_by:2
+```
+
+3.  <strong>编排连接:</strong> 在智能体的可视化编排界面中,将这些已配置的信息源插件(例如 `rss_24Hbj`、`searchRepository`、`arxiv` 等)作为数据输入节点,并将其连接至后续的逻辑处理模块(例如<strong>大模型</strong>模块),以构建完整的数据处理路径,如图5.9所示。
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-09.png" alt="图片描述" width="90%"/>
+  <p>图 5.9 每日AI简报编排流程图</p>
+</div>
+
+
+<strong>步骤二:设定智能体角色与提示词</strong>
+
+角色设定与提示词编写是定义智能体行为与输出质量的核心环节。该步骤旨在将抽象的指令转化为智能体可理解并执行的具体任务。
+
+(1)角色设定
+
+我们将智能体设定为一位<strong>资深且权威的科技媒体编辑</strong>。这一角色赋予了智能体明确的专业定位,使其在后续的内容创作中,能够模仿专业编辑的思维模式,进行高效的信息筛选、整合与概括。
+
+(2)提示词编写与结构化
+
+提示词是智能体执行任务的指导手册。我们将其分为<strong>系统提示(System Prompt)和用户提示(User Prompt)</strong>,以确保指令的清晰、完整与可控。
+
+<strong>系统提示(System Prompt)</strong>
+
+系统提示用于定义智能体的长期行为准则和输出格式规范。
+
+```
+# 角色
+你是一位资深且权威的科技媒体编辑,擅长高效精准地整合并创作极具专业性的科技简报,特别在AI领域的技术动态、前沿学术研究成果及热门开源项目方面拥有深入的分析与整合能力。
+
+## 工作流
+### 日报输出格式
+1. 日报开头显著标注“AI日报”、“by@jasonhuang“和当天日期,例如:“AI日报 | 2025年9月24日 | by@jasonhuang”。
+2. <!!!important!!!> 根据每则AI技术新闻、每篇AI学术论文、每个AI开源项目的不同内容,在其标题开头添加一个独有的Emoji表情符号。
+3. 输出的所有内容必须与AI、LLM、AIGC、大模型等技术主题高度相关,坚决排除任何无关信息、广告及营销类内容。
+4. 必须为每一条目(包括AI技术新闻、AI学术论文、AI开源项目)提供其对应的原始链接。
+5. 对输出的每一条新闻或项目,都进行一个简短、精准的概况描述。
+```
+
+<strong>用户提示(User Prompt)</strong>
+
+用户提示用于定义具体的任务指令和数据来源。
+
+```
+- **信息提取与整合:** 从输入源 `{{articles}}`、`{{articles1}}`、`{{articles2}}` 和 `{{articles3}}` 中,筛选并提取关于AI、大模型、AIGC、LLM等相关主题的文章标题及其对应链接,整理为**“AI技术新闻”**模块。
+- **学术论文摘要:** 从输入源 `{{arxiv}}` 中,根据字段 `arxiv_title` 和 `arxiv_link`,总结并整理最新的论文内容,形成**“AI学术论文”**模块。
+- **开源项目筛选:** 从输入源 `{{GitHub}}` 中,筛选出最受瞩目且具影响力的**5个AI开源项目**。提取这些项目的标题和对应链接,整理为**“AI开源项目”**模块。
+
+# 注意事项(Attention)
+- 严格遵循系统提示中定义的日报输出格式。
+- 输出内容总量应为:**10条AI技术新闻、5篇AI学术论文、5个AI开源项目**。
+```
+
+
+
+<strong>步骤三:测试、调试与多渠道发布</strong>
+
+完成智能体的核心逻辑构建后,必须进行严格的测试与调试,以确保其输出符合预期。
+
+<strong>运行预览:</strong> 在 Coze 平台的预览界面运行智能体,观察其生成的简报内容。
+
+```
+# AI日报 by@jasonhuang 2025-09-24
+
+## 🚀 AI技术新闻
+
+🤖 **智元机器人GO-1通用具身基座大模型全面开源**
+链接:https://36kr.com/p/3479085489708163?f=rss
+概况:智元机器人宣布其GO-1通用具身基座大模型全面开源,为机器人领域提供强大的AI基础能力。
+
+🔬 **微软攻克数据中心芯片散热瓶颈:微流体 + AI 精准降温**
+链接:https://www.ithome.com/0/885/391.htm
+概况:微软通过微流体技术与AI算法结合,实现数据中心芯片的精准温度控制,提升能效比。
+......
+
+## 📚 AI学术论文
+
+🧪 **Lyra: Generative 3D Scene Reconstruction via Video Diffusion Model Self-Distillation**
+链接:http://arxiv.org/pdf/2509.19296v1
+概况:提出通过视频扩散模型自蒸馏实现3D场景生成的创新框架,无需多视角训练数据。
+
+📊 **The ICML 2023 Ranking Experiment: Examining Author Self-Assessment in ML/AI Peer Review**
+链接:http://arxiv.org/pdf/2408.13430v3
+概况:研究机器学习会议评审过程中作者自我评估的有效性,提出改进评审机制的方法。
+......
+
+## 💻 AI开源项目
+
+🤖 **llmling-agent - 多智能体工作流框架**
+链接:https://github.com/phil65/llmling-agent
+概况:支持YAML配置和编程方式的多智能体交互框架,集成MCP和ACP协议支持。
+
+🚌 **College_EV_AI_Transportation - 校园AI电动交通系统**
+链接:https://github.com/LuisMc2005v/College_EV_AI_Transportation
+概况:AI驱动的校园电动交通优化系统,实现实时跟踪和高效拼车服务。
+......
+```
+
+仔细检查简报的内容准确性、格式完整性以及语言风格。如果发现不符合预期的部分,需返回提示词或插件配置环节进行细致调整。例如,若内容不够精炼,可修改提示词中的概括要求;若数据获取不准确,则需检查插件配置参数。
+
+多渠道发布: Coze 提供了将智能体一键发布到多个主流应用平台(如微信、豆包、飞书等)的能力,极大地扩展了智能体的应用场景,如图5.10所示。
+
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-10.png" alt="图片描述" width="90%"/>
+  <p>图 5.10 扣子平台的多元发布渠道</p>
+</div>
+
+智能体发布后,可以在扣子商店中看到我们创建的AI智能体,同时也可以将其集成到AI应用中为用户提供服务,如图5.11和图5.12所示。在这里也附上[每日AI新闻智能体体验链接](https://www.coze.cn/store/agent/7506052197071962153?bot_id=true&bid=6hkt3je8o2g16)
+
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-11.png" alt="图片描述" width="90%"/>
+  <p>图 5.11 AI智能体-每日AI新闻</p>
+</div>
+
+更进一步的,我们可以点击这个[体验链接](https://www.coze.cn/store/project/7458678213078777893?from=store_search_suggestion&bid=6gu3cmr7k5g1i)查看在AI应用中的每日AI新闻。
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-12.png" alt="图片描述" width="90%"/>
+  <p>图 5.12 AI应用中的每日AI新闻</p>
+</div>
+<strong>发布配置:</strong>如果想要发布自己的智能体,还需在发布前,为智能体配置恰当的名称、头像及欢迎语,以提供更友好的用户体验,如图5.13和图5.14所示。
+
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-13.png" alt="图片描述" width="90%"/>
+  <p>图 5.13 为智能体配置基础信息</p>
+</div>
+<div align="center">
+  <img src="https://raw.githubusercontent.com/datawhalechina/Hello-Agents/main/docs/images/5-figures/coze-14.png" alt="图片描述" width="90%"/>
+  <p>图 5.14 为智能体配置开场白和预设问题</p>
+</div>
+
+
+### <strong>5.2.3 Coze 的优势与局限性分析</strong>
+
+
+
+<strong>优势:</strong>
 
-案例说明: 这个实践将展示 Coze 强大的插件集成能力。我们将创建一个能生成“每日简报”的助理,它能自动查询当天的天气、抓取最新的AI领域头条新闻,并将这些信息整合成一段结构化的摘要。
+  * <strong>强大的插件生态系统:</strong> Coze 平台的核心优势在于其丰富的插件库,这使得智能体能够轻松接入外部服务与数据源,从而实现功能的高度扩展性。
+  * <strong>直观的可视化编排:</strong> 平台提供了一个低门槛的可视化工作流编排界面,用户无需深厚的编程知识,即可通过“拖拽”方式构建复杂的工作流,大大降低了开发难度。
+  * <strong>灵活的提示词控制:</strong> 通过精确的角色设定与提示词编写,用户可以对智能体的行为和内容生成进行细粒度的控制,实现高度定制化的输出。而且还支持提示词管理和模板,极大的方便开发者进行智能体的开发。
+  * <strong>便捷的多平台部署:</strong> 支持将同一智能体发布到不同的应用平台,实现了跨平台的无缝集成与应用。而且扣子还在不断的整合新平台加入他的生态圈,越来越多的手机厂商和硬件厂商都在陆续支持扣子智能体的发布。
 
-#### 5.2.2.1 步骤一:设定智能体角色与提示词
+<strong>局限性:</strong>
 
-#### 5.2.2.2 步骤二:添加并配置插件(新闻、天气)
+  * <strong>不支持MCP:</strong> 我觉得这是最致命的,尽管扣子的插件市场极其丰富,也极其有吸引力。但是不支持mcp可能会成为限制其发展的枷锁,如果放开那将是又一杀手锏。
+  * <strong>部分插件配置的复杂度高:</strong> 对于需要 API Key 或其他高级参数的插件,用户可能需要具备一定的技术背景才能完成正确的配置。复杂的工作流编排也不仅仅是零基础就可以掌握的,需要一定的js或者python的基础。
+  * <strong>无法导出编排json文件:</strong> 之前扣子是没有导出功能的,但是现在付费版是可以导出的,但是导出的不是像dify,n8n,fastgpt一样的json文件,而是一个zip。也就是说你只能在扣子导出然后扣子导入。
 
-#### 5.2.2.3 步骤三:测试、调试与多渠道发布
 
-### 5.2.3 Coze 的优势与局限性分析
 
 ## 5.3 平台二:Dify
 ### 5.3.1 Dify 的架构与特性
@@ -377,4 +614,4 @@ Description参数即AI Agent调用该工具时,对该工具的描述定义,
 ## 5.6 本章小结
 
 ## 参考文献
-[1]
+[1]

+ 254 - 31
docs/chapter7/第七章 构建你的Agent框架.md

@@ -107,6 +107,10 @@ pip install hello-agents==0.1.1
 ```python
 # 配置好同级文件夹下.env中的大模型API, 可参考code文件夹配套的.env.example,也可以拿前几章的案例的.env文件复用。
 from hello_agents import SimpleAgent, HelloAgentsLLM
+from dotenv import load_dotenv
+
+# 加载环境变量
+load_dotenv()
 
 # 创建LLM实例 - 框架自动检测provider
 llm = HelloAgentsLLM()
@@ -121,9 +125,21 @@ agent = SimpleAgent(
     system_prompt="你是一个有用的AI助手"
 )
 
-# 开始对话
+# 基础对话
 response = agent.run("你好!请介绍一下自己")
 print(response)
+
+# 添加工具功能(可选)
+from hello_agents.tools import CalculatorTool
+calculator = CalculatorTool()
+agent.add_tool(calculator)
+
+# 现在可以使用工具了
+response = agent.run("请帮我计算 2 + 3 * 4")
+print(response)
+
+# 查看对话历史
+print(f"历史消息数: {len(agent.get_history())}")
 ```
 
 
@@ -592,7 +608,7 @@ SimpleAgent是最基础的Agent实现,它展示了如何在框架基础上构
 
 ```python
 # my_simple_agent.py
-from typing import Optional
+from typing import Optional, Iterator
 from hello_agents import SimpleAgent, HelloAgentsLLM, Config, Message
 
 class MySimpleAgent(SimpleAgent):
@@ -606,31 +622,37 @@ class MySimpleAgent(SimpleAgent):
         name: str,
         llm: HelloAgentsLLM,
         system_prompt: Optional[str] = None,
-        config: Optional[Config] = None
+        config: Optional[Config] = None,
+        tool_registry: Optional['ToolRegistry'] = None,
+        enable_tool_calling: bool = True
     ):
         super().__init__(name, llm, system_prompt, config)
-        print(f"✅ {name} 初始化完成,基于框架基类构建")
+        self.tool_registry = tool_registry
+        self.enable_tool_calling = enable_tool_calling and tool_registry is not None
+        print(f"✅ {name} 初始化完成,工具调用: {'启用' if self.enable_tool_calling else '禁用'}")
 ```
 
-接下来,我们需要重写Agent基类的抽象方法`run`:
+接下来,我们需要重写Agent基类的抽象方法`run`。SimpleAgent支持可选的工具调用功能,也方便后续章节的扩展
 
 ```python
 # 继续在 my_simple_agent.py 中添加
-class MySimpleAgent(Agent):
+import re
+
+class MySimpleAgent(SimpleAgent):
     # ... 前面的 __init__ 方法
 
-    def run(self, input_text: str, **kwargs) -> str:
+    def run(self, input_text: str, max_tool_iterations: int = 3, **kwargs) -> str:
         """
-        重写的运行方法 - 实现简单对话逻辑
+        重写的运行方法 - 实现简单对话逻辑,支持可选工具调用
         """
         print(f"🤖 {self.name} 正在处理: {input_text}")
 
         # 构建消息列表
         messages = []
 
-        # 添加系统消息
-        if self.system_prompt:
-            messages.append({"role": "system", "content": self.system_prompt})
+        # 添加系统消息(可能包含工具信息)
+        enhanced_system_prompt = self._get_enhanced_system_prompt()
+        messages.append({"role": "system", "content": enhanced_system_prompt})
 
         # 添加历史消息
         for msg in self._history:
@@ -639,25 +661,173 @@ class MySimpleAgent(Agent):
         # 添加当前用户消息
         messages.append({"role": "user", "content": input_text})
 
-        # 调用LLM
-        response = self.llm.invoke(messages, **kwargs)
+        # 如果没有启用工具调用,使用简单对话逻辑
+        if not self.enable_tool_calling:
+            response = self.llm.invoke(messages, **kwargs)
+            self.add_message(Message(input_text, "user"))
+            self.add_message(Message(response, "assistant"))
+            print(f"✅ {self.name} 响应完成")
+            return response
+
+        # 支持多轮工具调用的逻辑
+        return self._run_with_tools(messages, input_text, max_tool_iterations, **kwargs)
+
+    def _get_enhanced_system_prompt(self) -> str:
+        """构建增强的系统提示词,包含工具信息"""
+        base_prompt = self.system_prompt or "你是一个有用的AI助手。"
+
+        if not self.enable_tool_calling or not self.tool_registry:
+            return base_prompt
+
+        # 获取工具描述
+        tools_description = self.tool_registry.get_tools_description()
+        if not tools_description or tools_description == "暂无可用工具":
+            return base_prompt
+
+        tools_section = "\n\n## 可用工具\n"
+        tools_section += "你可以使用以下工具来帮助回答问题:\n"
+        tools_section += tools_description + "\n"
+
+        tools_section += "\n## 工具调用格式\n"
+        tools_section += "当需要使用工具时,请使用以下格式:\n"
+        tools_section += "`[TOOL_CALL:{tool_name}:{parameters}]`\n"
+        tools_section += "例如:`[TOOL_CALL:search:Python编程]` 或 `[TOOL_CALL:memory:recall=用户信息]`\n\n"
+        tools_section += "工具调用结果会自动插入到对话中,然后你可以基于结果继续回答。\n"
+
+        return base_prompt + tools_section
+```
+
+现在我们实现工具调用的核心逻辑:
+
+```python
+# 继续在 my_simple_agent.py 中添加
+class MySimpleAgent(SimpleAgent):
+    # ... 前面的方法
+
+    def _run_with_tools(self, messages: list, input_text: str, max_tool_iterations: int, **kwargs) -> str:
+        """支持工具调用的运行逻辑"""
+        current_iteration = 0
+        final_response = ""
+
+        while current_iteration < max_tool_iterations:
+            # 调用LLM
+            response = self.llm.invoke(messages, **kwargs)
+
+            # 检查是否有工具调用
+            tool_calls = self._parse_tool_calls(response)
+
+            if tool_calls:
+                print(f"🔧 检测到 {len(tool_calls)} 个工具调用")
+                # 执行所有工具调用并收集结果
+                tool_results = []
+                clean_response = response
+
+                for call in tool_calls:
+                    result = self._execute_tool_call(call['tool_name'], call['parameters'])
+                    tool_results.append(result)
+                    # 从响应中移除工具调用标记
+                    clean_response = clean_response.replace(call['original'], "")
+
+                # 构建包含工具结果的消息
+                messages.append({"role": "assistant", "content": clean_response})
+
+                # 添加工具结果
+                tool_results_text = "\n\n".join(tool_results)
+                messages.append({"role": "user", "content": f"工具执行结果:\n{tool_results_text}\n\n请基于这些结果给出完整的回答。"})
+
+                current_iteration += 1
+                continue
+
+            # 没有工具调用,这是最终回答
+            final_response = response
+            break
+
+        # 如果超过最大迭代次数,获取最后一次回答
+        if current_iteration >= max_tool_iterations and not final_response:
+            final_response = self.llm.invoke(messages, **kwargs)
 
         # 保存到历史记录
         self.add_message(Message(input_text, "user"))
-        self.add_message(Message(response, "assistant"))
-
+        self.add_message(Message(final_response, "assistant"))
         print(f"✅ {self.name} 响应完成")
-        return response
+
+        return final_response
+
+    def _parse_tool_calls(self, text: str) -> list:
+        """解析文本中的工具调用"""
+        pattern = r'\[TOOL_CALL:([^:]+):([^\]]+)\]'
+        matches = re.findall(pattern, text)
+
+        tool_calls = []
+        for tool_name, parameters in matches:
+            tool_calls.append({
+                'tool_name': tool_name.strip(),
+                'parameters': parameters.strip(),
+                'original': f'[TOOL_CALL:{tool_name}:{parameters}]'
+            })
+
+        return tool_calls
+
+    def _execute_tool_call(self, tool_name: str, parameters: str) -> str:
+        """执行工具调用"""
+        if not self.tool_registry:
+            return f"❌ 错误:未配置工具注册表"
+
+        try:
+            # 智能参数解析
+            if tool_name == 'calculator':
+                # 计算器工具直接传入表达式
+                result = self.tool_registry.execute_tool(tool_name, parameters)
+            else:
+                # 其他工具使用智能参数解析
+                param_dict = self._parse_tool_parameters(tool_name, parameters)
+                tool = self.tool_registry.get_tool(tool_name)
+                if not tool:
+                    return f"❌ 错误:未找到工具 '{tool_name}'"
+                result = tool.run(param_dict)
+
+            return f"🔧 工具 {tool_name} 执行结果:\n{result}"
+
+        except Exception as e:
+            return f"❌ 工具调用失败:{str(e)}"
+
+    def _parse_tool_parameters(self, tool_name: str, parameters: str) -> dict:
+        """智能解析工具参数"""
+        param_dict = {}
+
+        if '=' in parameters:
+            # 格式: key=value 或 action=search,query=Python
+            if ',' in parameters:
+                # 多个参数:action=search,query=Python,limit=3
+                pairs = parameters.split(',')
+                for pair in pairs:
+                    if '=' in pair:
+                        key, value = pair.split('=', 1)
+                        param_dict[key.strip()] = value.strip()
+            else:
+                # 单个参数:key=value
+                key, value = parameters.split('=', 1)
+                param_dict[key.strip()] = value.strip()
+        else:
+            # 直接传入参数,根据工具类型智能推断
+            if tool_name == 'search':
+                param_dict = {'query': parameters}
+            elif tool_name == 'memory':
+                param_dict = {'action': 'search', 'query': parameters}
+            else:
+                param_dict = {'input': parameters}
+
+        return param_dict
 ```
 
-我们还可以为自定义Agent添加流式响应功能:
+我们还可以为自定义Agent添加流式响应功能和便利方法
 
 ```python
 # 继续在 my_simple_agent.py 中添加
-class MySimpleAgent(Agent):
+class MySimpleAgent(SimpleAgent):
     # ... 前面的方法
 
-    def stream_run(self, input_text: str, **kwargs):
+    def stream_run(self, input_text: str, **kwargs) -> Iterator[str]:
         """
         自定义的流式运行方法
         """
@@ -687,6 +857,33 @@ class MySimpleAgent(Agent):
         self.add_message(Message(input_text, "user"))
         self.add_message(Message(full_response, "assistant"))
         print(f"✅ {self.name} 流式响应完成")
+
+    def add_tool(self, tool) -> None:
+        """添加工具到Agent(便利方法)"""
+        if not self.tool_registry:
+            from hello_agents import ToolRegistry
+            self.tool_registry = ToolRegistry()
+            self.enable_tool_calling = True
+
+        self.tool_registry.register_tool(tool)
+        print(f"🔧 工具 '{tool.name}' 已添加")
+
+    def has_tools(self) -> bool:
+        """检查是否有可用工具"""
+        return self.enable_tool_calling and self.tool_registry is not None
+    
+    def remove_tool(self, tool_name: str) -> bool:
+        """移除工具(便利方法)"""
+        if self.tool_registry:
+            self.tool_registry.unregister(tool_name)
+            return True
+        return False
+    
+    def list_tools(self) -> list:
+        """列出所有可用工具"""
+        if self.tool_registry:
+            return self.tool_registry.list_tools()
+        return []
 ```
 
 创建一个测试文件`test_simple_agent.py`:
@@ -694,7 +891,8 @@ class MySimpleAgent(Agent):
 ```python
 # test_simple_agent.py
 from dotenv import load_dotenv
-from hello_agents import HelloAgentsLLM
+from hello_agents import HelloAgentsLLM, ToolRegistry
+from hello_agents.tools import CalculatorTool
 from my_simple_agent import MySimpleAgent
 
 # 加载环境变量
@@ -703,27 +901,52 @@ load_dotenv()
 # 创建LLM实例
 llm = HelloAgentsLLM()
 
-# 创建自定义SimpleAgent
-agent = MySimpleAgent(
-    name="我的简单助手",
+# 测试1:基础对话Agent(无工具)
+print("=== 测试1:基础对话 ===")
+basic_agent = MySimpleAgent(
+    name="基础助手",
     llm=llm,
     system_prompt="你是一个友好的AI助手,请用简洁明了的方式回答问题。"
 )
 
-# 测试标准调用
-response1 = agent.run("你好,请介绍一下自己")
-print(f"标准响应: {response1}")
+response1 = basic_agent.run("你好,请介绍一下自己")
+print(f"基础对话响应: {response1}\n")
+
+# 测试2:带工具的Agent
+print("=== 测试2:工具增强对话 ===")
+tool_registry = ToolRegistry()
+calculator = CalculatorTool()
+tool_registry.register_tool(calculator)
+
+enhanced_agent = MySimpleAgent(
+    name="增强助手",
+    llm=llm,
+    system_prompt="你是一个智能助手,可以使用工具来帮助用户。",
+    tool_registry=tool_registry,
+    enable_tool_calling=True
+)
+
+response2 = enhanced_agent.run("请帮我计算 15 * 8 + 32")
+print(f"工具增强响应: {response2}\n")
 
-# 测试流式调用
-print("\n流式响应:")
-for chunk in agent.stream_run("请解释什么是人工智能"):
+# 测试3:流式响应
+print("=== 测试3:流式响应 ===")
+print("流式响应: ", end="")
+for chunk in basic_agent.stream_run("请解释什么是人工智能"):
     pass  # 内容已在stream_run中实时打印
 
+# 测试4:动态添加工具
+print("\n=== 测试4:动态工具管理 ===")
+print(f"添加工具前: {basic_agent.has_tools()}")
+basic_agent.add_tool(calculator)
+print(f"添加工具后: {basic_agent.has_tools()}")
+print(f"可用工具: {basic_agent.list_tools()}")
+
 # 查看对话历史
-print(f"\n对话历史: {len(agent.get_history())} 条消息")
+print(f"\n对话历史: {len(basic_agent.get_history())} 条消息")
 ```
 
-在本节中,我们通过继承 `Agent` 基类,成功构建了一个功能完备且遵循框架规范的基础对话智能体 `MySimpleAgent`,并为其添加了流式响应能力。
+在本节中,我们通过继承 `Agent` 基类,成功构建了一个功能完备且遵循框架规范的基础对话智能体 `MySimpleAgent`。它不仅支持基础对话,还具备可选的工具调用能力、流式响应和便利的工具管理方法
 
 ### 7.4.2 ReActAgent
 

BIN
docs/images/5-figures/coze-01.png


BIN
docs/images/5-figures/coze-02.png


BIN
docs/images/5-figures/coze-03.png


BIN
docs/images/5-figures/coze-04.png


BIN
docs/images/5-figures/coze-05.png


BIN
docs/images/5-figures/coze-06.png


BIN
docs/images/5-figures/coze-07.png


BIN
docs/images/5-figures/coze-08.png


BIN
docs/images/5-figures/coze-09.png


BIN
docs/images/5-figures/coze-10.png


BIN
docs/images/5-figures/coze-11.png


BIN
docs/images/5-figures/coze-12.png


BIN
docs/images/5-figures/coze-13.png


BIN
docs/images/5-figures/coze-14.png


BIN
docs/images/star-history-2025922.png


BIN
docs/images/star-history-2025927.png