File size: 1,858 Bytes
cb505ff 76962bf cb505ff | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | from typing import List
import requests
from bs4 import BeautifulSoup
from langchain_core.tools import tool
DUCKDUCKGO_HTML_URL = "https://html.duckduckgo.com/html/"
MAX_RESULTS = 5
REQUEST_TIMEOUT_SECONDS = 10
FALLBACK_MESSAGE = (
"External search returned no results or is unavailable. "
"Answer using the available medical knowledge and clearly state "
"that no external source was retrieved."
)
def _search_duckduckgo(query: str) -> str:
response = requests.get(
DUCKDUCKGO_HTML_URL,
params={"q": query, "kl": "us-en", "kp": "-1"},
headers={"User-Agent": "dmChatbot/1.0"},
timeout=REQUEST_TIMEOUT_SECONDS,
)
response.raise_for_status()
soup = BeautifulSoup(response.text, "html.parser")
results: List[str] = []
for result in soup.select(".result")[:MAX_RESULTS]:
link = result.select_one(".result__a")
if not link:
continue
title = link.get_text(" ", strip=True)
url = link.get("href", "").strip()
snippet_element = result.select_one(".result__snippet")
snippet = snippet_element.get_text(" ", strip=True) if snippet_element else ""
details = [title]
if snippet:
details.append(snippet)
if url:
details.append(url)
results.append("\n".join(details))
if not results:
raise ValueError("DuckDuckGo returned no search results")
return "\n\n".join(results)
@tool
def web_search_tool(query: str) -> str:
"""Search the web for medical information or nutritional data."""
try:
return _search_duckduckgo(query)
except Exception:
return FALLBACK_MESSAGE
def search_web(query: str) -> str:
"""Useful for searching the web for medical information or nutritional data."""
return web_search_tool.invoke({"query": query}) |