在企业内网复制一个数据分析 Agent:从上下文层到离线评估
本文整理自 GitHub Blog《How we built an internal data analytics agent》。原文讲的是 GitHub 内部的 Qubot:员工可以在 Slack、VS Code 或 Copilot CLI 中用自然语言查询数据仓库。本文改写为企业内网可复制的实施教程。
>
Source URL: https://github.blog/ai-and-ml/github-copilot/how-we-built-an-internal-data-analytics-agent/
适用场景
这套方法适合已经有数据仓库、BI/数据团队、内部协作工具,并且希望降低业务团队“问数”门槛的企业。
优先适用:
- 产品、运营、业务团队经常问“哪个用户群体留存更高”“上周哪个产品拉动了指标”。
- 数据团队被大量重复性查询打断,复杂分析反而排不上队。
- 数据仓库里有大量可用数据,但业务口径、表粒度、过滤条件分散在文档和人员经验里。
- 企业已有内网 IM、代码平台、文档仓库、权限系统和数据查询引擎。
不建议一开始就做成“全自动决策系统”。更稳妥的目标是:先做一个内部探索式数据助手,帮助员工更快找到表、生成查询、解释结果,并保留人工复核边界。
最小可复制架构
把系统拆成三层:
- 用户入口:内网 IM、IDE 插件、CLI 或企业门户。
- 上下文层:指标定义、表说明、业务口径、数据血缘、常见过滤条件。
- 查询引擎层:连接数据仓库或查询服务,执行 SQL/KQL 等查询。
推荐先画出这样的边界:
员工问题
↓
内网入口(IM / IDE / CLI / 企业门户)
↓
Agent 编排层
├─ 读取上下文层:指标、表、口径、权限、示例查询
├─ 选择查询引擎:近期事件 / 历史分析 / 复杂 Join
├─ 生成并执行查询
└─ 生成 Markdown 分析报告
↓
结果返回:会话回复 + 可追溯报告链接企业内网复制时,先不要追求多入口。建议从 IM 群聊入口 + Markdown 报告归档 开始,因为它最容易形成团队协作和复核记录。
第 1 步:先定义 Agent 不做什么
这是最容易被忽略的一步。原文明确说 Qubot 不是报表工具或仪表盘替代品,而是用于探索性问题。
企业内网版本也应先写清边界:
# 数据分析 Agent 使用边界
## 适合的问题
- 这个指标最近一周为什么波动?
- 哪个用户 cohort 的留存更高?
- 某个功能上线后相关行为有没有变化?
- 我应该查哪张表、用哪个口径?
## 不适合的问题
- 需要正式财务披露或审计口径的问题
- 会直接触发业务动作的问题
- 涉及敏感个人数据但用户无权限的问题
- 跨多个系统且没有明确定义口径的问题
## 输出要求
- 必须展示使用的数据集、时间窗口、过滤条件
- 必须提供生成的查询语句或报告链接
- 对低置信度答案必须标注“需要数据分析师复核”验收标准:业务用户知道它适合“探索”,数据团队知道哪些问题必须人工接管。
第 2 步:整理数据分层,而不是让 Agent 猜表
GitHub 文中把数据仓库分为三类:
- bronze:原始事件数据;
- silver:标准化事实表和维度表;
- gold:面向具体业务场景的精选数据集。
企业可以用自己的命名,但要保留这三类含义。
可复制模板:
# 数据集分层说明
## 原始层
- 用途:事件回放、低层排查、近期行为探索
- 风险:字段含义可能不稳定,业务用户不应直接使用
- Agent 策略:仅在问题需要近期事件明细时使用
## 标准层
- 用途:稳定事实表、维度表、常规分析
- 风险:需要理解粒度、主键、时间字段
- Agent 策略:默认优先使用
## 业务层
- 用途:核心业务指标、管理看板、对外口径
- 风险:口径变更需要审批
- Agent 策略:涉及正式指标时优先使用,并展示口径说明落地建议:先覆盖 5–10 个最高频数据集,不要一开始接入全仓库。
第 3 步:建立上下文层,把文档变成一等资产
原文最重要的经验是:结构化、维护良好的上下文会显著提升 Agent 的准确性和响应速度。GitHub 称实验中获取正确答案的速度提升了 3 倍,但这个数字只代表其内部环境,不应直接当作通用承诺。
企业内网可先用 Markdown 管理上下文,因为它容易进入代码评审、版本管理和变更审计。
数据集上下文模板
# 数据集:product_feature_events
## 业务含义
记录用户在产品功能中的关键行为事件,用于分析功能使用、转化和留存。
## 推荐使用场景
- 分析某功能上线后的使用趋势
- 按用户 cohort 比较留存
- 排查某个事件是否采集异常
## 不推荐使用场景
- 财务收入分析
- 正式月度经营报表
- 需要跨产品线统一口径的指标
## 粒度
一行代表一次用户行为事件。
## 关键字段
- user_id:用户 ID;需要遵守权限策略
- event_name:事件名称
- event_time:事件发生时间,UTC
- feature_name:功能名称
- plan_type:用户套餐类型
## 常用过滤条件
- 排除内部测试账号
- event_time 使用业务分析窗口
- feature_name 必须匹配标准枚举
## 示例问题
- 最近 7 天哪个套餐用户使用 feature_x 最多?
- feature_x 上线后,新用户 7 日留存是否变化?
## 示例查询SELECT plan_type, COUNT(DISTINCT user_id) AS users FROM product_feature_events WHERE event_name = 'feature_used' AND feature_name = 'feature_x' AND event_time >= CURRENT_DATE - INTERVAL '7' DAY GROUP BY plan_type ORDER BY users DESC;
## 负责人
数据 Owner:数据平台组
业务 Owner:产品分析组注意:模板里的 SQL 是示例,不是原文提供的代码。正式落地时应替换成企业自己的表名、字段和权限规则。
第 4 步:设计上下文贡献流程
GitHub 的做法是让团队通过标准模板或关联文档仓库贡献上下文,并由 Context Agent 进行整理和规范化。
企业可复制成一条 PR 流程:
业务/数据团队提交上下文 PR
↓
自动检查模板字段是否完整
↓
Context Agent 规范化:字段、口径、示例问题、示例查询
↓
离线评估:准确率、延迟、回归
↓
数据 Owner 审核
↓
合并进入上下文层建议的 PR 检查清单:
# 上下文贡献 PR 检查
- [ ] 数据集业务含义已写清
- [ ] 粒度、主键、时间字段已写清
- [ ] 常用过滤条件已写清
- [ ] 至少包含 2 个示例问题
- [ ] 至少包含 1 个示例查询
- [ ] 标明数据 Owner 和业务 Owner
- [ ] 涉及敏感字段时写明权限限制
- [ ] 已通过离线评估集验收标准:上下文更新不靠私聊和口头经验,而是可以审查、回滚、比较。
第 5 步:连接查询引擎,并显式写出路由规则
原文中 Qubot 连接 Kusto 和 Trino:Kusto 更适合近期事件探索,Trino 更适合复杂 Join 和历史分析。企业内网可以替换成自己的查询系统,例如 ClickHouse、Trino、Presto、Hive、Doris、DuckDB、PostgreSQL 或内部查询服务。
关键不是具体用哪个引擎,而是让 Agent 知道何时选择哪个引擎。
query_engines:
fast_event_engine:
suitable_for:
- 最近事件探索
- 简单聚合
- 低延迟互动查询
avoid_for:
- 复杂跨域 Join
- 长历史窗口
- 正式经营口径
warehouse_engine:
suitable_for:
- 多表 Join
- 历史趋势分析
- 业务层 gold 数据集
avoid_for:
- 秒级互动探索
- 未建模的原始事件排查最低要求:每次回答都展示使用了哪个引擎、为什么使用它、查询语句是什么。
第 6 步:先做报告归档,再做漂亮界面
GitHub 的 Slack 入口会把结果保存成 Markdown 报告,用户可以引用它微调查询或放入 dashboard。
企业内网也建议先保存报告,原因很简单:可追溯比界面好看更重要。
报告模板:
# 数据分析 Agent 报告
## 用户问题
{原始问题}
## 问题解释
{Agent 对问题的理解}
## 使用数据
- 数据集:{dataset}
- 数据层级:{bronze/silver/gold 或企业等价分层}
- 查询引擎:{engine}
- 时间窗口:{time_window}
- 过滤条件:{filters}
## 查询语句{sql}
## 结果摘要
{核心结果,避免过度解释}
## 置信度
- 高:上下文明确,字段和口径稳定
- 中:存在轻微口径歧义,但不影响方向判断
- 低:需要数据分析师复核
## 后续建议
{可选:下一步追问或人工复核建议}验收标准:任何重要回答都能回到报告,看到原始问题、查询、口径和结果。
第 7 步:用离线评估保护上下文层
原文中,每次上下文层或 Agent 配置变更都会进入离线评估,评估准确率、找到正确答案的延迟,并捕捉回归。
企业复制时,不需要一开始做复杂评测平台。先维护一个黄金测试集即可。
评估集模板
{
"id": "retention_feature_x_by_plan",
"question": "feature_x 上线后,不同套餐用户的 7 日留存有什么变化?",
"expected_datasets": ["product_feature_events", "user_retention_daily"],
"expected_filters": ["exclude_internal_users", "feature_name = feature_x"],
"expected_time_window": "launch_date +/- 28 days",
"expected_output_contains": ["plan_type", "7_day_retention", "pre_launch", "post_launch"],
"manual_review_required": true
}评估流程
准备 20–50 个高频问题
↓
每个问题运行 Agent N 次
↓
记录使用的数据集、查询引擎、SQL、结果摘要、耗时
↓
与期望数据集、过滤条件、输出字段比较
↓
生成评估报告
↓
阻止明显回归的上下文/配置变更合并建议指标:
- 数据集选择正确率;
- 必要过滤条件覆盖率;
- 查询可执行率;
- 平均响应时间;
- 低置信度标注召回率;
- 与上一版本相比是否回归。
验收标准:上下文变更前后能比较,而不是靠“感觉更聪明”。
第 8 步:权限和安全边界必须前置
原文没有展开权限实现细节,因此这一节是企业落地时的必要补充,不应理解为 GitHub 原文已给出的完整方案。
最小安全要求:
- Agent 只能使用调用者已有的数据权限;
- 敏感字段默认不可直接返回明细;
- 对包含个人信息、财务、合同、客户敏感数据的问题强制人工复核;
- 查询语句、调用人、数据集、时间窗口必须记录审计日志;
- 禁止 Agent 绕过数据平台直接访问生产库。
权限检查清单:
# 数据分析 Agent 安全检查
- [ ] 调用身份来自企业 SSO
- [ ] 数据权限按用户身份下推,而不是使用共享超级账号
- [ ] 敏感字段有脱敏或聚合规则
- [ ] 查询结果有行数和成本限制
- [ ] 所有查询有审计日志
- [ ] 高风险问题进入人工复核队列第 9 步:分阶段上线
不要一次性把全公司数据仓库暴露给 Agent。推荐四阶段:
阶段 1:只读 PoC
范围:1 个业务域、5 个数据集、20 个评估问题。 目标:验证上下文层是否能让 Agent 稳定选对表、生成可执行查询。
通过标准:
- 高频问题中大部分能选对数据集;
- 查询失败原因可归类;
- 所有回答都有报告和审计记录。
阶段 2:内测群
范围:数据团队 + 1–2 个业务团队。 目标:验证真实追问、报告归档、人工复核流程。
通过标准:
- 业务用户能独立完成探索性问数;
- 数据团队重复性问答减少;
- 高风险问题没有绕过人工复核。
阶段 3:上下文贡献开放
范围:允许各团队提交上下文 PR。 目标:让领域知识进入统一上下文层,而不是散落在个人文档里。
通过标准:
- PR 模板完整;
- 每次上下文更新都跑离线评估;
- 回归能阻止合并。
阶段 4:多入口扩展
范围:从 IM 扩展到 IDE、CLI、企业门户。 目标:让不同角色在自己的工作流中使用同一个能力。
通过标准:
- 多入口共享同一上下文层;
- 权限策略一致;
- 报告归档和审计日志一致。
常见失败模式
失败 1:只接模型,不建上下文层
表现:Agent 会写 SQL,但经常选错表、错口径、漏过滤条件。 处理:暂停扩入口,先补数据集上下文和黄金测试集。
失败 2:上下文谁都能改,但没有评估
表现:一次“补文档”让原本稳定的问题开始退化。 处理:所有上下文 PR 必须跑离线评估;失败不能合并。
失败 3:把探索性助手当正式报表
表现:业务直接拿 Agent 输出做正式汇报或决策。 处理:区分探索问题和正式指标;正式指标必须链接到 gold 数据集和人工审批口径。
失败 4:权限用共享账号绕过
表现:Agent 看得到用户本来不该看的数据。 处理:权限按调用者身份下推;共享账号只能用于无敏感的系统元数据,不得用于业务数据查询。
失败 5:只看准确率,不看延迟和可解释性
表现:答案偶尔对,但用户等太久,或者无法复核查询过程。 处理:评估报告必须包含延迟、查询语句、数据集选择和失败原因。
企业内网落地清单
# 企业内网数据分析 Agent 落地清单
## 范围
- [ ] 明确首个业务域
- [ ] 选定 5–10 个高频数据集
- [ ] 明确不支持的问题类型
## 上下文层
- [ ] 每个数据集有 Markdown 上下文
- [ ] 有负责人、粒度、关键字段、过滤条件、示例查询
- [ ] 上下文通过 PR 管理
## 查询层
- [ ] 查询引擎路由规则已写清
- [ ] 每次回答展示数据集、引擎、时间窗口、过滤条件
- [ ] 查询有超时、成本和行数限制
## 评估
- [ ] 至少 20 个黄金问题
- [ ] 每次上下文/配置变更自动评估
- [ ] 评估包含准确率、延迟、回归
## 安全
- [ ] 使用企业身份认证
- [ ] 权限按调用者下推
- [ ] 敏感字段有脱敏/聚合限制
- [ ] 所有查询有审计日志
## 运营
- [ ] 有人工复核入口
- [ ] 有失败样例收集机制
- [ ] 有上下文贡献指南
- [ ] 有版本回滚方案最小成功标准
第一版不要用“像不像人”衡量,而用这 6 个标准:
- 用户能在内网入口提出自然语言问题。
- Agent 能说明自己使用了哪个数据集、哪个查询引擎、哪个时间窗口。
- Agent 能生成可复核的查询语句和 Markdown 报告。
- 高频问题有黄金评估集。
- 上下文更新会触发离线评估。
- 权限、审计、人工复核边界清楚。
如果这 6 条没满足,多接几个模型或入口意义不大。GitHub Qubot 的可迁移价值,不在于某个具体工具,而在于把分散的数据知识、自然语言入口和评估回归流程合成了一个可治理的内部系统。