import jsonimport reimport requestsfrom typing import Callable, Dict, List, Optional# --- 1. 定义工具 (Tools) ---def search_web(query: str) -> str: """ 模拟联网搜索工具。 在真实场景中,这里可以调用 Google Search API, Bing API... """ print(f"🔍 [工具调用] 正在搜索: {query}") # 这里为了演示,我们模拟一个搜索结果,或者你可以接入真实的 API try: # 这是一个简单的示例,实际使用中建议申请 API Key url = "https://uapis.cn/api/v1/search/aggregate" headers = {"Content-Type": "application/json"} payload = { "query": query, "fetch_full": False, "timeout_ms": 5000 } resp = requests.post(url, json=payload, headers=headers, timeout=5) if resp.status_code == 200: data = resp.json() rtn = "" for item in data.get("results", []): rtn += f"{item['title']} - {item['url']}" return f"搜索结果: {rtn}" else: return f"请求失败:{resp['text']}" except Exception as e: return f"搜索出错: {str(e)}"def calculate(expression: str) -> str: """ 安全计算数学表达式。 """ print(f"🧮 [工具调用] 正在计算: {expression}") try: # 仅允许数字和基本运算符,防止代码注入 if not re.match(r'^[0-9+\-*/().\s]+$', expression): return "错误: 无效的数学表达式" result = eval(expression) return f"计算结果: {result}" except Exception as e: return f"计算出错: {str(e)}"# 注册可用工具TOOLS = { "search_web": { "function": search_web, "description": "当用户需要查询事实、新闻、天气或未知信息时使用。参数是搜索关键词。", "parameters": {"type": "string", "name": "query"} }, "calculate": { "function": calculate, "description": "当用户需要进行数学计算时使用。参数是数学表达式(如 '2 + 2' 或 '10 * 5')。", "parameters": {"type": "string", "name": "expression"} }}# --- 2. 定义 Agent 核心逻辑 ---class SimpleAgent: def __init__(self): self.history = [] def _decide_tool(self, user_input: str) -> Optional[Dict]: """ 简单的规则引擎来决定使用哪个工具。 在实际复杂 Agent 中,这里通常会调用 LLM (如 GPT-4) 来进行意图识别。 """ user_input_lower = user_input.lower() # 规则 1: 数学计算 # 如果包含明显的数学符号或 "计算", "算一下" if any(op in user_input for op in ['+', '-', '*', '/', '=']) or "计算" in user_input or "算" in user_input: # 提取数字和运算符部分 (简化版提取) match = re.search(r'([\d+\-*/().\s]+)', user_input) if match: return {"tool": "calculate", "args": match.group(1).strip()} # 规则 2: 搜索查询 # 如果包含 "搜索", "查询", "是谁", "什么是", "天气", "新闻" 等 search_keywords = ["搜索", "查询", "是谁", "什么是", "weather", "news", "who is", "what is"] if any(kw in user_input_lower for kw in search_keywords): # 提取问题主体,去掉指令词 (简化版) query = user_input for kw in ["搜索", "查询", "请告诉我", "帮我查一下"]: query = query.replace(kw, "") return {"tool": "search_web", "args": query.strip()} return None def run(self, user_input: str) -> str: print(f"\n👤 用户: {user_input}") # 第一步:思考/决策 decision = self._decide_tool(user_input) if decision: tool_name = decision["tool"] args = decision["args"] if tool_name in TOOLS: # 第二步:行动 (调用工具) tool_func = TOOLS[tool_name]["function"] observation = tool_func(args) # 第三步:综合结果 response = f"我使用了 {tool_name} 工具,得到的结果是:{observation}" return response else: return "我找不到对应的工具来处理这个请求。" else: # 如果没有匹配到工具,直接回复 return "我不确定是否需要使用工具。你可以问我数学题,或者让我搜索某些信息(例如:'搜索 Python 教程' 或 '计算 123 * 456')。"# --- 3. 运行测试 ---if __name__ == "__main__": agent = SimpleAgent() # 测试用例 1: 触发搜索 q1 = "搜索一下 Python 3.12 新特性" print(f"🤖 Agent: {agent.run(q1)}") # 测试用例 2: 触发计算 q2 = "帮我计算 (120 + 50) * 3 等于多少" print(f"🤖 Agent: {agent.run(q2)}") # 测试用例 3: 无工具匹配 q3 = "你好,今天心情怎么样?" print(f"🤖 Agent: {agent.run(q3)}")