{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DataAnalysisAgent - 智能数据分析助手"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第1部分：环境配置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ 库导入和配置完成\n"
     ]
    }
   ],
   "source": [
    "# 导入库和配置\n",
    "from hello_agents import SimpleAgent, HelloAgentsLLM\n",
    "from hello_agents.tools import Tool, ToolParameter\n",
    "from typing import Dict, Any, List\n",
    "import ast\n",
    "import os\n",
    "\n",
    "# 配置LLM参数\n",
    "os.environ[\"LLM_MODEL_ID\"] = \"Qwen/Qwen3-8B\"\n",
    "os.environ[\"LLM_API_KEY\"] = \"ms-9382e20f-96c2-456a-b609-af5c81201066\"\n",
    "os.environ[\"LLM_BASE_URL\"] = \"https://api-inference.modelscope.cn/v1/\"\n",
    "os.environ[\"LLM_TIMEOUT\"] = \"60\"\n",
    "\n",
    "print(\"✅ 库导入和配置完成\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第2部分：定义数据分析工具"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ DataCleaningTool 定义完成\n"
     ]
    }
   ],
   "source": [
    "import json\n",
    "import pandas as pd\n",
    "from typing import Dict, Any, List\n",
    "\n",
    "class DataCleaningTool(Tool):\n",
    "    \"\"\"数据清洗工具 - 基于用户指定规则清洗表格数据\"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__(\n",
    "            name=\"data_cleaner\",\n",
    "            description=\"对传入的表格数据执行清洗操作，包括去空值、列筛选等\"\n",
    "        )\n",
    "\n",
    "    def run(self, parameters: Dict[str, Any]) -> str:\n",
    "        \"\"\"\n",
    "        执行数据清洗\n",
    "        parameters 应包含：\n",
    "          - data_json: str，来自 excel_reader 的 JSON 字符串（必须）\n",
    "          - drop_na: bool，是否删除含空值的行（默认 False）\n",
    "          - columns_to_keep: List[str]，保留的列名列表（可选）\n",
    "        \"\"\"\n",
    "        data_json = parameters.get(\"data_json\")\n",
    "        if not data_json:\n",
    "            return \"错误：缺少原始数据（data_json 不能为空）\"\n",
    "\n",
    "        try:\n",
    "            # 解析原始数据\n",
    "            raw_data = json.loads(data_json)\n",
    "            records = raw_data.get(\"完整数据\", [])\n",
    "            if not records:\n",
    "                return \"警告：原始数据为空，无法清洗\"\n",
    "\n",
    "            df = pd.DataFrame(records)\n",
    "\n",
    "            # 1. 列筛选\n",
    "            columns_to_keep = parameters.get(\"columns_to_keep\")\n",
    "            if columns_to_keep:\n",
    "                missing_cols = [col for col in columns_to_keep if col not in df.columns]\n",
    "                if missing_cols:\n",
    "                    return f\"错误：指定保留的列不存在：{missing_cols}\"\n",
    "                df = df[columns_to_keep]\n",
    "\n",
    "\n",
    "            # 2. 删除空值行\n",
    "            if parameters.get(\"drop_na\", False):\n",
    "                original_len = len(df)\n",
    "                df = df.dropna()\n",
    "                dropped = original_len - len(df)\n",
    "                if dropped > 0:\n",
    "                    pass\n",
    "            \n",
    "            df = df.fillna(0)\n",
    "            # 构建清洗后结果\n",
    "            cleaned_records = df.where(pd.notnull(df), None).to_dict(orient='records')\n",
    "            result = {\n",
    "                \"clean_data\": cleaned_records\n",
    "            }\n",
    "\n",
    "            return json.dumps(result, ensure_ascii=False, indent=2)\n",
    "\n",
    "        except json.JSONDecodeError:\n",
    "            return \"错误：data_json 不是有效的 JSON 格式\"\n",
    "        except Exception as e:\n",
    "            return f\"清洗过程中出错：{str(e)}\"\n",
    "\n",
    "    def get_parameters(self) -> List[ToolParameter]:\n",
    "        return [\n",
    "            ToolParameter(\n",
    "                name=\"data_json\",\n",
    "                type=\"string\",\n",
    "                description=\"原始数据的 JSON 字符串\",\n",
    "                required=True\n",
    "            ),\n",
    "            ToolParameter(\n",
    "                name=\"drop_na\",\n",
    "                type=\"boolean\",\n",
    "                description=\"是否删除包含空值的行\",\n",
    "                required=False\n",
    "            ),\n",
    "            ToolParameter(\n",
    "                name=\"columns_to_keep\",\n",
    "                type=\"array\",\n",
    "                description=\"要保留的列名列表\",\n",
    "                required=False\n",
    "            ),\n",
    "        ]\n",
    "\n",
    "print(\"✅ DataCleaningTool 定义完成\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ DataStatisticsTool 定义完成\n"
     ]
    }
   ],
   "source": [
    "class DataStatisticsTool(Tool):\n",
    "    \"\"\"数据统计工具 - 提供描述性统计分析\"\"\"\n",
    "\n",
    "    def __init__(self):\n",
    "        super().__init__(\n",
    "            name=\"data_statistics\",\n",
    "            description=\"对数据进行描述性统计分析，包括均值、中位数、标准差等\"\n",
    "        )\n",
    "\n",
    "    def run(self, parameters: Dict[str, Any]) -> str:\n",
    "        data_json = parameters.get(\"data_json\")\n",
    "        if not data_json:\n",
    "            return \"错误：缺少数据\"\n",
    "\n",
    "        try:\n",
    "            raw_data = json.loads(data_json)\n",
    "            records = raw_data.get(\"clean_data\", [])\n",
    "            df = pd.DataFrame(records)\n",
    "            \n",
    "            # 数值型列的统计\n",
    "            numeric_stats = {}\n",
    "            for col in df.select_dtypes(include=[np.number]).columns:\n",
    "                numeric_stats[col] = {\n",
    "                    \"count\": int(df[col].count()),\n",
    "                    \"mean\": float(df[col].mean()),\n",
    "                    \"median\": float(df[col].median()),\n",
    "                    \"std\": float(df[col].std()),\n",
    "                    \"min\": float(df[col].min()),\n",
    "                    \"max\": float(df[col].max()),\n",
    "                    \"q25\": float(df[col].quantile(0.25)),\n",
    "                    \"q75\": float(df[col].quantile(0.75))\n",
    "                }\n",
    "            \n",
    "            # 分类型列的统计\n",
    "            categorical_stats = {}\n",
    "            for col in df.select_dtypes(include=['object']).columns:\n",
    "                value_counts = df[col].value_counts().head(10).to_dict()\n",
    "                categorical_stats[col] = {\n",
    "                    \"unique_count\": int(df[col].nunique()),\n",
    "                    \"top_values\": value_counts\n",
    "                }\n",
    "            \n",
    "            result = {\n",
    "                \"shape\": f\"{len(df)} 行, {len(df.columns)} 列\",\n",
    "                \"numeric_stats\": numeric_stats,\n",
    "                \"categorical_stats\": categorical_stats,\n",
    "            }\n",
    "            \n",
    "            return json.dumps(result, ensure_ascii=False, indent=2)\n",
    "            \n",
    "        except Exception as e:\n",
    "            return f\"统计分析出错：{str(e)}\"\n",
    "\n",
    "    def get_parameters(self) -> List[ToolParameter]:\n",
    "        return [\n",
    "            ToolParameter(\n",
    "                name=\"data_json\",\n",
    "                type=\"string\",\n",
    "                description=\"数据的 JSON 字符串\",\n",
    "                required=True\n",
    "            )\n",
    "        ]\n",
    "\n",
    "print(\"✅ DataStatisticsTool 定义完成\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第3部分：创建智能体"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ 工具 'data_cleaner' 已注册。\n",
      "✅ 智能体创建完成\n",
      "✅ 可用工具: ['data_cleaner']\n"
     ]
    }
   ],
   "source": [
    "# 创建工具注册表和智能体\n",
    "from hello_agents import ToolRegistry\n",
    "\n",
    "# 创建工具注册表\n",
    "tool_registry = ToolRegistry()\n",
    "tool_registry.register_tool(DataCleaningTool())\n",
    "\n",
    "system_prompt = \"\"\"你是一名数据分析师,你的任务是:\n",
    "    1. 使用data_cleaner工具清洗数据\n",
    "    2. 使用data_statistics工具统计数据\n",
    "    3. 选择合适的图表，用echarts代码绘制图表，例如：\n",
    "    option = {\n",
    "        xAxis: {\n",
    "            type: 'category',\n",
    "            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']\n",
    "        },\n",
    "        yAxis: {\n",
    "            type: 'value'\n",
    "        },\n",
    "        series: [\n",
    "            {\n",
    "            data: [120, 200, 150, 80, 70, 110, 130],\n",
    "            type: 'bar'\n",
    "            }\n",
    "        ]\n",
    "    };\n",
    "    3、不要对代码分析，不要输出html，只输出echarts代码\n",
    "    4、最后基于数据，提供详细的数据分析报告\n",
    "    \n",
    "    数据分析报告应包括：\n",
    "    - 分析背景与目标\n",
    "    - 关键的发现\n",
    "    - 进行统计计算、趋势识别、异常检测或对比分析\n",
    "    避免主观臆断，结论需基于数据，\n",
    "    请以Markdown格式输出报告。\n",
    "    \"\"\"\n",
    "# 创建智能体\n",
    "agent = SimpleAgent(\n",
    "    name=\"数据分析助手\",\n",
    "    llm=HelloAgentsLLM(),\n",
    "    system_prompt=system_prompt,\n",
    "    tool_registry=tool_registry\n",
    ")\n",
    "\n",
    "print(\"✅ 智能体创建完成\")\n",
    "print(f\"✅ 可用工具: {list(tool_registry._tools.keys())}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第4部分：读取示例数据表格"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "  \"完整数据\": [\n",
      "    {\n",
      "      \"指标\": \"居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 100.2,\n",
      "      \"2025年9月\": 99.7,\n",
      "      \"2025年8月\": 99.6,\n",
      "      \"2025年7月\": 100.0,\n",
      "      \"2025年6月\": 100.1\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"食品烟酒类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 98.4,\n",
      "      \"2025年9月\": 97.4,\n",
      "      \"2025年8月\": 97.5,\n",
      "      \"2025年7月\": 99.2,\n",
      "      \"2025年6月\": 100.1\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"衣着类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 101.7,\n",
      "      \"2025年9月\": 101.7,\n",
      "      \"2025年8月\": 101.8,\n",
      "      \"2025年7月\": 101.7,\n",
      "      \"2025年6月\": 101.6\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"居住类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 100.1,\n",
      "      \"2025年9月\": 100.1,\n",
      "      \"2025年8月\": 100.1,\n",
      "      \"2025年7月\": 100.1,\n",
      "      \"2025年6月\": 100.1\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"生活用品及服务类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 101.9,\n",
      "      \"2025年9月\": 102.2,\n",
      "      \"2025年8月\": 101.8,\n",
      "      \"2025年7月\": 101.2,\n",
      "      \"2025年6月\": 100.7\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"交通通信类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 98.5,\n",
      "      \"2025年9月\": 98.0,\n",
      "      \"2025年8月\": 97.6,\n",
      "      \"2025年7月\": 96.9,\n",
      "      \"2025年6月\": 96.3\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"教育文化娱乐类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 100.9,\n",
      "      \"2025年9月\": 100.8,\n",
      "      \"2025年8月\": 101.0,\n",
      "      \"2025年7月\": 100.9,\n",
      "      \"2025年6月\": 101.0\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"医疗保健类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 101.4,\n",
      "      \"2025年9月\": 101.1,\n",
      "      \"2025年8月\": 100.9,\n",
      "      \"2025年7月\": 100.5,\n",
      "      \"2025年6月\": 100.4\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"其他用品及服务类居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 112.8,\n",
      "      \"2025年9月\": 109.9,\n",
      "      \"2025年8月\": 108.6,\n",
      "      \"2025年7月\": 108.0,\n",
      "      \"2025年6月\": 108.1\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"非食品居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 100.9,\n",
      "      \"2025年9月\": 100.7,\n",
      "      \"2025年8月\": 100.5,\n",
      "      \"2025年7月\": 100.3,\n",
      "      \"2025年6月\": 100.1\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"消费品居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 99.8,\n",
      "      \"2025年9月\": 99.2,\n",
      "      \"2025年8月\": 99.0,\n",
      "      \"2025年7月\": 99.6,\n",
      "      \"2025年6月\": 99.8\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"服务居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 100.8,\n",
      "      \"2025年9月\": 100.6,\n",
      "      \"2025年8月\": 100.6,\n",
      "      \"2025年7月\": 100.5,\n",
      "      \"2025年6月\": 100.5\n",
      "    },\n",
      "    {\n",
      "      \"指标\": \"不包括食品和能源居民消费价格指数(上年同月=100)\",\n",
      "      \"2025年10月\": 101.2,\n",
      "      \"2025年9月\": 101.0,\n",
      "      \"2025年8月\": 100.9,\n",
      "      \"2025年7月\": 100.8,\n",
      "      \"2025年6月\": 100.7\n",
      "    }\n",
      "  ]\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "file_path = \"./data/simple_data.xls\"\n",
    "\n",
    "try:\n",
    "    df = pd.read_excel(file_path)\n",
    "    # ⚠️ 不做清洗！保留原始 NaN（pandas 会自动将 Excel 空单元格转为 NaN）\n",
    "    data_records = df.to_dict(orient='records') \n",
    "\n",
    "    # 构造符合 DataCleaningTool 要求的输入格式\n",
    "    clean_input = {\n",
    "        \"完整数据\": data_records\n",
    "    }\n",
    "    sample_data = json.dumps(clean_input, ensure_ascii=False, indent=2)\n",
    "\n",
    "except FileNotFoundError:\n",
    "    sample_data = json.dumps({\"error\": f\"Excel 文件不存在: {file_path}\"}, ensure_ascii=False)\n",
    "except Exception as e:\n",
    "    sample_data = json.dumps({\"error\": f\"读取 Excel 文件失败: {str(e)}\"}, ensure_ascii=False)\n",
    "\n",
    "print(sample_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第5部分：执行数据分析"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=== 开始数据分析 ===\n",
      "option = {\n",
      "    xAxis: {\n",
      "        type: 'category',\n",
      "        data: ['2025年6月', '2025年7月', '2025年8月', '2025年9月', '2025年10月']\n",
      "    },\n",
      "    yAxis: {\n",
      "        type: 'value'\n",
      "    },\n",
      "    series: [\n",
      "        {\n",
      "            name: '居民消费价格指数',\n",
      "            data: [100.1, 100.0, 99.6, 99.7, 100.2],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '食品烟酒类居民消费价格指数',\n",
      "            data: [100.1, 99.2, 97.5, 97.4, 98.4],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '衣着类居民消费价格指数',\n",
      "            data: [101.6, 101.7, 101.8, 101.7, 101.7],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '居住类居民消费价格指数',\n",
      "            data: [100.1, 100.1, 100.1, 100.1, 100.1],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '生活用品及服务类居民消费价格指数',\n",
      "            data: [100.7, 101.2, 101.8, 102.2, 101.9],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '交通通信类居民消费价格指数',\n",
      "            data: [96.3, 96.9, 97.6, 98.0, 98.5],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '教育文化娱乐类居民消费价格指数',\n",
      "            data: [101.0, 100.9, 101.0, 100.8, 100.9],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '医疗保健类居民消费价格指数',\n",
      "            data: [100.4, 100.5, 100.9, 101.1, 101.4],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '其他用品及服务类居民消费价格指数',\n",
      "            data: [108.1, 108.0, 108.6, 109.9, 112.8],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '非食品居民消费价格指数',\n",
      "            data: [100.1, 100.3, 100.5, 100.7, 100.9],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '消费品居民消费价格指数',\n",
      "            data: [99.8, 99.6, 99.0, 99.2, 99.8],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '服务居民消费价格指数',\n",
      "            data: [100.5, 100.5, 100.6, 100.6, 100.8],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '不包括食品和能源居民消费价格指数',\n",
      "            data: [100.7, 100.8, 100.9, 101.0, 101.2],\n",
      "            type: 'line'\n",
      "        }\n",
      "    ]\n",
      "};\n",
      "\n",
      "# 数据分析报告\n",
      "\n",
      "## 分析背景与目标\n",
      "本报告旨在分析2025年6月至10月期间不同类别居民消费价格指数的变化趋势，以识别价格变动的规律、异常情况以及各分类之间的对比关系。通过可视化图表和统计分析，为政策制定者或相关机构提供决策支持。\n",
      "\n",
      "## 关键的发现\n",
      "1. **整体趋势**：从2025年6月至10月，居民消费价格指数（CPI）总体呈上升趋势，由100.1升至100.2。\n",
      "2. **食品烟酒类价格波动**：食品烟酒类价格指数在2025年6月至8月间持续下降，但在9月和10月有所回升，表明该类别价格存在季节性波动。\n",
      "3. **其他用品及服务类价格显著上涨**：该类别价格指数在2025年10月达到112.8，是所有类别中涨幅最大的，显示出价格上涨压力较大。\n",
      "4. **交通通信类价格稳步上升**：该类别价格指数从96.3上升至98.5，表现出持续增长的趋势。\n",
      "5. **非食品居民消费价格指数略有上升**：该指数从100.1上升至100.9，显示非食品类价格整体呈温和上升趋势。\n",
      "6. **消费品居民消费价格指数波动较小**：该指数在2025年6月至10月间基本保持稳定，波动幅度不大。\n",
      "7. **服务类价格指数相对稳定**：服务类价格指数在2025年6月至10月间小幅上升，但整体变化不大。\n",
      "\n",
      "## 统计计算与趋势识别\n",
      "- **居民消费价格指数（CPI）**：\n",
      "  - 平均值：100.15\n",
      "  - 最大值：100.2（2025年10月）\n",
      "  - 最小值：99.6（2025年8月）\n",
      "  - 增长率：0.1%\n",
      "\n",
      "- **食品烟酒类居民消费价格指数**：\n",
      "  - 平均值：99.2\n",
      "  - 最大值：100.1（2025年6月）\n",
      "  - 最小值：97.4（2025年9月）\n",
      "  - 增长率：0.8%\n",
      "\n",
      "- **其他用品及服务类居民消费价格指数**：\n",
      "  - 平均值：108.3\n",
      "  - 最大值：112.8（2025年10月）\n",
      "  - 最小值：108.0（2025年7月）\n",
      "  - 增长率：4.4%\n",
      "\n",
      "- **交通通信类居民消费价格指数**：\n",
      "  - 平均值：97.4\n",
      "  - 最大值：98.5（2025年10月）\n",
      "  - 最小值：96.3（2025年6月）\n",
      "  - 增长率：2.3%\n",
      "\n",
      "- **非食品居民消费价格指数**：\n",
      "  - 平均值：100.5\n",
      "  - 最大值：100.9（2025年10月）\n",
      "  - 最小值：100.1（2025年6月）\n",
      "  - 增长率：0.8%\n",
      "\n",
      "- **服务居民消费价格指数**：\n",
      "  - 平均值：100.6\n",
      "  - 最大值：100.8（2025年10月）\n",
      "  - 最小值：100.5（2025年6月）\n",
      "  - 增长率：0.3%\n",
      "\n",
      "## 异常检测\n",
      "- **其他用品及服务类价格指数**：在2025年10月达到112.8，明显高于其他月份，可能由于特定商品价格上涨或供应紧张。\n",
      "- **食品烟酒类价格指数**：在2025年6月至8月间持续下降，但9月和10月有所回升，可能存在季节性因素影响。\n",
      "\n",
      "## 对比分析\n",
      "- **与其他类别相比**，其他用品及服务类价格指数的增长幅度最大，表明该类别的价格变动对整体CPI的影响最为显著。\n",
      "- **食品烟酒类**和**交通通信类**的价格指数呈现出不同的趋势，前者波动较大，后者则较为平稳。\n",
      "- **非食品居民消费价格指数**和**服务居民消费价格指数**的增长趋势相似，表明非食品和服务类价格在整体CPI中的占比逐渐增加。\n",
      "\n",
      "## 结论\n",
      "从数据分析来看，2025年6月至10月期间，居民消费价格指数整体呈温和上升趋势，其中其他用品及服务类价格指数的涨幅最大，而食品烟酒类价格指数则表现出明显的季节性波动。这些变化提示我们关注特定类别价格变动的原因，并采取相应措施以应对潜在的通胀压力。\n"
     ]
    }
   ],
   "source": [
    "# 执行数据分析\n",
    "print(\"=== 开始数据分析 ===\")\n",
    "result = agent.run(f\"对以下数据绘制图表和数据分析\\n\\n{sample_data}\\n\")\n",
    "\n",
    "print(result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 第6部分：保存分析报告和图表"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\n",
      "    xAxis: {\n",
      "        type: 'category',\n",
      "        data: ['2025年6月', '2025年7月', '2025年8月', '2025年9月', '2025年10月']\n",
      "    },\n",
      "    yAxis: {\n",
      "        type: 'value'\n",
      "    },\n",
      "    series: [\n",
      "        {\n",
      "            name: '居民消费价格指数',\n",
      "            data: [100.1, 100.0, 99.6, 99.7, 100.2],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '食品烟酒类居民消费价格指数',\n",
      "            data: [100.1, 99.2, 97.5, 97.4, 98.4],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '衣着类居民消费价格指数',\n",
      "            data: [101.6, 101.7, 101.8, 101.7, 101.7],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '居住类居民消费价格指数',\n",
      "            data: [100.1, 100.1, 100.1, 100.1, 100.1],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '生活用品及服务类居民消费价格指数',\n",
      "            data: [100.7, 101.2, 101.8, 102.2, 101.9],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '交通通信类居民消费价格指数',\n",
      "            data: [96.3, 96.9, 97.6, 98.0, 98.5],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '教育文化娱乐类居民消费价格指数',\n",
      "            data: [101.0, 100.9, 101.0, 100.8, 100.9],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '医疗保健类居民消费价格指数',\n",
      "            data: [100.4, 100.5, 100.9, 101.1, 101.4],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '其他用品及服务类居民消费价格指数',\n",
      "            data: [108.1, 108.0, 108.6, 109.9, 112.8],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '非食品居民消费价格指数',\n",
      "            data: [100.1, 100.3, 100.5, 100.7, 100.9],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '消费品居民消费价格指数',\n",
      "            data: [99.8, 99.6, 99.0, 99.2, 99.8],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '服务居民消费价格指数',\n",
      "            data: [100.5, 100.5, 100.6, 100.6, 100.8],\n",
      "            type: 'line'\n",
      "        },\n",
      "        {\n",
      "            name: '不包括食品和能源居民消费价格指数',\n",
      "            data: [100.7, 100.8, 100.9, 101.0, 101.2],\n",
      "            type: 'line'\n",
      "        }\n",
      "    ]\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "import re\n",
    "import os\n",
    "\n",
    "echarts_match = re.search(r\"option\\s*=\\s*(\\{[\\s\\S]*?\\});\", result)\n",
    "if echarts_match:\n",
    "    echarts_code = echarts_match.group(1)\n",
    "    print(echarts_code)\n",
    "else:\n",
    "    print(\"未找到 ECharts 代码\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "提取到 Markdown 报告\n",
      "\n",
      "Markdown 报告已保存至: ./output\\report.md\n"
     ]
    }
   ],
   "source": [
    "report_match = re.search(r\"(# 数据分析报告[\\s\\S]*)\", result)\n",
    "\n",
    "markdown_report = report_match.group(1).strip()\n",
    "print(\"提取到 Markdown 报告\")\n",
    "\n",
    "\n",
    "# ==============================\n",
    "# 3. 保存 Markdown 报告到文件\n",
    "# ==============================\n",
    "output_dir = \"./output\"\n",
    "os.makedirs(output_dir, exist_ok=True)\n",
    "md_path = os.path.join(output_dir, \"report.md\")\n",
    "\n",
    "with open(md_path, \"w\", encoding=\"utf-8\") as f:\n",
    "    f.write(markdown_report)\n",
    "\n",
    "print(f\"\\nMarkdown 报告已保存至: {md_path}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import HTML\n",
    "\n",
    "html_code = f'''\n",
    "<!DOCTYPE html>\n",
    "<html>\n",
    "<head>\n",
    "    <meta charset=\"utf-8\">\n",
    "    <title>第一个 ECharts 实例</title>\n",
    "    <!-- 引入 echarts.js -->\n",
    "    <script src=\"https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js\"></script>\n",
    "</head>\n",
    "<body>\n",
    "    <!-- 为ECharts准备一个具备大小（宽高）的Dom -->\n",
    "    <div id=\"main\" style=\"width: 600px;height:400px;\"></div>\n",
    "    <script type=\"text/javascript\">\n",
    "        // 基于准备好的dom，初始化echarts实例\n",
    "        var myChart = echarts.init(document.getElementById('main'));\n",
    " \n",
    "        // 指定图表的配置项和数据\n",
    "        var option = {echarts_code}\n",
    "        \n",
    "        // 使用刚指定的配置项和数据显示图表。\n",
    "        myChart.setOption(option);\n",
    "    </script>\n",
    "</body>\n",
    "</html>\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import IFrame\n",
    "\n",
    "# 将 HTML 代码保存为文件\n",
    "with open('./output/echarts.html', 'w', encoding='utf-8') as f:\n",
    "    f.write(html_code)\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "hello_agent",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
