File size: 4,117 Bytes
ca1a2dd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# 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}"