Claude 不能本地部署?这套企业内网接入方案更现实|含网关源码
Claude 私有化部署方案|附源码
说明:严格意义上,Claude 是 Anthropic 的闭源大模型产品,当前并不支持像开源模型一样将模型权重下载到本地服务器后完全离线部署。因此,本文所说的“Claude 私有化部署”,主要指两类方案:
- 企业内网私有化接入 Claude API:通过私有网关、权限控制、审计日志、数据脱敏、缓存与限流,实现企业级安全接入。
- Claude-like 私有化替代方案:使用开源大模型在本地或私有云部署,能力上尽量接近 Claude,用于对数据安全要求极高、不能出公网的场景。
本文将重点介绍第一种方案,并附带可运行的源码示例。
一、为什么企业需要 Claude 私有化部署方案?
Claude 在长文本理解、复杂推理、代码生成、知识问答、文档总结等场景中表现优秀,很多企业希望将其接入内部系统,例如:
- 企业知识库问答;
- 合同、标书、制度文档解读;
- 客服智能助手;
- 研发代码助手;
- 数据分析助手;
- OA、CRM、ERP、工单系统智能化改造。
但是,如果直接让员工使用公网 Claude 或者简单调用 Claude API,会遇到很多问题。
1. 数据安全不可控
企业内部文档、客户信息、财务数据、研发代码、业务报表等都可能包含敏感信息。如果用户直接把这些内容提交给外部 AI 服务,企业难以控制数据流向,也难以进行审计。
2. 权限无法统一管理
企业通常已经有统一身份认证系统,例如 LDAP、OAuth2、企业微信、飞书、钉钉或 SSO。如果每个人单独使用 Claude,权限管理会非常混乱。
3. 调用成本不可控
Claude API 按 token 计费。如果没有统一限流、额度、统计和缓存机制,成本可能迅速增长。
4. 缺少审计与追踪
企业级 AI 系统必须能够回答以下问题:
- 谁在什么时候调用了 AI?
- 提交了什么问题?
- 是否包含敏感信息?
- 消耗了多少 token?
- 调用结果是否命中风控规则?
5. 无法和内部系统深度集成
企业真正需要的不是一个单独的聊天框,而是将 Claude 能力嵌入内部业务系统,例如知识库、工单、报表、审批流、代码仓库等。
因此,一个合理的 Claude 私有化部署方案,不是简单地把 API Key 写进代码,而是要建设一套企业内部可控的 AI 网关与应用平台。
二、整体架构设计
Claude 私有化接入方案可以设计为如下架构:
┌─────────────────────────────┐
│ 企业用户 │
│ Web / App / OA / ERP / IM │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ 企业 AI 应用层 │
│ 聊天助手 / 知识库 / 工单助手 │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ 私有 AI 网关层 │
│ 鉴权 / 脱敏 / 限流 / 审计 / 缓存 │
└──────────────┬──────────────┘
│
▼
┌─────────────────────────────┐
│ Claude API 服务 │
│ Anthropic Claude Models │
└─────────────────────────────┘
其中,最核心的是 私有 AI 网关层。它承担以下职责:
| 模块 | 作用 |
|---|---|
| 身份认证 | 确认调用者身份,例如用户、部门、系统 |
| 权限控制 | 控制不同角色可使用的模型和额度 |
| 敏感词检测 | 检测手机号、身份证、银行卡、密钥等敏感信息 |
| 数据脱敏 | 将敏感字段替换为占位符后再发送 |
| 调用 Claude | 统一封装 Claude API |
| 审计日志 | 记录请求、响应、token、时间、用户等信息 |
| 限流控制 | 防止滥用和异常调用 |
| 成本统计 | 统计不同用户、部门、系统的 token 消耗 |
| 缓存优化 | 对重复问题进行缓存,降低成本 |
三、部署方式选择
方案一:Claude API 私有网关模式
这是目前最现实、落地成本最低的方案。
企业在内网或私有云中部署一个 AI Gateway,所有内部应用只能访问这个网关,由网关统一访问 Claude API。
优点:
- 不需要训练模型;
- 能快速接入 Claude 的最新能力;
- 可以统一管理 API Key;
- 可以增加脱敏、审计、限流;
- 适合大多数企业应用场景。
缺点:
- 依然需要访问 Anthropic API;
- 不是完全离线部署;
- 对网络合规、跨境数据有要求。
适用场景:
- 企业内部智能助手;
- 研发代码辅助;
- 文档总结;
- 知识库问答;
- 非强制离线场景。
方案二:开源模型私有化替代 Claude
如果企业要求所有数据必须保留在本地,不能访问外部 API,可以选择开源大模型,例如:
- Qwen;
- DeepSeek;
- Llama;
- Mixtral;
- Yi;
- Baichuan;
- ChatGLM。
可以通过 vLLM、Ollama、Text Generation Inference、LMDeploy 等框架部署。
优点:
- 数据完全留在本地;
- 可控性强;
- 可结合企业数据微调;
- 可离线运行。
缺点:
- 模型能力可能与 Claude 有差距;
- 需要 GPU 资源;
- 部署和运维成本更高;
- 模型安全、幻觉、效果需要持续优化。
适用场景:
- 金融、政务、军工等高安全场景;
- 私有知识库问答;
- 离线文档分析;
- 内部代码助手。
四、本文实现目标
本文提供一个可运行的 Claude 私有化网关示例,包含:
- 后端服务;
- Claude API 封装;
- API Key 统一管理;
- 简单用户鉴权;
- 敏感信息脱敏;
- 请求审计日志;
- 限流;
- Docker 部署。
技术栈如下:
| 技术 | 说明 |
|---|---|
| Node.js | 后端运行环境 |
| Express | Web API 框架 |
| Axios | 请求 Claude API |
| dotenv | 环境变量管理 |
| Docker | 容器化部署 |
| Nginx | 可选反向代理 |
五、目录结构
项目目录如下:
claude-private-gateway/
├── src/
│ ├── index.js
│ ├── claude.js
│ ├── auth.js
│ ├── audit.js
│ ├── desensitize.js
│ └── rateLimit.js
├── logs/
│ └── audit.log
├── .env
├── package.json
├── Dockerfile
└── docker-compose.yml
六、后端源码
1. package.json
{
"name": "claude-private-gateway",
"version": "1.0.0",
"description": "Enterprise private gateway for Claude API",
"main": "src/index.js",
"type": "commonjs",
"scripts": {
"start": "node src/index.js",
"dev": "node src/index.js"
},
"dependencies": {
"axios": "^1.7.7",
"dotenv": "^16.4.5",
"express": "^4.18.3",
"express-rate-limit": "^7.4.1"
}
}
2. .env
PORT=3000
# Anthropic Claude API Key
ANTHROPIC_API_KEY=sk-ant-api03-xxxxxxxxxxxxxxxxxxxx
# Claude model
CLAUDE_MODEL=claude-3-5-sonnet-20241022
# Internal gateway token
INTERNAL_API_TOKEN=your-internal-token
注意:
.env文件不要提交到 Git 仓库,生产环境中建议使用 Kubernetes Secret、Vault 或云厂商密钥管理服务。
3. src/auth.js
该模块用于企业内部调用鉴权。这里为了演示,使用固定 Token,真实生产环境建议接入 SSO、OAuth2、JWT 或企业统一身份认证系统。
function authMiddleware(req, res, next) {
const token = req.headers["x-api-token"];
if (!token) {
return res.status(401).json({
error: "Missing x-api-token"
});
}
if (token !== process.env.INTERNAL_API_TOKEN) {
return res.status(403).json({
error: "Invalid internal token"
});
}
req.user = {
id: req.headers["x-user-id"] || "anonymous",
department: req.headers["x-department"] || "unknown"
};
next();
}
module.exports = authMiddleware;
4. src/desensitize.js
该模块用于简单脱敏。实际生产环境中可以接入更复杂的 DLP 系统,对身份证、手机号、银行卡、邮箱、密钥、客户姓名等进行识别和处理。
function desensitizeText(text) {
if (!text || typeof text !== "string") {
return text;
}
let result = text;
// 手机号脱敏
result = result.replace(/1[3-9]\d{9}/g, "[PHONE_MASKED]");
// 邮箱脱敏
result = result.replace(
/[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/g,
"[EMAIL_MASKED]"
);
// 身份证号脱敏
result = result.replace(
/\b\d{17}[\dXx]\b/g,
"[ID_CARD_MASKED]"
);
// 银行卡号简易脱敏
result = result.replace(
/\b\d{16,19}\b/g,
"[BANK_CARD_MASKED]"
);
// 常见密钥字段脱敏
result = result.replace(
/(api_key|secret|password|token)\s*[:=]\s*['"]?([a-zA-Z0-9_\-\.]+)['"]?/gi,
"$1=[SECRET_MASKED]"
);
return result;
}
function desensitizeMessages(messages) {
return messages.map(item => {
if (typeof item.content === "string") {
return {
...item,
content: desensitizeText(item.content)
};
}
return item;
});
}
module.exports = {
desensitizeText,
desensitizeMessages
};
5. src/audit.js
该模块用于记录审计日志,包括用户、部门、模型、请求内容、响应摘要、耗时等。
const fs = require("fs");
const path = require("path");
const logDir = path.join(process.cwd(), "logs");
const logFile = path.join(logDir, "audit.log");
if (!fs.existsSync(logDir)) {
fs.mkdirSync(logDir, { recursive: true });
}
function writeAuditLog(data) {
const record = {
time: new Date().toISOString(),
...data
};
fs.appendFileSync(logFile, JSON.stringify(record, null, 0) + "\n");
}
module.exports = {
writeAuditLog
};
6. src/rateLimit.js
该模块用于限流,防止某个用户或系统短时间内过度调用。
const rateLimit = require("express-rate-limit");
const limiter = rateLimit({
windowMs: 60 * 1000,
limit: 30,
standardHeaders: true,
legacyHeaders: false,
message: {
error: "Too many requests, please try again later."
}
});
module.exports = limiter;
7. src/claude.js
这是调用 Claude API 的核心模块。
const axios = require("axios");
async function callClaude({ messages, system, maxTokens = 1024, temperature = 0.7 }) {
const apiKey = process.env.ANTHROPIC_API_KEY;
const model = process.env.CLAUDE_MODEL || "claude-3-5-sonnet-20241022";
if (!apiKey) {
throw new Error("ANTHROPIC_API_KEY is not configured");
}
const payload = {
model,
max_tokens: maxTokens,
temperature,
messages
};
if (system) {
payload.system = system;
}
const response = await axios.post(
"https://api.anthropic.com/v1/messages",
payload,
{
headers: {
"Authorization": `Bearer ${apiKey}`,
"Content-Type": "application/json",
"anthropic-version": "2023-06-01"
},
timeout: 60000
}
);
return response.data;
}
module.exports = {
callClaude
};
8. src/index.js
主入口文件,提供 /v1/chat 接口。
require("dotenv").config();
const express = require("express");
const authMiddleware = require("./auth");
const limiter = require("./rateLimit");
const { callClaude } = require("./claude");
const { desensitizeMessages, desensitizeText } = require("./desensitize");
const { writeAuditLog } = require("./audit");
const app = express();
app.use(express.json({ limit: "2mb" }));
app.use(limiter);
app.get("/health", (req, res) => {
res.json({
status: "ok",
service: "claude-private-gateway"
});
});
app.post("/v1/chat", authMiddleware, async (req, res) => {
const startTime = Date.now();
try {
const {
messages,
system,
maxTokens,
temperature
} = req.body;
if (!Array.isArray(messages)) {
return res.status(400).json({
error: "messages must be an array"
});
}
const safeMessages = desensitizeMessages(messages);
const safeSystem = desensitizeText(system);
const result = await callClaude({
messages: safeMessages,
system: safeSystem,
maxTokens,
temperature
});
const latency = Date.now() - startTime;
writeAuditLog({
user: req.user,
endpoint: "/v1/chat",
model: process.env.CLAUDE_MODEL,
request: {
system: safeSystem,
messages: safeMessages
},
response: {
id: result.id,
model: result.model,
usage: result.usage,
contentPreview: result.content
? JSON.stringify(result.content).slice(0, 500)
: ""
},
latency
});
res.json({
id: result.id,
model: result.model,
usage: result.usage,
content: result.content
});
} catch (error) {
const latency = Date.now() - startTime;
writeAuditLog({
user: req.user,
endpoint: "/v1/chat",
error: error.message,
latency
});
res.status(500).json({
error: "Claude gateway error",
message: error.message
});
}
});
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Claude private gateway running on port ${port}`);
});
七、Docker 部署
1. Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm install --production
COPY src ./src
COPY .env ./.env
RUN mkdir -p logs
EXPOSE 3000
CMD ["npm", "start"]
2. docker-compose.yml
version: "3.8"
services:
claude-gateway:
build: .
container_name: claude-private-gateway
ports:
- "3000:3000"
env_file:
- .env
volumes:
- ./logs:/app/logs
restart: always
3. 启动服务
npm install
docker compose up -d --build
查看服务状态:
docker ps
查看日志:
docker logs -f claude-private-gateway
健康检查:
curl http://localhost:3000/health
返回:
{
"status": "ok",
"service": "claude-private-gateway"
}
八、调用示例
1. curl 调用
curl -X POST http://localhost:3000/v1/chat \
-H "Content-Type: application/json" \
-H "x-api-token: your-internal-token" \
-H "x-user-id: user001" \
-H "x-department: rd" \
-d '{
"system": "你是企业内部AI助手,请用简洁、专业的中文回答。",
"messages": [
{
"role": "user",
"content": "请帮我总结一下企业知识库建设的关键步骤。我的邮箱是 test@example.com,手机号是13812345678。"
}
],
"maxTokens": 800,
"temperature": 0.5
}'
发送给 Claude 前,邮箱和手机号会被替换为:
[EMAIL_MASKED]
[PHONE_MASKED]
这样可以降低敏感信息直接暴露的风险。
2. 返回示例
{
"id": "msg_xxxxxxxxx",
"model": "claude-3-5-sonnet-20241022",
"usage": {
"input_tokens": 120,
"output_tokens": 350
},
"content": [
{
"type": "text",
"text": "企业知识库建设通常包括以下几个关键步骤:第一,明确业务目标..."
}
]
}
九、生产环境增强建议
上面的代码是一个可运行的基础版本,如果要用于生产环境,建议继续增强以下能力。
1. 接入统一身份认证
示例中使用固定 Token,只适合演示。生产环境建议接入:
- OAuth2;
- OIDC;
- LDAP;
- SAML;
- 企业微信登录;
- 飞书登录;
- 钉钉登录;
- 自建 SSO。
认证后可以获得用户 ID、部门、角色等信息,便于做权限控制和费用统计。
2. 增加细粒度权限控制
不同用户可以设置不同权限,例如:
| 角色 | 可用能力 |
|---|---|
| 普通员工 | 文档总结、知识库问答 |
| 研发人员 | 代码解释、代码生成 |
| 财务人员 | 报表分析 |
| 管理员 | 配额配置、审计查看 |
| 外包人员 | 仅可访问指定知识库 |
同时可以限制不同用户使用不同模型,例如:
- Claude Haiku:低成本、高并发;
- Claude Sonnet:通用任务;
- Claude Opus:复杂推理任务。
3. 增加额度和成本控制
可以按用户、部门、应用系统设置调用额度:
用户 A:每天最多 100 次调用
研发部门:每月最多 5000 万 token
客服系统:每分钟最多 100 次请求
同时,应记录:
- 输入 token;
- 输出 token;
- 模型类型;
- 调用时间;
- 调用成本;
- 所属部门;
- 所属项目。
这对于成本分摊和预算控制非常重要。
4. 增加敏感信息识别能力
当前示例只做了正则脱敏,实际生产环境建议增加:
- DLP 敏感数据识别;
- 个人隐私识别;
- 客户信息识别;
- 源代码密钥检测;
- 财务数据检测;
- 数据分级分类;
- 风险等级评分。
对于高风险内容,可以采取以下策略:
- 直接拒绝发送;
- 脱敏后发送;
- 进入人工审批;
- 只允许调用本地模型;
- 记录高风险审计日志。
5. 增加 RAG 知识库能力
Claude 私有化网关可以进一步扩展为企业知识库问答系统。常见流程如下:
用户提问
↓
查询向量数据库
↓
召回相关文档片段
↓
拼接 Prompt
↓
调用 Claude
↓
返回带引用来源的答案
可选技术组件:
| 组件 | 说明 |
|---|---|
| Milvus | 向量数据库 |
| Qdrant | 向量数据库 |
| Elasticsearch | 关键词检索 |
| PostgreSQL + pgvector | 结构化数据和向量检索 |
| LangChain | RAG 编排 |
| LlamaIndex | 文档索引框架 |
企业知识库问答不建议直接把整份文档发送给 Claude,而应通过检索召回相关片段,既降低成本,也减少数据暴露范围。
6. 增加缓存机制
对于重复问题,可以使用 Redis 缓存结果。例如:
缓存 Key = 用户问题摘要 + 知识库版本 + 模型名称
缓存可以带来几个好处:
- 降低 Claude API 调用成本;
- 提升响应速度;
- 减少重复 token 消耗;
- 缓解高峰期压力。
但缓存也要注意权限隔离,不能让 A 用户查询到 B 用户无权访问的结果。
7. 增加流式输出
实际聊天产品中,用户体验更好的方式是流式输出。Claude API 支持 streaming,可以将返回内容逐步推送给前端。
后端可以使用:
- Server-Sent Events;
- WebSocket;
- HTTP chunked response。
流式输出适合:
- 长文本生成;
- 代码生成;
- 报告生成;
- 多轮对话。
8. 增加多模型路由
企业 AI 网关不一定只接 Claude,也可以同时接入:
- Claude;
- OpenAI;
- Gemini;
- Azure OpenAI;
- 本地 Qwen;
- 本地 DeepSeek;
- 本地 Llama。
可以根据场景自动路由:
| 场景 | 推荐模型 |
|---|---|
| 高安全数据 | 本地模型 |
| 长文档分析 | Claude |
| 低成本客服 | 小模型 |
| 代码生成 | Claude / DeepSeek |
| 简单摘要 | 轻量模型 |
这样可以在效果、成本和安全之间取得平衡。
十、Nginx 反向代理配置
如果服务部署在内网服务器上,可以使用 Nginx 作为统一入口。
server {
listen 80;
server_name claude-gateway.internal.example.com;
client_max_body_size 10m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 120s;
proxy_connect_timeout 30s;
proxy_send_timeout 120s;
}
}
生产环境建议启用 HTTPS,并限制访问来源,仅允许企业内网、VPN 或指定业务系统访问。
十一、安全合规注意事项
部署 Claude 私有化网关时,需要重点关注以下问题。
1. API Key 保护
Claude API Key 不能暴露给前端,也不能写在客户端代码中。必须由后端统一管理。
推荐做法:
- 使用环境变量;
- 使用 Secret 管理系统;
- 定期轮换密钥;
- 设置最小权限;
- 开启访问审计。
2. 敏感数据处理
在调用 Claude 前,应根据企业数据安全要求进行处理:
- 个人隐私数据脱敏;
- 客户数据脱敏;
- 财务数据脱敏;
- 源代码密钥扫描;
- 业务机密关键词检测。
对高风险数据,应阻断调用或转入本地模型处理。
3. 日志合规
审计日志很重要,但日志本身也可能包含敏感信息。因此要注意:
- 日志中的请求内容也要脱敏;
- 日志文件要设置访问权限;
- 日志定期归档;
- 日志定期清理;
- 管理员访问日志要审计。
4. 网络边界控制
建议将 Claude Gateway 部署在企业内网或私有云中,只开放给内部系统访问。
可以增加:
- IP 白名单;
- VPN 访问;
- mTLS 双向认证;
- 防火墙策略;
- WAF;
- 零信任网关。
十二、如果要完全本地化部署怎么办?
如果企业明确要求“不允许任何数据出内网”,则不能使用 Claude API 网关模式,而应采用开源模型本地部署。
一个典型方案如下:
用户
↓
企业 AI 应用
↓
AI 网关
↓
本地大模型服务
↓
GPU 推理集群
可以选择使用 Ollama 快速部署:
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen2.5:14b
ollama run qwen2.5:14b
也可以使用 vLLM 部署更高性能服务:
python -m vllm.entrypoints.openai.api_server \
--model Qwen/Qwen2.5-32B-Instruct \
--host 0.0.0.0 \
--port 8000
然后企业 AI 网关可以同时支持 Claude API 和本地 OpenAI-compatible API,根据数据安全等级选择调用路径。
十三、总结
Claude 本身并不提供传统意义上的模型权重私有化部署,但企业仍然可以通过“私有 AI 网关”的方式,实现可控、安全、可审计的 Claude 接入。
本文方案的核心思路是:
- API Key 不下发到客户端;
- 所有请求统一经过企业网关;
- 调用前进行敏感信息脱敏;
- 调用过程增加权限控制和限流;
- 调用后记录审计日志和成本信息;
- 高安全数据优先走本地开源模型;
- 通过多模型路由兼顾效果、成本与合规。
对于大多数企业来说,最推荐的落地路径是:
第一阶段:部署 Claude 私有网关,实现统一接入
第二阶段:增加知识库 RAG、权限、审计和成本统计
第三阶段:接入本地开源模型,形成混合 AI 架构
第四阶段:建设企业级 AI 平台和模型治理体系
这样既能快速使用 Claude 的强大能力,又能满足企业在安全、合规、成本和管理方面的要求。