戒酒的李白

Multimodal search tools have been completed.

1 """ 1 """
2 -专为 AI Agent 设计的舆情搜索工具集 (Tavily) 2 +专为 AI Agent 设计的多模态搜索工具集 (Bocha)
3 3
4 -版本: 1.5 4 +版本: 1.1
5 最后更新: 2025-08-22 5 最后更新: 2025-08-22
6 6
7 -此脚本将复杂的Tavily搜索功能分解为一系列目标明确、参数极少的独立工具,  
8 -专为AI Agent调用而设计。Agent只需根据任务意图选择合适的工具,  
9 -无需理解复杂的参数组合。所有工具默认搜索“新闻”(topic='news')。 7 +此脚本将复杂的 Bocha AI Search 功能分解为一系列目标明确、参数极少的独立工具,
  8 +专为 AI Agent 调用而设计。Agent 只需根据任务意图(如常规搜索、查找结构化数据或时效性新闻)
  9 +选择合适的工具,无需理解复杂的参数组合。
10 10
11 -新特性:  
12 -- 新增 `basic_search_news` 工具,用于执行标准、通用的新闻搜索。  
13 -- 每个搜索结果现在都包含 `published_date` (新闻发布日期)。 11 +核心特性:
  12 +- 强大多模态能力: 能同时返回网页、图片、AI总结、追问建议,以及丰富的“模态卡”结构化数据。
  13 +- 模态卡支持: 针对天气、股票、汇率、百科、医疗等特定查询,可直接返回结构化数据卡片,便于Agent直接解析和使用。
14 14
15 主要工具: 15 主要工具:
16 -- basic_search_news: (新增) 执行标准、快速的通用新闻搜索。  
17 -- deep_search_news: 对主题进行最全面的深度分析。  
18 -- search_news_last_24_hours: 获取24小时内的最新动态。  
19 -- search_news_last_week: 获取过去一周的主要报道。  
20 -- search_images_for_news: 查找与新闻主题相关的图片。  
21 -- search_news_by_date: 在指定的历史日期范围内搜索。 16 +- comprehensive_search: 执行全面搜索,返回网页、图片、AI总结及可能的模态卡。
  17 +- search_for_structured_data: 专门用于查询天气、股票、汇率等可触发“模态卡”的结构化信息。
  18 +- web_search_only: 执行纯网页搜索,不请求AI总结,速度更快。
  19 +- search_last_24_hours: 获取过去24小时内的最新信息。
  20 +- search_last_week: 获取过去一周内的主要报道。
22 """ 21 """
23 22
24 import os 23 import os
25 -from typing import List, Dict, Any, Optional  
26 -from dataclasses import dataclass, field 24 +import json
  25 +from typing import List, Dict, Any, Optional, Literal
27 26
28 -# 运行前请确保已安装Tavily库: pip install tavily-python 27 +# 运行前请确保已安装 requests 库: pip install requests
29 try: 28 try:
30 - from tavily import TavilyClient 29 + import requests
31 except ImportError: 30 except ImportError:
32 - raise ImportError("Tavily库未安装,请运行 `pip install tavily-python` 进行安装。") 31 + raise ImportError("requests 库未安装,请运行 `pip install requests` 进行安装。")
33 32
34 # --- 1. 数据结构定义 --- 33 # --- 1. 数据结构定义 ---
  34 +from dataclasses import dataclass, field
35 35
36 @dataclass 36 @dataclass
37 -class SearchResult:  
38 - """  
39 - 网页搜索结果数据类  
40 - 包含 published_date 属性来存储新闻发布日期  
41 - """  
42 - title: str 37 +class WebpageResult:
  38 + """网页搜索结果"""
  39 + name: str
43 url: str 40 url: str
44 - content: str  
45 - score: Optional[float] = None  
46 - raw_content: Optional[str] = None  
47 - published_date: Optional[str] = None 41 + snippet: str
  42 + display_url: Optional[str] = None
  43 + date_last_crawled: Optional[str] = None
48 44
49 @dataclass 45 @dataclass
50 class ImageResult: 46 class ImageResult:
51 - """图片搜索结果数据类"""  
52 - url: str  
53 - description: Optional[str] = None 47 + """图片搜索结果"""
  48 + name: str
  49 + content_url: str
  50 + host_page_url: Optional[str] = None
  51 + thumbnail_url: Optional[str] = None
  52 + width: Optional[int] = None
  53 + height: Optional[int] = None
