complete_agent_flow_rule.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. """
  2. 完整的智能体工作流 (Complete Agent Flow)
  3. =====================================
  4. 此工作流整合了规划、大纲生成和指标计算四个核心智能体,实现完整的报告生成流程。
  5. 包含的智能体:
  6. 1. PlanningAgent (规划智能体) - 分析状态并做出决策
  7. 2. OutlineAgent (大纲生成智能体) - 生成报告结构和指标需求
  8. 3. MetricCalculationAgent (指标计算智能体) - 执行标准指标计算
  9. 4. RulesEngineMetricCalculationAgent (规则引擎指标计算智能体) - 执行规则引擎指标计算
  10. 工作流程:
  11. 1. 规划节点 → 分析当前状态,决定下一步行动
  12. 2. 大纲生成节点 → 生成报告大纲和指标需求
  13. 3. 指标判断节点 → 根据大纲确定需要计算的指标
  14. 4. 指标计算节点 → 执行具体的指标计算任务
  15. 技术特点:
  16. - 基于LangGraph的状态机工作流
  17. - 支持条件路由和状态管理
  18. - 完善的错误处理机制
  19. - 详细的执行日志记录
  20. 作者: Big Agent Team
  21. 版本: 1.0.0
  22. 创建时间: 2024-12-20
  23. """
  24. import asyncio
  25. from typing import Dict, Any, List
  26. from datetime import datetime
  27. from langgraph.graph import StateGraph, START, END
  28. from workflow_state import (
  29. IntegratedWorkflowState,
  30. create_initial_integrated_state,
  31. get_calculation_progress,
  32. update_state_with_outline_generation,
  33. update_state_with_planning_decision,
  34. convert_numpy_types,
  35. )
  36. from agents.outline_agent import OutlineGeneratorAgent, generate_report_outline
  37. from agents.planning_agent import PlanningAgent, plan_next_action, analyze_current_state
  38. from agents.rules_engine_metric_calculation_agent import RulesEngineMetricCalculationAgent
  39. class CompleteAgentFlow:
  40. """完整的智能体工作流"""
  41. def __init__(self, api_key: str, base_url: str = "https://api.deepseek.com"):
  42. """
  43. 初始化完整的工作流
  44. Args:
  45. api_key: DeepSeek API密钥
  46. base_url: DeepSeek API基础URL
  47. """
  48. self.api_key = api_key
  49. self.base_url = base_url
  50. # 初始规则引擎智能体
  51. self.rules_engine_agent = RulesEngineMetricCalculationAgent(api_key, base_url)
  52. # 创建工作流图
  53. self.workflow = self._create_workflow()
  54. def _create_workflow(self) -> StateGraph:
  55. """创建LangGraph工作流"""
  56. workflow = StateGraph(IntegratedWorkflowState)
  57. # 添加节点
  58. workflow.add_node("planning_node", self._planning_node)
  59. workflow.add_node("outline_generator", self._outline_generator_node)
  60. workflow.add_node("metric_calculator", self._metric_calculator_node)
  61. # 设置入口点
  62. workflow.set_entry_point("planning_node")
  63. # 添加条件边 - 基于规划决策路由
  64. workflow.add_conditional_edges(
  65. "planning_node",
  66. self._route_from_planning,
  67. {
  68. "outline_generator": "outline_generator",
  69. "metric_calculator": "metric_calculator",
  70. END: END
  71. }
  72. )
  73. # 从各个节点返回规划节点重新决策
  74. workflow.add_edge("outline_generator", "planning_node")
  75. workflow.add_edge("metric_calculator", "planning_node")
  76. return workflow
  77. def _route_from_planning(self, state: IntegratedWorkflowState) -> str:
  78. """
  79. 从规划节点路由到下一个节点
  80. Args:
  81. state: 当前状态
  82. Returns:
  83. 目标节点名称
  84. """
  85. print(f"\n🔍 [路由决策] 步骤={state['planning_step']}, "
  86. f"大纲={state.get('outline_draft') is not None}, "
  87. f"指标需求={len(state.get('metrics_requirements', []))}")
  88. # 防止无限循环
  89. if state['planning_step'] > 30:
  90. print("⚠️ 规划步骤超过30次,强制结束流程")
  91. return END
  92. # 如果大纲为空 → 生成大纲
  93. if not state.get("outline_draft"):
  94. print("→ 路由到 outline_generator(生成大纲)")
  95. return "outline_generator"
  96. # 计算覆盖率
  97. progress = get_calculation_progress(state)
  98. coverage = progress["coverage_rate"]
  99. print(f" 指标覆盖率 = {coverage:.2%}")
  100. # 如果有待计算指标且覆盖率 < 100% → 计算指标
  101. if state.get("pending_metric_ids") and coverage < 1.0:
  102. print(f"→ 路由到 metric_calculator(计算指标,覆盖率={coverage:.2%})")
  103. return "metric_calculator"
  104. # 检查是否应该结束流程
  105. pending_ids = state.get("pending_metric_ids", [])
  106. failed_attempts = state.get("failed_metric_attempts", {})
  107. max_retries = 3
  108. # 计算还有哪些指标可以重试(未达到最大重试次数)
  109. retryable_metrics = [
  110. mid for mid in pending_ids
  111. if failed_attempts.get(mid, 0) < max_retries
  112. ]
  113. # 如果覆盖率 >= 80%,或者没有可重试的指标 → 结束流程
  114. if coverage >= 0.8 or not retryable_metrics:
  115. reason = "覆盖率达到80%" if coverage >= 0.8 else "没有可重试指标"
  116. print(f"→ 结束流程(覆盖率={coverage:.2%},原因:{reason})")
  117. return END
  118. # 默认返回规划节点
  119. return "planning_node"
  120. async def _planning_node(self, state: IntegratedWorkflowState) -> IntegratedWorkflowState:
  121. """规划节点:分析状态并做出决策"""
  122. try:
  123. print("🧠 正在执行规划分析...")
  124. # 使用规划智能体做出决策
  125. decision = await plan_next_action(
  126. question=state["question"],
  127. industry=state["industry"],
  128. current_state=state,
  129. api_key=self.api_key
  130. )
  131. # 更新状态
  132. new_state = update_state_with_planning_decision(state, {
  133. "decision": decision.decision,
  134. "next_route": self._decision_to_route(decision.decision),
  135. "metrics_to_compute": decision.metrics_to_compute
  136. })
  137. # 添加决策消息
  138. decision_msg = self._format_decision_message(decision)
  139. new_state["messages"].append({
  140. "role": "assistant",
  141. "content": decision_msg,
  142. "timestamp": datetime.now().isoformat()
  143. })
  144. print(f"✅ 规划决策完成:{decision.decision}")
  145. return convert_numpy_types(new_state)
  146. except Exception as e:
  147. print(f"❌ 规划节点执行失败: {e}")
  148. new_state = state.copy()
  149. new_state["errors"].append(f"规划节点错误: {str(e)}")
  150. return convert_numpy_types(new_state)
  151. async def _outline_generator_node(self, state: IntegratedWorkflowState) -> IntegratedWorkflowState:
  152. """大纲生成节点"""
  153. try:
  154. print("📝 正在生成报告大纲...")
  155. # 生成大纲(支持重试机制)
  156. outline = await generate_report_outline(
  157. question=state["question"],
  158. industry=state["industry"],
  159. sample_data=state["data_set"][:3], # 使用前3个样本
  160. api_key=self.api_key,
  161. max_retries=3, # 最多重试5次
  162. retry_delay=3.0 # 每次重试间隔3秒
  163. )
  164. # 更新状态
  165. new_state = update_state_with_outline_generation(state, outline)
  166. print(f"✅ 大纲生成完成:{outline.report_title}")
  167. print(f" 包含 {len(outline.sections)} 个章节,{len(outline.global_metrics)} 个指标需求")
  168. # 分析并打印AI的指标选择推理过程
  169. self._print_ai_selection_analysis(outline)
  170. return convert_numpy_types(new_state)
  171. except Exception as e:
  172. print(f"❌ 大纲生成失败: {e}")
  173. new_state = state.copy()
  174. new_state["errors"].append(f"大纲生成错误: {str(e)}")
  175. return convert_numpy_types(new_state)
  176. def _print_ai_selection_analysis(self, outline):
  177. """打印AI指标选择的推理过程分析 - 完全通用版本"""
  178. print()
  179. print('╔══════════════════════════════════════════════════════════════════════════════╗')
  180. print('║ 🤖 AI指标选择分析 ║')
  181. print('╚══════════════════════════════════════════════════════════════════════════════╝')
  182. print()
  183. # 计算总指标数 - outline可能是字典格式,需要适配
  184. if hasattr(outline, 'sections'):
  185. # Pydantic模型格式
  186. total_metrics = sum(len(section.metrics_needed) for section in outline.sections)
  187. sections = outline.sections
  188. else:
  189. # 字典格式
  190. total_metrics = sum(len(section.get('metrics_needed', [])) for section in outline.get('sections', []))
  191. sections = outline.get('sections', [])
  192. # 获取可用指标总数(这里可以从状态或其他地方动态获取)
  193. available_count = 26 # 这个可以从API调用中动态获取
  194. print('📊 选择统计:')
  195. print(' ┌─────────────────────────────────────────────────────────────────────┐')
  196. print(' │ 系统可用指标: {}个 │ AI本次选择: {}个 │ 选择率: {:.1f}% │'.format(
  197. available_count, total_metrics, total_metrics/available_count*100 if available_count > 0 else 0))
  198. print(' └─────────────────────────────────────────────────────────────────────┘')
  199. print()
  200. print('📋 AI决策过程:')
  201. print(' 大模型已根据用户需求从{}个可用指标中选择了{}个最相关的指标。'.format(available_count, total_metrics))
  202. print(' 选择过程完全由大模型基于语义理解和业务逻辑进行,不涉及任何硬编码规则。')
  203. print()
  204. print('🔍 选择结果:')
  205. print(' • 总章节数: {}个'.format(len(sections)))
  206. print(' • 平均每章节指标数: {:.1f}个'.format(total_metrics/len(sections) if sections else 0))
  207. print(' • 选择策略: 基于用户需求的相关性分析')
  208. print()
  209. print('🎯 AI Agent核心能力:')
  210. print(' • 语义理解: 理解用户查询的业务意图和分析需求')
  211. print(' • 智能筛选: 从海量指标中挑选最相关的组合')
  212. print(' • 逻辑推理: 为每个分析维度提供充分的选择依据')
  213. print(' • 动态适配: 根据不同场景自动调整选择策略')
  214. print()
  215. print('💡 关键洞察:')
  216. print(' AI Agent通过大模型的推理能力,实现了超越传统规则引擎的智能化指标选择,')
  217. print(' 能够根据具体业务场景动态调整分析框架,确保分析的针对性和有效性。')
  218. print()
  219. async def _metric_calculator_node(self, state: IntegratedWorkflowState) -> IntegratedWorkflowState:
  220. """指标计算节点"""
  221. try:
  222. # 检查计算模式
  223. use_rules_engine_only = state.get("use_rules_engine_only", False)
  224. use_traditional_engine_only = state.get("use_traditional_engine_only", False)
  225. if use_rules_engine_only:
  226. print("🧮 正在执行规则引擎指标计算(专用模式)...")
  227. elif use_traditional_engine_only:
  228. print("🧮 正在执行传统引擎指标计算(专用模式)...")
  229. else:
  230. print("🧮 正在执行指标计算...")
  231. new_state = state.copy()
  232. # 使用规划决策指定的指标批次,如果没有指定则使用所有待计算指标
  233. current_batch = state.get("current_batch_metrics", [])
  234. if current_batch:
  235. pending_ids = current_batch
  236. print(f"🧮 本次计算批次包含 {len(pending_ids)} 个指标")
  237. else:
  238. pending_ids = state.get("pending_metric_ids", [])
  239. print(f"🧮 计算所有待计算指标,共 {len(pending_ids)} 个")
  240. if not pending_ids:
  241. print("⚠️ 没有待计算的指标")
  242. return convert_numpy_types(new_state)
  243. # 获取指标需求信息
  244. metrics_requirements = state.get("metrics_requirements", [])
  245. if not metrics_requirements:
  246. print("⚠️ 没有指标需求信息")
  247. return convert_numpy_types(new_state)
  248. # 计算成功和失败的指标
  249. successful_calculations = 0
  250. failed_calculations = 0
  251. # 遍历待计算的指标(创建副本避免修改时遍历的问题)
  252. for metric_id in pending_ids.copy():
  253. try:
  254. # 找到对应的指标需求
  255. metric_req = next((m for m in metrics_requirements if m.metric_id == metric_id), None)
  256. if not metric_req:
  257. print(f"⚠️ 找不到指标 {metric_id} 的需求信息,跳过")
  258. # 仍然从待计算列表中移除,避免无限循环
  259. if metric_id in new_state["pending_metric_ids"]:
  260. new_state["pending_metric_ids"].remove(metric_id)
  261. continue
  262. print(f"🧮 计算指标: {metric_id} - {metric_req.metric_name}")
  263. # 根据模式决定使用哪种计算方式
  264. if use_rules_engine_only:
  265. # 只使用规则引擎计算
  266. use_rules_engine = True
  267. print(f" 使用规则引擎模式")
  268. elif use_traditional_engine_only:
  269. # 只使用传统引擎计算
  270. use_rules_engine = False
  271. print(f" 使用传统引擎模式")
  272. else:
  273. # 自动选择计算方式:优先使用规则引擎,只在规则引擎不可用时使用传统计算
  274. use_rules_engine = True # 默认使用规则引擎计算所有指标
  275. if use_rules_engine:
  276. # 使用规则引擎计算
  277. # 现在metric_id已经是知识ID,直接使用它作为配置名
  278. config_name = metric_id # metric_id 已经是知识ID,如 "metric-分析账户数量"
  279. intent_result = {
  280. "target_configs": [config_name],
  281. "intent_category": "指标计算"
  282. }
  283. print(f" 使用知识ID: {config_name}")
  284. results = await self.rules_engine_agent.calculate_metrics(intent_result)
  285. else:
  286. # 使用传统指标计算(模拟)
  287. # 这里简化处理,实际应该根据配置文件调用相应的API
  288. results = {
  289. "success": True,
  290. "results": [{
  291. "config_name": metric_req.metric_id,
  292. "result": {
  293. "success": True,
  294. "data": f"传统引擎计算结果:{metric_req.metric_name}",
  295. "value": 100.0 # 模拟数值
  296. }
  297. }]
  298. }
  299. # 处理计算结果
  300. calculation_success = False
  301. for result in results.get("results", []):
  302. if result.get("result", {}).get("success"):
  303. # 计算成功
  304. new_state["computed_metrics"][metric_id] = result["result"]
  305. successful_calculations += 1
  306. calculation_success = True
  307. print(f"✅ 指标 {metric_id} 计算成功")
  308. break # 找到一个成功的就算成功
  309. else:
  310. # 计算失败
  311. failed_calculations += 1
  312. print(f"❌ 指标 {metric_id} 计算失败")
  313. # 初始化失败尝试记录
  314. if "failed_metric_attempts" not in new_state:
  315. new_state["failed_metric_attempts"] = {}
  316. # 根据计算结果处理指标
  317. if calculation_success:
  318. # 计算成功:从待计算列表中移除
  319. if metric_id in new_state["pending_metric_ids"]:
  320. new_state["pending_metric_ids"].remove(metric_id)
  321. # 重置失败计数
  322. new_state["failed_metric_attempts"].pop(metric_id, None)
  323. else:
  324. # 计算失败:记录失败次数,不从待计算列表移除
  325. new_state["failed_metric_attempts"][metric_id] = new_state["failed_metric_attempts"].get(metric_id, 0) + 1
  326. max_retries = 3
  327. if new_state["failed_metric_attempts"][metric_id] >= max_retries:
  328. print(f"⚠️ 指标 {metric_id} 已达到最大重试次数 ({max_retries}),从待计算列表中移除")
  329. if metric_id in new_state["pending_metric_ids"]:
  330. new_state["pending_metric_ids"].remove(metric_id)
  331. except Exception as e:
  332. print(f"❌ 计算指标 {metric_id} 时发生异常: {e}")
  333. failed_calculations += 1
  334. # 初始化失败尝试记录
  335. if "failed_metric_attempts" not in new_state:
  336. new_state["failed_metric_attempts"] = {}
  337. # 记录失败次数
  338. new_state["failed_metric_attempts"][metric_id] = new_state["failed_metric_attempts"].get(metric_id, 0) + 1
  339. max_retries = 3
  340. if new_state["failed_metric_attempts"][metric_id] >= max_retries:
  341. print(f"⚠️ 指标 {metric_id} 异常已达到最大重试次数 ({max_retries}),从待计算列表中移除")
  342. if metric_id in new_state["pending_metric_ids"]:
  343. new_state["pending_metric_ids"].remove(metric_id)
  344. # 更新计算结果统计
  345. new_state["calculation_results"] = {
  346. "total_configs": len(pending_ids),
  347. "successful_calculations": successful_calculations,
  348. "failed_calculations": failed_calculations
  349. }
  350. # 添加消息
  351. if use_rules_engine_only:
  352. message_content = f"🧮 规则引擎指标计算完成:{successful_calculations} 成功,{failed_calculations} 失败"
  353. elif use_traditional_engine_only:
  354. message_content = f"🧮 传统引擎指标计算完成:{successful_calculations} 成功,{failed_calculations} 失败"
  355. else:
  356. message_content = f"🧮 指标计算完成:{successful_calculations} 成功,{failed_calculations} 失败"
  357. new_state["messages"].append({
  358. "role": "assistant",
  359. "content": message_content,
  360. "timestamp": datetime.now().isoformat()
  361. })
  362. if use_rules_engine_only:
  363. print(f"✅ 规则引擎指标计算完成:{successful_calculations} 成功,{failed_calculations} 失败")
  364. elif use_traditional_engine_only:
  365. print(f"✅ 传统引擎指标计算完成:{successful_calculations} 成功,{failed_calculations} 失败")
  366. else:
  367. print(f"✅ 指标计算完成:{successful_calculations} 成功,{failed_calculations} 失败")
  368. return convert_numpy_types(new_state)
  369. except Exception as e:
  370. print(f"❌ 指标计算节点失败: {e}")
  371. new_state = state.copy()
  372. new_state["errors"].append(f"指标计算错误: {str(e)}")
  373. return convert_numpy_types(new_state)
  374. def _decision_to_route(self, decision: str) -> str:
  375. """将规划决策转换为路由"""
  376. decision_routes = {
  377. "generate_outline": "outline_generator",
  378. "compute_metrics": "metric_calculator",
  379. "finalize_report": END # 直接结束流程
  380. }
  381. return decision_routes.get(decision, "planning_node")
  382. def _format_decision_message(self, decision: Any) -> str:
  383. """格式化决策消息"""
  384. try:
  385. decision_type = getattr(decision, 'decision', 'unknown')
  386. reasoning = getattr(decision, 'reasoning', '')
  387. if decision_type == "compute_metrics" and hasattr(decision, 'metrics_to_compute'):
  388. metrics = decision.metrics_to_compute
  389. return f"🧮 规划决策:计算 {len(metrics)} 个指标"
  390. elif decision_type == "finalize_report":
  391. return f"✅ 规划决策:生成最终报告"
  392. elif decision_type == "generate_outline":
  393. return f"📋 规划决策:生成大纲"
  394. else:
  395. return f"🤔 规划决策:{decision_type}"
  396. except:
  397. return "🤔 规划决策已完成"
  398. async def run_workflow(self, question: str, industry: str, data: List[Dict[str, Any]], session_id: str = None, use_rules_engine_only: bool = False, use_traditional_engine_only: bool = False) -> Dict[str, Any]:
  399. """
  400. 运行完整的工作流
  401. Args:
  402. question: 用户查询
  403. industry: 行业
  404. data: 数据集
  405. session_id: 会话ID
  406. use_rules_engine_only: 是否只使用规则引擎指标计算
  407. use_traditional_engine_only: 是否只使用传统引擎指标计算
  408. Returns:
  409. 工作流结果
  410. """
  411. try:
  412. print("🚀 启动完整智能体工作流...")
  413. print(f"问题:{question}")
  414. print(f"行业:{industry}")
  415. print(f"数据条数:{len(data)}")
  416. if use_rules_engine_only:
  417. print("计算模式:只使用规则引擎")
  418. elif use_traditional_engine_only:
  419. print("计算模式:只使用传统引擎")
  420. else:
  421. print("计算模式:标准模式")
  422. # 创建初始状态
  423. initial_state = create_initial_integrated_state(question, industry, data, session_id)
  424. # 设置计算模式标记
  425. if use_rules_engine_only:
  426. initial_state["use_rules_engine_only"] = True
  427. initial_state["use_traditional_engine_only"] = False
  428. elif use_traditional_engine_only:
  429. initial_state["use_rules_engine_only"] = False
  430. initial_state["use_traditional_engine_only"] = True
  431. else:
  432. initial_state["use_rules_engine_only"] = False
  433. initial_state["use_traditional_engine_only"] = False
  434. # 编译工作流
  435. app = self.workflow.compile()
  436. # 执行工作流
  437. result = await app.ainvoke(initial_state)
  438. print("✅ 工作流执行完成")
  439. return {
  440. "success": True,
  441. "result": result,
  442. "answer": result.get("answer"),
  443. "report": result.get("report_draft"),
  444. "session_id": result.get("session_id"),
  445. "execution_summary": {
  446. "planning_steps": result.get("planning_step", 0),
  447. "outline_generated": result.get("outline_draft") is not None,
  448. "metrics_computed": len(result.get("computed_metrics", {})),
  449. "completion_rate": result.get("completeness_score", 0)
  450. }
  451. }
  452. except Exception as e:
  453. print(f"❌ 工作流执行失败: {e}")
  454. return {
  455. "success": False,
  456. "error": str(e),
  457. "result": None
  458. }
  459. # 便捷函数
  460. async def run_complete_agent_flow(question: str, industry: str, data: List[Dict[str, Any]], api_key: str, session_id: str = None, use_rules_engine_only: bool = False, use_traditional_engine_only: bool = False) -> Dict[str, Any]:
  461. """
  462. 运行完整智能体工作流的便捷函数
  463. Args:
  464. question: 用户查询
  465. data: 数据集
  466. api_key: API密钥
  467. session_id: 会话ID
  468. use_rules_engine_only: 是否只使用规则引擎指标计算
  469. use_traditional_engine_only: 是否只使用传统引擎指标计算
  470. Returns:
  471. 工作流结果
  472. """
  473. workflow = CompleteAgentFlow(api_key)
  474. return await workflow.run_workflow(question, industry, data, session_id, use_rules_engine_only, use_traditional_engine_only)
  475. # 主函数用于测试
  476. async def main():
  477. """主函数:执行系统测试"""
  478. print("🚀 执行CompleteAgentFlow系统测试")
  479. print("=" * 50)
  480. # 导入配置
  481. import config
  482. if not config.DEEPSEEK_API_KEY:
  483. print("❌ 未找到API密钥")
  484. return
  485. # 测试数据
  486. test_data = [
  487. {
  488. }
  489. ]
  490. print(f"📊 测试数据: {len(test_data)} 条记录")
  491. # 执行测试
  492. result = await run_complete_agent_flow(
  493. question="请生成一份详细的农业经营贷流水分析报告,需要包含:1.总收入和总支出统计 2.收入笔数和支出笔数 3.各类型收入支出占比分析 4.交易对手收入支出TOP3排名 5.按月份的收入支出趋势分析 6.账户数量和交易时间范围统计 7.资金流入流出月度统计等全面指标",
  494. industry = "农业",
  495. # question="请生成一份详细的黑色金属相关经营贷流水分析报告,需要包含:1.总收入统计 2.收入笔数 3.各类型收入占比分析 4.交易对手收入排名 5.按月份的收入趋势分析 6.账户数量和交易时间范围统计 7.资金流入流出月度统计等全面指标",
  496. # industry = "黑色金属",
  497. data=test_data,
  498. api_key=config.DEEPSEEK_API_KEY,
  499. session_id="direct-test"
  500. )
  501. print(f"📋 结果: {'✅ 成功' if result.get('success') else '❌ 失败'}")
  502. if result.get('success'):
  503. summary = result.get('execution_summary', {})
  504. print(f" 规划步骤: {summary.get('planning_steps', 0)}")
  505. print(f" 指标计算: {summary.get('metrics_computed', 0)}")
  506. print("🎉 测试成功!")
  507. if __name__ == "__main__":
  508. import asyncio
  509. asyncio.run(main())