数据加载模型设计
一、介绍
在 AI Agent 的功能实现中,有一个至关重要的步骤:根据用户配置,动态实例化各类组件——包括 API、对话模型、MCP、顾问角色、系统提示词 等。这也是我们此前基于 ai-agent case 将代码抽象为 库表配置 的根本原因。
因此,本节的重点在于思考并实现:程序如何按配置加载并实例化 AI Agent 所需组件,例如:
- 客户端实例化:依据客户端配置装配所需的模型、提示词、顾问与工具;
- 对话模型实例化:从模型与 API 关联关系中恢复具体模型与连接参数;
- MCP 工具实例化:根据传输类型(SSE/STDIO)与配置 JSON 创建工具客户端;
- 顾问角色实例化:加载记忆与知识库等能力,并注入到客户端;
- 提示词装配:按场景选择并注入系统提示词(defaultSystem 等)。
通过上述动态装配流程,系统即可在运行期按需构建出满足业务诉求的 AI Agent。
二、功能流程
如图,Ai Agent 实现过程,数据加载策略设计;

首先,AI Agent 的实例化本质上是各项组件的创建与组装过程。为提升实现代码的可维护性与可扩展性,我们可以将这一创建流程抽象为一棵规则树(Rule Tree):通过规则节点按顺序/条件进行串联与编排,使组件(API、对话模型、MCP、顾问、提示词等)的装配具备可配置、可复用、可插拔的特性。
三、编码实现
1. 工程结构

如图;整个 Agent 领域旨在实现各模块的动态化加载。因此,本节首先聚焦于数据加载方案的设计。
adapter(适配器层):负责数据获取与对接。可将其理解为“水管接头”,用于对接不同来源与形态的数据通道,屏蔽差异、统一输入。
model(领域对象层):承载领域数据与行为的核心对象模型。围绕服务实现所需,定义并维护各类领域对象,确保数据在各环节间规范传递。
service(服务实现层):采用规则树 / 责任链等设计模式对流程节点进行编排与串联,使代码更加简洁与可维护。本节重点在于数据加载策略:
- 需兼容不同粒度的加载需求——例如仅实例化 API,或直接实例化完整的 Client;
2. 类的关系

