AI 助手直连数据库与通过 MCP 协议代理连接的安全边界、权限控制和故障半径存在本质差异,文中给出具体场景的选择建议。
迟早,团队里会有人想把 AI 助手指向生产数据库。也许是一位支持工程师,想在不用写 SQL 的前提下回答"为什么这个客户的发票卡住了?";也许是你自己,想让 Claude 或 Cursor 帮忙起草一条针对真实表的多表关联查询,而不是靠猜测列名。
一旦你决定这么做,就面临一个分岔口。你可以直接给 AI 工具一条数据库连接——把连接字符串交给它,让它直连 Postgres 或 MySQL;也可以在中间放一个代理,用类似 Model Context Protocol(MCP)这样的协议来协调,让 AI 永远不接触你的凭据,只看到你允许它看到的内容。
两种方式都能用。从开发者的视角看体验相似——你输入一个问题,SQL 就回来了。但底层的安全、影响范围和工作流方面的权衡截然不同。下面来做具体对比,帮你主动选择,而不是稀里糊涂地默认。
两种架构并列
直连正是字面意思。AI 工具(或你写的 agent)持有一条连接字符串,比如:
postgresql://app_user:s3cr3t@db.internal:5432/production
它打开一个到数据库的 socket,运行模型生成的任意 SQL。简单、快速,但危险之处在第一天并不明显。
代理连接则在中间放一台服务器。AI 客户端通过标准协议与代理通信;代理持有真实的数据库凭据,并决定如何处理每个请求。AI 从来看不到 s3cr3t。MCP 就是这种模式的新兴开放标准——主机扮演安全代理的角色,调停每一次 AI 对资源的交互,它通常用 OAuth 而非静态密钥来做认证。
这就是两者差异的轮廓:
最大的差异在于谁知道了密码。
直连模式下,连接字符串最终落在配置文件、环境变量、聊天记录里——如果运气不好,还会粘贴到提示词窗口,存到别人的服务器上。连接字符串出了名地难以保密:它们被硬编码、被提交、被从编译后的二进制文件中反汇编出来、被泄漏到客户端代码里。一旦泄漏,攻击者就获得了对你数据的特权无认证访问,而轮换密钥意味着追查每一个复制过它的地方。
代理模式把这一点翻转了过来。AI 工具用 token 向代理认证;代理把真实凭据放在一个受控的地方。如果笔记本被入侵或员工离职,你只需撤销一个 token,而不用到处轮换数据库密码。这和把 API 放在数据库前面、不让每个客户端直连的道理一样——高价值凭据存在于你管理的受控环境中,而不是分布在每台用户机器上。
有一点值得指出:聚合访问的代理本身成了高价值目标。一旦被攻破,它能暴露其背后的一切。这就是为什么代理会大力采用最小权限角色、短生命周期 token 和审计日志——缓解措施和模式本身一样重要。
LLM 会产生幻觉。当最坏情况不过是一条返回空结果的 SELECT 时,这还可以容忍。但当模型自信满满地生成这样的 SQL 时,情况就完全不同了:
-- The model "cleaning up test data"
DELETE FROM users WHERE created_at < '2020-01-01';
直连模式下,如果用的是读写角色,这条查询就会执行。而在只读的代理下,这条查询在到达数据库之前就会被拒绝,因为写操作和 DDL 根本不在允许的操作集合里。
直连也能获得只读安全——通过创建一个专用角色并谨慎授权:
-- Direct-connection approach: a read-only role you must maintain yourself
CREATE ROLE ai_readonly LOGIN PASSWORD 'another-secret';
GRANT CONNECT ON DATABASE production TO ai_readonly;
GRANT USAGE ON SCHEMA public TO ai_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;
-- ...and remember to re-grant for every new table, forever
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ai_readonly;
这是正确的思路。但注意,现在维护这个角色随着 schema 演化保持正确、管理又一个密钥、以及确保没人不小心把读写角色交给 AI,这些都是你的责任。只读即设计的代理把这种保证变成了结构性的,而不是需要你记住的事情。
撇开安全不谈,两种设置的使用体验不同。
AI 生成 SQL 最常见的失败模式是凭空捏造表名和列名。解决办法是给模型真实的 schema。直连也可以做到——AI 可以 introspection information_schema,如果它的角色有权限的话:
SELECT table_name, column_name, data_type
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position;
代理通常会把这些作为一等公民的能力暴露出来:"获取 schema"是一条专用命令,这样模型在写 SQL 之前就能拿到准确的表名和列名,减少捏造列名的情况。无论哪种方式,经验教训都是一样的——分享 schema,不分享凭据——但代理把这一点变成了默认路径。
从用户视角看,典型的代理化循环是这样的:
You: "How many active subscriptions did we add last month, by plan?"
AI (via broker):
1. fetch schema -> sees subscriptions(plan, status, created_at)
2. draft SQL:
SELECT plan, COUNT(*) AS new_subs
FROM subscriptions
WHERE status = 'active'
AND created_at >= date_trunc('month', now()) - interval '1 month'
AND created_at < date_trunc('month', now())
GROUP BY plan
ORDER BY new_subs DESC;
3. run (read-only) -> returns rows
4. optionally save the query or drop it on a dashboard
最后一步暗示了另一个工作流优势:为分析而建的代理通常允许你保存一条查询或把它钉到仪表板上,这样一次性的问题就变成了可复用的报表。托管型 MCP 服务器如 Draxlr 实现了这种形态——只读、OAuth、schema 感知,有命令可以运行、保存和图表化查询——但模式本身才是重要的,你也可以用开源组件自行组装。
直连保持轻量:没有额外服务、没有 OAuth 握手,就是一条字符串和一个 socket。对于本地开发数据库上的一次性脚本,这种简单性是恰当的选择。
无论选哪条路,有几个坑都会让人栽跟头:
复用你应用的数据库用户给 AI 用。 那个角色通常有写权限和宽泛的授权。创建一个独立的、最小权限的角色——或者让代理替你强制只读。
以为只读就等于安全。 只读角色仍然可以运行一条扫描十亿行数据并把 CPU 打满的 SELECT,或者读取不该读的 PII。将授权范围限制到特定 schema,并考虑为查询设置超时。
把数据库暴露到整个网络。 直连的情况下,每个查询的客户端都需要有到数据库的网络路径。代理把这一条缩小到一台主机,让数据库离开开放网络。
把连接字符串粘贴到提示词里。 如果工具把上下文发送给模型提供商,你的凭据可能被记录下来。这是代理本来要防止的失败——不要亲手把它重新制造出来。
没有审计日志。 分散的直连通常让你无法回答"谁在什么时候问了 AI 什么?"在代理上集中记录日志可以让你有一个统一的查看位置。
直连在简单性上胜出:最小化配置、没有运动部件、非常适合本地实验和一次性脚本。代价是凭据四处散布、AI 可以运行其角色允许的任何操作、以及你的数据库更接近开放网络。
代理 / MCP 风格连接在安全性和治理上胜出:凭据集中管理、访问通过设计只读且可凭单个 token 撤销、schema 在不暴露密钥的前提下共享、每条查询都可审计。代价是需要搭建或接入一个代理,外加保护这个高价值目标的责任。
粗略的经验法则:对于存放任何真实数据的数据库——客户、财务、PII——或者任何超过一个人接触的环境,在中间放一个代理。对于你乐意扔掉重建的本地沙箱,直连没问题。错误不在于选了这一种或那一种,而在于默认选择而没有意识到这里存在一个选择。
你目前是怎样把 AI 工具连接到数据库的——直接连接字符串、自定义 API 层、还是 MCP 服务器?很期待在评论区听到什么做法有效、什么做法坑过你。
Sources: Anthropic — Introducing MCP, Model Context Protocol — Architecture, SentinelOne — MCP Security Guide, Microsoft — Protecting connection information, Microsoft Security — Least privilege for AI agents, datamcp — PostgreSQL permissions for AI tools.