PersonaTrip-Agent / tools /web_search.py
tracyshen301
Configure Git LFS for image assets and prepare for push
ca1a2dd
raw
history blame
4.12 kB
# filename: web_search.py (Hybrid Intelligence Version)
import os
import asyncio
from tavily import TavilyClient
from anthropic import AsyncAnthropic
from dotenv import load_dotenv
load_dotenv()
tavily_client = TavilyClient(api_key=os.getenv("TAVILY_API_KEY"))
async_anthropic_client = AsyncAnthropic()
async def get_travel_intelligence_briefing(destination: str, time_period: str, user_keywords: list[str] = None) -> str:
"""
接收目的地、时间段和用户特定的关键词,执行一个混合了
“基础情报”和“关键词情报”的网络搜索,然后汇总成一份简报。
"""
print(f"\n--- [Hybrid Intelligence] Briefing for: {destination} ({time_period}) with keywords: {user_keywords} ---")
queries = [
f"major holidays or festivals in {destination} during {time_period}",
f"weather advisories or natural disaster risk for {destination} {time_period}",
f"general transport strikes or protests planned for {destination} {time_period}",
f"official travel warnings or geopolitical issues for {destination}",
]
if user_keywords:
for keyword in user_keywords:
queries.append(f"latest news, closures, or strikes related to {keyword} {destination}")
print(f"--- Step 1: Generated {len(queries)} hybrid queries. ---")
async def _run_single_search(query):
try:
return await asyncio.to_thread(
tavily_client.search,
query=query, search_depth="basic", max_results=3
)
except Exception as e:
print(f" - Search failed for query '{query}': {e}")
return None
print("--- Step 2: Executing all searches in parallel...")
search_tasks = [_run_single_search(q) for q in queries]
all_results = await asyncio.gather(*search_tasks)
raw_context = ""
for query, result_pack in zip(queries, all_results):
if result_pack and result_pack.get('results'):
raw_context += f"Intelligence regarding '{query}':\n"
for res in result_pack['results']:
raw_context += f"- {res['content']}\n"
raw_context += "\n---\n"
if not raw_context:
return "Could not retrieve any relevant travel intelligence from the web."
print("--- Step 3: Synthesizing all intelligence into a final briefing...")
system_prompt = "You are a professional travel intelligence analyst. Your job is to synthesize raw data into a clear, concise, and actionable briefing for a trip planner. Structure your output with clear headings."
synthesis_prompt = f"""
Please analyze the following raw web search results for a trip to **{destination}** during **{time_period}**.
Consolidate all information into a structured 'Travel Intelligence Briefing'.
For each category (General Safety, Weather, Events, Transportation, and **User-Specific Keywords**), provide a concise summary.
If no information is found for a category, state "No significant information found."
**Raw Intelligence Data:**
---
{raw_context}
---
**Required Output Format:**
**Travel Intelligence Briefing: {destination} ({time_period})**
**1. General Safety & Advisories:**
- [Summary of wars, warnings, policy changes]
**2. Weather & Environment:**
- [Summary of forecasts, climate patterns, disaster risks]
**3. Cultural Events & Holidays:**
- [Summary of festivals, holidays, major events]
**4. General Transportation:**
- [Summary of general strikes or disruptions]
**5. User-Specific Items:**
- [For each keyword from the user_keywords list, provide a specific summary. e.g., "Regarding Finnair: ...", "Regarding Louvre Museum: ..."]
"""
try:
response = await async_anthropic_client.messages.create(
model="claude-3-haiku-20240307", max_tokens=1000,
system=system_prompt, messages=[{"role": "user", "content": synthesis_prompt}]
)
return response.content[0].text
except Exception as e:
return f"Error during final synthesis: {e}"