Initial commit: jaspersoft-agent-learn teaching project
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
"""
|
||||
Step 01 练习题答案
|
||||
|
||||
⚠️ 先自己思考,再看答案!
|
||||
⚠️ 答案不是唯一的,这里只是其中一种实现
|
||||
"""
|
||||
|
||||
from step_01_tools.concept import BaseTool, ToolResult
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# 练习 1 答案:TextProcessorTool
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
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":
|
||||
result = self.word_count(text)
|
||||
elif operation == "character_count":
|
||||
result = self.character_count(text)
|
||||
elif operation == "sentence_count":
|
||||
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:
|
||||
"""统计单词数量"""
|
||||
# 按空格分割,过滤空字符串
|
||||
words = [w for w in text.split() if w.strip()]
|
||||
return len(words)
|
||||
|
||||
def character_count(self, text: str) -> int:
|
||||
"""统计字符数量(不包括空格)"""
|
||||
# 去除所有空白字符后统计
|
||||
return len(text.replace(" ", "").replace("\n", "").replace("\t", ""))
|
||||
|
||||
def sentence_count(self, text: str) -> int:
|
||||
"""统计句子数量"""
|
||||
# 按常见句子结束符分割
|
||||
import re
|
||||
sentences = re.split(r'[.!?]+', text)
|
||||
# 过滤空字符串
|
||||
sentences = [s for s in sentences if s.strip()]
|
||||
return len(sentences)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# 练习 2 答案:EmailTool
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
class EmailTool(BaseTool):
|
||||
"""邮件处理工具"""
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "email"
|
||||
|
||||
@property
|
||||
def description(self) -> str:
|
||||
return """
|
||||
邮件处理工具,用于发送和搜索邮件。
|
||||
|
||||
支持的操作:
|
||||
send_email: 发送邮件
|
||||
- to: 收件人邮箱
|
||||
- subject: 邮件主题
|
||||
- body: 邮件正文
|
||||
返回: {"success": true, "message_id": "xxx"}
|
||||
|
||||
search_emails: 搜索邮件
|
||||
- keyword: 搜索关键词
|
||||
- limit: 返回数量(默认10)
|
||||
返回: [{"from": "...", "subject": "...", "date": "..."}, ...]
|
||||
|
||||
get_unread_count: 获取未读邮件数量
|
||||
无需参数
|
||||
返回: {"count": 5}
|
||||
"""
|
||||
|
||||
def execute(self, **kwargs) -> ToolResult:
|
||||
"""执行邮件操作"""
|
||||
operation = kwargs.get("operation", "get_unread_count")
|
||||
|
||||
if operation == "send_email":
|
||||
return self.send_email(
|
||||
to=kwargs.get("to", ""),
|
||||
subject=kwargs.get("subject", ""),
|
||||
body=kwargs.get("body", "")
|
||||
)
|
||||
elif operation == "search_emails":
|
||||
return self.search_emails(
|
||||
keyword=kwargs.get("keyword", ""),
|
||||
limit=kwargs.get("limit", 10)
|
||||
)
|
||||
elif operation == "get_unread_count":
|
||||
return self.get_unread_count()
|
||||
else:
|
||||
return ToolResult(success=False, error=f"不支持的操作: {operation}")
|
||||
|
||||
def send_email(self, to: str, subject: str, body: str) -> ToolResult:
|
||||
"""发送邮件"""
|
||||
if not to:
|
||||
return ToolResult(success=False, error="收件人不能为空")
|
||||
if not subject:
|
||||
return ToolResult(success=False, error="主题不能为空")
|
||||
|
||||
# 实际场景:调用邮件发送 API
|
||||
# 这里用模拟数据
|
||||
message_id = f"msg_{hash(to + subject) % 100000}"
|
||||
|
||||
return ToolResult(
|
||||
success=True,
|
||||
result={
|
||||
"success": True,
|
||||
"message_id": message_id,
|
||||
"to": to,
|
||||
"subject": subject
|
||||
}
|
||||
)
|
||||
|
||||
def search_emails(self, keyword: str, limit: int) -> ToolResult:
|
||||
"""搜索邮件"""
|
||||
if not keyword:
|
||||
return ToolResult(success=False, error="搜索关键词不能为空")
|
||||
|
||||
# 模拟搜索结果
|
||||
mock_results = [
|
||||
{
|
||||
"from": "boss@company.com",
|
||||
"subject": f"关于项目的{keyword}",
|
||||
"date": "2024-01-15",
|
||||
"snippet": "..."
|
||||
},
|
||||
{
|
||||
"from": "colleague@company.com",
|
||||
"subject": f"回复: {keyword}的讨论",
|
||||
"date": "2024-01-14",
|
||||
"snippet": "..."
|
||||
},
|
||||
]
|
||||
|
||||
return ToolResult(
|
||||
success=True,
|
||||
result=mock_results[:limit]
|
||||
)
|
||||
|
||||
def get_unread_count(self) -> ToolResult:
|
||||
"""获取未读邮件数量"""
|
||||
# 实际场景:调用邮件 API 获取未读数
|
||||
return ToolResult(success=True, result={"count": 5})
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# 练习 3 答案:给 ToolRegistry 添加 search_tools
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
from step_01_tools.concept import ToolRegistry, CalculatorTool, SearchTool
|
||||
|
||||
|
||||
def add_search_to_registry():
|
||||
"""
|
||||
演示如何给 ToolRegistry 添加 search_tools 方法
|
||||
"""
|
||||
|
||||
# 方法1:在原类上添加(直接修改原类)
|
||||
def search_tools_original(self, keyword: str) -> list[dict]:
|
||||
"""根据关键词搜索工具"""
|
||||
keyword_lower = keyword.lower()
|
||||
results = []
|
||||
|
||||
for tool in self._tools.values():
|
||||
# 检查名称或描述中是否包含关键词
|
||||
name_match = keyword_lower in tool.name.lower()
|
||||
desc_match = keyword_lower in tool.description.lower()
|
||||
|
||||
if name_match or desc_match:
|
||||
results.append(tool.to_dict())
|
||||
|
||||
return results
|
||||
|
||||
# 给 ToolRegistry 添加方法
|
||||
ToolRegistry.search_tools = search_tools_original
|
||||
|
||||
# 测试
|
||||
registry = ToolRegistry()
|
||||
registry.register(CalculatorTool())
|
||||
registry.register(SearchTool())
|
||||
registry.register(TextProcessorTool())
|
||||
|
||||
print("搜索 'text':")
|
||||
for t in registry.search_tools("text"):
|
||||
print(f" - {t['name']}")
|
||||
|
||||
print("搜索 'calculate':")
|
||||
for t in registry.search_tools("calculate"):
|
||||
print(f" - {t['name']}")
|
||||
|
||||
print("搜索 'web':")
|
||||
for t in registry.search_tools("web"):
|
||||
print(f" - {t['name']}")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# 测试运行
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
def test_answers():
|
||||
"""测试答案"""
|
||||
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")
|
||||
email_tool = EmailTool()
|
||||
|
||||
print("\n 发送邮件:")
|
||||
result = email_tool.send_email("test@example.com", "测试", "这是一封测试邮件")
|
||||
print(f" 结果: {result.result}")
|
||||
|
||||
print("\n 搜索邮件:")
|
||||
result = email_tool.search_emails("项目", limit=5)
|
||||
print(f" 结果: {result.result}")
|
||||
|
||||
print("\n 未读邮件数:")
|
||||
result = email_tool.get_unread_count()
|
||||
print(f" 结果: {result.result}")
|
||||
|
||||
# 测试练习 3
|
||||
print("\n📝 练习 3: search_tools")
|
||||
add_search_to_registry()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_answers()
|
||||
Reference in New Issue
Block a user