""" Agent 编排层 —— 调度四层架构完成分析 Layer 1: Planner 意图规划 Layer 2: Explorer 自适应探索 Layer 3: Insight 异常洞察 Layer 4: Context 上下文记忆 """ from typing import Optional from config import DB_PATH, MAX_EXPLORATION_ROUNDS from schema_extractor import extract_schema, schema_to_text from sandbox_executor import SandboxExecutor from planner import Planner from explorer import Explorer from insights import InsightEngine, quick_detect from reporter import ReportGenerator from context import ContextManager class DataAnalysisAgent: """ 数据分析 Agent 四层架构: 1. Planner - 理解用户意图,生成分析计划 2. Explorer - 基于计划多轮迭代探索 3. Insights - 从结果中检测异常、输出主动洞察 4. Context - 管理多轮对话上下文 Agent 负责编排这四层,从问题到报告。 """ def __init__(self, db_path: str): # 数据层 self.db_path = db_path self.schema = extract_schema(db_path) self.schema_text = schema_to_text(self.schema) self.executor = SandboxExecutor(db_path) # 四层组件 self.planner = Planner() self.explorer = Explorer(self.executor) self.insight_engine = InsightEngine() self.reporter = ReportGenerator() self.context = ContextManager() def analyze(self, question: str, max_rounds: Optional[int] = None) -> str: """ 完整分析流程 Args: question: 用户分析问题 max_rounds: 最大探索轮数(默认用配置值) Returns: 格式化的分析报告 """ max_rounds = max_rounds or MAX_EXPLORATION_ROUNDS print(f"\n{'='*60}") print(f"📊 {question}") print(f"{'='*60}") # ── Layer 0: 检查上下文 ────────────────────────── prev_context = self.context.get_context_for(question) if prev_context: print("📎 发现历史分析上下文,将结合之前的发现") # ── Layer 1: 意图规划 ──────────────────────────── print("\n🎯 [Layer 1] 意图规划...") plan = self.planner.plan(question, self.schema_text) analysis_type = plan.get("analysis_type", "unknown") dimensions = plan.get("dimensions", []) rationale = plan.get("rationale", "") print(f" 类型: {analysis_type}") print(f" 维度: {', '.join(dimensions) if dimensions else '自动发现'}") print(f" 理由: {rationale[:80]}{'...' if len(rationale) > 80 else ''}") # ── Layer 2: 自适应探索 ────────────────────────── print(f"\n🔍 [Layer 2] 自适应探索 (最多 {max_rounds} 轮)...") steps = self.explorer.explore(plan, self.schema_text, max_rounds=max_rounds) successful = sum(1 for s in steps if s.success) print(f"\n 完成: {len(steps)} 轮, {successful} 条成功查询") # ── Layer 3: 异常洞察 ──────────────────────────── print("\n🔎 [Layer 3] 异常洞察...") # 先做规则检测 rule_alerts = quick_detect(steps) for alert in rule_alerts: print(f" {alert}") # 再做 LLM 深度分析 insights = self.insight_engine.analyze(steps, question) if insights: print(f" 发现 {len(insights)} 条洞察") for insight in insights: print(f" {insight}") else: print(" 未发现异常") # ── 生成报告 ──────────────────────────────────── print("\n📝 正在生成报告...") report = self.reporter.generate(question, plan, steps, insights) # 追加主动洞察 if insights: insight_text = self.insight_engine.format_insights(insights) report += f"\n\n---\n\n{insight_text}" # ── Layer 4: 记录上下文 ────────────────────────── self.context.add_session( question=question, plan=plan, steps=steps, insights=insights, report=report, ) return report def get_schema(self) -> str: """获取 Schema 文本""" return self.schema_text def get_history(self) -> str: """获取分析历史摘要""" return self.context.get_history_summary() def get_audit(self) -> str: """获取执行审计日志""" return self.executor.get_execution_summary() def clear_history(self): """清空分析历史""" self.context.clear()