""" 交互式 CLI —— 四层架构自适应分析 用法: python cli.py [数据库路径] """ import os import sys sys.path.insert(0, os.path.dirname(__file__)) from core.config import DB_PATH, LLM_CONFIG, MAX_EXPLORATION_ROUNDS, PLAYBOOK_DIR from agent import DataAnalysisAgent def print_help(): print(""" 可用命令: <问题> 分析一个问题 rounds= <问题> 设置探索轮数 report [主题] 整合所有分析,生成综合报告 schema 查看数据库 Schema playbooks 查看已加载的预设剧本 regen 重新生成预设剧本 history 查看分析历史 audit 查看 SQL 审计日志 clear 清空分析历史 help 显示帮助 quit / q 退出 """) def main(): db_path = sys.argv[1] if len(sys.argv) > 1 else DB_PATH if not os.path.exists(db_path): print(f"❌ 数据库不存在: {db_path}") sys.exit(1) if not LLM_CONFIG["api_key"]: print("⚠️ 未配置 LLM_API_KEY") sys.exit(1) agent = DataAnalysisAgent(db_path) print("=" * 60) print(" 🤖 数据分析 Agent —— 四层架构") print("=" * 60) print(f"\n🔗 LLM: {LLM_CONFIG['model']} @ {LLM_CONFIG['base_url']}") print(f"🔄 最大探索轮数: {MAX_EXPLORATION_ROUNDS}") print(f"💾 数据库: {db_path}") print(f"📋 预设剧本: {len(agent.playbook_mgr.playbooks)} 个") print(f"\n💬 输入分析问题(help 查看命令)\n") while True: try: user_input = input("📊 > ").strip() except (EOFError, KeyboardInterrupt): print("\n👋 再见!") break if not user_input: continue cmd = user_input.lower() if cmd in ("quit", "exit", "q"): print("👋 再见!") break elif cmd == "help": print_help() elif cmd == "schema": print(agent.get_schema()) elif cmd == "history": print(agent.get_history()) elif cmd == "audit": print(agent.get_audit()) elif cmd == "clear": agent.clear_history() print("✅ 历史已清空") elif cmd.startswith("report"): topic = user_input[6:].strip() try: report = agent.full_report(question=topic) print("\n" + report) print("\n" + "~" * 60) except Exception as e: print(f"\n❌ 报告整合出错: {e}") import traceback traceback.print_exc() elif cmd == "playbooks": if not agent.playbook_mgr.playbooks: print("(无预设剧本,输入 regen 让 AI 自动生成)") else: for i, pb in enumerate(agent.playbook_mgr.playbooks, 1): print(f" {i}. 📋 {pb.name} — {pb.description} ({len(pb.preset_queries)} 条预设)") elif cmd == "regen": if os.path.isdir(PLAYBOOK_DIR): for f in os.listdir(PLAYBOOK_DIR): if f.startswith("auto_") and f.endswith(".json"): os.remove(os.path.join(PLAYBOOK_DIR, f)) agent.playbook_mgr.playbooks.clear() print("🤖 AI 正在重新生成预设剧本...") generated = agent.playbook_mgr.auto_generate(agent.schema_text, save_dir=PLAYBOOK_DIR) if generated: print(f"✅ 生成 {len(generated)} 个剧本:") for pb in generated: print(f" 📋 {pb.name} — {pb.description}") else: print("⚠️ 生成失败") else: # 解析 rounds=N max_rounds = MAX_EXPLORATION_ROUNDS question = user_input if "rounds=" in question.lower(): parts = question.split("rounds=") question = parts[0].strip() try: max_rounds = int(parts[1].strip().split()[0]) except (ValueError, IndexError): pass try: report = agent.analyze(question, max_rounds=max_rounds) print("\n" + report) print("\n" + "~" * 60) except Exception as e: print(f"\n❌ 分析出错: {e}") import traceback traceback.print_exc() print("\n📋 本次会话审计:") print(agent.get_audit()) agent.close() if __name__ == "__main__": main()