""" Step 01 练习题:设计你的第一个 Tool ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🎯 练习目标: 1. 巩固 Tool 的基本结构 2. 设计一个业务相关的 Tool 3. 理解 Tool 注册系统 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ """ # ═══════════════════════════════════════════════════════════════════════════════ # 练习 1:完善 TextProcessorTool # ═══════════════════════════════════════════════════════════════════════════════ """ 任务: 完善 TextProcessorTool,这个工具用于处理文本。 要求: 1. 实现 word_count 方法:统计单词数量 2. 实现 character_count 方法:统计字符数量(不包括空格) 3. 实现 sentence_count 方法:统计句子数量(按句号、问号、感叹号分割) 提示: - text 可能包含多行 - 句子分割要考虑常见的句子结束符:. ! ? - 单词分割可以考虑按空格分割 完成后测试: text = "Hello, world! This is a test. How are you?" 预期结果: - word_count: 9 - character_count: 38 (不包括空格) - sentence_count: 3 """ from step_01_tools.concept import BaseTool, ToolResult class TextProcessorTool(BaseTool): """文本处理工具""" @property def name(self) -> str: return "text_processor" @property def description(self) -> str: return "文本处理工具,统计文本的各种特征" def execute(self, **kwargs) -> ToolResult: """处理文本请求""" text = kwargs.get("text", "") operation = kwargs.get("operation", "word_count") # 默认操作 if not text: return ToolResult(success=False, error="文本不能为空") if operation == "word_count": # TODO: 实现单词统计 result = self.word_count(text) elif operation == "character_count": # TODO: 实现字符统计 result = self.character_count(text) elif operation == "sentence_count": # TODO: 实现句子统计 result = self.sentence_count(text) else: return ToolResult(success=False, error=f"不支持的操作: {operation}") return ToolResult(success=True, result=result) def word_count(self, text: str) -> int: """统计单词数量""" # 提示:按空格分割,过滤空字符串 # 你的代码: pass def character_count(self, text: str) -> int: """统计字符数量(不包括空格)""" # 提示:去除所有空白字符后统计长度 # 你的代码: pass def sentence_count(self, text: str) -> int: """统计句子数量""" # 提示:按 . ! ? 分割 # 你的代码: pass # ═══════════════════════════════════════════════════════════════════════════════ # 练习 2:设计一个 EmailTool # ═══════════════════════════════════════════════════════════════════════════════ """ 任务: 设计一个 EmailTool,用于处理邮件相关操作。 功能要求: 1. send_email: 发送邮件(收件人、主题、正文) 2. search_emails: 搜索邮件(关键词) 3. get_unread_count: 获取未读邮件数量 设计提示: - 工具名称要简洁明了 - 描述要告诉 LLM 这个工具能做什么 - execute 方法要处理不同的 operation 这个练习的目的是让你学会: - 如何设计多功能的 Tool - 如何用 operation 参数区分不同功能 - 如何返回结构化的结果 """ class EmailTool(BaseTool): """邮件处理工具""" # TODO: 实现属性和方法 pass # ═══════════════════════════════════════════════════════════════════════════════ # 练习 3:改进工具注册表 # ═══════════════════════════════════════════════════════════════════════════════ """ 任务: 给 ToolRegistry 添加一个新功能:根据描述关键词搜索工具 方法签名: def search_tools(self, keyword: str) -> list[dict]: ''' 根据关键词搜索工具 参数: keyword: str - 搜索关键词 返回: 匹配的工具列表,格式同 list_tools() 匹配规则: 如果关键词出现在工具名称或描述中,就算匹配 匹配应该不区分大小写 ''' 预期行为: registry = ToolRegistry() registry.register(CalculatorTool()) registry.register(SearchTool()) registry.register(TextProcessorTool()) # 用你刚完成的 results = registry.search_tools("text") # 应该返回 text_processor results = registry.search_tools("calculate") # 应该返回 calculator results = registry.search_tools("web") # 应该返回 web_search """ # 从 step_01_tools.concept 导入已有的类 from step_01_tools.concept import ToolRegistry, CalculatorTool, SearchTool def add_search_to_registry(): """ 在这里实现 search_tools 方法 提示: 1. 遍历所有已注册的工具 2. 检查 name 或 description 中是否包含 keyword 3. 收集匹配的工具 4. 返回列表 完成后,在 main.py 中测试 """ # 你的代码: pass # ═══════════════════════════════════════════════════════════════════════════════ # 运行测试 # ═══════════════════════════════════════════════════════════════════════════════ def test_exercises(): """测试所有练习""" print("\n" + "=" * 60) print("测试练习答案") print("=" * 60) # 测试练习 1 print("\n📝 练习 1: TextProcessorTool") tool = TextProcessorTool() test_text = "Hello, world! This is a test. How are you?" print(f"测试文本: {test_text}") print(f"单词数量: {tool.word_count(test_text)}") # 应该是 9 print(f"字符数量: {tool.character_count(test_text)}") # 应该是 38 print(f"句子数量: {tool.sentence_count(test_text)}") # 应该是 3 # 测试练习 2 print("\n📝 练习 2: EmailTool") # 运行看看你完成了多少 # 测试练习 3 print("\n📝 练习 3: search_tools") registry = ToolRegistry() registry.register(CalculatorTool()) registry.register(SearchTool()) registry.register(tool) # 你的测试代码: if __name__ == "__main__": test_exercises()