54 54
55 @dataclass 55 @dataclass
56 -class TavilyResponse:  
57 - """封装Tavily API的完整返回结果,以便在工具间传递""" 56 +class ModalCardResult:
  57 + """
  58 + 模态卡结构化数据结果
  59 + 这是 Bocha 搜索的核心特色,用于返回特定类型的结构化信息。
  60 + """
  61 + card_type: str # 例如: weather_china, stock, baike_pro, medical_common
  62 + content: Dict[str, Any] # 解析后的JSON内容
  63 +
  64 +@dataclass
  65 +class BochaResponse:
  66 + """封装 Bocha API 的完整返回结果,以便在工具间传递"""
58 query: str 67 query: str
59 - answer: Optional[str] = None  
60 - results: List[SearchResult] = field(default_factory=list) 68 + conversation_id: Optional[str] = None
  69 + answer: Optional[str] = None # AI生成的总结答案
  70 + follow_ups: List[str] = field(default_factory=list) # AI生成的追问
  71 + webpages: List[WebpageResult] = field(default_factory=list)
61 images: List[ImageResult] = field(default_factory=list) 72 images: List[ImageResult] = field(default_factory=list)
62 - response_time: Optional[float] = None 73 + modal_cards: List[ModalCardResult] = field(default_factory=list)
63 74
64 75
65 # --- 2. 核心客户端与专用工具集 --- 76 # --- 2. 核心客户端与专用工具集 ---
66 77
67 -class TavilyNewsAgency: 78 +class BochaMultimodalSearch:
68 """ 79 """
69 - 一个包含多种专用新闻舆情搜索工具的客户端。 80 + 一个包含多种专用多模态搜索工具的客户端。
70 每个公共方法都设计为供 AI Agent 独立调用的工具。 81 每个公共方法都设计为供 AI Agent 独立调用的工具。
71 """ 82 """
72 83
  84 + BASE_URL = "https://api.bochaai.com/v1/ai-search"
  85 +
73 def __init__(self, api_key: Optional[str] = None): 86 def __init__(self, api_key: Optional[str] = None):
74 """ 87 """
75 初始化客户端。 88 初始化客户端。
76 Args: 89 Args:
77 - api_key: Tavily API密钥,若不提供则从环境变量 TAVILY_API_KEY 读取。 90 + api_key: Bocha API密钥,若不提供则从环境变量 BOCHA_API_KEY 读取。
78 """ 91 """
79 if api_key is None: 92 if api_key is None:
80 - api_key = os.getenv("TAVILY_API_KEY") 93 + api_key = os.getenv("BOCHA_API_KEY")
81 if not api_key: 94 if not api_key:
82 - raise ValueError("Tavily API Key未找到!请设置TAVILY_API_KEY环境变量或在初始化时提供")  
83 - self._client = TavilyClient(api_key=api_key) 95 + raise ValueError("Bocha API Key未找到!请设置 BOCHA_API_KEY 环境变量或在初始化时提供")
  96 +
  97 + self._headers = {
  98 + 'Authorization': f'Bearer {api_key}',
  99 + 'Content-Type': 'application/json',
  100 + 'Accept': '*/*'
  101 + }
