| """ |
| tools/web_search.py —— 工具①:联网搜索 |
| |
| 给 agent 一个"上网搜东西"的能力。 |
| """ |
|
|
| import time |
|
|
| from langchain_core.tools import tool |
|
|
| from config import TAVILY_API_KEY |
|
|
|
|
| def _tavily(query: str): |
| """用 Tavily 搜索。函数名以下划线开头,表示这是"内部辅助函数",只给本文件自己调用。""" |
| |
| if not TAVILY_API_KEY: |
| return None |
| import requests |
|
|
| |
| r = requests.post( |
| "https://api.tavily.com/search", |
| json={"api_key": TAVILY_API_KEY, "query": query, "max_results": 8, "include_answer": True}, |
| timeout=30, |
| ) |
| r.raise_for_status() |
| data = r.json() |
| |
| parts = [] |
| if data.get("answer"): |
| parts.append("Answer: " + data["answer"]) |
| for it in data.get("results", []): |
| parts.append(f"[{it.get('title')}]({it.get('url')})\n{it.get('content', '')}") |
| return "## Search Results\n\n" + "\n\n".join(parts) if parts else None |
|
|
|
|
| def _duckduckgo(query: str): |
| """备用搜索引擎:DuckDuckGo。同样是内部辅助函数。""" |
| |
| try: |
| from ddgs import DDGS |
| except ImportError: |
| from duckduckgo_search import DDGS |
|
|
| results = DDGS().text(query, max_results=10) |
| if not results: |
| return None |
| |
| return "## Search Results\n\n" + "\n\n".join( |
| f"[{r.get('title')}]({r.get('href') or r.get('url')})\n{r.get('body') or r.get('content', '')}" |
| for r in results |
| ) |
|
|
|
|
| @tool |
| def web_search(query: str) -> str: |
| """Search the web and return the top results (title, url, snippet). Use for general, |
| up-to-date research; follow up with `visit_webpage` to read a result in full. For |
| encyclopedic facts prefer `wikipedia_search`, which is more reliable.""" |
| |
| try: |
| out = _tavily(query) |
| if out: |
| return out |
| except Exception: |
| pass |
|
|
| |
| last_err = None |
| for attempt in range(4): |
| try: |
| out = _duckduckgo(query) |
| if out: |
| return out |
| except Exception as e: |
| last_err = e |
| |
| time.sleep(1.5 * (attempt + 1)) |
| |
| return ( |
| f"Web search returned nothing (last error: {last_err}). " |
| "Try `wikipedia_search`, rephrase the query, or `visit_webpage` on a known url." |
| ) |
|
|