类关系结构:抽取后的类关系中,以
AbstractArmorySupport作为扩展支撑基类,首先实现RootNode根节点,作为装配流程的入口。数据加载策略:
Node的职责是加载数据,但数据类型多样,因此需要引入数据加载策略。通过ILoadDataStrategy接口定义策略抽象,并以多实现类承载不同的数据加载方式。当前先提供 2 种实现,后续可随功能扩展持续补充。基础设施层落地:全部数据加载由 基础设施层实现类 完成:
AgentRepository通过 DAO 进行持久化访问,统一对外提供各项数据的装配所需内容。
3. 核心编码
本节编码只需先跑通一条完整线路,其余部分便容易类推,因为实现方式基本同构。因此,这里仅展示核心代码与关键路径,其他细节可对照工程代码自行查看与扩展。
3.1 引入POM
<!-- 扳手工程(下载后,用 idea 打开,点击 install) https://gitcode.net/KnowledgePlanet/ai-agent-station -->
<dependency>
<groupId>cn.bugstack.wrench</groupId>
<artifactId>xfg-wrench-bom</artifactId>
<version>3.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 通用设计模式框架 -->
<dependency>
<groupId>cn.bugstack.wrench</groupId>
<artifactId>xfg-wrench-starter-design-framework</artifactId>
</dependency>首先在 ai-agent-station-study 根 POM 中引入 xfg-wrench-bom;随后在 domain 领域层 引入 xfg-wrench-starter-design-framework。
3.2 框架编码(设计模式)
public abstract class AbstractArmorySupport extends AbstractMultiThreadStrategyRouter<ArmoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext, String> {
private final Logger log = LoggerFactory.getLogger(AbstractArmorySupport.class);
@Resource
protected ApplicationContext applicationContext;
@Resource
protected ThreadPoolExecutor threadPoolExecutor;
@Resource
protected IAgentRepository repository;
@Override
protected void multiThread(ArmoryCommandEntity armoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext dynamicContext) throws ExecutionException, InterruptedException, TimeoutException {
}
@Slf4j
@Service
public class RootNode extends AbstractArmorySupport {
private final Map<String, ILoadDataStrategy> loadDataStrategyMap;
public RootNode(Map<String, ILoadDataStrategy> loadDataStrategyMap) {
this.loadDataStrategyMap = loadDataStrategyMap;
}
@Override
protected void multiThread(ArmoryCommandEntity requestParameter, DefaultArmoryStrategyFactory.DynamicContext dynamicContext) throws ExecutionException, InterruptedException, TimeoutException {
// 通过策略加载数据
String commandType = requestParameter.getCommandType();
ILoadDataStrategy loadDataStrategy = loadDataStrategyMap.get(commandType);
loadDataStrategy.loadData(requestParameter, dynamicContext);
}
@Override
protected String doApply(ArmoryCommandEntity requestParameter, DefaultArmoryStrategyFactory.DynamicContext dynamicContext) throws Exception {
return router(requestParameter, dynamicContext);
}
@Override
public StrategyHandler<ArmoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext, String> get(ArmoryCommandEntity armoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext dynamicContext) throws Exception {
return defaultStrategyHandler;
}
}理解并运用规则树设计模式框架。
3.3 数据加载
3.3.1 定义策略接口
public interface ILoadDataStrategy {
void loadData(ArmoryCommandEntity armoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext dynamicContext);
}@Data
public class ArmoryCommandEntity {
/**
* 命令类型
*/
private String commandType;
/**
* 命令索引(clientId、modelId、apiId...)
*/
private List<String> commandIdList;
}- ArmoryCommandEntity,对象用于请求加载数据策略。
- 数据加载的核心思路是:通过策略模式指定要加载的数据类型,然后传入一组 ID 集合(统一为
String类型)。无论加载哪类数据,最终都基于这种统一的策略入口完成处理。
3.3.2 策略1;Client 数据
@Slf4j
@Service("aiClientLoadDataStrategy")
public class AiClientLoadDataStrategy implements ILoadDataStrategy {
@Resource
private IAgentRepository repository;
@Resource
protected ThreadPoolExecutor threadPoolExecutor;
@Override
public void loadData(ArmoryCommandEntity armoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext dynamicContext) {
List<String> clientIdList = armoryCommandEntity.getCommandIdList();
CompletableFuture<List<AiClientApiVO>> aiClientApiListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_api) {}", clientIdList);
return repository.queryAiClientApiVOListByClientIds(clientIdList);
}, threadPoolExecutor);
CompletableFuture<List<AiClientModelVO>> aiClientModelListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_model) {}", clientIdList);
return repository.AiClientModelVOByClientIds(clientIdList);
}, threadPoolExecutor);
CompletableFuture<List<AiClientToolMcpVO>> aiClientToolMcpListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_tool_mcp) {}", clientIdList);
return repository.AiClientToolMcpVOByClientIds(clientIdList);
}, threadPoolExecutor);
CompletableFuture<List<AiClientSystemPromptVO>> aiClientSystemPromptListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_system_prompt) {}", clientIdList);
return repository.AiClientSystemPromptVOByClientIds(clientIdList);
}, threadPoolExecutor);
CompletableFuture<List<AiClientAdvisorVO>> aiClientAdvisorListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_advisor) {}", clientIdList);
return repository.AiClientAdvisorVOByClientIds(clientIdList);
}, threadPoolExecutor);
CompletableFuture<List<AiClientVO>> aiClientListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client) {}", clientIdList);
return repository.AiClientVOByClientIds(clientIdList);
}, threadPoolExecutor);
}
}如前文所述,一个 Client 的加载需要按顺序装配其所依赖的全部资源,因此这部分的数据加载最为全面,需依次获取:ai_client_api、ai_client_model、ai_client_tool_mcp、ai_client_system_prompt、ai_client_advisor、ai_client。
上述逻辑均属于 CRUD 操作,应在基础设施层实现并对外提供统一查询能力。可参考:AgentRepository.queryAiClientApiVOListByClientIds 等方法的具体实现,按 Client ID 集合 批量加载相关资源,完成装配所需的数据准备。
3.3.3 策略2;Mode 数据
@Slf4j
@Service
public class AiClientModelLoadDataStrategy implements ILoadDataStrategy {
@Resource
private IAgentRepository repository;
@Resource
protected ThreadPoolExecutor threadPoolExecutor;
@Override
public void loadData(ArmoryCommandEntity armoryCommandEntity, DefaultArmoryStrategyFactory.DynamicContext dynamicContext) {
List<String> modelIdList = armoryCommandEntity.getCommandIdList();
CompletableFuture<List<AiClientApiVO>> aiClientApiListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_api) {}", modelIdList);
return repository.queryAiClientApiVOListByModelIds(modelIdList);
}, threadPoolExecutor);
CompletableFuture<List<AiClientModelVO>> aiClientModelListFuture = CompletableFuture.supplyAsync(() -> {
log.info("查询配置数据(ai_client_model) {}", modelIdList);
return repository.AiClientModelVOByModelIds(modelIdList);
}, threadPoolExecutor);
}
}注意:本节无需运行代码,只需理解并掌握结构与实现思路。后续我们会逐步完善流程并补充对应的测试用例。