企业 AI 治理最容易出问题的地方,往往不是模型团队写错了提示词,也不是合规团队没有流程,而是数据层和模型层之间的假设没人验证。数据工程、AI、平台、合规四个团队都在认真做事,但客户数据可能已经被复制到三套环境里:字段定义略有不同,访问控制略有不同,刷新频率也不同。模型层说“只给授权用户看”,数据层反问:“哪一份数据?按哪套权限?什么时候刷新?”
这正是 C.A.L.M. Platform Test 要解决的问题。它不是问 PostgreSQL 能不能跑 AI workload,而是问:当 AI 项目扩大时,这个平台还能不能保持可治理、可证明、可观测。
C.A.L.M. 看的是平台成熟度,不是功能清单
C.A.L.M. 分成四个问题:
- C - Changeability:平台能否在新增数据源、检索模式、合规要求时演进,而不是每次都制造一份新的影子数据?
- A - Assurance:平台能否证明 AI 使用的数据来自哪里、由谁治理、按什么权限访问?
- L - Leverage:平台是在减少系统、管道、权限模型的数量,还是把复杂度搬到另一个地方?
- M - Measurability:平台能否在数据漂移、权限绕行、查询异常变成事故之前发现信号?
这四个问题放在一起,核心判断很直接:AI 治理不能只停在模型层。模型层的控制只有在底层数据被一致治理时才成立。
Changeability:不要让每次 AI 需求都变成新副本
AI 项目变化很快:新的 agent、新的 embedding 策略、新的 RAG 检索路径、新的审计要求。假如每次变化都要复制一份数据、单独写一条 pipeline、申请一组例外权限,平台会越来越脆。
PostgreSQL 的逻辑复制可以作为一种实践方式:从核心业务库发布受控数据集,在 AI 平台侧订阅并构建 AI-ready 数据层。这样可以不修改源应用 schema,同时保留明确的复制边界和 lineage。
下面是一个可改造的最小示例。运行前需要确认源库和目标库都已启用 logical replication,并把连接串、表名、角色替换成你的环境值。
-- 源库:发布 AI 数据层需要的表
CREATE PUBLICATION ai_data_layer
FOR TABLE customers, transactions, policies
WITH (publish = 'insert, update, delete');
-- 目标库:订阅源库发布的数据
CREATE SUBSCRIPTION ai_platform_sub
CONNECTION 'host=source_db port=5432 dbname=core_app user=replicator password=change_me'
PUBLICATION ai_data_layer;
这个模式的治理价值不来自“复制”本身,而来自复制被设计成受控路径:发布范围清楚、负责人清楚、延迟可监控、访问策略在目标侧重新声明。
有一个边界必须说清楚:PostgreSQL 逻辑复制复制的是数据变更,不会自动复制 RLS 策略、索引、grant 或完整治理语义。订阅端必须独立建立权限、索引、审计和监控。否则它仍然可能变成另一份没人真正负责的副本。
Assurance:访问控制应该落在行级,而不是应用层口头约定
AI grounding 的访问决策通常不是“能不能看这张表”,而是“这个身份能不能看这个客户、这个账户、这份保单”。这类控制天然应该落在行级。
PostgreSQL Row Level Security(RLS)适合承担这件事。策略定义在表上后,不管请求来自应用、agent、pipeline,数据库都会按同一套规则筛选行。
可以这样实践租户隔离:
-- 假设 customers 表里有 tenant_id 字段
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;
CREATE ROLE ai_agent_role;
CREATE POLICY ai_agent_tenant_isolation
ON customers
FOR SELECT
TO ai_agent_role
USING (tenant_id = current_setting('app.current_tenant')::uuid);
-- 应用或 agent 每次连接后设置当前租户上下文
SET app.current_tenant = '00000000-0000-0000-0000-000000000001';
SELECT id, name, tenant_id
FROM customers;
这里的关键点不是 SQL 多漂亮,而是控制点不再散落在多个应用里。数据库本身知道当前请求属于哪个 tenant,并且只返回允许访问的行。
但 RLS 也有容易踩的坑:表 owner 和带有 BYPASSRLS 的角色默认可以绕过 RLS。高风险场景下,应避免 AI agent 角色继承 owner、superuser 或 BYPASSRLS 权限;必要时对表启用强制 RLS:
ALTER TABLE customers FORCE ROW LEVEL SECURITY;
审计也是 Assurance 的一部分。数据 trace 和 AI trace 不是一回事:
- 数据 trace 回答:用了哪份数据、谁拥有、谁治理、当时是否有效、按什么权限访问。
- AI trace 回答:模型看了哪些证据、拒绝了哪些证据、如何生成最终输出或动作。
PostgreSQL 的 RLS、pgAudit、查询日志能解决数据 trace 的一大部分问题;模型推理链路仍需要独立的 AI observability 工具。把两者混在一起,会制造一种“看起来可审计”的错觉。
Leverage:pgvector 的价值在于让语义数据继承治理
很多 AI 平台失控,是因为结构化数据在一个系统里,embedding 在另一个系统里,权限模型又在第三个系统里。同步一旦出错,RAG 检索可能拿到用户本不该看到的语义片段。
PostgreSQL 加 pgvector 的一个实用价值,是把向量和受治理的业务上下文放在同一个治理边界内。embedding 不再是孤立资产,而是可以通过外键、RLS、审计和 SQL 查询与客户、账户、租户关系绑定。
以下示例假设已经安装 pgvector,并且 customers 表上的 RLS 已经生效。你可以把维度 1536 改成自己 embedding 模型的维度。
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE customer_context (
id bigserial PRIMARY KEY,
customer_id uuid NOT NULL REFERENCES customers(id),
content text NOT NULL,
embedding vector(1536) NOT NULL
);
ALTER TABLE customer_context ENABLE ROW LEVEL SECURITY;
CREATE POLICY customer_context_isolation
ON customer_context
FOR SELECT
TO ai_agent_role
USING (
customer_id IN (
SELECT id FROM customers
)
);
-- 示例检索:只会在 RLS 允许的 customer_context 行中做相似度排序
SELECT customer_id, content
FROM customer_context
ORDER BY embedding <-> '[0.01,0.02,0.03]'::vector
LIMIT 5;
这个例子里的向量值只是占位,实际运行时需要提供与你的维度一致的数组。生产环境还需要向量索引、刷新策略、embedding 版本记录和删除传播机制。
这并不意味着所有 AI workload 都应该塞进 PostgreSQL。湖仓、流处理、专用向量库、模型平台都有各自位置。Leverage 问的不是“能不能统一到一个数据库”,而是“这个架构有没有减少治理面、权限模型和数据 lineage 的数量”。
Measurability:看 agent 实际跑了什么 SQL
AI 编排框架说 agent 应该做什么,和数据库实际收到什么 SQL,不一定完全一致。治理要看后者。
pg_stat_statements 可以帮助平台团队观察查询模式、调用次数、平均耗时、扫描行数等信号,用来发现异常访问、低效检索或绕过既定路径的查询。
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
SELECT
query,
calls,
mean_exec_time,
rows,
shared_blks_read
FROM pg_stat_statements
WHERE query ILIKE '%customer_context%'
ORDER BY calls DESC
LIMIT 20;
更高风险的 AI 流程,可以在应用层写入显式审计事件,把 agent 身份、请求 ID、查询 hash、检索到的记录 ID、业务上下文关联起来。下面是一个可改造的审计表:
CREATE TABLE ai_retrieval_audit (
id bigserial PRIMARY KEY,
occurred_at timestamptz NOT NULL DEFAULT now(),
agent_id text NOT NULL,
request_id text NOT NULL,
tenant_id uuid NOT NULL,
query_hash text NOT NULL,
retrieved_customer_ids uuid[] NOT NULL,
purpose text NOT NULL
);
INSERT INTO ai_retrieval_audit (
agent_id,
request_id,
tenant_id,
query_hash,
retrieved_customer_ids,
purpose
) VALUES (
'claims-agent-v2',
'req-20250101-001',
'00000000-0000-0000-0000-000000000001',
'sha256:replace_with_real_query_hash',
ARRAY['11111111-1111-1111-1111-111111111111']::uuid[],
'claim_summary_grounding'
);
这类表不能替代 pgAudit 或数据库日志,但它能把应用语义补上:这次检索属于哪个 agent、哪个用户请求、哪个业务目的。数据层审计和应用层事件能关联起来,事故排查才不会变成跨团队考古。
上线前用四个问题压一遍
在批准下一个 AI 用例之前,技术负责人可以直接拿 C.A.L.M. 做一次检查:
- Changeability:明天新增一个检索模式或数据源时,会不会又产生一份无人治理的数据副本?
- Assurance:监管要求追溯某个 AI 决策时,能不能用 SQL 查出数据副本、owner、权限策略和有效时间?
- Leverage:平台是在减少 pipeline、系统和访问控制实现,还是让每个团队都维护一套?
- Measurability:如果数据延迟、embedding 过期、agent 绕过治理路径,平台能不能在客户或监管发现前报警?
PostgreSQL 不能自动解决组织协作问题。它能提供一组扎实的控制点:逻辑复制让 AI 数据层有边界,RLS 让访问控制落到行级,pgvector 让语义检索贴近治理数据,pg_stat_statements 与审计表让平台看到真实查询行为。
真正难的是把这些能力系统化使用,并明确谁负责持续保持它们为真。企业 AI 治理不是从模型开始的,而是从数据可信到足以支撑模型那一刻开始的。