戒酒的李白

The multimodal agent has been basically completed.

@@ -19,7 +19,7 @@ from .nodes import ( @@ -19,7 +19,7 @@ from .nodes import (
19 ReportFormattingNode 19 ReportFormattingNode
20 ) 20 )
21 from .state import State 21 from .state import State
22 -from .tools import TavilyNewsAgency, TavilyResponse 22 +from .tools import BochaMultimodalSearch, BochaResponse
23 from .utils import Config, load_config, format_search_results_for_prompt 23 from .utils import Config, load_config, format_search_results_for_prompt
24 24
25 25
@@ -40,7 +40,7 @@ class DeepSearchAgent: @@ -40,7 +40,7 @@ class DeepSearchAgent:
40 self.llm_client = self._initialize_llm() 40 self.llm_client = self._initialize_llm()
41 41
42 # 初始化搜索工具集 42 # 初始化搜索工具集
43 - self.search_agency = TavilyNewsAgency(api_key=self.config.tavily_api_key) 43 + self.search_agency = BochaMultimodalSearch(api_key=self.config.bocha_api_key)
44 44
45 # 初始化节点 45 # 初始化节点
46 self._initialize_nodes() 46 self._initialize_nodes()
@@ -53,7 +53,7 @@ class DeepSearchAgent: @@ -53,7 +53,7 @@ class DeepSearchAgent:
53 53
54 print(f"Deep Search Agent 已初始化") 54 print(f"Deep Search Agent 已初始化")
55 print(f"使用LLM: {self.llm_client.get_model_info()}") 55 print(f"使用LLM: {self.llm_client.get_model_info()}")
56 - print(f"搜索工具集: TavilyNewsAgency (支持6种搜索工具)") 56 + print(f"搜索工具集: BochaMultimodalSearch (支持5种多模态搜索工具)")
57 57
58 def _initialize_llm(self) -> BaseLLM: 58 def _initialize_llm(self) -> BaseLLM:
59 """初始化LLM客户端""" 59 """初始化LLM客户端"""
@@ -103,46 +103,40 @@ class DeepSearchAgent: @@ -103,46 +103,40 @@ class DeepSearchAgent:
103 except ValueError: 103 except ValueError:
104 return False 104 return False
105 105
106 - def execute_search_tool(self, tool_name: str, query: str, **kwargs) -> TavilyResponse: 106 + def execute_search_tool(self, tool_name: str, query: str, **kwargs) -> BochaResponse:
107 """ 107 """
108 执行指定的搜索工具 108 执行指定的搜索工具
109 109
110 Args: 110 Args:
111 tool_name: 工具名称,可选值: 111 tool_name: 工具名称,可选值:
112 - - "basic_search_news": 基础新闻搜索(快速、通用)  
113 - - "deep_search_news": 深度新闻分析  
114 - - "search_news_last_24_hours": 24小时内最新新闻  
115 - - "search_news_last_week": 本周新闻  
116 - - "search_images_for_news": 新闻图片搜索  
117 - - "search_news_by_date": 按日期范围搜索新闻 112 + - "comprehensive_search": 全面综合搜索(默认)
  113 + - "web_search_only": 纯网页搜索
  114 + - "search_for_structured_data": 结构化数据查询
  115 + - "search_last_24_hours": 24小时内最新信息
  116 + - "search_last_week": 本周信息
