@@ -317,72 +317,103 @@ def _on_progress(fetched, total, platform, country):
317317 c_data = self ._apply_semantic_dedup_pain_points (c_data , pp_merge_map )
318318 aggregated ["by_country" ][c_code ]["combined" ] = c_data
319319
320- # ── Phase 4: 生成报告(多国家动态章节)──
320+ # ── Phase 4: 生成报告(多国家动态章节,并发优化 )──
321321 self .on_event ("phase" , {"phase" : "Phase 4: 生成报告" , "phase_number" : 4 , "total_phases" : 5 })
322322
323- # Step 0: 执行摘要
324- self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "生成执行摘要" })
325- exec_summary_result = tool_generate_report (
326- app_name = display_name , analysis_data = aggregated ,
327- report_step = "executive_summary" , countries = countries , platforms = platforms ,
328- )
329- self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : exec_summary_result .get ("message" , "" )})
330-
331- # Step 1: 大纲
332- self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "生成大纲" })
333- outline_result = tool_generate_report (
334- app_name = display_name , analysis_data = aggregated ,
335- report_step = "outline" , countries = countries , platforms = platforms ,
336- )
337- outline = outline_result .get ("outline" , "" )
338- self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : outline_result .get ("message" , "" )})
339-
340- chapters = []
323+ from concurrent .futures import ThreadPoolExecutor , as_completed
341324
342- # 执行摘要作为第一个章节
343- chapters . append ( exec_summary_result . get ( "chapter_content " , "" ) )
325+ # Wave 1: 执行摘要、大纲、总览 并发生成
326+ self . on_event ( "tool_call " , { "tool" : "generate_report" , "input_summary" : "并发生成执行摘要+大纲+总览" } )
344327
345- # Step 2: 总览
346- self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "生成总览" })
347- overview = tool_generate_report (
348- app_name = display_name , analysis_data = aggregated ,
349- report_step = "overview" , countries = countries , platforms = platforms ,
350- )
351- chapters .append (overview .get ("chapter_content" , "" ))
352- self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : overview .get ("message" , "" )})
328+ def _gen_exec_summary ():
329+ return tool_generate_report (
330+ app_name = display_name , analysis_data = aggregated ,
331+ report_step = "executive_summary" , countries = countries , platforms = platforms ,
332+ )
353333
354- # Step 3: 各国家章节
355- for c_code in countries :
356- c_name = COUNTRIES .get (c_code , c_code )
357- self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : f"生成 { c_name } 分析" })
358- ch = tool_generate_report (
334+ def _gen_outline ():
335+ return tool_generate_report (
359336 app_name = display_name , analysis_data = aggregated ,
360- report_step = "country" , countries = countries , platforms = platforms ,
361- country_code = c_code , outline = outline , sample_reviews = all_reviews ,
337+ report_step = "outline" , countries = countries , platforms = platforms ,
362338 )
363- chapters .append (ch .get ("chapter_content" , "" ))
364- self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : ch .get ("message" , "" )})
365339
366- # Step 4: 跨国对比(多国家时)
367- if len (countries ) > 1 :
368- self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "生成跨国对比" })
369- cross = tool_generate_report (
340+ def _gen_overview ():
341+ return tool_generate_report (
370342 app_name = display_name , analysis_data = aggregated ,
371- report_step = "cross_country " , countries = countries , platforms = platforms ,
343+ report_step = "overview " , countries = countries , platforms = platforms ,
372344 )
373- chapters .append (cross .get ("chapter_content" , "" ))
374- self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : cross .get ("message" , "" )})
375345
376- # Step 5: 行动建议
377- self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "生成行动建议" })
378- action = tool_generate_report (
379- app_name = display_name , analysis_data = aggregated ,
380- report_step = "action" , countries = countries , platforms = platforms ,
381- )
382- chapters .append (action .get ("chapter_content" , "" ))
383- self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : action .get ("message" , "" )})
346+ with ThreadPoolExecutor (max_workers = 3 ) as executor :
347+ f_exec = executor .submit (_gen_exec_summary )
348+ f_outline = executor .submit (_gen_outline )
349+ f_overview = executor .submit (_gen_overview )
350+
351+ exec_summary_result = f_exec .result ()
352+ outline_result = f_outline .result ()
353+ overview_result = f_overview .result ()
354+ outline = outline_result .get ("outline" , "" )
355+
356+ self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : "执行摘要+大纲+总览 生成完成" })
357+
358+ # Wave 2: 各国家章节 + 跨国对比 + 行动建议 并发生成
359+ wave2_tasks = {}
360+ self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "并发生成国家章节+跨国对比+行动建议" })
361+
362+ with ThreadPoolExecutor (max_workers = max (len (countries ) + 2 , 4 )) as executor :
363+ # 各国家章节(依赖 outline,但彼此独立)
364+ for c_code in countries :
365+ def _gen_country (cc = c_code ):
366+ return tool_generate_report (
367+ app_name = display_name , analysis_data = aggregated ,
368+ report_step = "country" , countries = countries , platforms = platforms ,
369+ country_code = cc , outline = outline , sample_reviews = all_reviews ,
370+ )
371+ wave2_tasks [executor .submit (_gen_country )] = ("country" , c_code )
372+
373+ # 跨国对比(多国家时)
374+ if len (countries ) > 1 :
375+ def _gen_cross ():
376+ return tool_generate_report (
377+ app_name = display_name , analysis_data = aggregated ,
378+ report_step = "cross_country" , countries = countries , platforms = platforms ,
379+ )
380+ wave2_tasks [executor .submit (_gen_cross )] = ("cross_country" , None )
381+
382+ # 行动建议
383+ def _gen_action ():
384+ return tool_generate_report (
385+ app_name = display_name , analysis_data = aggregated ,
386+ report_step = "action" , countries = countries , platforms = platforms ,
387+ )
388+ wave2_tasks [executor .submit (_gen_action )] = ("action" , None )
389+
390+ # 收集 Wave 2 结果,按类型归位
391+ country_chapters = {} # c_code -> content
392+ cross_chapter = ""
393+ action_chapter = ""
394+ for future in wave2_tasks :
395+ task_type , task_key = wave2_tasks [future ]
396+ result = future .result ()
397+ if task_type == "country" :
398+ country_chapters [task_key ] = result .get ("chapter_content" , "" )
399+ elif task_type == "cross_country" :
400+ cross_chapter = result .get ("chapter_content" , "" )
401+ elif task_type == "action" :
402+ action_chapter = result .get ("chapter_content" , "" )
403+
404+ self .on_event ("tool_result" , {"tool" : "generate_report" , "message" : "国家章节+跨国对比+行动建议 生成完成" })
405+
406+ # 按正确顺序组装章节
407+ chapters = []
408+ chapters .append (exec_summary_result .get ("chapter_content" , "" ))
409+ chapters .append (overview_result .get ("chapter_content" , "" ))
410+ for c_code in countries :
411+ chapters .append (country_chapters .get (c_code , "" ))
412+ if cross_chapter :
413+ chapters .append (cross_chapter )
414+ chapters .append (action_chapter )
384415
385- # Step 6 : 格式化
416+ # Wave 3 : 格式化(依赖所有章节)
386417 self .on_event ("tool_call" , {"tool" : "generate_report" , "input_summary" : "格式化报告" })
387418 final = tool_generate_report (
388419 app_name = display_name , analysis_data = aggregated ,
0 commit comments