fix: prompt for viz enhanced
This commit is contained in:
@@ -17,8 +17,10 @@ You are an expert data analyst. You have access to a powerful `nl2sql` tool that
|
||||
- Call the `nl2sql` tool with the user's natural language query.
|
||||
- If the user explicitly asks to "visualize" or "plot" the data in the SAME message as the query (e.g., "Show me sales by region and plot it as a pie chart"), you can set `generate_chart=True` in the `nl2sql` tool.
|
||||
- If the user ONLY asks to query data, set `generate_chart=False` (default).
|
||||
- If `generate_chart=True` was used and a chart is returned, do not call the `visualization` tool again in the same turn.
|
||||
- Do not use `exec`, Python, matplotlib, or any manual plotting flow for this task.
|
||||
|
||||
## After using the tool
|
||||
- The tool will return a summary of the executed query and a sample of the results.
|
||||
- Use this information to provide a clear, concise, and helpful response to the user.
|
||||
- If a chart was successfully generated by the tool, inform the user that the chart is available in the visualization panel.
|
||||
- If a chart was successfully generated by the tool, reuse that Vega chart in the visualization panel.
|
||||
|
||||
@@ -12,11 +12,14 @@ You are an expert data visualization specialist. You have access to a `visualiza
|
||||
## When to use this skill
|
||||
- When the user asks to visualize, plot, or draw a chart based on data that has ALREADY been queried or is currently in context.
|
||||
- Examples: "Visualize it as a bar chart", "Plot the trend over time", "Draw a pie chart of the regions".
|
||||
- DO NOT use this tool if the data hasn't been queried yet. If the user asks a new question and wants it visualized (e.g., "Show me sales and plot it"), use the `nl2sql` tool with `generate_chart=True` instead, or call `nl2sql` first and then this tool.
|
||||
- DO NOT use this tool if the data hasn't been queried yet. If the user asks a new question and wants it visualized (e.g., "Show me sales and plot it"), use the `nl2sql` tool with `generate_chart=True`.
|
||||
- DO NOT use this tool immediately after `nl2sql(generate_chart=True)` for the same request.
|
||||
|
||||
## How to use this skill
|
||||
- Call the `visualization` tool with the user's specific visualization request (e.g., "plot as a pie chart").
|
||||
- The tool relies on the data from the most recent SQL query. It will automatically read this data from the context.
|
||||
- Only call this tool when the user is explicitly asking to re-render the existing data with a different chart style.
|
||||
- Do not use `exec`, Python, matplotlib, or manual plotting scripts.
|
||||
|
||||
## After using the tool
|
||||
- The tool will return a success message and the reasoning for the chosen chart type.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from nanobot.agent.tools.base import Tool
|
||||
@@ -9,12 +10,19 @@ from fastapi.encoders import jsonable_encoder
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def _build_sql_chart_viz(nl2sql_result: NL2SQLResponse) -> dict:
|
||||
def _normalize_query(value: str) -> str:
|
||||
return re.sub(r"\s+", "", (value or "")).lower()
|
||||
|
||||
|
||||
def _build_sql_chart_viz(nl2sql_result: NL2SQLResponse, query: str) -> dict:
|
||||
chart = nl2sql_result.chart
|
||||
payload = {
|
||||
"sql": nl2sql_result.sql,
|
||||
"result": nl2sql_result.result,
|
||||
"chart": chart.model_dump(by_alias=True, exclude_none=True) if chart else None,
|
||||
"chart_query": query,
|
||||
"chart_query_normalized": _normalize_query(query),
|
||||
"chart_generated_by": "nl2sql",
|
||||
"error": nl2sql_result.error,
|
||||
}
|
||||
return jsonable_encoder(payload)
|
||||
@@ -34,7 +42,8 @@ class NL2SQLTool(Tool):
|
||||
return (
|
||||
"Query the connected database or data source using natural language. "
|
||||
"Use this tool when the user asks to query, analyze, aggregate, or fetch data from the database. "
|
||||
"Set generate_chart=True if the user also wants to visualize or plot the data."
|
||||
"Set generate_chart=True if the user also wants to visualize or plot the data. "
|
||||
"If generate_chart=True, do not call visualization again for the same request."
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -76,7 +85,7 @@ class NL2SQLTool(Tool):
|
||||
|
||||
# Always save visualization payload to context so the chat stream can pick it up
|
||||
# Even if there's an error, we want the frontend to see the generated SQL
|
||||
viz_payload = _build_sql_chart_viz(result)
|
||||
viz_payload = _build_sql_chart_viz(result, query)
|
||||
existing_viz = current_viz_data.get()
|
||||
if isinstance(existing_viz, dict):
|
||||
existing_viz.clear()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
from nanobot.agent.tools.base import Tool
|
||||
@@ -8,6 +9,10 @@ from fastapi.encoders import jsonable_encoder
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _normalize_query(value: str) -> str:
|
||||
return re.sub(r"\s+", "", (value or "")).lower()
|
||||
|
||||
class VisualizationTool(Tool):
|
||||
"""
|
||||
Tool for generating a visualization (chart) from existing data.
|
||||
@@ -22,7 +27,8 @@ class VisualizationTool(Tool):
|
||||
return (
|
||||
"Generate a chart or visualization based on the most recently queried data. "
|
||||
"Use this tool when the user asks to plot, visualize, or create a chart from data that has already been retrieved. "
|
||||
"Note: This tool relies on the data from the last executed SQL query. If no query has been executed yet, you must use the nl2sql tool first."
|
||||
"Note: This tool relies on the data from the last executed SQL query. If no query has been executed yet, you must use the nl2sql tool first. "
|
||||
"Do not call this tool right after nl2sql(generate_chart=True) for the same request."
|
||||
)
|
||||
|
||||
@property
|
||||
@@ -47,6 +53,20 @@ class VisualizationTool(Tool):
|
||||
return "Error: No data available to visualize. Please query the data first using the nl2sql tool."
|
||||
|
||||
try:
|
||||
existing_viz = current_viz_data.get() or {}
|
||||
existing_chart = existing_viz.get("chart") if isinstance(existing_viz, dict) else None
|
||||
existing_result = existing_viz.get("result") if isinstance(existing_viz, dict) else None
|
||||
existing_query_normalized = (
|
||||
existing_viz.get("chart_query_normalized") if isinstance(existing_viz, dict) else None
|
||||
)
|
||||
if (
|
||||
existing_chart
|
||||
and existing_result == data
|
||||
and existing_query_normalized
|
||||
and existing_query_normalized == _normalize_query(query)
|
||||
):
|
||||
return "Chart already exists for this query and dataset. Reusing existing Vega visualization."
|
||||
|
||||
if on_progress:
|
||||
await on_progress("正在分析数据特征并生成可视化方案...")
|
||||
|
||||
@@ -61,6 +81,9 @@ class VisualizationTool(Tool):
|
||||
"sql": existing_viz.get("sql", ""),
|
||||
"result": data,
|
||||
"chart": chart_response.model_dump(by_alias=True, exclude_none=True),
|
||||
"chart_query": query,
|
||||
"chart_query_normalized": _normalize_query(query),
|
||||
"chart_generated_by": "visualization",
|
||||
"error": None,
|
||||
}
|
||||
encoded_viz = jsonable_encoder(viz_payload)
|
||||
|
||||
@@ -470,6 +470,9 @@ async def nanobot_chat(request: ChatRequest):
|
||||
instructions = []
|
||||
if request.route_mode == "sql" or request.prefer_sql_chart:
|
||||
instructions.append("Use the nl2sql tool to answer the query")
|
||||
instructions.append("If the user also asks for visualization, set generate_chart=true in the same nl2sql call")
|
||||
instructions.append("Do not call visualization after nl2sql if a chart is already generated for this request")
|
||||
instructions.append("Do not use exec, Python scripts, or matplotlib for chart plotting")
|
||||
elif request.route_mode == "chat":
|
||||
instructions.append("Normal chat mode. Do NOT use the nl2sql tool")
|
||||
|
||||
@@ -581,6 +584,9 @@ async def nanobot_chat_stream(request: ChatRequest):
|
||||
instructions = []
|
||||
if request.route_mode == "sql" or request.prefer_sql_chart:
|
||||
instructions.append("Use the nl2sql tool to answer the query")
|
||||
instructions.append("If the user also asks for visualization, set generate_chart=true in the same nl2sql call")
|
||||
instructions.append("Do not call visualization after nl2sql if a chart is already generated for this request")
|
||||
instructions.append("Do not use exec, Python scripts, or matplotlib for chart plotting")
|
||||
elif request.route_mode == "chat":
|
||||
instructions.append("Normal chat mode. Do NOT use the nl2sql tool")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user