118 query: 搜索查询 117 query: 搜索查询
119 - **kwargs: 额外参数(如start_date, end_date, max_results) 118 + **kwargs: 额外参数(如max_results)
120 119
121 Returns: 120 Returns:
122 - TavilyResponse对象 121 + BochaResponse对象
123 """ 122 """
124 print(f" → 执行搜索工具: {tool_name}") 123 print(f" → 执行搜索工具: {tool_name}")
125 124
126 - if tool_name == "basic_search_news":  
127 - max_results = kwargs.get("max_results", 7)  
128 - return self.search_agency.basic_search_news(query, max_results)  
129 - elif tool_name == "deep_search_news":  
130 - return self.search_agency.deep_search_news(query)  
131 - elif tool_name == "search_news_last_24_hours":  
132 - return self.search_agency.search_news_last_24_hours(query)  
133 - elif tool_name == "search_news_last_week":  
134 - return self.search_agency.search_news_last_week(query)  
135 - elif tool_name == "search_images_for_news":  
136 - return self.search_agency.search_images_for_news(query)  
137 - elif tool_name == "search_news_by_date":  
138 - start_date = kwargs.get("start_date")  
139 - end_date = kwargs.get("end_date")  
140 - if not start_date or not end_date:  
141 - raise ValueError("search_news_by_date工具需要start_date和end_date参数")  
142 - return self.search_agency.search_news_by_date(query, start_date, end_date) 125 + if tool_name == "comprehensive_search":
  126 + max_results = kwargs.get("max_results", 10)
  127 + return self.search_agency.comprehensive_search(query, max_results)
  128 + elif tool_name == "web_search_only":
  129 + max_results = kwargs.get("max_results", 15)
  130 + return self.search_agency.web_search_only(query, max_results)
  131 + elif tool_name == "search_for_structured_data":
  132 + return self.search_agency.search_for_structured_data(query)
  133 + elif tool_name == "search_last_24_hours":
  134 + return self.search_agency.search_last_24_hours(query)
  135 + elif tool_name == "search_last_week":
  136 + return self.search_agency.search_last_week(query)
143 else: 137 else:
144 - print(f" ⚠️ 未知的搜索工具: {tool_name},使用默认基础搜索")  
145 - return self.search_agency.basic_search_news(query) 138 + print(f" ⚠️ 未知的搜索工具: {tool_name},使用默认综合搜索")
  139 + return self.search_agency.comprehensive_search(query)
146 140
147 def research(self, query: str, save_report: bool = True) -> str: 141 def research(self, query: str, save_report: bool = True) -> str:
148 """ 142 """
@@ -231,7 +225,7 @@ class DeepSearchAgent: @@ -231,7 +225,7 @@ class DeepSearchAgent:
231 print(" - 生成搜索查询...") 225 print(" - 生成搜索查询...")
232 search_output = self.first_search_node.run(search_input) 226 search_output = self.first_search_node.run(search_input)
233 search_query = search_output["search_query"] 227 search_query = search_output["search_query"]
234 - search_tool = search_output.get("search_tool", "basic_search_news") # 默认工具 228 + search_tool = search_output.get("search_tool", "comprehensive_search") # 默认工具
235 reasoning = search_output["reasoning"] 229 reasoning = search_output["reasoning"]
236 230
237 print(f" - 搜索查询: {search_query}") 231 print(f" - 搜索查询: {search_query}")
@@ -241,41 +235,27 @@ class DeepSearchAgent: @@ -241,41 +235,27 @@ class DeepSearchAgent:
241 # 执行搜索 235 # 执行搜索
242 print(" - 执行网络搜索...") 236 print(" - 执行网络搜索...")
243 237
244 - # 处理search_news_by_date的特殊参数 238 + # 处理特殊参数(新的工具集不需要日期参数处理)
245 search_kwargs = {} 239 search_kwargs = {}
246 - if search_tool == "search_news_by_date":  
247 - start_date = search_output.get("start_date")  
248 - end_date = search_output.get("end_date")  
249 -  
250 - if start_date and end_date:  
251 - # 验证日期格式  
252 - if self._validate_date_format(start_date) and self._validate_date_format(end_date):  
253 - search_kwargs["start_date"] = start_date  
254 - search_kwargs["end_date"] = end_date  
255 - print(f" - 时间范围: {start_date} 到 {end_date}")  
256 - else:  
257 - print(f" ⚠️ 日期格式错误(应为YYYY-MM-DD),改用基础搜索")  
258 - print(f" 提供的日期: start_date={start_date}, end_date={end_date}")  
259 - search_tool = "basic_search_news"  
260 - else:  
261 - print(f" ⚠️ search_news_by_date工具缺少时间参数,改用基础搜索")  
262 - search_tool = "basic_search_news" 240 + if search_tool in ["comprehensive_search", "web_search_only"]:
  241 + # 这些工具支持max_results参数
  242 + search_kwargs["max_results"] = 10
263 243
264 search_response = self.execute_search_tool(search_tool, search_query, **search_kwargs) 244 search_response = self.execute_search_tool(search_tool, search_query, **search_kwargs)
265 245
266 # 转换为兼容格式 246 # 转换为兼容格式
267 search_results = [] 247 search_results = []
268 - if search_response and search_response.results: 248 + if search_response and search_response.webpages:
269 # 每种搜索工具都有其特定的结果数量,这里取前10个作为上限 249 # 每种搜索工具都有其特定的结果数量,这里取前10个作为上限
270 - max_results = min(len(search_response.results), 10)  
271 - for result in search_response.results[:max_results]: 250 + max_results = min(len(search_response.webpages), 10)
  251 + for result in search_response.webpages[:max_results]:
