从脚本到应用:给 Web 加个安全的问答接口
正要交付给业务方使用时,我们还需要一个 Web 接口,并加上安全认证。这正是 Vanna 中文文档里 web-app-auth 示例所着重强调的。
下面是一个用 Flask 搭建的最小安全接口思路(简化版):
from flask import Flask, request, jsonify
import vanna as vn
app = Flask(name)
vn.set_api_key(‘your-api-key’)
vn.connect_to_sqlite(‘prod.db’)
vn.train(…) # 已训练
简单的 token 认证装饰器
def require_auth(f):
def decorated(*args, **kwargs):
token = request.headers.get(‘Authorization’)
if token != ‘Bearer my-secret-token’:
return jsonify({“error”: “Unauthorized”}), 401
return f(*args, **kwargs)
return decorated
@app.route(‘/ask’, methods=[‘POST’])
@require_auth
def ask():
question = request.json.get(‘question’)
# allow_llm_to_see_data=False 可以先只生成SQL,由你审核后再执行
sql = vn.generate_sql(question)
# 在这里可以加入权限校验:如表白名单、Limit 强制添加等
if not sql.lower().startswith(‘select’):
return jsonify({“error”: “Only SELECT allowed”}), 403
df = vn.run_sql(sql)
return jsonify({“sql”: sql, “data”: df.to_dict()})
几个关键的安全实践:
只给数据库只读账户:Vanna 连接的数据库账号永远不要给 DROP、DELETE 权限。
SQL 白名单校验:在 run_sql 前用正则确保只执行 SELECT 语句,并强制加上 LIMIT 1000。
按用户注入行级过滤:在生成 SQL 后,自动拼接 WHERE tenant_id = ‘当前用户所属租户’,实现数据隔离。
这些手段,在 Vanna 的文档中都有详尽的最佳实践,确保你能把 AI 的能力安全地封装成产品功能,而不是制造一个 SQL 注入的后门。
凭什么不自己从零撸?
你可能会说:“我用 LangChain 的 SQL Agent,或者直接拼 Prompt 调 GPT-4o,也能跑起来呀。” 确实,但 LangChain 的 Agent 更加通用且重,面向 SQL 场景时往往需要你写大量脚手架代码去管理 Schema 上下文、历史缓存、连接池等。而 Vanna 专注一件事:成为连接数据库和 LLM 最高效的那根管道。它用简短的代码量,提供了开箱即用的训练机制、向量记忆和结果缓存,让你能把精力放在理解业务问题本身。
写在最后
Vanna 正在让"自然语言查数据"从一个需要整个团队啃半年的项目,变成一名后端工程师一个下午就能集成完的特性。它把最复杂的语义理解、SQL 生成、上下文检索打包成了一个优雅的 Python 库,同时又把模型和存储的掌控权完整地交到了你手上。
下次产品经理再拍出那个"搜索框"需求时,你可以云淡风轻地回一句:“好啊,下班前给你 demo。”
