摘要
当企业同时建设智能客服、知识库问答、数据分析助手和业务 Agent 时,如果每个项目单独接入模型、向量数据库和工具系统,很快会形成重复建设、权限不一致、费用难统计和难以统一运维的问题。
本文从企业级 AI 中台的边界出发,设计模型接入层、知识库服务、Agent 运行时、业务编排、统一鉴权、观测与成本控制等核心模块,并结合 Spring Boot 给出一套可落地的服务拆分和接口示例。
一、背景与问题
一个 AI 应用通常需要连接以下系统:
text
用户 / 业务系统
│
├─ 大模型
├─ Embedding 服务
├─ 向量数据库
├─ 文档解析与对象存储
├─ 业务数据库
├─ 搜索、订单、工单等内部工具
└─ 监控、审计和费用系统
如果这些能力全部写在单个业务服务里,会出现:
| 问题 | 具体表现 |
|---|---|
| 模型重复接入 | 不同项目分别实现 OpenAI、国产模型和本地模型适配 |
| 知识库重复建设 | 文件上传、切片、Embedding、召回逻辑各自维护 |
| 权限难统一 | AI 应用能看到的业务数据边界不清晰 |
| 成本不可控 | Token 和模型费用无法按租户、应用统计 |
| Agent 难治理 | 工具调用、循环次数和敏感操作没有统一策略 |
| 运维复杂 | 每个项目单独配置日志、告警和链路追踪 |
AI 中台不是简单地把所有能力堆成一个"大服务",而是把稳定的公共能力抽取出来,让业务应用通过清晰契约调用。
二、核心概念
1. AI 中台的分层
可以把企业 AI 中台分成四层:
| 层级 | 主要职责 |
|---|---|
| 接入层 | API、鉴权、租户隔离、限流和协议转换 |
| AI 能力层 | 模型、Embedding、重排、知识库和 Agent Runtime |
| 业务连接层 | 工具注册、业务 API、MCP、数据权限 |
| 治理层 | 观测、评估、审计、成本、配置和运营 |
业务应用只应依赖必要的能力接口,不应该直接访问供应商 SDK、向量数据库或模型密钥。
2. 模型服务与模型路由
模型服务需要统一以下差异:
- 请求和响应格式。
- 流式输出格式。
- Token 用量字段。
- 工具调用结构。
- 错误码和重试语义。
- 模型能力标签。
模型路由不只是"随机挑一个模型",还要考虑任务类型、上下文长度、租户预算、数据区域和实时健康状态。
3. 知识库服务
知识库服务通常包含:
text
文件上传
→ 文档解析
→ 清洗与切片
→ Embedding
→ 向量存储
→ 权限过滤
→ 召回与重排
知识库的权限不能只在上传时检查。查询阶段仍然要根据用户、租户、部门和业务对象过滤结果。
4. Agent Runtime
Agent Runtime 负责执行任务循环:
text
用户目标
→ 规划
→ 模型决策
→ 工具调用
→ 结果校验
→ 继续执行或结束
它需要控制最大步数、工具白名单、超时、并发、人工确认和失败恢复。Agent 不是拥有无限权限的业务用户。
三、工作原理
1. 总体架构
一个较完整的企业 AI 中台可以设计为:
text
┌──────────────┐
│ 管理控制台 │
└──────┬───────┘
│
┌──────────┐ ┌──────────┐ ┌─────▼──────┐
│ Web 应用 │ │ 移动应用 │ │ 业务系统 │
└────┬─────┘ └────┬─────┘ └─────┬──────┘
└─────────────┼──────────────┘
▼
┌─────────────┐
│ API Gateway │
└──────┬──────┘
▼
┌─────────────────────────┐
│ AI 应用编排与会话服务 │
└───┬────────┬────────┬───┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌───────┐ ┌────────────┐
│模型服务 │ │知识库 │ │ Agent运行时│
└────┬─────┘ └───┬───┘ └─────┬──────┘
│ │ │
▼ ▼ ▼
多模型供应商 向量库/对象存储 业务工具/MCP
治理能力横向覆盖全部模块,包括权限、审计、成本、观测、评估和配置管理。
2. 一次知识库问答
一次 RAG 请求可拆分为:
- 校验用户身份、租户和知识库权限。
- 对问题进行改写或查询扩展。
- 召回候选文档。
- 根据文档 ACL 过滤结果。
- 重排并截取上下文。
- 调用模型生成答案。
- 保存引用、用量、延迟和反馈。
权限过滤必须发生在把内容交给模型之前,不能只依赖 Prompt 告诉模型"不要泄露"。
3. 一次 Agent 请求
Agent 运行时应为每次任务建立独立执行上下文:
json
{
"task_id": "task-20260929-001",
"tenant_id": "tenant-a",
"application_id": "service-desk",
"max_steps": 8,
"allowed_tools": [
"query_ticket",
"search_knowledge"
],
"require_confirmation": [
"update_ticket"
]
}
上下文中的权限和工具列表由服务端生成,不能完全信任客户端传入的值。
四、实战示例
1. 定义模型抽象
java
public interface AiModelService {
ChatResult chat(ChatRequest request, CallContext context);
Flux<ChatChunk> stream(ChatRequest request, CallContext context);
ModelCapabilities capabilities(String model);
}
java
public record CallContext(
String tenantId,
String applicationId,
String traceId,
String userId,
Set<String> scopes) {
}
业务层只依赖 AiModelService,模型供应商的 SDK 适配放在基础设施层。
2. 模型路由
java
@Service
public class ModelRouter {
private final List<ModelProvider> providers;
private final HealthService healthService;
public ModelRouter(List<ModelProvider> providers,
HealthService healthService) {
this.providers = providers;
this.healthService = healthService;
}
public ModelProvider route(RouteRequest request) {
return providers.stream()
.filter(provider -> provider.supports(request.capability()))
.filter(provider -> healthService.isHealthy(provider.name()))
.filter(provider -> provider.accepts(request.tenantId()))
.min(Comparator.comparing(
provider -> provider.score(request)))
.orElseThrow(() -> new NoAvailableModelException(
"no model provider available"));
}
}
生产实现中还应加入预算、区域、上下文长度、实时错误率和供应商限额判断。
3. 统一知识库查询接口
java
public interface KnowledgeBaseService {
SearchResult search(
String knowledgeBaseId,
String query,
KnowledgeAccessContext accessContext,
int topK);
}
java
@Service
public class SecureKnowledgeBaseService
implements KnowledgeBaseService {
private final DocumentRepository documentRepository;
private final VectorSearchService vectorSearchService;
@Override
public SearchResult search(
String knowledgeBaseId,
String query,
KnowledgeAccessContext context,
int topK) {
List<DocumentChunk> candidates = vectorSearchService.search(
knowledgeBaseId, query, topK * 4);
List<DocumentChunk> allowed = candidates.stream()
.filter(chunk -> context.canRead(
chunk.tenantId(),
chunk.departmentId(),
chunk.resourceId()))
.limit(topK)
.toList();
return new SearchResult(allowed);
}
}
真实系统还需要检查文档版本、删除状态、数据驻留区域和敏感字段策略。
4. Agent 工具注册
java
public record ToolDefinition(
String name,
String description,
Set<String> requiredScopes,
boolean mutating,
Duration timeout) {
}
java
@Service
public class ToolPolicyService {
public void check(ToolDefinition tool,
CallContext context,
boolean confirmed) {
if (!context.scopes().containsAll(tool.requiredScopes())) {
throw new AccessDeniedException(
"missing tool scope: " + tool.name());
}
if (tool.mutating() && !confirmed) {
throw new ConfirmationRequiredException(tool.name());
}
}
}
工具注册表不应只保存函数名称,还要保存权限、数据等级、是否有副作用、超时和审计要求。
5. 服务边界
初期可以采用模块化单体:
text
ai-platform
├─ model
├─ knowledge
├─ agent
├─ tool
├─ conversation
├─ governance
└─ billing
当模型调用、文件解析、Agent 执行和计费统计出现不同的扩缩容需求时,再拆成独立服务。过早微服务化会增加调用链、部署和调试成本。
五、常见问题与实践建议
1. AI 中台是不是越大越好?
不是。中台应沉淀多个业务都会使用且契约相对稳定的能力。一次性把所有业务流程、Prompt 和工具都放入中台,会让平台变成难以修改的超级应用。
2. Prompt 应该放在中台还是业务系统?
通用安全规则、系统角色和模型参数可以由平台治理;具体业务 Prompt 通常由业务应用维护。建议引入 Prompt 模板版本和发布流程,但不要让平台团队成为所有业务文案的单点瓶颈。
3. 如何避免一个租户影响其他租户?
至少隔离以下资源:
- 模型并发和 Token 配额。
- 知识库查询 QPS。
- Agent 最大任务数。
- 文件解析队列。
- 工具调用频率。
- 费用预算和告警。
资源限制应在入口和执行层同时生效。
4. 为什么不建议让 Agent 直接访问数据库?
直接访问数据库会扩大权限范围,增加 SQL 注入、误读和数据泄露风险。更安全的方式是把业务动作包装成参数化、可审计、带权限检查的领域工具。
5. 如何选择模块化单体还是微服务?
根据团队规模、部署边界、数据隔离和弹性需求决定。模型调用、异步任务和文件处理通常较早需要独立扩缩容;管理后台和基础配置可以继续留在主服务中。
六、进阶思考
1. 从功能中台走向能力平台
能力平台应提供稳定的接口,而不是暴露内部实现:
text
应用层:对话、问答、自动化任务
平台层:模型、检索、工具、Agent、评估
基础设施:数据库、队列、对象存储、监控
平台接口要明确输入、输出、错误、幂等、超时和权限,避免业务代码依赖内部数据库表。
2. 质量、成本和延迟的联合决策
同一问题可能有多个可行模型。路由可以基于历史评估结果和实时运行数据做选择:
text
候选模型
├─ 能力满足度
├─ 质量评分
├─ P95 延迟
├─ 单次成本
├─ 当前配额
└─ 数据合规
最终选择不应只追求最低成本,也不能只追求最高模型能力。
3. 评估系统要进入发布流程
Prompt、模型和工具变化都会影响结果。可以为每个应用维护一组黄金问题,发布前自动评估:
- 事实正确性。
- 引用完整性。
- 工具调用成功率。
- 敏感信息拦截率。
- 平均 Token 和费用。
- 首 Token 与总延迟。
没有评估数据,平台只能依靠主观体验判断升级是否成功。
结论
企业级 AI 中台的核心不是集中所有代码,而是统一模型、知识库、Agent 和治理能力的契约。模型服务解决供应商差异,知识库服务解决检索和权限,Agent Runtime 解决任务执行,治理层解决安全、成本、观测和评估。
落地时建议先从两个以上业务都会使用的公共能力开始,采用模块化单体验证边界,再根据真实负载拆分模型调用、文件处理和 Agent 执行服务。
参考资料
- Spring AI Reference: https://docs.spring.io/spring-ai/reference/
- OpenTelemetry GenAI Semantic Conventions: https://opentelemetry.io/docs/specs/semconv/gen-ai/
- Model Context Protocol: https://modelcontextprotocol.io/