272 search_results.append({ 252 search_results.append({
273 - 'title': result.title, 253 + 'title': result.name,
274 'url': result.url, 254 'url': result.url,
275 - 'content': result.content,  
276 - 'score': result.score,  
277 - 'raw_content': result.raw_content,  
278 - 'published_date': result.published_date # 新增字段 255 + 'content': result.snippet,
  256 + 'score': None, # Bocha API不提供score
  257 + 'raw_content': result.snippet,
  258 + 'published_date': result.date_last_crawled # 使用爬取日期
279 }) 259 })
280 260
281 if search_results: 261 if search_results:
@@ -324,7 +304,7 @@ class DeepSearchAgent: @@ -324,7 +304,7 @@ class DeepSearchAgent:
324 # 生成反思搜索查询 304 # 生成反思搜索查询
325 reflection_output = self.reflection_node.run(reflection_input) 305 reflection_output = self.reflection_node.run(reflection_input)
326 search_query = reflection_output["search_query"] 306 search_query = reflection_output["search_query"]
327 - search_tool = reflection_output.get("search_tool", "basic_search_news") # 默认工具 307 + search_tool = reflection_output.get("search_tool", "comprehensive_search") # 默认工具
328 reasoning = reflection_output["reasoning"] 308 reasoning = reflection_output["reasoning"]
329 309
330 print(f" 反思查询: {search_query}") 310 print(f" 反思查询: {search_query}")
@@ -332,41 +312,27 @@ class DeepSearchAgent: @@ -332,41 +312,27 @@ class DeepSearchAgent:
332 print(f" 反思推理: {reasoning}") 312 print(f" 反思推理: {reasoning}")
333 313
334 # 执行反思搜索 314 # 执行反思搜索
335 - # 处理search_news_by_date的特殊参数 315 + # 处理特殊参数
336 search_kwargs = {} 316 search_kwargs = {}
337 - if search_tool == "search_news_by_date":  
338 - start_date = reflection_output.get("start_date")  
339 - end_date = reflection_output.get("end_date")  
340 -  
341 - if start_date and end_date:  
342 - # 验证日期格式  
343 - if self._validate_date_format(start_date) and self._validate_date_format(end_date):  
344 - search_kwargs["start_date"] = start_date  
345 - search_kwargs["end_date"] = end_date  
346 - print(f" 时间范围: {start_date} 到 {end_date}")  
347 - else:  
348 - print(f" ⚠️ 日期格式错误(应为YYYY-MM-DD),改用基础搜索")  
349 - print(f" 提供的日期: start_date={start_date}, end_date={end_date}")  
350 - search_tool = "basic_search_news"  
351 - else:  
352 - print(f" ⚠️ search_news_by_date工具缺少时间参数,改用基础搜索")  
353 - search_tool = "basic_search_news" 317 + if search_tool in ["comprehensive_search", "web_search_only"]:
  318 + # 这些工具支持max_results参数
  319 + search_kwargs["max_results"] = 10
354 320
355 search_response = self.execute_search_tool(search_tool, search_query, **search_kwargs) 321 search_response = self.execute_search_tool(search_tool, search_query, **search_kwargs)
356 322
357 # 转换为兼容格式 323 # 转换为兼容格式
358 search_results = [] 324 search_results = []
359 - if search_response and search_response.results: 325 + if search_response and search_response.webpages:
360 # 每种搜索工具都有其特定的结果数量,这里取前10个作为上限 326 # 每种搜索工具都有其特定的结果数量,这里取前10个作为上限
361 - max_results = min(len(search_response.results), 10)  
362 - for result in search_response.results[:max_results]: 327 + max_results = min(len(search_response.webpages), 10)
  328 + for result in search_response.webpages[:max_results]:
