Skill: wyb92/mysteel-chartgeneration (version 1.0.0)

--- name: Mysteel_ChartGeneration description: 基于文本描述或数据自动生成各类图表（趋势图、对比图、结构图等）；当用户需要创建可视化图表、将数据转化为直观表达、生成分析报告插图时使用 dependency: python: - requests --- # AI图表生成 Skill ## 任务目标 - 本 Skill 用于：通过AI自动生成ECharts图表配置并渲染为HTML文件 - 能力包含：文本描述生图、数据可视化、多种图表类型支持、自动标题生成 - 触发条件：用户要求生成图表、可视化数据、创建分析报告插图 ## 前置准备 ### API密钥配置（必需） 在调用脚本前，需要先配置API密钥： **步骤1：检查api_key.md文件** - 检查项目的references目录下是否存在 `api_key.md` 文件 - 如果不存在，提示用户创建并输入密钥 **步骤2：创建/更新api_key.md文件** ```bash # 在项目的references目录下创建文件 cd /path/to/my-generation/references echo "api_key: 你的密钥" > api_key.md ``` **文件格式**： ``` [REDACTED_SECRET] ``` **注意**： - api_key.md文件应在**项目的references目录**下 - 脚本会自动从references目录读取该文件 - 密钥信息将用于接口请求头的token字段 - 每次调用前会检查文件是否存在 **项目目录结构**： ``` my-generation/ ├── SKILL.md ├── scripts/ │ ├── generate_chart.py │ └── render_html.py └── references/ ├── api_key.md # API密钥文件（需要创建） └── api-parameters.md ``` ### 依赖说明 - 使用 Python 内置模块，需要安装 requests 库（见 dependency 字段） ## 操作步骤 ### 智能模式选择（由智能体判断） 根据用户需求，智能体应自动选择最合适的生成模式： #### 1. FREEDOM模式（自由模式）- 默认推荐 **适用场景**： - 用户通过自然语言描述图表需求 - 数据量较小或数据已包含在描述中 - 快速原型设计或验证 - 不确定使用哪种模式的场景 **判断依据**： - 用户输入："生成一个销售趋势图"、"画个柱状图"、"帮我做个对比图表" - 数据内嵌在描述中："数据为：[100, 200, 300]" - 没有提供结构化数据文件 **使用方式**： ```bash node scripts/generate_chart.py --task "用户的自然语言描述" ``` --- #### 2. STRICT模式（严格模式） **适用场景**： - 用户提供了结构化数据（JSON数组/对象） - 数据量较大（超过50条记录） - 需要高性能数据转换 - 有明确的数据结构说明需求 **判断依据**： - 用户提供了完整的数据文件或JSON数据 - 数据记录数较多（>50条） - 用户明确说明数据字段含义 **使用方式**： ```bash node scripts/generate_chart.py \ --task "转换任务描述" \ --mode STRICT \ --data '{"field1": "value1", ...}' \ --data-example '[{"field1": "value1"}]' \ --data-description "数据包含字段1和字段2" ``` --- #### 3. TEMPLATE模式（模板模式） **适用场景**： - 用户明确指定图表类型（折线图/柱状图/饼图） - 需要标准格式的图表 - 快速生成常见图表类型 - 对图表样式要求标准化 **判断依据**： - 用户明确说："生成一个饼图"、"画条形图"、"用折线图展示" - 图表类型是标准类型之一 - 数据量适中且结构简单 **使用方式**： ```bash node scripts/generate_chart.py \ --task "生成图表描述" \ --mode TEMPLATE \ --type 折线图 \ --data '[{"name": "A", "value": 100}]' ``` --- #### 4. AUTO模式（自动模式） **适用场景**： - 智能体无法确定最佳模式 - 需要系统自动选择 - 混合场景 **使用方式**： ```bash node scripts/generate_chart.py --task "用户需求" --mode AUTO ``` --- ### 完整执行流程 1. **检查API密钥配置** - 检查 `api_key.md` 文件是否存在 - 如果不存在，提示用户创建并输入密钥 - 如果存在，读取密钥信息 2. **分析用户需求**（智能体完成） - 提取图表类型、数据来源、数据量、复杂度 - 根据上述规则选择最合适的模式 3. **调用图表生成脚本** - 脚本自动从 `api_key.md` 读取密钥 - 将密钥设置到请求头的 `token` 字段 - 根据选择的模式调用 `scripts/generate_chart.py` - 传递相应参数（task、mode、data、type等） - asyncEnable固定为false（仅支持同步模式） 4. **处理结果** - 同步模式：直接获取option配置 5. **渲染HTML文件** - 调用 `scripts/render_html.py` 将配置转换为HTML - 自动读取meta文件中的标题 - 返回HTML文件路径 --- ## 资源索引 - **必要脚本**： - [scripts/generate_chart.py](scripts/generate_chart.py)（调用AI图表生成API，仅支持同步模式） - [scripts/render_html.py](scripts/render_html.py)（将ECharts配置渲染为HTML文件） - **领域参考**： - [references/api-parameters.md](references/api-parameters.md)（API参数详细说明和使用示例） - [references/api_key.md](references/api_key.md)（API密钥配置文件，需用户创建） ## 注意事项 - **API密钥配置**：首次使用前必须在**项目的references目录**下创建 `api_key.md` 文件并填入密钥，格式为 `[REDACTED_SECRET]` - **密钥文件位置**：api_key.md文件必须放在项目的references目录下，脚本会自动从references目录读取该文件 - **密钥传递方式**：密钥会自动从references目录的 `api_key.md` 读取并设置到请求头的 `token` 字段 - **仅支持同步模式**：asyncEnable固定为false，不支持异步处理 - **自动标题生成**：脚本会根据用户的task描述自动生成图表标题，并保存到meta文件中 - **标题使用规则**：render_html.py会自动读取meta文件中的标题，如果找不到则使用默认标题 - **模式选择优先级**：FREEDOM > TEMPLATE > STRICT > AUTO（智能体根据场景自动选择） - **数据内嵌优先**：如果数据已在task描述中，无需额外提供--data参数 - **STRICT模式要求**：必须提供data、dataExample、dataDescription三个参数 - **TEMPLATE模式限制**：仅支持标准图表类型（折线图、柱状图、饼图等） - **脚本自动生成唯一的requestId，无需手动指定** - **HTML文件使用ECharts渲染，支持交互操作** ## 使用示例 ### 示例1：自然语言生图（FREEDOM模式） **用户需求**："帮我生成一个展示2024年各月份销售额的折线图，数据为：[1200, 1500, 1800, 2000, 2200, 2500, 2800, 3000, 3200, 3500, 3800, 4000]" **智能体判断**： - 自然语言描述 → FREEDOM模式 - 数据已内嵌 → 无需--data参数 **自动生成标题**： - 原始task："帮我生成一个展示2024年各月份销售额的折线图，数据为：[1200, 1500, ...]" - 提取标题："2024年各月份销售额" **执行步骤**： ```bash # 1. 检查api_key.md文件（如果不存在，提示用户创建） # 2. 调用生成脚本（同步模式） node scripts/generate_chart.py --task "帮我生成一个展示2024年各月份销售额的折线图，数据为：[1200, 1500, 1800, 2000, 2200, 2500, 2800, 3000, 3200, 3500, 3800, 4000]" # 3. 渲染HTML node scripts/render_html.py --option-file output/req-xxx_option.json --output output/sales_trend.html ``` **注意**：脚本会自动从 `api_key.md` 读取密钥并设置到请求头 --- ### 示例2：指定图表类型（TEMPLATE模式） **用户需求**："生成一个饼图展示市场份额，数据如下：A产品30%，B产品25%，C产品20%" **智能体判断**： - 明确指定"饼图" → TEMPLATE模式 - 数据简单且结构清晰 → TEMPLATE模式优先 ```bash node scripts/generate_chart.py \ --task "生成一个饼图展示市场份额" \ --mode TEMPLATE \ --type 饼图 \ --data '[{"name": "A产品", "value": 30}, {"name": "B产品", "value": 25}, {"name": "C产品", "value": 20}, {"name": "其他", "value": 25}]' node scripts/render_html.py --option-file output/req-xxx_option.json --output output/market_share.html ``` --- ### 示例3：大数据量处理（STRICT模式） **用户需求**："我有销售数据文件，包含1000条记录，请生成销量排名前10的柱状图。数据结构：product_name, sales_amount, region" **智能体判断**： - 数据量1000条 → STRICT模式 - 有明确数据结构 → 提供dataDescription ```bash node scripts/generate_chart.py \ --task "将销售数据转换为柱状图，展示销量排名前10的产品" \ --mode STRICT \ --data '$(cat sales_data.json)' \ --data-example '[{"product_name": "产品A", "sales_amount": 12000, "region": "华东"}]' \ --data-description "数据包含产品名称、销量金额、区域三个字段" node scripts/render_html.py --option-file output/req-xxx_option.json --output output/top10_sales.html ``` --- ### 示例4：对比类图表（FREEDOM模式） **用户需求**："画个柱状图对比华东、华南、华北三个区域的钢材库存量，数据：华东5000吨，华南4500吨，华北6000吨" **智能体判断**： - 自然语言描述 + 数据内嵌 → FREEDOM模式 ```bash node scripts/generate_chart.py --task "画个柱状图对比华东、华南、华北三个区域的钢材库存量，数据：华东5000吨，华南4500吨，华北6000吨" node scripts/render_html.py --option-file output/req-xxx_option.json --output output/inventory_comparison.html ``` --- ### 示例5：趋势分析（FREEDOM模式） **用户需求**："生成一个钢联螺纹钢价格走势图，展示最近一年的价格变化趋势" **智能体判断**： - 自然语言描述，无明确数据 → FREEDOM模式（AI会自动推断或生成数据） ```bash node scripts/generate_chart.py --task "生成一个钢联螺纹钢价格走势图，展示最近一年的价格变化趋势" node scripts/render_html.py --option-file output/req-xxx_option.json --output output/price_trend.html ``` --- ## 模式选择决策树 ``` 用户请求 ├─ 是否明确指定图表类型？（饼图/柱状图/折线图等） │ └─ 是 → TEMPLATE模式 │ ├─ 是否提供大量结构化数据？（>50条） │ └─ 是 → STRICT模式 │ └─ 自然语言描述 + 数据量小/内嵌数据 └─ FREEDOM模式（默认） ``` **注意**：所有模式均为同步处理，asyncEnable固定为false --- ## 推荐执行流程（智能体视角） 1. **接收用户需求** 2. **检查API密钥配置**： - 检查 `api_key.md` 文件是否存在 - 如果不存在，提示用户："请先配置API密钥，创建 api_key.md 文件并填入密钥，格式：[REDACTED_SECRET]" - 如果存在，继续执行 3. **分析需求特征**： - 提取关键词（图表类型、数据、复杂度） - 判断数据来源（描述内嵌/提供文件/无数据） - 评估数据量级 4. **选择生成模式**：根据上述决策树 5. **构建命令参数**：准备task、mode、data等参数 6. **调用脚本执行**（同步模式）： - 脚本自动从 `api_key.md` 读取密钥 - 密钥自动设置到请求头的 `token` 字段 - asyncEnable固定为false 7. **渲染HTML并返回** ## API密钥配置示例 ### 创建api_key.md文件 ```bash # 在项目的references目录下创建文件 cd /path/to/my-generation/references echo "[REDACTED_SECRET]" > api_key.md ``` ### 文件内容格式 ``` [REDACTED_SECRET] ``` ### 错误处理 - 如果文件不存在，脚本会提示：`api_key.md 文件不存在。请先在项目的references目录下创建该文件并填入API密钥。文件路径：{项目目录}/references/api_key.md` - 如果文件为空，脚本会提示：`api_key.md 文件为空，请填入API密钥。文件路径：{项目目录}/references/api_key.md`

