
聊《我用数据分析经验做了次 AI 项目最先失效的是旧方法》之前先说一句实在的别急着背概念先看它在真实项目里到底解决什么问题。摘要先把这篇文章的目标说清楚看完之后你应该能判断这件事值不值得做以及从哪里动手。上周做需求评审产品经理提了一个很典型的场景“老板想看销售漏斗以前我要写 SQL 跑三天现在想用自然语言直接出图最好还能自动下钻。”我点头说是但在心里打了个问号。因为我知道一旦这个需求从 Jupyter Notebook 里的 Demo 变成公司内网的生产服务最大的坑根本不是模型答不对题而是谁有资格看什么数据。做数据分析出身的朋友转型做大模型应用特别是 Analytics Agent时最容易陷入一种误区认为只要 Prompt 写得够好模型就能像资深分析师一样思考。但实际上Demo 阶段的“万能钥匙”在生产环境就是“安全漏洞”。今天不聊虚的就聊聊我是怎么从一个只会写 SQL 的数据分析师一步步把“智能分析 Agent”从玩具变成能扛住高并发、高安全要求的产品的以及在这个过程中我们被迫放弃的那些“聪明”想法。目录从“自由联想”到“严格边界”的阵痛指标解释 Agent让模型懂业务而不是懂 SQL数据工具调用从“直接连库”到“沙箱隔离”项目案例一个“失败”的优化总结从“炫技”回归“工程”从“自由联想”到“严格边界”的阵痛记得刚接触 LLM 时为了追求“智能”我给 Agent 赋予了极大的自由度。Prompt 里写着“你可以访问数据库自由查询任何表如果发现数据异常尝试自行修正并给出建议。”这在本地跑test.py时效果惊艳模型能自主发现某字段为空然后尝试用均值填充最后画出一张漂亮的折线图。直到有一次测试同事随手问了一句“帮我查一下上个月所有用户的身份证号后四位。”模型愣了一下反问“请问您有管理员权限吗”那一刻我背脊发凉。虽然它拒绝了但如果我把它部署在内网并且没有做好严格的 RBAC基于角色的访问控制 隔离后果不堪设想。这就是传统 BI 和大模型应用的第一次剧烈碰撞传统 BI权限在数据源层解决SQL 执行前就过滤了。传统 LLM 应用权限往往在 Prompt 层“祈求”而大模型并不理解什么是“敏感”它只理解“概率”。我的取舍我砍掉了“自由查询任意表”的功能。现在的 Agent入口不再是“你想问什么”而是“你被允许看什么”。指标解释 Agent让模型懂业务而不是懂 SQL很多同行一上来就搞 Text-to-SQL这其实是把活儿干反了。对于复杂的业务分析直接生成 SQL 容易出错尤其是涉及到多表 JOIN 和业务口径定义时。我的做法是引入一层“指标解释 Agent”。这一步的核心价值在于标准化。我们在知识库Knowledge Base里不只存表结构而是存“业务定义”。比如“GMV”在我们的系统里定义为“支付成功金额”不包含退款且时间截断点为“用户点击支付按钮的时间”而非“银行扣款时间”。这些信息模型在生成 SQL 之前必须先进行检索和确认。这里有一个具体的代码片段展示我们是如何通过 LangChain 的 Tool 调用机制强制模型先确认业务口径再执行查询的from langchain.tools import tool tool def verify_metric_definition(metric_name: str) - str: 验证指标的业务定义。 在生成任何查询之前必须先调用此工具获取该指标的标准口径。 返回值为该指标的计算公式、关联表及时间窗口定义。 # 模拟从向量数据库中检索业务元数据 db_lookup { GMV: 计算逻辑sum(order_amount)时间窗created_at now() - 1 month状态paid_only, DAU: 计算逻辑count(distinct user_id)时间窗login_time去重策略当日首次登录 } return db_lookup.get(metric_name, f未找到指标 {metric_name} 的定义请联系数据负责人。) # 在 Agent 的工作流中verify_metric_definition 被置于首位 # 如果用户问上个月GMV多少Agent 首先调用 verify_metric_definition(GMV) # 只有拿到“paid_only”和“created_at”这些关键字段才会进入下一步 SQL 生成这种做法看似增加了步骤降低了响应速度但它极大地减少了“幻觉式回答”。对于企业级应用来说准确性 响应速度 灵活性。数据工具调用从“直接连库”到“沙箱隔离”传统的 Text-to-SQL 是直接让模型连接数据库。在生产环境中这是绝对禁止的。我们采用的架构是LLM - SQL 生成器 - SQL 校验器 - 只读副本查询 - 结果格式化。其中“SQL 校验器”是关键。它不仅仅检查语法还要检查语义。比如模型生成了DELETE FROM users校验器会直接拦截并报错如果模型生成了SELECT * FROM sensitive_table校验器会根据当前用户的 Token 权限进行二次过滤。我还做了一个决定不使用通用的大模型直连数据库而是封装了一套数据查询 API。import requests def safe_query_executor(user_token, query_params): 安全查询执行器 1. 验证 User Token 对应的权限范围 2. 将 query_params 转换为预编译 SQL 参数 3. 返回脱敏后的 JSON 数据 # 假设 user_permissions 是从中间件获取的用户角色数据 permissions get_user_permissions(user_token) # 强制注入权限过滤条件防止模型越权 final_query inject_permission_filter(query_params, permissions) try: response requests.post(API_ENDPOINT, json{sql: final_query}) if response.status_code 200: return format_data(response.json(), permissions[mask_level]) else: raise Exception(fQuery failed: {response.text}) except Exception as e: log_error(e, user_token) return {error: 查询失败请稍后重试}这种架构下模型甚至不知道数据库的具体表名它只知道“我有权限查哪些维度的数据”。这不仅解决了安全问题还实现了多租户隔离。项目案例一个“失败”的优化上个季度我们试图优化一个“异常检测”功能。业务方希望 Agent 能自动发现销售额骤降的原因并给出归因建议。Demo 阶段模型表现得像个天才分析师它会说“销售额下降可能是因为竞品降价或者是物流延迟。”——这都是废话因为模型根本不知道内部数据。后来我们调整了方向不做“原因推测”只做“数据切片”。Agent 不再主动给出因果结论而是根据用户的问题自动生成一系列对比查询。例如当用户问“为什么昨天销量跌了”Agent 不会瞎猜而是返回一组结构化数据1. 昨日 vs 前日 GMV 对比。2. 各渠道昨日转化率对比。3. 各区域昨日订单量分布。然后它会给用户三个选项“请查看渠道 A 的详细数据”、“请查看区域 B 的库存情况”、“请导出完整日报”。这个改动看起来“智能”程度下降了但可用性提升了三倍。因为在前端界面用户需要的是可操作的洞察而不是模型一本正经地胡说八道。这也符合我们现在的验收标准Agent 的输出必须是可验证的、可追溯的而不是不可控的文本生成。总结从“炫技”回归“工程”从数据分析转到 LLM 应用开发最大的心路历程不是学会写 Prompt而是学会克制。1. 克制模型的自由用权限控制和元数据管理替代“信任”。2. 克制业务的期望不要指望 Agent 成为全知全能的分析师让它成为最高效的“数据快递员”和“查询助手”。3. 克制技术的炫技Log 追踪、Trace 可视化、SQL 审计这些枯燥的工程化细节比花哨的 RAG 演示更能决定项目的生死。如果你正准备转型或者正在搭建自己的 AI 数据产品请记住在生产环境一个能稳定执行 90% 正确查询的 Agent远胜过那个能回答 100% 问题但经常出错且无法追溯的“聪明”模型。技术没有银弹只有取舍。而在大模型时代最大的取舍往往是把“智能”交给人类判断把“效率”交给机器执行。资料展示下面是我整理的AI大模型学习资料和工具包预览适合收藏后按主题逐步学习。如果你想看完整资料目录可以在评论区留言「资料」也欢迎告诉我你更关注AI大模型里的哪类内容。