363 search_results.append({ 329 search_results.append({
364 - 'title': result.title, 330 + 'title': result.name,
365 'url': result.url, 331 'url': result.url,
366 - 'content': result.content,  
367 - 'score': result.score,  
368 - 'raw_content': result.raw_content,  
369 - 'published_date': result.published_date 332 + 'content': result.snippet,
  333 + 'score': None, # Bocha API不提供score
  334 + 'raw_content': result.snippet,
  335 + 'published_date': result.date_last_crawled
370 }) 336 })
371 337
372 if search_results: 338 if search_results:
@@ -34,9 +34,7 @@ output_schema_first_search = { @@ -34,9 +34,7 @@ output_schema_first_search = {
34 "properties": { 34 "properties": {
35 "search_query": {"type": "string"}, 35 "search_query": {"type": "string"},
36 "search_tool": {"type": "string"}, 36 "search_tool": {"type": "string"},
37 - "reasoning": {"type": "string"},  
38 - "start_date": {"type": "string", "description": "开始日期,格式YYYY-MM-DD,仅search_news_by_date工具需要"},  
39 - "end_date": {"type": "string", "description": "结束日期,格式YYYY-MM-DD,仅search_news_by_date工具需要"} 37 + "reasoning": {"type": "string"}
40 }, 38 },
41 "required": ["search_query", "search_tool", "reasoning"] 39 "required": ["search_query", "search_tool", "reasoning"]
42 } 40 }
@@ -79,9 +77,7 @@ output_schema_reflection = { @@ -79,9 +77,7 @@ output_schema_reflection = {
79 "properties": { 77 "properties": {
80 "search_query": {"type": "string"}, 78 "search_query": {"type": "string"},
81 "search_tool": {"type": "string"}, 79 "search_tool": {"type": "string"},
82 - "reasoning": {"type": "string"},  
83 - "start_date": {"type": "string", "description": "开始日期,格式YYYY-MM-DD,仅search_news_by_date工具需要"},  
84 - "end_date": {"type": "string", "description": "结束日期,格式YYYY-MM-DD,仅search_news_by_date工具需要"} 80 + "reasoning": {"type": "string"}
85 }, 81 },
86 "required": ["search_query", "search_tool", "reasoning"] 82 "required": ["search_query", "search_tool", "reasoning"]
87 } 83 }
@@ -147,41 +143,34 @@ SYSTEM_PROMPT_FIRST_SEARCH = f""" @@ -147,41 +143,34 @@ SYSTEM_PROMPT_FIRST_SEARCH = f"""
147 {json.dumps(input_schema_first_search, indent=2, ensure_ascii=False)} 143 {json.dumps(input_schema_first_search, indent=2, ensure_ascii=False)}
148 </INPUT JSON SCHEMA> 144 </INPUT JSON SCHEMA>
149 145
150 -你可以使用以下6种专业的新闻搜索工具: 146 +你可以使用以下5种专业的多模态搜索工具:
151 147
152 -1. **basic_search_news** - 基础新闻搜索工具  
153 - - 适用于:一般性的新闻搜索,不确定需要何种特定搜索时  
154 - - 特点:快速、标准的通用搜索,是最常用的基础工具 148 +1. **comprehensive_search** - 全面综合搜索工具
  149 + - 适用于:一般性的研究需求,需要完整信息时
  150 + - 特点:返回网页、图片、AI总结、追问建议和可能的结构化数据,是最常用的基础工具
155 151
156 -2. **deep_search_news** - 深度新闻分析工具  
157 - - 适用于:需要全面深入了解某个主题时  
158 - - 特点:提供最详细的分析结果,包含高级AI摘要 152 +2. **web_search_only** - 纯网页搜索工具
  153 + - 适用于:只需要网页链接和摘要,不需要AI分析时
  154 + - 特点:速度更快,成本更低,只返回网页结果
159 155
160 -3. **search_news_last_24_hours** - 24小时最新新闻工具 156 +3. **search_for_structured_data** - 结构化数据查询工具
  157 + - 适用于:查询天气、股票、汇率、百科定义等结构化信息时
  158 + - 特点:专门用于触发"模态卡"的查询,返回结构化数据
  159 +
  160 +4. **search_last_24_hours** - 24小时内信息搜索工具