path: scripts/generate_chart.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI图表生成API调用脚本

功能：
- 调用AI图表生成API生成ECharts配置
- 自动生成唯一requestId
- 将结果保存为JSON文件
- 自动从task描述生成图表标题
- 仅支持同步模式（asyncEnable固定为false）

授权方式: ApiKey（从api_key.md文件读取）
"""

import os
import sys
import json
import uuid
import argparse
import requests
from pathlib import Path


def load_api_key():
    """
    从项目的references目录下读取api_key.md文件
    
    Returns:
        str: API密钥
    
    Raises:
        Exception: 文件不存在或格式错误
    """
    script_dir = Path(__file__).parent.parent
    api_key_file = script_dir / 'references' / 'api_key.md'
    
    if not api_key_file.exists():
        raise Exception(
            f"api_key.md 文件不存在。请先在项目的references目录下创建该文件并填入API密钥。\n"
            f"文件路径：{api_key_file}\n"
            f"文件格式：api_key: 你的密钥"
        )
    
    content = api_key_file.read_text(encoding='utf-8').strip()
    
    if not content:
        raise Exception(f"api_key.md 文件为空，请填入API密钥。文件路径：{api_key_file}")
    
    if content.startswith('api_key:'):
        [REDACTED_SECRET]':', 1)[1].strip()
    else:
        [REDACTED_SECRET]
    
    if not api_key:
        raise Exception(f"未能从api_key.md文件中解析出有效的API密钥。文件路径：{api_key_file}")
    
    return api_key


def generate_request_id():
    """
    生成唯一的请求标识符
    
    Returns:
        str: 唯一的requestId
    """
    unique_id = str(uuid.uuid4()).replace('-', '')
    return f"req-{unique_id[:16]}"


def generate_title_from_task(task):
    """
    从任务描述中生成图表标题
    
    Args:
        task (str): 任务描述
    
    Returns:
        str: 生成的图表标题
    """
    task_clean = task.strip()
    
    prefixes_to_remove = [
        '生成一个', '生成', '画一个', '画个', '创建一个', '创建',
        '帮我生成', '帮我画', '请生成', '请画', '展示',
        '显示', '呈现', '可视化'
    ]
    
    for prefix in prefixes_to_remove:
        if task_clean.startswith(prefix):
            task_clean = task_clean[len(prefix):].strip()
            break
    
    # 移除数据部分
    if '，数据为：' in task_clean:
        task_clean = task_clean.split('，数据为：')[0].strip()
    elif ',数据为：' in task_clean:
        task_clean = task_clean.split(',数据为：')[0].strip()
    elif '数据为：' in task_clean:
        task_clean = task_clean.split('数据为：')[0].strip()
    
    # 移除图表类型后缀
    suffixes_to_remove = [
        '图表', '图', '走势图', '趋势图', '折线图', '柱状图',
        '饼图', '对比图', '结构图', '关系图'
    ]
    
    for suffix in suffixes_to_remove:
        if task_clean.endswith(suffix):
            task_clean = task_clean[:-len(suffix)].strip()
            break
    
    if not task_clean or len(task_clean) < 2:
        return 'AI生成图表'
    
    return task_clean


def generate_chart(task, mode='FREEDOM', data=None, type_param=None,
                   data_example=None, data_description=None, option=None,
                   robust_mode=False, session_id=None, output_dir='./output'):
    """
    调用AI图表生成API（同步模式）
    
    Args:
        task (str): 任务描述
        mode (str): 生成模式
        data (str): JSON字符串形式的数据
        type_param (str): 图表类型
        data_example (str): JSON字符串形式的数据示例
        data_description (str): 数据描述
        option (str): JSON字符串形式的图表配置
        robust_mode (bool): 是否开启健壮模式
        session_id (str): 会话标识符
        output_dir (str): 输出目录
    
    Returns:
        dict: API响应结果
    
    Raises:
        Exception: API调用失败或解析错误
    """
    [REDACTED_SECRET])
    request_id = generate_request_id()
    
    payload = {
        'requestId': request_id,
        'task': task,
        'mode': mode,
        'asyncEnable': False
    }
    
    if data is not None:
        payload['data'] = json.loads(data)
    if type_param is not None:
        payload['type'] = type_param
    if data_example is not None:
        payload['dataExample'] = json.loads(data_example)
    if data_description is not None:
        payload['dataDescription'] = data_description
    if option is not None:
        payload['option'] = json.loads(option)
    if robust_mode:
        payload['robustMode'] = True
    if session_id is not None:
        payload['sessionId'] = session_id
    
    url = 'https://mcp.mysteel.com/mcp/info/genie-tool/v1/tool/ai-chart'
    
    print(f"[INFO] 调用AI图表生成API...")
    print(f"[INFO] requestId: {request_id}")
    print(f"[INFO] mode: {mode}")
    
    headers = {
        'Content-Type': 'application/json',
        'token': api_key
    }
    
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=30)
        
        if response.status_code >= 400:
            raise Exception(f"HTTP请求失败: 状态码 {response.status_code}, 响应内容: {response.text}")
        
        result = response.json()
        code = result.get('code')
        
        if str(code) != '200':
            error_msg = result.get('message', '未知错误')
            raise Exception(f"API错误: {error_msg}")
        
        print(f"[INFO] API调用成功")
        
        data_result = result.get('data', {})
        option_data = data_result.get('option')
        option_url = data_result.get('optionUrl')
        preview_url = data_result.get('previewUrl')
        
        print(f"[INFO] optionUrl: {option_url}")
        print(f"[INFO] previewUrl: {preview_url}")
        
        # 创建输出目录
        output_path = Path(output_dir).resolve()
        output_path.mkdir(parents=True, exist_ok=True)
        
        # 保存option文件
        option_file = output_path / f"{request_id}_option.json"
        option_file.write_text(json.dumps(option_data, indent=2, ensure_ascii=False), encoding='utf-8')
        
        # 生成标题并保存meta文件
        chart_title = generate_title_from_task(task)
        meta_file = output_path / f"{request_id}_meta.json"
        meta_info = {
            'requestId': request_id,
            'task': task,
            'title': chart_title
        }
        meta_file.write_text(json.dumps(meta_info, indent=2, ensure_ascii=False), encoding='utf-8')
        
        print(f"[INFO] 图表配置已保存到: {option_file}")
        print(f"[INFO] 图表标题: {chart_title}")
        
        return result
        
    except requests.exceptions.RequestException as e:
        raise Exception(f"API调用失败: {str(e)}")
    except json.JSONDecodeError as e:
        raise Exception(f"解析响应失败: {str(e)}")


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='AI图表生成API调用脚本')
    parser.add_argument('--task', required=True, help='任务描述')
    parser.add_argument('--mode', default='FREEDOM', help='生成模式')
    parser.add_argument('--session-id', help='会话标识符')
    parser.add_argument('--output-dir', default='./output', help='输出目录')
    parser.add_argument('--data', help='JSON字符串形式的数据')
    parser.add_argument('--type', dest='type_param', help='图表类型')
    parser.add_argument('--data-example', help='JSON字符串形式的数据示例')
    parser.add_argument('--data-description', help='数据描述')
    parser.add_argument('--option', help='JSON字符串形式的图表配置')
    parser.add_argument('--robust-mode', action='store_true', help='是否开启健壮模式')
    
    args = parser.parse_args()
    
    try:
        result = generate_chart(
            task=args.task,
            mode=args.mode,
            data=args.data,
            type_param=args.type_param,
            data_example=args.data_example,
            data_description=args.data_description,
            option=args.option,
            robust_mode=args.robust_mode,
            session_id=getattr(args, 'session_id', None),
            output_dir=args.output_dir
        )
        print('[SUCCESS] 图表生成成功')
        request_id = result['data'].get('requestId', '')
        if request_id:
            print(f"图表配置文件: {args.output_dir}/{request_id}_option.json")
    except Exception as e:
        print(f"[ERROR] {e}")
        if 'api_key.md' in str(e):
            print('[提示] 请创建 api_key.md 文件，内容格式：api_key: 你的密钥')
        sys.exit(1)


if __name__ == '__main__':
    main()


path: scripts/render_html.py
content: #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
ECharts配置渲染HTML脚本

功能：
- 读取ECharts配置文件
- 生成包含ECharts库的HTML文件
- 支持响应式布局和交互操作
"""

