四层元数据:解密 Bella OpenAPI 的可扩展架构设计
引言:架构设计的挑战
当企业需要构建一个支持多种 AI 能力的统一网关时,面临的最大挑战之一是如何设计一个既足够灵活又便于管理的架构。传统的 API 网关通常采用简单的 API 注册模式,难以应对 AI 服务种类繁多、配置复杂且快速迭代的特点。Bella OpenAPI 通过其独特的四层元数据架构优雅地解决了这一问题,本文将深入分析其设计思想与实现细节。
四层元数据架构:优雅的分层设计
从 Bella OpenAPI 的源代码中,我们可以清晰地看到其核心采用了 Category-Endpoint-Model-Channel 四层结构。这种分层不是任意设计的,而是基于 AI 服务的本质特性和管理需求精心构建的。
第一层:Category(类别)
Category 是整个元数据体系的顶层结构,用于对不同类型的 AI 能力进行逻辑分组。从代码实现来看:
// CategoryRepo.java
@Component
public class CategoryRepo extends StatusRepo<CategoryDB,
CategoryRecord, String> {
// ...
private String generateCategoryCode(String parentCode) {
// 层级式编码生成逻辑
}
// 支持树状结构的查询
public List<CategoryDB>
queryAllChildrenIncludeSelfByCategoryCode(String categoryCode,
String status) {
// ...
}
}
核心设计特点:
- 树状结构:支持父子关系,可以构建多级类别树
- 编码机制:自动生成类别编码,确保唯一性和可读性
- 灵活分组:允许按业务需求或技术特性进行分类
这一层解决了"如何组织和管理多种 AI 能力"的问题,使用户可以按照语音服务、文本服务、图像服务等方式直观地浏览和选择所需功能。
第二层:Endpoint(端点)
Endpoint 代表具体的 API 功能入口,如聊天补全、实时语音识别等。从代码实现看:
// ModelRepo.java
@Component
public class ModelRepo extends StatusRepo<ModelDB, ModelRecord,
String> {
// 支持模型与端点的关联
// 模型可见性控制
@Transactional
public void updateVisibility(String modelName, String
visibility) {
// ...
}
// 支持模型特性的精确查询
private SelectSeekStep1<Record, Long>
constructSql(Condition.ModelCondition op) {
// 基于 JSON 属性的复杂查询
if (CollectionUtils.isNotEmpty(op.getFeatures())) {
for (String feature : op.getFeatures()) {
featuresCondition = featuresCondition.and(
MODEL.FEATURES.like("%\"" + feature +
"\":true%")
);
}
}
// ...
}
}
核心设计特点:
- 多维属性:通过 JSON 字段存储复杂的模型属性和特性
- 可见性控制:支持公开、私有等多种可见性级别
- 与端点关联:通过 ModelEndpointRel 表实现与 Endpoint 的多对多关联
- 授权机制:通过 ModelAuthorizerRel 表实现基于用户或组织的精细授权
这一层解决了"如何灵活配置不同 AI 模型及其能力特性"的问题,使系统能够支持多种模型并进行精细的权限控制。
第四层:Channel(通道)
Channel 是具体的服务提供方实现,关联能力点/模型,包含供应商、协议和配置信息。从代码实现看:
// ChannelRepo.java
@Component
public class ChannelRepo extends StatusRepo<ChannelDB,
ChannelRecord, String> implements AutogenCodeRepo<ChannelRecord>
{
// 支持价格信息查询
public Map<String, String> queryPriceInfo(List<String>
entityCodes) {
// ...
}
// 支持供应商列表
public List<String> listSuppliers() {
return
db.selectDistinct(CHANNEL.SUPPLIER).from(CHANNEL).fetchInto(String.class);
}
// 支持多种过滤条件
private SelectSeekStep1<ChannelRecord, Long>
constructSql(Condition.ChannelCondition op) {
// 供应商、协议、优先级、目标等多维度条件
}
}
从 EndpointContext.java 中,我们可以看到 Channel 在实际调用中的作用:
public static void setEndpointData(String endpoint, String model,
ChannelDB channel, Object request) {
EndpointContext.getProcessData().setRequest(request);
EndpointContext.getProcessData().setEndpoint(endpoint);
EndpointContext.getProcessData().setModel(model);
EndpointContext.getProcessData().setChannelCode(channel.getChannelCode());
EndpointContext.getProcessData().setForwardUrl(channel.getUrl());
EndpointContext.getProcessData().setProtocol(channel.getProtocol());
EndpointContext.getProcessData().setPriceInfo(channel.getPriceInfo());
EndpointContext.getProcessData().setSupplier(channel.getSupplier());
}
核心设计特点:
- 多实体支持: 提供了能力点/模型两种实体类型,提供了灵活的绑定方式,既可以通过模型请求,也可以不指定模型直接通过能力点请求
- 多供应商支持:可以配置不同的 AI 服务提供商
- 协议封装:抽象不同服务商的 API 差异,提供统一接口
- 价格管理:包含价格信息,支持计费功能
- 路由控制:通过优先级和目标设置实现智能路由
这一层解决了"如何灵活对接不同服务提供商"的问题,使系统能够透明地管理和切换多个底层服务。
四层架构的协同工作机制
这四层架构按如下方式协同工作:
- 类别选择:用户根据分类选择所需的 Endpoint
- 请求入口:用户通过 Endpoint 发起请求
- 模型选择:发起请求时,如果要指定模型,可在 Endpoint 下选择合适的 Model
- 通道路由:根据路由策略选择合适的 Channel
- 请求转发:将请求转发到目标服务,并处理响应