161 - 适用于:需要了解最新动态、突发事件时 161 - 适用于:需要了解最新动态、突发事件时
162 - - 特点:只搜索过去24小时的新闻 162 + - 特点:只搜索过去24小时内发布的内容
163 163
164 -4. **search_news_last_week** - 本周新闻工具 164 +5. **search_last_week** - 本周信息搜索工具
165 - 适用于:需要了解近期发展趋势时 165 - 适用于:需要了解近期发展趋势时
166 - - 特点:搜索过去一周的新闻报道  
167 -  
168 -5. **search_images_for_news** - 图片搜索工具  
169 - - 适用于:需要可视化信息、图片资料时  
170 - - 特点:提供相关图片和图片描述  
171 -  
172 -6. **search_news_by_date** - 按日期范围搜索工具  
173 - - 适用于:需要研究特定历史时期时  
174 - - 特点:可以指定开始和结束日期进行搜索  
175 - - 特殊要求:需要提供start_date和end_date参数,格式为'YYYY-MM-DD'  
176 - - 注意:只有这个工具需要额外的时间参数 166 + - 特点:搜索过去一周内的主要报道
177 167
178 你的任务是: 168 你的任务是:
179 1. 根据段落主题选择最合适的搜索工具 169 1. 根据段落主题选择最合适的搜索工具
180 2. 制定最佳的搜索查询 170 2. 制定最佳的搜索查询
181 -3. 如果选择search_news_by_date工具,必须同时提供start_date和end_date参数(格式:YYYY-MM-DD)  
182 -4. 解释你的选择理由 171 +3. 解释你的选择理由
183 172
184 -注意:除了search_news_by_date工具外,其他工具都不需要额外参数 173 +注意:所有工具都不需要额外参数,选择工具主要基于搜索意图和需要的信息类型
185 请按照以下JSON模式定义格式化输出(文字请使用中文): 174 请按照以下JSON模式定义格式化输出(文字请使用中文):
186 175
187 <OUTPUT JSON SCHEMA> 176 <OUTPUT JSON SCHEMA>
@@ -219,23 +208,21 @@ SYSTEM_PROMPT_REFLECTION = f""" @@ -219,23 +208,21 @@ SYSTEM_PROMPT_REFLECTION = f"""
219 {json.dumps(input_schema_reflection, indent=2, ensure_ascii=False)} 208 {json.dumps(input_schema_reflection, indent=2, ensure_ascii=False)}
220 </INPUT JSON SCHEMA> 209 </INPUT JSON SCHEMA>
221 210
222 -你可以使用以下6种专业的新闻搜索工具: 211 +你可以使用以下5种专业的多模态搜索工具:
223 212
224 -1. **basic_search_news** - 基础新闻搜索工具  
225 -2. **deep_search_news** - 深度新闻分析工具  
226 -3. **search_news_last_24_hours** - 24小时最新新闻工具  
227 -4. **search_news_last_week** - 本周新闻工具  
228 -5. **search_images_for_news** - 图片搜索工具  
229 -6. **search_news_by_date** - 按日期范围搜索工具(需要时间参数) 213 +1. **comprehensive_search** - 全面综合搜索工具
  214 +2. **web_search_only** - 纯网页搜索工具
  215 +3. **search_for_structured_data** - 结构化数据查询工具
  216 +4. **search_last_24_hours** - 24小时内信息搜索工具
  217 +5. **search_last_week** - 本周信息搜索工具
