
每一家人数超过 30 的公司,都应该有一个内部数据 agent。
今天把这件事做得非常简单:用 Dash(免费、开源),跑在自家云上(私有、安全),再通过 Slack 把访问权限给到团队。
大多数拥抱 AI 的公司,早就做了自己的版本:
-
OpenAI: OpenAI 内部自研数据 agent
-
Vercel: d0,另一篇文章
-
Uber: QueryGPT
-
LinkedIn: SQLBot
-
Salesforce: Horizon Agent
-
DoorDash: 值得一读,但 buzzword 太多
这篇文章会带你搭建一个一流的数据系统,并通过 Slack 提供给团队使用。做得好,Dash 应该能处理大约 80% 的日常数据问题,发送每日报告,并在任何人发问之前就抓到指标异常。
Dash 是什么?
Dash 是一个由 3 个 agent 组成的自学习数据系统。
它使用双层的知识与学习体系,带来非常出色的数据协作体验。可以在 Slack 里和它聊天,也可以用 AgentOS 的 UI。它当然会写 SQL、执行 SQL、解释数字代表什么,但更重要的是,当它犯错或被纠正时,它会从中学习。团队反复问同一个问题时,它会搭建基础设施,让下次回答更快。
这是一个自学习的数据系统,不只是一个数据 agent。
Dash 使用自己的 PostgreSQL 数据库。不会把它直接指向生产数据库。需要逐步把希望它处理的表加载进去,并同时提供让它真正有用的上下文。这一步大多数人会跳过,而这一步也正是它特别的地方。
下面是在 Slack 里的样子:
mgr.create(
name="knowledge-refresh",
cron="0 4 * * *",
endpoint="/knowledge/reload",
payload={},
timezone="UTC",
description="Daily knowledge file re-index",
)
注:这是合成数据。虽然挺疯的,但还没疯到把真实数字发在这里 😂
再看 AgentOS UI:
git clone https://github.com/agno-agi/dash && cd dash
cp example.env .env # Add OPENAI_API_KEY
docker compose up -d --build
docker exec -it dash-api python scripts/generate_data.py
docker exec -it dash-api python scripts/load_knowledge.py
在 AgentOS UI 里,可以和 agents 聊天,查看 sessions、traces、metrics、schedules。它就是那个你以前不知道自己需要的 agent 平台。
它怎么工作
1) 上下文决定一切
大多数数据 agent 只拿到一份 schema dump,然后被要求从只存在于数据工程师脑海里的业务逻辑中写出 SQL。这就是它们不行的原因。列名和类型并不能告诉你数据是什么。它们不会告诉你 ended_at IS NULL 代表订阅仍在生效。不会告诉你年付有 10% 折扣。不会告诉你用量指标每月只抽样 3–5 天,而不是每天都有,所以把它们加总只会得到垃圾结果。
Dash 用的是一套精心策划的知识体系,底层由 PgVector 支撑。它包含:
1a) 表元数据:表结构、列类型、每个字段的含义、每张表适合用来做什么、各种坑(比如日期是某种特定格式)。每张表都会带着用例与数据质量说明。例如:status 只有 active、churned、trial;但真相永远要对 subscriptions 做核对。
1b) 已验证的查询(必备):经过实战检验的 SQL,包含正确的 JOIN、正确的 NULL 处理、正确的边界情况处理。Analyst 收到问题后会先搜索知识库。在写第一行 SQL 之前,它已经知道数据长什么样,也知道哪些陷阱要避开。
1c) 业务规则:MRR 怎么算,NRR 是什么含义,客户为什么会有多条订阅记录(因为升级会关掉旧行并开启新行)。这些上下文,决定了答案是正确的,还是看起来很像但其实错的。
这套知识由用户来策划,但让 Dash 与众不同的是它能自己学会更多东西。
2) 自学习循环
除了知识以外,Dash 还会自动(或通过 agent 调用工具的方式)记录它学到的东西。Analyst 遇到类型错误并修复后,修复会被保存。用户纠正结果时,纠正会被记录。系统发现数据的怪癖时,也会写下来。
下一次任何人问类似问题,Analyst 会在写 SQL 之前先检查 learnings。Dash 用得越多就越强。
3) 三个 agent,两套 schema
Dash 由三个 agent 组成。Leader 负责路由请求并综合答案。Analyst 负责写并运行 SQL。Engineer 负责构建 views、汇总表、计算后的数据。它们协同工作,共享知识与 learnings。
3a) Leader 没有任何 SQL 工具,碰不到数据库。
3b) Analyst 只读。不是因为 prompt 里写了只读,而是因为 PostgreSQL 连接配置了 default_transaction_read_only=on。数据库自己拒绝写入。没有任何 prompt injection 或花式 jailbreak 能改变这点。数据库会拒绝。
3c) Engineer 可以写,但只能写到 dash schema。一个 SQLAlchemy event listener 会在每条 SQL 执行前拦截语句,阻止任何指向 public schema 的操作。公司的数据不会被触碰。
因此会有两套 schema,而且边界是硬的:
-
public schema:公司数据。由你来加载。agents 读取它。
-
dash schema:views、汇总表、计算数据。由 Engineer 拥有并维护。人类不去动它。
*另外还有一个
aischema,Dash 会把 sessions、learnings、knowledge vectors 以及其它运行数据存放在这里。它支撑了 AgentOS UI。
不会直接和它交互,但自我改进循环靠的就是它(Dash 改进自己的代码库)。v3 会讲更多。*
别人都没有的那部分
当 Leader 发现团队总在问同一个昂贵的问题(按套餐的 MRR、按分群的 churn、收入瀑布图),它会让 Engineer 去建一个 view。
Engineer 创建 dash.monthly_mrr_by_plan。这是一张 SQL view,会 join 对的表,处理所有边界情况,输出干净的结果。然后它会做最关键的一步:调用 update_knowledge,把这个 view 记录进知识库。记录它是什么、有哪些列、示例查询。
下次有人再问按套餐的 MRR,Analyst 会搜索知识库,找到这个 view,直接查询它。无需复杂 join。不会把 NULL 处理写错。更快。预先验证过。结果一致。
这些 agents 会在彼此的工作之上继续构建。Engineer 负责搭基础设施。Analyst 发现并使用它。Leader 识别模式并触发循环。久而久之,dash schema 会被 views 和汇总表填满,而这些东西没有任何人手动创建过。它是一层由系统为自己搭起来的分析层,形状由团队真实会问的问题决定。
完整闭环
-
你提一个问题。Leader 分派任务。
-
Analyst 搜索知识库,写出正确 SQL,返回洞见。
-
好的查询会被保存到知识库。错误会变成 learnings。
-
重复模式会变成 views。views 会被记录到知识库。
-
下一次,Analyst 直接用 view。更快、预先验证、一致。
前面提过,Dash 不是一个聊天机器人。它是一套系统,会沉淀关于数据的组织知识,并随着使用不断复利。
自己搭一套
Dash 免费且开源,去 github repo 按 README 跟着做就行,那里有更深入的说明。
快速开始
https://www.linkedin.com/blog/engineering/ai/practical-text-to-sql-for-data-analytics
这会用一个合成数据集(约 900 个客户、6 张表)启动 Dash,并加载知识库(表元数据、已验证查询、业务规则)。
可以在不接任何真实数据的情况下演示整个系统。
连接 Web UI
-
打开 os.agno.com
-
Add OS → Local →
http://localhost:8000 -
Connect
python scripts/load_knowledge.py # Upsert changes
python scripts/load_knowledge.py --recreate # Fresh start
连接 Slack
Dash 生活在 Slack 里。可以私聊它,也可以在频道里 @Dash。每个 thread 对应一个 session,所以每段对话都有自己的上下文。
-
运行 Dash,并给它一个公网 URL(本地用 ngrok,或用你部署后的域名)。
-
按 docs/SLACK_CONNECT 的说明,通过 manifest 创建并安装 Slack app。
-
设置
SLACK_TOKEN和SLACK_SIGNING_SECRET,然后重启 Dash。
https://openai.com/index/inside-our-in-house-data-agent/
添加自己的数据
Dash 跑起来后,要把它变成自己的系统,其实就是用你的数据替换示例数据集,并给 Dash 提供它需要的上下文,就这么简单。
1) 把表加载进 public schema
用你现有的任何 pipeline 都行。pg_dump、Python 脚本、dbt、Airbyte 都可以。无所谓。Dash 从 public 读取,但永远不会写入它。
可以用现有的工作流编排工具(airflow、dagster),也可以用 Dash 自带的 scheduler 来加载数据(后面会讲)。
2) 添加表知识
对每张表,在 knowledge/tables/ 里建一个 JSON 文件:
这是投入产出比最高的一件事。知识越好,Dash 表现越好。
也可以自动生成,但这事改天再说。
3) 添加已验证查询
针对最常见的问题,把能给出正确答案的 SQL 写好,并保存到 knowledge/queries/:
这是最简单的方式,确保 Dash 回答日常问题时使用你们内部的语义。记住,你的工作是给团队提供最好的数据协作体验,这一步让它成为可能。
4) 添加业务规则
在 knowledge/business/ 里记录指标、定义、坑点:
这对 Dash 很有用,但如果工作量太大也可以跳过。
5) 加载知识
都设置好以后,加载知识库,让 Dash 能访问。
https://github.com/agno-agi/agno
定时任务
Dash 自带 scheduler。任何容器能扛得住的任务都能定时跑(比如别在 2gb 的容器上安排 90TB 的 map-reduce)。
开箱即用,dash 预置了 1 个 schedule,会在每天 UTC 早上 4 点重建知识库索引:
https://github.com/agno-agi/dash
用的就是同一种模式,可以用来安排任何任务:
-
每日指标汇总发到 Slack
-
异常检测任务
-
每周邮件 digest
-
自动化数据质量检查
注册一个 schedule,指向一个 endpoint,剩下的 Dash 全包。最好的 agents 会主动出击,而定时任务就是迈向主动性的第一步。
运行 Evals
Dash 内置五类 eval:
-
Accuracy: 数据正确且洞见有意义
-
Routing: 团队请求被路由到正确的 agent
-
Security: 不泄露凭据或密钥
-
Governance: 拒绝破坏性 SQL 操作
-
Boundaries: schema 访问边界被严格遵守
{
"metrics": [
{
"name": "MRR",
"definition": "Sum of active subscriptions excluding trials",
"calculation": "SUM(mrr) FROM subscriptions WHERE status = 'active'"
}
],
"common_gotchas": [
{
"issue": "Active subscription detection",
"solution": "Filter on ended_at IS NULL, not status column"
}
]
}
部署到生产环境
只用一条命令,就能把 Dash 部署到 railway:
Railway 用来起步挺好,但最终还是会希望它部署在你现有的数据基础设施所在的环境里。所有东西都容器化了,部署应该很直接。注意出网成本。
注:生产环境需要从 os.agno.com 获取一个
JWT_VERIFICATION_KEY用于 RBAC。把 dash 暴露在公网 endpoint 上会非常离谱。
更多细节见 README。
接下来是什么
Dash 按系统工程的原则构建,可以在这里读更多:
https://openai.com/index/inside-our-in-house-data-agent/
如果大家感兴趣,后面可能会分别深挖系统的每一层:
-
Agent Engineering: 业务逻辑层。模型、指令、工具、知识,以及自学习循环。
-
Data Engineering: 上下文层。Memory、knowledge、learnings、storage。为什么数据层是整个栈里最被低估投入的一部分。
-
Security Engineering: 认证、RBAC、治理、数据隔离,以及作为核心原语内建的审计链路。
-
Interface Engineering: 把 agent 做成产品。REST APIs、web UIs、Slack、MCP,以及一个 agent 如何服务多个 surface。
-
Infrastructure Engineering: Dash 如何部署与扩展。容器、部署、调度。