84 102
85 - def _search_internal(self, **kwargs) -> TavilyResponse: 103 + def _parse_search_response(self, response_dict: Dict[str, Any], query: str) -> BochaResponse:
  104 + """从API的原始字典响应中解析出结构化的BochaResponse对象"""
  105 +
  106 + final_response = BochaResponse(query=query)
  107 + final_response.conversation_id = response_dict.get('conversation_id')
  108 +
  109 + messages = response_dict.get('messages', [])
  110 + for msg in messages:
  111 + role = msg.get('role')
  112 + if role != 'assistant':
  113 + continue
  114 +
  115 + msg_type = msg.get('type')
  116 + content_type = msg.get('content_type')
  117 + content_str = msg.get('content', '{}')
  118 +
  119 + try:
  120 + content_data = json.loads(content_str)
  121 + except json.JSONDecodeError:
  122 + # 如果内容不是合法的JSON字符串(例如纯文本的answer),则直接使用
  123 + content_data = content_str
  124 +
  125 + if msg_type == 'answer' and content_type == 'text':
  126 + final_response.answer = content_data
  127 +
  128 + elif msg_type == 'follow_up' and content_type == 'text':
  129 + final_response.follow_ups.append(content_data)
  130 +
  131 + elif msg_type == 'source':
  132 + if content_type == 'webpage':
  133 + web_results = content_data.get('value', [])
  134 + for item in web_results:
  135 + final_response.webpages.append(WebpageResult(
  136 + name=item.get('name'),
  137 + url=item.get('url'),
  138 + snippet=item.get('snippet'),
  139 + display_url=item.get('displayUrl'),
  140 + date_last_crawled=item.get('dateLastCrawled')
  141 + ))
  142 + elif content_type == 'image':
  143 + final_response.images.append(ImageResult(
  144 + name=content_data.get('name'),
  145 + content_url=content_data.get('contentUrl'),
  146 + host_page_url=content_data.get('hostPageUrl'),
  147 + thumbnail_url=content_data.get('thumbnailUrl'),
  148 + width=content_data.get('width'),
  149 + height=content_data.get('height')
  150 + ))
  151 + # 所有其他 content_type 都视为模态卡
  152 + else:
  153 + final_response.modal_cards.append(ModalCardResult(
  154 + card_type=content_type,
  155 + content=content_data
  156 + ))
  157 +
  158 + return final_response
  159 +
  160 +
  161 + def _search_internal(self, **kwargs) -> BochaResponse:
86 """内部通用的搜索执行器,所有工具最终都调用此方法""" 162 """内部通用的搜索执行器,所有工具最终都调用此方法"""
  163 + query = kwargs.get("query", "Unknown Query")
  164 + payload = {
  165 + "stream": False, # Agent工具通常使用非流式以获取完整结果
  166 + }
  167 + payload.update(kwargs)
  168 +
87 try: 169 try:
88 - kwargs['topic'] = 'general'  
89 - api_params = {k: v for k, v in kwargs.items() if v is not None}  
90 - response_dict = self._client.search(**api_params) 170 + response = requests.post(self.BASE_URL, headers=self._headers, json=payload, timeout=30)
  171 + response.raise_for_status() # 如果HTTP状态码是4xx或5xx,则抛出异常
91 172
92 - search_results = [  
93 - SearchResult(  
94 - title=item.get('title'),  
95 - url=item.get('url'),  
96 - content=item.get('content'),  
97 - score=item.get('score'),  
98 - raw_content=item.get('raw_content'),  
99 - published_date=item.get('published_date')  
100 - ) for item in response_dict.get('results', [])  
101 - ]  
102 -  
103 - image_results = [ImageResult(url=item.get('url'), description=item.get('description')) for item in response_dict.get('images', [])]  
104 -  
105 - return TavilyResponse(  
106 - query=response_dict.get('query'), answer=response_dict.get('answer'),  
107 - results=search_results, images=image_results,  
108 - response_time=response_dict.get('response_time')  
109 - ) 173 + response_dict = response.json()
  174 + if response_dict.get("code") != 200:
  175 + print(f"API返回错误: {response_dict.get('msg', '未知错误')}")
  176 + return BochaResponse(query=query)
  177 +
  178 + return self._parse_search_response(response_dict, query)
  179 +
  180 + except requests.exceptions.RequestException as e:
  181 + print(f"搜索时发生网络错误: {str(e)}")
  182 + return BochaResponse(query=query)
110 except Exception as e: 183 except Exception as e:
111 - print(f"搜索时发生错误: {str(e)}")  
112 - return TavilyResponse(query=kwargs.get("query", "Unknown Query")) 184 + print(f"处理响应时发生未知错误: {str(e)}")
  185 + return BochaResponse(query=query)
113 186
114 # --- Agent 可用的工具方法 --- 187 # --- Agent 可用的工具方法 ---
115 188
116 - def basic_search_news(self, query: str, max_results: int = 7) -> TavilyResponse: 189 + def comprehensive_search(self, query: str, max_results: int = 10) -> BochaResponse:
117 """ 190 """
118 - 【工具】基础新闻搜索: 执行一次标准、快速的新闻搜索。  
119 - 这是最常用的通用搜索工具,适用于不确定需要何种特定搜索时。 191 + 【工具】全面综合搜索: 执行一次标准的、包含所有信息类型的综合搜索。
  192 + 返回网页、图片、AI总结、追问建议和可能的模态卡。这是最常用的通用搜索工具。