230 218
231 你的任务是: 219 你的任务是:
232 1. 反思段落文本的当前状态,思考是否遗漏了主题的某些关键方面 220 1. 反思段落文本的当前状态,思考是否遗漏了主题的某些关键方面
233 2. 选择最合适的搜索工具来补充缺失信息 221 2. 选择最合适的搜索工具来补充缺失信息
234 3. 制定精确的搜索查询 222 3. 制定精确的搜索查询
235 -4. 如果选择search_news_by_date工具,必须同时提供start_date和end_date参数(格式:YYYY-MM-DD)  
236 -5. 解释你的选择和推理 223 +4. 解释你的选择和推理
237 224
238 -注意:除了search_news_by_date工具外,其他工具都不需要额外参数 225 +注意:所有工具都不需要额外参数,选择工具主要基于搜索意图和需要的信息类型
239 请按照以下JSON模式定义格式化输出: 226 请按照以下JSON模式定义格式化输出:
240 227
241 <OUTPUT JSON SCHEMA> 228 <OUTPUT JSON SCHEMA>
1 """ 1 """
2 工具调用模块 2 工具调用模块
3 -提供外部工具接口,如网络搜索等 3 +提供外部工具接口,如多模态搜索等
4 """ 4 """
5 5
6 from .search import ( 6 from .search import (
7 - TavilyNewsAgency,  
8 - SearchResult,  
9 - TavilyResponse, 7 + BochaMultimodalSearch,
  8 + WebpageResult,
10 ImageResult, 9 ImageResult,
  10 + ModalCardResult,
  11 + BochaResponse,
11 print_response_summary 12 print_response_summary
12 ) 13 )
13 14
14 __all__ = [ 15 __all__ = [
15 - "TavilyNewsAgency",  
16 - "SearchResult",  
17 - "TavilyResponse", 16 + "BochaMultimodalSearch",
  17 + "WebpageResult",
18 "ImageResult", 18 "ImageResult",
  19 + "ModalCardResult",
  20 + "BochaResponse",
19 "print_response_summary" 21 "print_response_summary"
20 ] 22 ]
@@ -14,7 +14,7 @@ class Config: @@ -14,7 +14,7 @@ class Config:
14 # API密钥 14 # API密钥
15 deepseek_api_key: Optional[str] = None 15 deepseek_api_key: Optional[str] = None
16 openai_api_key: Optional[str] = None 16 openai_api_key: Optional[str] = None
17 - tavily_api_key: Optional[str] = None 17 + bocha_api_key: Optional[str] = None
18 18
19 # 模型配置 19 # 模型配置
20 default_llm_provider: str = "deepseek" # deepseek 或 openai 20 default_llm_provider: str = "deepseek" # deepseek 或 openai
@@ -44,8 +44,8 @@ class Config: @@ -44,8 +44,8 @@ class Config:
44 print("错误: OpenAI API Key未设置") 44 print("错误: OpenAI API Key未设置")
45 return False 45 return False
46 46
47 - if not self.tavily_api_key:  
48 - print("错误: Tavily API Key未设置") 47 + if not self.bocha_api_key:
  48 + print("错误: Bocha API Key未设置")
