一年过去,“AI 主权”已经从政策口号变成了架构问题:模型在哪里运行,数据经过哪些地区,谁能审计调用链,以及未来能否更换供应商。越来越多政府把它理解成一场零和竞争,但更可持续的答案不是只押注某一个国家、云平台或模型,而是增加本地开源模型供给,用模型无关的安全层统一治理,并让部署方保留真实的迁移权。
主权真正约束的是控制面,而不只是模型
把模型下载到本地,并不自动获得 AI 主权。一个完整的 AI 系统还包括提示词、检索数据、向量数据库、身份系统、内容过滤、日志、评测流水线和运维平台。只要其中某个关键环节只能由外部服务控制,本地部署仍可能受到数据出境、服务中断或供应商锁定的影响。
可以把主权需求拆成几个可验证的问题:
- 数据驻留:提示词、附件、检索结果和日志实际存储在哪里?
- 执行位置:推理是否发生在指定司法辖区,故障切换会不会把请求送往其他地区?
- 技术可替换性:应用是否依赖某一家模型特有的请求格式、工具调用协议或安全接口?
- 运营控制权:谁能暂停服务、更新模型、查看审计记录和撤销访问权限?
- 供应链透明度:模型权重、容器镜像、依赖包和安全策略能否接受独立检查?
这也是为什么“更多本地开源模型”与“模型无关的安全工具”需要同时出现。前者提供部署选择,后者避免每更换一次模型就重写治理体系。
选择权需要架构支持
比较稳妥的设计,是让业务应用只调用统一的 AI 网关,再由网关选择本地模型、区域模型或外部服务。身份验证、数据分类、速率限制、审计和内容策略都放在模型之前,而不是写进某一家供应商的 SDK。
一条典型链路可以是:
业务应用
│
▼
统一 AI 网关 ── 身份、数据分级、审计、限流、策略检查
│
├── 本地开源或开放权重模型
├── 区域内托管模型
└── 经批准的外部模型 API
这种架构并不意味着所有请求都必须留在本地。公开资料摘要可以使用性价比更合适的外部模型,包含公民信息、医疗记录或未公开政府文件的请求则可以强制进入本地环境。主权由明确政策实现,而不是由“默认相信某个端点”实现。
可运行实践:在模型前增加数据驻留网关
下面是一个最小示例。它假设不同模型提供方暴露兼容 OpenAI Chat Completions 的接口;如果实际协议不同,可以在网关中增加适配器。示例会阻止 restricted 数据发往标记为外部的提供方。
先启动一个本地模型。以下命令使用 Ollama;运行前请确认模型许可证和组织政策满足你的使用场景:
docker run -d --name ollama -p 11434:11434 ollama/ollama:latest
docker exec ollama ollama pull qwen2.5:3b
安装网关依赖:
python -m venv .venv
. .venv/bin/activate
pip install fastapi uvicorn httpx
保存为 gateway.py:
import os
from typing import Literal
import httpx
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI(title="Sovereign AI Gateway")
# 生产环境应从受控配置中心加载,并为每个提供方维护地区、
# 数据处理协议、允许模型及出站属性。
PROVIDERS = {
"local": {
"base_url": os.getenv("LOCAL_BASE_URL", "http://127.0.0.1:11434/v1"),
"api_key": os.getenv("LOCAL_API_KEY", "ollama"),
"external": False,
"models": {"qwen2.5:3b"},
},
"approved_external": {
"base_url": os.getenv("EXTERNAL_BASE_URL", "https://example.invalid/v1"),
"api_key": os.getenv("EXTERNAL_API_KEY", ""),
"external": True,
"models": {"approved-model"},
},
}
class Message(BaseModel):
role: Literal["system", "user", "assistant"]
content: str
class ChatRequest(BaseModel):
provider: str
model: str
data_class: Literal["public", "internal", "restricted"]
messages: list[Message]
@app.post("/chat")
async def chat(req: ChatRequest):
provider = PROVIDERS.get(req.provider)
if provider is None:
raise HTTPException(status_code=400, detail="Unknown provider")
if req.model not in provider["models"]:
raise HTTPException(status_code=400, detail="Model is not approved")
if req.data_class == "restricted" and provider["external"]:
raise HTTPException(
status_code=403,
detail="Restricted data must remain in the controlled environment",
)
payload = {
"model": req.model,
"messages": [message.model_dump() for message in req.messages],
"temperature": 0.2,
}
headers = {"Authorization": f"Bearer {provider['api_key']}"}
async with httpx.AsyncClient(timeout=60) as client:
response = await client.post(
f"{provider['base_url']}/chat/completions",
json=payload,
headers=headers,
)
if response.is_error:
# 生产环境不要把上游响应原样写入日志,其中可能包含敏感内容。
raise HTTPException(status_code=502, detail="Model provider failed")
return response.json()
启动并调用本地模型:
uvicorn gateway:app --host 127.0.0.1 --port 8080
curl http://127.0.0.1:8080/chat \
-H 'Content-Type: application/json' \
-d '{
"provider": "local",
"model": "qwen2.5:3b",
"data_class": "restricted",
"messages": [
{"role": "user", "content": "用三点总结这份内部流程。"}
]
}'
这个示例的重点不是某个模型,而是策略位于网关。应用可以切换提供方,restricted 数据不得出站的规则却不需要随模型重写。生产版本还应补充强身份认证、请求大小限制、密钥托管、恶意提示检测、输出过滤、不可篡改审计和故障降级策略。
不要把“模型无关”误解成“模型完全等价”
统一接口只能降低切换成本,不能消除模型差异。不同模型在上下文长度、工具调用、结构化输出、多语言能力、安全边界和吞吐量上仍然不同。迁移前需要用本组织的任务集做回归评测,而不是只比较通用排行榜。
本地部署同样有代价:GPU 采购、容量规划、补丁更新和事故响应都会转移到运营团队。开放权重也不必然等于许可证无限制、训练数据透明或供应链安全。政府和受监管组织尤其需要分别检查代码许可证、模型许可证、数据来源说明及再分发条件。
落地时检查这六件事
- 为数据建立
public、internal、restricted等可执行分类,而不只是文档标签。 - 记录每个模型的运行地区、运营主体、许可证、版本和允许的数据等级。
- 让应用调用内部稳定接口,不直接绑定单一供应商 SDK。
- 在网关执行身份、出站和审计策略,同时避免记录原始敏感提示词。
- 为替代模型建立真实任务评测集,并定期演练供应商切换。
- 保留混合部署能力:本地模型承担敏感任务,其他模型在政策允许时补充能力和容量。
主权 AI 的核心不是把所有技术都关在边界以内,而是确保关键决策不会被单一供应商替你做出。能看见数据去向、能执行本地政策、也能在必要时替换模型,才是可持续的选择权。