120 Agent可提供搜索查询(query)和可选的最大结果数(max_results)。 193 Agent可提供搜索查询(query)和可选的最大结果数(max_results)。
121 """ 194 """
122 - print(f"--- TOOL: 基础新闻搜索 (query: {query}) ---") 195 + print(f"--- TOOL: 全面综合搜索 (query: {query}) ---")
123 return self._search_internal( 196 return self._search_internal(
124 query=query, 197 query=query,
125 - max_results=max_results,  
126 - search_depth="basic",  
127 - include_answer=False 198 + count=max_results,
  199 + answer=True # 开启AI总结
128 ) 200 )
129 201
130 - def deep_search_news(self, query: str) -> TavilyResponse: 202 + def web_search_only(self, query: str, max_results: int = 15) -> BochaResponse:
131 """ 203 """
132 - 【工具】深度新闻分析: 对一个主题进行最全面、最深入的搜索。  
133 - 返回AI生成的“高级”详细摘要答案和最多20条最相关的新闻结果。适用于需要全面了解某个事件背景的场景。  
134 - Agent只需提供搜索查询(query)。 204 + 【工具】纯网页搜索: 只获取网页链接和摘要,不请求AI生成答案。
  205 + 适用于需要快速获取原始网页信息,而不需要AI额外分析的场景。速度更快,成本更低。
135 """ 206 """
136 - print(f"--- TOOL: 深度新闻分析 (query: {query}) ---") 207 + print(f"--- TOOL: 纯网页搜索 (query: {query}) ---")
137 return self._search_internal( 208 return self._search_internal(
138 - query=query, search_depth="advanced", max_results=20, include_answer="advanced" 209 + query=query,
  210 + count=max_results,
  211 + answer=False # 关闭AI总结
139 ) 212 )
140 213
141 - def search_news_last_24_hours(self, query: str) -> TavilyResponse: 214 + def search_for_structured_data(self, query: str) -> BochaResponse:
142 """ 215 """
143 - 【工具】搜索24小时内新闻: 获取关于某个主题的最新动态。  
144 - 此工具专门查找过去24小时内发布的新闻。适用于追踪突发事件或最新进展。  
145 - Agent只需提供搜索查询(query)。 216 + 【工具】结构化数据查询: 专门用于可能触发“模态卡”的查询。
  217 + 当Agent意图是查询天气、股票、汇率、百科定义、火车票、汽车参数等结构化信息时,应优先使用此工具。
  218 + 它会返回所有信息,但Agent应重点关注结果中的 `modal_cards` 部分。
146 """ 219 """
147 - print(f"--- TOOL: 搜索24小时内新闻 (query: {query}) ---")  
148 - return self._search_internal(query=query, time_range='d', max_results=10) 220 + print(f"--- TOOL: 结构化数据查询 (query: {query}) ---")
  221 + # 实现上与 comprehensive_search 相同,但通过命名和文档引导Agent的意图
  222 + return self._search_internal(
  223 + query=query,
  224 + count=5, # 结构化查询通常不需要太多网页结果
  225 + answer=True
  226 + )
149 227
150 - def search_news_last_week(self, query: str) -> TavilyResponse: 228 + def search_last_24_hours(self, query: str) -> BochaResponse:
151 """ 229 """
152 - 【工具】搜索本周新闻: 获取关于某个主题过去一周内的主要新闻报道。  
153 - 适用于进行周度舆情总结或回顾。  
154 - Agent只需提供搜索查询(query)。 230 + 【工具】搜索24小时内信息: 获取关于某个主题的最新动态。
  231 + 此工具专门查找过去24小时内发布的内容。适用于追踪突发事件或最新进展。
155 """ 232 """
156 - print(f"--- TOOL: 搜索本周新闻 (query: {query}) ---")  
157 - return self._search_internal(query=query, time_range='w', max_results=10) 233 + print(f"--- TOOL: 搜索24小时内信息 (query: {query}) ---")
  234 + return self._search_internal(query=query, freshness='oneDay', answer=True)
158 235
159 - def search_images_for_news(self, query: str) -> TavilyResponse: 236 + def search_last_week(self, query: str) -> BochaResponse:
160 """ 237 """
161 - 【工具】查找新闻图片: 搜索与某个新闻主题相关的图片。  
162 - 此工具会返回图片链接及描述,适用于需要为报告或文章配图的场景。  
163 - Agent只需提供搜索查询(query)。 238 + 【工具】搜索本周信息: 获取关于某个主题过去一周内的主要报道。
  239 + 适用于进行周度舆情总结或回顾。