49 return False 49 return False
50 50
51 return True 51 return True
@@ -65,7 +65,7 @@ class Config: @@ -65,7 +65,7 @@ class Config:
65 return cls( 65 return cls(
66 deepseek_api_key=getattr(config_module, "DEEPSEEK_API_KEY", None), 66 deepseek_api_key=getattr(config_module, "DEEPSEEK_API_KEY", None),
67 openai_api_key=getattr(config_module, "OPENAI_API_KEY", None), 67 openai_api_key=getattr(config_module, "OPENAI_API_KEY", None),
68 - tavily_api_key=getattr(config_module, "TAVILY_API_KEY", None), 68 + bocha_api_key=getattr(config_module, "BOCHA_API_KEY", None),
69 default_llm_provider=getattr(config_module, "DEFAULT_LLM_PROVIDER", "deepseek"), 69 default_llm_provider=getattr(config_module, "DEFAULT_LLM_PROVIDER", "deepseek"),
70 deepseek_model=getattr(config_module, "DEEPSEEK_MODEL", "deepseek-chat"), 70 deepseek_model=getattr(config_module, "DEEPSEEK_MODEL", "deepseek-chat"),
71 openai_model=getattr(config_module, "OPENAI_MODEL", "gpt-4o-mini"), 71 openai_model=getattr(config_module, "OPENAI_MODEL", "gpt-4o-mini"),
@@ -92,7 +92,7 @@ class Config: @@ -92,7 +92,7 @@ class Config:
92 return cls( 92 return cls(
93 deepseek_api_key=config_dict.get("DEEPSEEK_API_KEY"), 93 deepseek_api_key=config_dict.get("DEEPSEEK_API_KEY"),
94 openai_api_key=config_dict.get("OPENAI_API_KEY"), 94 openai_api_key=config_dict.get("OPENAI_API_KEY"),
95 - tavily_api_key=config_dict.get("TAVILY_API_KEY"), 95 + bocha_api_key=config_dict.get("BOCHA_API_KEY"),
96 default_llm_provider=config_dict.get("DEFAULT_LLM_PROVIDER", "deepseek"), 96 default_llm_provider=config_dict.get("DEFAULT_LLM_PROVIDER", "deepseek"),
97 deepseek_model=config_dict.get("DEEPSEEK_MODEL", "deepseek-chat"), 97 deepseek_model=config_dict.get("DEEPSEEK_MODEL", "deepseek-chat"),
98 openai_model=config_dict.get("OPENAI_MODEL", "gpt-4o-mini"), 98 openai_model=config_dict.get("OPENAI_MODEL", "gpt-4o-mini"),
@@ -147,7 +147,7 @@ def print_config(config: Config): @@ -147,7 +147,7 @@ def print_config(config: Config):
147 print(f"LLM提供商: {config.default_llm_provider}") 147 print(f"LLM提供商: {config.default_llm_provider}")
148 print(f"DeepSeek模型: {config.deepseek_model}") 148 print(f"DeepSeek模型: {config.deepseek_model}")
149 print(f"OpenAI模型: {config.openai_model}") 149 print(f"OpenAI模型: {config.openai_model}")
150 - print(f"最大搜索结果数: {config.max_search_results}") 150 +
151 print(f"搜索超时: {config.search_timeout}秒") 151 print(f"搜索超时: {config.search_timeout}秒")
152 print(f"最大内容长度: {config.max_content_length}") 152 print(f"最大内容长度: {config.max_content_length}")
153 print(f"最大反思次数: {config.max_reflections}") 153 print(f"最大反思次数: {config.max_reflections}")
@@ -158,5 +158,5 @@ def print_config(config: Config): @@ -158,5 +158,5 @@ def print_config(config: Config):
158 # 显示API密钥状态(不显示实际密钥) 158 # 显示API密钥状态(不显示实际密钥)
159 print(f"DeepSeek API Key: {'已设置' if config.deepseek_api_key else '未设置'}") 159 print(f"DeepSeek API Key: {'已设置' if config.deepseek_api_key else '未设置'}")
160 print(f"OpenAI API Key: {'已设置' if config.openai_api_key else '未设置'}") 160 print(f"OpenAI API Key: {'已设置' if config.openai_api_key else '未设置'}")
161 - print(f"Tavily API Key: {'已设置' if config.tavily_api_key else '未设置'}") 161 + print(f"Bocha API Key: {'已设置' if config.bocha_api_key else '未设置'}")
162 print("==================\n") 162 print("==================\n")
@@ -12,8 +12,8 @@ import json @@ -12,8 +12,8 @@ import json
12 # 添加src目录到Python路径 12 # 添加src目录到Python路径
13 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '.')) 13 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '.'))
14 14
15 -from QueryEngine import DeepSearchAgent, Config  
16 -from config import DEEPSEEK_API_KEY, TAVILY_API_KEY 15 +from MediaEngine import DeepSearchAgent, Config
  16 +from config import DEEPSEEK_API_KEY, BOCHA_Web_Search_API_KEY
17 17
18 18
19 def main(): 19 def main():
@@ -98,19 +98,19 @@ def main(): @@ -98,19 +98,19 @@ def main():
98 98
99 # 自动使用配置文件中的API密钥 99 # 自动使用配置文件中的API密钥
100 deepseek_key = DEEPSEEK_API_KEY 100 deepseek_key = DEEPSEEK_API_KEY
101 - tavily_key = TAVILY_API_KEY 101 + bocha_key = BOCHA_Web_Search_API_KEY
102 102
103 # 创建配置 103 # 创建配置
104 config = Config( 104 config = Config(
105 deepseek_api_key=deepseek_key if llm_provider == "deepseek" else None, 105 deepseek_api_key=deepseek_key if llm_provider == "deepseek" else None,
106 openai_api_key=openai_key if llm_provider == "openai" else None, 106 openai_api_key=openai_key if llm_provider == "openai" else None,
107 - tavily_api_key=tavily_key, 107 + bocha_api_key=bocha_key,
108 default_llm_provider=llm_provider, 108 default_llm_provider=llm_provider,
109 deepseek_model=model_name if llm_provider == "deepseek" else "deepseek-chat", 109 deepseek_model=model_name if llm_provider == "deepseek" else "deepseek-chat",
110 openai_model=model_name if llm_provider == "openai" else "gpt-4o-mini", 110 openai_model=model_name if llm_provider == "openai" else "gpt-4o-mini",
111 max_reflections=max_reflections, 111 max_reflections=max_reflections,
112 max_content_length=max_content_length, 112 max_content_length=max_content_length,
113 - output_dir="query_engine_streamlit_reports" 113 + output_dir="media_engine_streamlit_reports"
114 ) 114 )
115 115
116 # 执行研究 116 # 执行研究