ChatGPT Work 中的 Data agent 把企业数据分析入口变成了自然语言:连接公司数据、发现洞察,并生成可交互的仪表盘。变化不只是少写几条 SQL,而是让业务人员能够围绕同一份数据持续追问,同时让分析结果更快进入决策流程。
自然语言正在成为新的分析入口
传统的数据分析链路通常要经过需求沟通、SQL 开发、图表制作和结果解释。任何口径变化,都可能让流程重新走一遍。数据智能体试图把这些步骤压缩到一次连续对话中,例如:
- “按月份比较各区域收入,并标出增长最快的区域。”
- “只看企业客户,解释第三季度收入下降的主要原因。”
- “把结果做成可以筛选区域和客户类型的仪表盘。”
这里真正重要的是上下文延续能力。第一次查询得到结果后,用户可以继续缩小范围、改变维度或要求可视化,而不必重新描述全部背景。
不过,自然语言不能自动解决指标口径问题。“收入”“活跃客户”和“流失”仍然需要清晰定义。否则,智能体只是更快地产生一个可能错误的答案。
连接数据只是开始,语义层才决定可信度
将数据源接入智能体之后,至少还要补齐三层约束:
- 业务语义:明确指标公式、时间粒度、币种和过滤条件。
- 访问控制:沿用数据仓库中的用户权限,避免智能体扩大数据可见范围。
- 结果溯源:保留查询语句、数据来源、运行时间和过滤条件,便于复核。
例如,“月度经常性收入”不应只是一段藏在某张报表里的 SQL。可以把它定义在受版本控制的指标文件中:
metrics:
monthly_revenue:
label: Monthly recognized revenue
expression: SUM(orders.revenue)
time_column: orders.ordered_at
default_grain: month
filters:
- orders.status = 'completed'
owner: finance-analytics
这不是 Data agent 的官方配置格式,而是一种可以这样实践的语义层设计。关键在于让人、仪表盘和智能体引用同一套定义。
动手搭一个最小的数据智能体原型
下面的示例是独立的本地原型,并非 ChatGPT Work Data agent 的官方 API。它演示了一条可改造的链路:自然语言问题进入模型,模型只生成只读 SQL,应用验证 SQL 后查询 SQLite,再用 Streamlit 展示表格和图表。
运行前需要 Python 3.10+ 和 OpenAI API 密钥。将 OPENAI_MODEL 改成账户可用的模型名称:
python -m venv .venv
source .venv/bin/activate
pip install openai streamlit pandas sqlglot
export OPENAI_API_KEY="your-api-key"
export OPENAI_MODEL="gpt-4.1-mini"
streamlit run app.py
把下面代码保存为 app.py:
import os
import sqlite3
import pandas as pd
import streamlit as st
from openai import OpenAI
from sqlglot import exp, parse_one
DB = sqlite3.connect("demo.db", check_same_thread=False)
DB.executescript("""
CREATE TABLE IF NOT EXISTS orders (
ordered_at TEXT NOT NULL,
region TEXT NOT NULL,
customer_type TEXT NOT NULL,
revenue REAL NOT NULL
);
DELETE FROM orders;
INSERT INTO orders VALUES
('2025-01-08', 'East', 'Enterprise', 12000),
('2025-01-19', 'West', 'SMB', 4200),
('2025-02-03', 'East', 'Enterprise', 15500),
('2025-02-14', 'West', 'Enterprise', 9100),
('2025-03-02', 'East', 'SMB', 5300),
('2025-03-18', 'West', 'Enterprise', 13200);
""")
SCHEMA = """
Table orders:
- ordered_at TEXT: ISO date
- region TEXT: East or West
- customer_type TEXT: Enterprise or SMB
- revenue REAL: recognized revenue in USD
"""
SYSTEM_PROMPT = f"""
You are a SQLite analytics assistant.
Return exactly one SELECT statement and no Markdown.
Use only the schema below. Never modify data.
When grouping dates by month, use substr(ordered_at, 1, 7).
{SCHEMA}
"""
def validate_sql(sql: str) -> str:
tree = parse_one(sql, read="sqlite")
if not isinstance(tree, exp.Select):
raise ValueError("Only SELECT statements are allowed")
tables = {table.name for table in tree.find_all(exp.Table)}
if not tables or not tables.issubset({"orders"}):
raise ValueError("Query references a non-approved table")
blocked = (exp.Insert, exp.Update, exp.Delete, exp.Drop, exp.Alter, exp.Create)
if any(tree.find(node_type) for node_type in blocked):
raise ValueError("Mutating SQL is not allowed")
return tree.sql(dialect="sqlite")
st.title("Revenue data agent prototype")
question = st.text_input(
"Ask a question",
"Show monthly revenue by region"
)
if st.button("Analyze", type="primary"):
client = OpenAI()
response = client.responses.create(
model=os.environ["OPENAI_MODEL"],
instructions=SYSTEM_PROMPT,
input=question,
)
sql = validate_sql(response.output_text.strip())
data = pd.read_sql_query(sql, DB)
st.code(sql, language="sql")
st.dataframe(data, use_container_width=True)
if len(data.columns) >= 2:
numeric = data.select_dtypes(include="number").columns.tolist()
if numeric:
st.bar_chart(data.set_index(data.columns[0])[numeric])
这个原型刻意暴露生成的 SQL,而不是只显示结论。生产系统还应加入列级权限、查询超时、行数限制、敏感字段脱敏、审计日志,以及对高成本查询的预算控制。仅靠提示词要求“不要修改数据”并不构成安全边界;数据库账号本身也必须是只读的。
采用时先选窄场景
适合优先落地的场景通常具有稳定的数据表、明确的指标和可验证的历史报表,例如销售漏斗、运营日报或客户支持趋势。不要一开始就让智能体跨越所有数据仓库回答任意问题。
上线前可以检查以下事项:
- 核心指标是否有唯一、可版本化的定义。
- 智能体是否继承用户身份和数据权限。
- 每个答案是否能展示来源、过滤条件与生成的查询。
- 仪表盘中的数字是否能与现有可信报表对账。
- 遇到歧义、空数据或查询失败时,系统是否明确说明限制。
数据智能体降低的是使用数据的交互成本,而不是数据治理的必要性。连接、语义、权限和审计同时成立,自然语言分析才可能从演示功能变成可靠的日常工具。