164 """ 240 """
165 - print(f"--- TOOL: 查找新闻图片 (query: {query}) ---")  
166 - return self._search_internal(  
167 - query=query, include_images=True, include_image_descriptions=True, max_results=5  
168 - )  
169 -  
170 - def search_news_by_date(self, query: str, start_date: str, end_date: str) -> TavilyResponse:  
171 - """  
172 - 【工具】按指定日期范围搜索新闻: 在一个明确的历史时间段内搜索新闻。  
173 - 这是唯一需要Agent提供详细时间参数的工具。适用于需要对特定历史事件进行分析的场景。  
174 - Agent需要提供查询(query)、开始日期(start_date)和结束日期(end_date),格式均为 'YYYY-MM-DD'。  
175 - """  
176 - print(f"--- TOOL: 按指定日期范围搜索新闻 (query: {query}, from: {start_date}, to: {end_date}) ---")  
177 - return self._search_internal(  
178 - query=query, start_date=start_date, end_date=end_date, max_results=15  
179 - ) 241 + print(f"--- TOOL: 搜索本周信息 (query: {query}) ---")
  242 + return self._search_internal(query=query, freshness='oneWeek', answer=True)
180 243
181 244
182 # --- 3. 测试与使用示例 --- 245 # --- 3. 测试与使用示例 ---
183 246
184 -def print_response_summary(response: TavilyResponse):  
185 - """简化的打印函数,用于展示测试结果,现在会显示发布日期""" 247 +def print_response_summary(response: BochaResponse):
  248 + """简化的打印函数,用于展示测试结果"""
186 if not response or not response.query: 249 if not response or not response.query:
187 print("未能获取有效响应。") 250 print("未能获取有效响应。")
188 return 251 return
189 252
190 - print(f"\n查询: '{response.query}' | 耗时: {response.response_time}s") 253 + print(f"\n查询: '{response.query}' | 会话ID: {response.conversation_id}")
191 if response.answer: 254 if response.answer:
192 - print(f"AI摘要: {response.answer[:120]}...")  
193 - print(f"找到 {len(response.results)} 条网页, {len(response.images)} 张图片。")  
194 - if response.results:  
195 - first_result = response.results[0]  
196 - date_info = f"(发布于: {first_result.published_date})" if first_result.published_date else ""  
197 - print(f"第一条结果: {first_result.title} {date_info}") 255 + print(f"AI摘要: {response.answer[:150]}...")
  256 +
  257 + print(f"找到 {len(response.webpages)} 个网页, {len(response.images)} 张图片, {len(response.modal_cards)} 个模态卡。")
  258 +
  259 + if response.modal_cards:
  260 + first_card = response.modal_cards[0]
  261 + print(f"第一个模态卡类型: {first_card.card_type}")
  262 +
  263 + if response.webpages:
  264 + first_result = response.webpages[0]
  265 + print(f"第一条网页结果: {first_result.name}")
  266 +
  267 + if response.follow_ups:
  268 + print(f"建议追问: {response.follow_ups}")
  269 +
198 print("-" * 60) 270 print("-" * 60)
199 271
200 272
201 if __name__ == "__main__": 273 if __name__ == "__main__":
202 - # 在运行前,请确保您已设置 TAVILY_API_KEY 环境变量 274 + # 在运行前,请确保您已设置 BOCHA_API_KEY 环境变量
203 275
204 try: 276 try:
205 - # 初始化“新闻社”客户端,它内部包含了所有工具  
206 - agency = TavilyNewsAgency() 277 + # 初始化多模态搜索客户端,它内部包含了所有工具
  278 + search_client = BochaMultimodalSearch()
207 279
208 - # 场景1: Agent 进行一次常规、快速的搜索  
209 - response1 = agency.basic_search_news(query="奥运会最新赛况", max_results=5) 280 + # 场景1: Agent进行一次常规的、需要AI总结的综合搜索
  281 + response1 = search_client.comprehensive_search(query="人工智能对未来教育的影响")
210 print_response_summary(response1) 282 print_response_summary(response1)
211 283
212 - # 场景2: Agent 需要全面了解“全球芯片技术竞争”的背景  
213 - response2 = agency.deep_search_news(query="全球芯片技术竞争") 284 + # 场景2: Agent需要查询特定结构化信息 - 天气
  285 + response2 = search_client.search_for_structured_data(query="上海明天天气怎么样")
