# ════════════════════════════════════════════════════════════════ # tools/web_search.py # ════════════════════════════════════════════════════════════════ """网络搜索工具(从配置读取 max_results / engine / api_key)""" import time from tools.base_tool import BaseTool, ToolResult from config.settings import settings _MOCK_RESULTS: dict[str, list[dict]] = { "天气": [{"title": "今日天气预报", "snippet": "晴转多云,气温 15°C ~ 24°C,东南风 3 级"}, {"title": "未来 7 天天气", "snippet": "本周整体晴好,周末有小雨"}], "python":[{"title": "Python 官方文档", "snippet": "Python 3.12 新特性:改进的错误提示"}, {"title": "Python 教程", "snippet": "从零开始学 Python,包含 300+ 实战案例"}], } _DEFAULT_RESULTS = [ {"title": "搜索结果 1", "snippet": "找到相关内容,请查看详情"}, {"title": "搜索结果 2", "snippet": "更多相关信息可通过链接访问"}, ] class WebSearchTool(BaseTool): name = "web_search" description = "在互联网上搜索信息,返回相关网页摘要" parameters = { "query": {"type": "string", "description": "搜索关键词"}, "max_results": {"type": "integer", "description": "返回结果数量"}, } def __init__(self): super().__init__() cfg = settings.tools.web_search self._default_max = cfg.max_results self._engine = cfg.engine self._api_key = cfg.api_key self._timeout = cfg.timeout self.logger.debug( f"⚙️ WebSearch engine={self._engine}, " f"max_results={self._default_max}, " f"api_key={'***' if self._api_key else '(未设置)'}" ) def execute(self, query: str, max_results: int | None = None, **_) -> ToolResult: max_results = max_results or self._default_max time.sleep(0.1) if self._engine != "mock" and self._api_key: # 生产环境:调用真实搜索 API # results = self._call_real_api(query, max_results) pass results = _DEFAULT_RESULTS for kw, data in _MOCK_RESULTS.items(): if kw in query: results = data break results = results[:max_results] formatted = "\n".join( f"[{i+1}] {r['title']}\n {r['snippet']}" for i, r in enumerate(results) ) return ToolResult( success=True, output=f"搜索「{query}」({self._engine}),共 {len(results)} 条:\n{formatted}", metadata={"query": query, "engine": self._engine, "count": len(results)}, )