import json
import argparse
from pathlib import Path


def render_html(option_file, output, title='AI生成图表'):
    """
    将ECharts配置渲染为HTML文件
    
    Args:
        option_file (str): ECharts配置文件路径
        output (str): 输出HTML文件路径
        title (str): 页面标题
    
    Raises:
        Exception: 配置文件不存在或格式错误
    """
    print(f"[INFO] 读取ECharts配置: {option_file}")
    
    option_path = Path(option_file)
    if not option_path.exists():
        raise Exception(f"配置文件不存在: {option_file}")
    
    try:
        option_content = option_path.read_text(encoding='utf-8')
        option = json.loads(option_content)
    except json.JSONDecodeError as e:
        raise Exception(f"配置文件格式错误: {option_file}")
    
    # 尝试从meta文件读取标题
    if title == 'AI生成图表':
        meta_file = option_path.parent / option_path.name.replace('_option.json', '_meta.json')
        if meta_file.exists():
            try:
                meta_content = meta_file.read_text(encoding='utf-8')
                meta = json.loads(meta_content)
                title = meta.get('title', 'AI生成图表')
                print(f"[INFO] 从meta文件读取标题: {title}")
            except json.JSONDecodeError:
                print('[WARN] meta文件格式错误，使用默认标题')
    
    option_json = json.dumps(option, ensure_ascii=False)
    
    html_template = f'''<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{title}</title>
    <style>
        * {{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }}
        
        body {{
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }}
        
        .container {{
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            padding: 20px;
        }}
        
        .header {{
            text-align: center;
            margin-bottom: 20px;
            padding-bottom: 20px;
            border-bottom: 1px solid #eee;
        }}
        
        .header h1 {{
            font-size: 24px;
            color: #333;
            margin-bottom: 8px;
        }}
        
        .header p {{
            color: #666;
            font-size: 14px;
        }}
        
        #chart {{
            width: 100%;
            height: 600px;
        }}
        
        .footer {{
            margin-top: 20px;
            padding-top: 20px;
            border-top: 1px solid #eee;
            text-align: center;
            color: #999;
            font-size: 12px;
        }}
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>{title}</h1>
            <p>AI智能生成的可视化图表</p>
        </div>
        <div id="chart"></div>
        <div class="footer">
            <p>Generated by AI Chart Generator</p>
        </div>
    </div>
    
    <!-- ECharts CDN -->
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    
    <script>
        // 初始化图表
        var chartDom = document.getElementById('chart');
        var myChart = echarts.init(chartDom);
        
        // 图表配置
        var option = {option_json};
        
        // 渲染图表
        myChart.setOption(option);
        
        // 响应式调整
        window.addEventListener('resize', function() {{
            myChart.resize();
        }});
        
        // 监听图表点击事件
        myChart.on('click', function(params) {{
            console.log('图表点击:', params);
        }});
    </script>
</body>
</html>
'''
    
    # 创建输出目录
    output_path = Path(output)
    output_path.parent.mkdir(parents=True, exist_ok=True)
    
    print(f"[INFO] 生成HTML文件: {output}")
    output_path.write_text(html_template, encoding='utf-8')
    print('[SUCCESS] HTML文件生成成功')


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='ECharts配置渲染HTML脚本')
    parser.add_argument('--option-file', required=True, help='ECharts配置文件路径')
    parser.add_argument('--output', required=True, help='输出HTML文件路径')
    parser.add_argument('--title', default='AI生成图表', help='页面标题')
    
    args = parser.parse_args()
    
    try:
        render_html(args.option_file, args.output, args.title)
    except Exception as e:
        print(f"[ERROR] {e}")
        sys.exit(1)