214 print_response_summary(response2) 286 print_response_summary(response2)
  287 + # 深度解析第一个模态卡
  288 + if response2.modal_cards and response2.modal_cards[0].card_type == 'weather_china':
  289 + print("天气模态卡详情:", json.dumps(response2.modal_cards[0].content, indent=2, ensure_ascii=False))
  290 +
215 291
216 - # 场景3: Agent 需要追踪“GTC大会”的最新消息  
217 - response3 = agency.search_news_last_24_hours(query="Nvidia GTC大会 最新发布") 292 + # 场景3: Agent需要查询特定结构化信息 - 股票
  293 + response3 = search_client.search_for_structured_data(query="东方财富股票")
218 print_response_summary(response3) 294 print_response_summary(response3)
219 295
220 - # 场景4: Agent 需要为一篇关于“自动驾驶”的周报查找素材  
221 - response4 = agency.search_news_last_week(query="自动驾驶商业化落地") 296 + # 场景4: Agent需要追踪某个事件的最新进展
  297 + response4 = search_client.search_last_24_hours(query="C929大飞机最新消息")
222 print_response_summary(response4) 298 print_response_summary(response4)
223 299
224 - # 场景5: Agent 需要查找“韦伯太空望远镜”的新闻图片  
225 - response5 = agency.search_images_for_news(query="韦伯太空望远镜最新发现") 300 + # 场景5: Agent只需要快速获取网页信息,不需要AI总结
  301 + response5 = search_client.web_search_only(query="Python dataclasses用法")
226 print_response_summary(response5) 302 print_response_summary(response5)
227 303
228 - # 场景6: Agent 需要研究2025年第一季度关于“人工智能法规”的新闻  
229 - response6 = agency.search_news_by_date(  
230 - query="人工智能法规",  
231 - start_date="2025-01-01",  
232 - end_date="2025-03-31"  
233 - ) 304 + # 场景6: Agent需要回顾一周内关于某项技术的新闻
  305 + response6 = search_client.search_last_week(query="量子计算商业化")
234 print_response_summary(response6) 306 print_response_summary(response6)
235 307
  308 + '''下面是测试程序的输出:
  309 + --- TOOL: 全面综合搜索 (query: 人工智能对未来教育的影响) ---
  310 +
  311 +查询: '人工智能对未来教育的影响' | 会话ID: bf43bfe4c7bb4f7b8a3945515d8ab69e
  312 +AI摘要: 人工智能对未来教育有着多方面的影响。
  313 +
  314 +从积极影响来看:
  315 +- 在教学资源方面,人工智能有助于教育资源的均衡分配[引用:4]。例如通过人工智能云平台,可以实现优质资源的共享,这对于偏远地区来说意义重大,能让那里的学生也接触到优质的教育内 容,一定程度上缓解师资短缺的问题,因为AI驱动的智能教学助手或虚拟...
  316 +找到 10 个网页, 1 张图片, 1 个模态卡。
  317 +第一个模态卡类型: video
  318 +第一条网页结果: 人工智能如何影响教育变革
  319 +建议追问: [['人工智能将如何改变未来的教育模式?', '在未来教育中,人工智能会给教师带来哪些挑战?', '未来教育中,学生如何利用人工智能提升学习效果?']]
  320 +------------------------------------------------------------
  321 +--- TOOL: 结构化数据查询 (query: 上海明天天气怎么样) ---
  322 +
  323 +查询: '上海明天天气怎么样' | 会话ID: e412aa1548cd43a295430e47a62adda2
  324 +AI摘要: 根据所给信息,无法确定上海明天的天气情况。
  325 +
  326 +首先,所提供的信息都是关于2025年8月22日的天气状况,包括当天的气温、降水、风力、湿度以及高温预警等信息[引用:1][引用:2][引用:3][引用:5]。然而,这些信息没有涉及到明天(8月23 日)天气的预测内容。虽然提到了副热带高压一直到8月底高温都...
  327 +找到 5 个网页, 1 张图片, 2 个模态卡。
  328 +第一个模态卡类型: video
  329 +第一条网页结果: 今日冲击38!上海八月高温天数和夏季持续高温天数有望双双破纪录_天气_低压_气象站
  330 +建议追问: [['能告诉我上海明天的气温范围吗?', '上海明天会有降雨吗?', '上海明天的天气是晴天还是阴天呢?']]
  331 +------------------------------------------------------------
  332 +--- TOOL: 结构化数据查询 (query: 东方财富股票) ---
  333 +
  334 +查询: '东方财富股票' | 会话ID: 584d62ed97834473b967127852e1eaa0
  335 +AI摘要: 仅根据提供的上下文,无法确切获取东方财富股票的相关信息。
  336 +
  337 +从给出的这些数据来看,并没有直接表明与东方财富股票相关的特定数据。例如,没有东方财富股票的涨跌幅情况、成交量、市值等具体数据[引用:1][引用:3]。也没有涉及东方财富股票在研报 、评级方面的信息[引用:2]。同时,上下文里关于股票价格、成交...
  338 +找到 5 个网页, 1 张图片, 2 个模态卡。
  339 +第一个模态卡类型: video
  340 +第一条网页结果: 股票价格_分时成交_行情_走势图—东方财富网
  341 +建议追问: [['东方财富股票近期的走势如何?', '东方财富股票有哪些主要的投资亮点?', '东方财富股票的历史最高和最低股价是多少?']]
  342 +------------------------------------------------------------
  343 +--- TOOL: 搜索24小时内信息 (query: C929大飞机最新消息) ---
  344 +
  345 +查询: 'C929大飞机最新消息' | 会话ID: 5904021dc29d497e938e04db18d7f2e2
  346 +AI摘要: 根据提供的上下文,没有关于C929大飞机的直接消息,无法确切给出C929大飞机的最新消息。
  347 +
  348 +目前提供的上下文涵盖了众多航空领域相关事件,但多是围绕波音787、空客A380相关专家的人事变动、国产飞机“C909云端之旅”、科德数控的营收情况、俄制航空发动机供应相关以及其他非C929大飞机相关的内容。...
  349 +找到 10 个网页, 1 张图片, 1 个模态卡。
  350 +第一个模态卡类型: video
  351 +第一条网页结果: 放弃美国千万年薪,波音787顶尖专家回国,或可协助破解C929
  352 +建议追问: [['C929大飞机目前的研发进度如何?', '有没有关于C929大飞机预计首飞时间的消息?', 'C929大飞机在技术创新方面有哪些新进展?']]
  353 +------------------------------------------------------------
  354 +--- TOOL: 纯网页搜索 (query: Python dataclasses用法) ---
  355 +
  356 +查询: 'Python dataclasses用法' | 会话ID: 74c742759d2e4b17b52d8b735ce24537
  357 +找到 15 个网页, 1 张图片, 1 个模态卡。
  358 +第一个模态卡类型: video
  359 +第一条网页结果: 不可不知的dataclasses python小知识_python dataclasses-CSDN博客
  360 +------------------------------------------------------------
  361 +--- TOOL: 搜索本周信息 (query: 量子计算商业化) ---
  362 +
  363 +AI摘要: 量子计算商业化正在逐步推进。
  364 +
  365 +量子计算商业化有着多方面的体现和推动因素。从国际上看,美国能源部橡树岭国家实验室选择IQM Radiance作为其首台本地部署的量子计算机,计划于2025年第三季度交付并集成至高性能计算系统中[引用:4];英国量子计算公司Oxford Ionics的全栈离子阱量子计算...
  366 +找到 10 个网页, 1 张图片, 1 个模态卡。
  367 +第一个模态卡类型: video
  368 +第一条网页结果: 量子计算商业潜力释放正酣,微美全息(WIMI.US)创新科技卡位“生态高地”
  369 +建议追问: [['量子计算商业化目前有哪些成功的案例?', '哪些公司在推动量子计算商业化进程?', '量子计算商业化面临的主要挑战是什么?']]
  370 +------------------------------------------------------------'''
  371 +
236 except ValueError as e: 372 except ValueError as e:
237 print(f"初始化失败: {e}") 373 print(f"初始化失败: {e}")
238 - print("请确保 TAVILY_API_KEY 环境变量已正确设置。") 374 + print("请确保 BOCHA_API_KEY 环境变量已正确设置。")
239 except Exception as e: 375 except Exception as e:
240 print(f"测试过程中发生未知错误: {e}") 376 print(f"测试过程中发生未知错误: {e}")