if __name__ == '__main__':
    main()


path: references/api-parameters.md
content: # AI图表生成API参数说明

## 目录

- [接口概述](#接口概述)
- [基础参数](#基础参数)
- [核心参数](#核心参数)
- [严格模式专用参数](#严格模式专用参数)
- [高级参数](#高级参数)
- [生成模式说明](#生成模式说明)
- [返回结果](#返回结果)
- [使用示例](#使用示例)

## 接口概述

**接口路径**: `https://mcp.mysteel.com/mcp/info/genie-tool/v1/tool/ai-chart`
**请求方法**: `POST`

本接口提供智能图表生成能力，根据任务描述自动生成ECharts图表配置。

## 基础参数

| 参数名         | 类型     | 必填 | 说明             |
|-------------|--------|----|----------------|
| `requestId` | string | ✅  | 请求唯一标识符（脚本自动生成） |
| `sessionId` | string | ❌  | 会话标识符          |

## 核心参数

| 参数名    | 类型            | 必填 | 默认值       | 说明                                   |
|--------|---------------|----|-----------|--------------------------------------|
| `task` | string        | ✅  | -         | 任务描述，描述需要生成的图表需求                     |
| `data` | array/object  | ❌  | null      | 图表数据，可以是数组或对象                        |
| `type` | string        | ❌  | null      | 图表类型，如：折线图、柱状图、饼图等                  |
| `mode` | string        | ❌  | `FREEDOM` | 生成模式，可选值：`FREEDOM`、`STRICT`、`TEMPLATE`、`AUTO` |

**Header 参数**：

| 参数名       | 类型   | 必填 | 说明                   |
| ------------ | ------ | ---- | ---------------------- |
| `Content-Type` | string | ✅   | 固定值：application/json |
| `token`      | string | ✅   | 身份秘钥标识符         |

## 严格模式专用参数

| 参数名               | 类型   | 必填 | 说明                       |
|-------------------|------|----|--------------------------|
| `dataDescription` | string | ❌  | 数据描述，说明数据结构和字段含义（严格模式推荐使用）   |
| `dataExample`     | array/object | ❌  | 数据示例，提供小样本数据作为参考（严格模式推荐使用） |

## 高级参数

| 参数名            | 类型      | 必填 | 默认值    | 说明                                   |
|----------------|---------|----|--------|--------------------------------------|
| `option`       | object  | ❌  | null   | 自定义图表配置模板，会与生成的配置合并                |
| `asyncEnable`  | boolean | ❌  | `false` | 是否启用异步模式                             |
| `robustMode`   | boolean | ❌  | `false` | 是否开启健壮模式（仅严格模式下生效，提高容错性）            |

## 生成模式说明

### 1. FREEDOM（自由模式）- 默认模式

**适用场景**: 快速生成图表，数据量小或无需提供数据

**特点**:
- 只需提供任务描述即可
- AI 根据描述自动生成图表配置
- 适合原型设计和快速验证

**示例**:
```json
{
  "requestId": "req-001",
  "task": "生成一个展示2024年各月份销售额的折线图",
  "mode": "FREEDOM",
  "token": "your_api_key"
}
```

### 2. STRICT（严格模式）

**适用场景**: 大数据量可视化，需要高性能转换

**特点**:
- 必须提供 `data`（实际数据）和 `dataExample`（数据示例）
- 推荐提供 `dataDescription`（数据描述）
- AI 生成 Python 代码进行数据转换，性能更好
- 自动执行代码并生成图表配置

**示例**:
```json
{
  "requestId": "req-002",
  "task": "将销售数据转换为折线图",
  "mode": "STRICT",
  "data": [
    {"month": "1月", "sales": 1200},
    {"month": "2月", "sales": 1500},
    {"month": "3月", "sales": 1800}
  ],
  "dataExample": [
    {"month": "1月", "sales": 1200}
  ],
  "dataDescription": "数据结构包含月份和销售额两个字段",
  "token": "your_api_key"
}
```

### 3. TEMPLATE（模板模式）

**适用场景**: 使用预定义的图表模板快速生成标准图表

**特点**:
- 基于注册的图表类型生成
- 支持折线图（line）、柱状图（bar）、饼图（pie）等模板
- 通过 `type` 参数指定图表类型，系统自动匹配对应的模板
- 生成速度快，配置标准化

**支持的模板类型**:
- `line` / `折线图` / `折线` - 折线图模板
- `bar` / `柱状图` / `柱形图` / `条形图` - 柱状图模板

**示例**:
```json
{
  "requestId": "req-003",
  "task": "生成一个折线图展示销售趋势",
  "mode": "TEMPLATE",
  "type": "折线图",
  "data": [...],
  "token": "your_api_key"
}
```

### 4. AUTO（自动模式）

**适用场景**: 让系统智能选择最适合的模式

**特点**:
- 当前实现中，AUTO 模式默认使用自由模式（FREEDOM）的处理逻辑
- 适合不确定使用哪种模式的场景

## 返回结果

### 同步模式响应（asyncEnable=false）

#### 成功响应
```json
{
  "code": 200,
  "data": {
    "option": {
      "title": {...},
      "xAxis": {...},
      "yAxis": {...},
      "series": [...]
    },
    "optionUrl": "",
    "previewUrl": ""
  },
  "requestId": "req-001"
}
```

**字段说明**:
- `option`: 图表配置对象（ECharts 配置），直接可用
- `optionUrl`: 图表配置文件的远程 URL
- `previewUrl`: 图表预览页面的 URL

#### 错误响应
```json
{
  "code": 500,
  "message": "图表生成失败",
  "requestId": "req-001"
}
```

### 异步模式响应（asyncEnable=true）

#### 立即响应
```json
{
  "code": 200,
  "data": {
    "pollUrl": ""
  },
  "requestId": "req-001"
}
```

**字段说明**:
- `pollUrl`: 轮询任务结果的 URL，需要通过 GET 请求此 URL 获取任务状态和结果

#### 轮询任务结果

**任务运行中**:
```json
{
  "taskId": "req-001",
  "status": "running",
  "result": null,
  "startTime": 1704067200000,
  "endTime": null
}
```

**任务完成**:
```json
{
  "taskId": "req-001",
  "status": "completed",
  "result": {
    "title": {...},
    "xAxis": {...},
    "yAxis": {...},
    "series": [...]
  },
  "startTime": 1704067200000,
  "endTime": 1704067250000
}
```

**任务失败**:
```json
{
  "taskId": "req-001",
  "status": "failed",
  "result": "图表生成失败：数据格式错误",
  "startTime": 1704067200000,
  "endTime": 1704067210000
}
```

## 使用示例

### 示例1: 基础折线图（自由模式）

**请求**:
```json
{
  "requestId": "example-001",
  "task": "生成一个展示2024年1-12月销售额趋势的折线图，数据为：[1200, 1500, 1800, 2000, 2200, 2500, 2800, 3000, 3200, 3500, 3800, 4000]",
  "mode": "FREEDOM",
  "token": "your_api_key"
}
```

### 示例2: 大数据量柱状图（严格模式）

**请求**:
```json
{
  "requestId": "example-002",
  "task": "将销售数据转换为柱状图，展示各产品的销量对比",
  "mode": "STRICT",
  "data": [
    {"product": "产品A", "sales": 12000},
    {"product": "产品B", "sales": 15000},
    {"product": "产品C", "sales": 18000},
    {"product": "产品D", "sales": 20000}
  ],
  "dataExample": [
    {"product": "产品A", "sales": 12000}
  ],
  "dataDescription": "数据包含产品名称和销售额两个字段",
  "token": "your_api_key"
}
```

### 示例3: 模板模式生成饼图

**请求**:
```json
{
  "requestId": "example-003",
  "task": "生成一个展示市场份额的饼图",
  "mode": "TEMPLATE",
  "type": "饼图",
  "data": [
    {"name": "产品A", "value": 30},
    {"name": "产品B", "value": 25},
    {"name": "产品C", "value": 20},
    {"name": "产品D", "value": 15},
    {"name": "其他", "value": 10}
  ],
  "token": "your_api_key"
}
```

### 示例4: 异步模式

**请求**:
```json
{
  "requestId": "example-004",
  "task": "生成一个包含多个数据系列的复杂折线图",
  "asyncEnable": true,
  "token": "your_api_key"
}
```

返回轮询URL后，定期轮询获取结果。

## 注意事项

1. **模式选择**:
   - 快速原型：使用 `FREEDOM` 模式
   - 大数据量：使用 `STRICT` 模式，并提供 `data`、`dataExample`、`dataDescription`
   - 标准图表：使用 `TEMPLATE` 模式，配合 `type` 参数指定图表类型
   - 不确定场景：使用 `AUTO` 模式

2. **数据格式**:
   - `data` 可以是数组或对象
   - 严格模式下，`dataExample` 应与 `data` 结构一致

3. **健壮模式（robustMode）**:
   - 仅在严格模式下生效
   - 开启后，即使图表配置验证失败，只要检测到有效数据（series 中有数据），也会接受生成的配置

4. **异步模式**:
   - 适用于复杂图表生成或可能超时的场景
   - 设置 `asyncEnable=true` 后，立即返回 `pollUrl`
   - 建议轮询间隔：1-3 秒

5. **返回数据**:
   - 同步模式下，`option` 字段包含完整的图表配置
   - `optionUrl` 是配置文件的远程访问地址
   - `previewUrl` 是图表预览页面地址


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)