一、引言:模型层是智能体的"大脑接口"
在 AgentScope Java 2.0 的构建块体系中,Model(模型) 是连接智能体推理引擎与大语言模型的唯一桥梁。官方文档将其定位为:
io.agentscope.core.model 是 AgentScope 2.0 的模型接入层,提供统一的 LLM 调用抽象。
一个 Agent 框架真正的模型复杂度,不在"把 messages 发给 LLM、把响应流回来"这条主干——AgentScope 已经用 Model + Formatter 把这件事做完了,而且做得很干净。真正的复杂度在于:多 Key 怎么轮转、坏 Key 怎么摘除、限流配额怎么闸、失败怎么降级、成本怎么核算、配置怎么热更新。
本文将系统解析 AgentScope Java 2.0 模型层的三层架构、Formatter 适配机制、ModelRegistry 全局注册、FallbackModel 容错设计以及生产级治理实践。
二、三层调用抽象:Model → ChatModelBase → Formatter
AgentScope Java 2.0 的模型层采用三层调用抽象,这是其最核心的架构设计:
┌─────────────────────────────────────────────────────────────┐
│ Agent 层(ReActAgent / HarnessAgent) │
│ 只依赖 Model 接口,对具体实现透明 │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 第一层:Model 接口(统一抽象) │
│ 定义 generate() / streamGenerate() 契约 │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 第二层:ChatModelBase(抽象基类) │
│ 封装流式调用、错误处理、重试逻辑、事件发射等通用逻辑 │
└────────────────────────────┬────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 第三层:Formatter(格式适配器) │
│ 屏蔽不同模型提供商的消息格式、工具描述、响应解析差异 │
└─────────────────────────────────────────────────────────────┘
2.1 核心设计理念
| 接口统一 | 所有模型通过 Model 接口接入,对上层 Agent 完全透明 |
| 基类复用 | ChatModelBase 封装流式调用、错误处理等通用逻辑 |
| Builder 模式 | 每个模型提供 Builder,支持链式配置 |
| 全局注册 | ModelRegistry 支持按名称解析模型(如 “dashscope:qwen-plus”) |
| 格式隔离 | Formatter 机制屏蔽不同模型提供商的格式差异 |
三、Model 接口:统一调用契约
3.1 接口定义
Model 是模型层最顶层的抽象接口,定义了 Agent 与 LLM 交互的最小契约:
package io.agentscope.core.model;
public interface Model {
/**
* 同步调用:发送消息列表,返回完整响应
*/
Mono<ChatResponse> generate(List<Msg> messages, GenerateOptions options);
/**
* 流式调用:发送消息列表,返回响应事件流
*/
Flux<ChatResponse> streamGenerate(List<Msg> messages, GenerateOptions options);
/**
* 获取模型名称
*/
String getModelName();
}
3.2 设计要点
- 响应式原生:基于 Project Reactor 的 Mono / Flux,天然支持异步非阻塞
- 消息无关性:接收统一的 List,不关心消息来自哪个 Agent 或哪个用户
- 选项透传:GenerateOptions 承载所有生成参数,与具体模型实现解耦
四、ChatModelBase:通用逻辑的抽象基类
4.1 职责定位
ChatModelBase 是所有具体模型实现的公共基类,封装了与具体提供商无关的通用逻辑:
package io.agentscope.core.model;
public abstract class ChatModelBase implements Model {
// === 通用能力 ===
protected final String modelName;
protected final Formatter formatter;
protected final ExecutionConfig executionConfig;
/**
* 模板方法:子类只需实现 doGenerate / doStreamGenerate
*/
@Override
public final Mono<ChatResponse> generate(List<Msg> messages, GenerateOptions options) {
// 1. 通过 Formatter 将 Msg 转换为提供商特定格式
Object formattedRequest = formatter.formatRequest(messages, options);
// 2. 调用子类的实际 HTTP 请求逻辑
return doGenerate(formattedRequest)
// 3. 通过 Formatter 将提供商响应转换为统一 ChatResponse
.map(rawResponse -> formatter.parseResponse(rawResponse))
// 4. 通用错误处理与重试
.retryWhen(buildRetrySpec());
}
// === 子类必须实现的抽象方法 ===
protected abstract Mono<Object> doGenerate(Object formattedRequest);
protected abstract Flux<Object> doStreamGenerate(Object formattedRequest);
}
4.2 封装的通用逻辑
| 流式调用管理 | SSE 连接建立、心跳检测、超时断开 |
| 错误处理 | 统一异常分类(超时、限流、认证失败、服务不可用) |
| 重试策略 | 基于 ExecutionConfig 的指数退避重试 |
| 事件发射 | 在模型调用前后发射 ModelCallStartEvent / ModelCallEndEvent |
| Token 统计 | 自动解析响应中的 usage 信息 |
五、Formatter:屏蔽提供商差异的适配器
5.1 为什么需要 Formatter?
不同 LLM 提供商的 API 格式差异巨大:
| 消息角色 | system/user/assistant | user/assistant(system 单独字段) | 类 OpenAI | user/model |
| 工具描述 | tools[] | tools[](不同 schema) | tools[] | functionDeclarations |
| 流式格式 | SSE data: | SSE event: | SSE data: | SSE data: |
| 思考过程 | 无 | thinking block | 无 | thought |
| 多模态 | image_url | base64 | image_url | inline_data |
5.2 Formatter 接口
public interface Formatter {
/**
* 将统一 Msg 列表转换为提供商特定的请求格式
*/
Object formatRequest(List<Msg> messages, GenerateOptions options);
/**
* 将提供商的原始响应解析为统一的 ChatResponse
*/
ChatResponse parseResponse(Object rawResponse);
/**
* 将提供商的流式 chunk 解析为统一的 ChatResponse 片段
*/
ChatResponse parseStreamChunk(Object rawChunk);
}
5.3 内置 Formatter 实现
| OpenAIChatFormatter | OpenAI / DeepSeek / Moonshot | 标准 OpenAI 协议 |
| AnthropicChatFormatter | Claude 系列 | system 字段独立、thinking block |
| DashScopeChatFormatter | 通义千问系列 | OpenAI 兼容端点 |
| GeminiChatFormatter | Google Gemini | functionDeclarations、inline_data |
| OllamaChatFormatter | 本地 Ollama | 简化协议、无认证 |
5.4 设计优势
Formatter 让"换模型"变成"换一行配置",而非"改一堆代码"。
Agent 层完全不感知底层是 OpenAI 还是 Anthropic——它只操作统一的 Msg 和 ChatResponse。
六、ModelRegistry:字符串即模型
6.1 核心机制
ModelRegistry 是 AgentScope 2.0 的全局模型注册中心,支持以字符串形式声明模型,框架自动解析并实例化:
// 字符串形式 → ModelRegistry 自动解析
.model("dashscope:qwen-plus")
解析规则:{provider}:{model-name}
| “dashscope:qwen-plus” | DashScope | DASHSCOPE_API_KEY |
| “openai:gpt-5.5” | OpenAI | OPENAI_API_KEY |
| “anthropic:claude-sonnet-4-5” | Anthropic | ANTHROPIC_API_KEY |
| “gemini:gemini-2.0-flash” | Gemini | GEMINI_API_KEY |
| “ollama:llama3” | Ollama | 无需 Key(本地) |
| “deepseek:deepseek-chat” | DeepSeek | DEEPSEEK_API_KEY |
6.2 解析流程
.model("dashscope:qwen-plus")
│
▼
ModelRegistry.resolve("dashscope:qwen-plus")
│
├── 1. 解析 provider = "dashscope", modelName = "qwen-plus"
├── 2. 查找已注册的 ModelFactory(SPI 机制)
├── 3. 读取环境变量 DASHSCOPE_API_KEY
├── 4. 构建 DashScopeChatModel 实例
│ .apiKey(envKey)
│ .modelName("qwen-plus")
│ .formatter(new DashScopeChatFormatter())
└── 5. 返回 Model 实例
6.3 手动注册自定义模型
// 注册自定义模型工厂
ModelRegistry.register("my-provider", (modelName, config) -> {
return MyCustomChatModel.builder()
.apiKey(config.getApiKey())
.modelName(modelName)
.baseUrl(config.getBaseUrl())
.formatter(new MyCustomFormatter())
.build();
});
// 使用
.model("my-provider:custom-model-v1")
6.4 直接传入 Model 实例
对于需要精细控制的场景,也可以直接传入 Model 实例:
OpenAIChatModel model = OpenAIChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.5")
.baseUrl("https://api.openai.com/v1")
.formatter(new OpenAIChatFormatter())
.build();
ReActAgent agent = ReActAgent.builder()
.model(model) // 直接传入实例
.build();
七、模型实现类:六大提供商适配器
7.1 支持的模型提供商
AgentScope Java 2.0 通过独立扩展包支持主流模型提供商:
| agentscope-extensions-model-dashscope | 阿里云 DashScope | qwen-plus, qwen-max, qwen-turbo |
| agentscope-extensions-model-openai | OpenAI | gpt-5.5, gpt-4o |
| agentscope-extensions-model-anthropic | Anthropic | claude-sonnet-4-5, claude-opus-4 |
| agentscope-extensions-model-gemini | gemini-2.0-flash, gemini-2.5-pro | |
| agentscope-extensions-model-ollama | Ollama(本地) | llama3, qwen2.5:7b |
| agentscope-extensions-model-deepseek | DeepSeek | deepseek-chat, deepseek-reasoner |
7.2 模块化依赖设计
<!– 核心框架(不含任何模型实现) –>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-core</artifactId>
<version>2.0.0</version>
</dependency>
<!– 按需引入模型扩展 –>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-model-dashscope</artifactId>
<version>2.0.0</version>
</dependency>
设计原则:核心轻量化、模型可插拔。业务项目只引入实际使用的模型扩展,避免不必要的依赖膨胀。
7.3 Builder 配置示例
// DashScope
DashScopeChatModel dashscopeModel = DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen-plus")
.build();
// OpenAI
OpenAIChatModel openaiModel = OpenAIChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.5")
.build();
// Anthropic
AnthropicChatModel anthropicModel = AnthropicChatModel.builder()
.apiKey(System.getenv("ANTHROPIC_API_KEY"))
.modelName("claude-sonnet-4-5")
.build();
// Ollama(本地)
OllamaChatModel ollamaModel = OllamaChatModel.builder()
.baseUrl("http://localhost:11434")
.modelName("llama3")
.formatter(new OllamaChatFormatter())
.build();
八、GenerateOptions:生成参数配置
8.1 参数体系
GenerateOptions 承载所有与生成行为相关的参数:
GenerateOptions options = GenerateOptions.builder()
.temperature(0.7) // 采样温度
.topP(0.9) // 核采样
.maxTokens(4096) // 最大生成 Token 数
.stop(List.of("\\n\\n")) // 停止序列
.tools(toolSchemas) // 可用工具描述
.responseFormat("json") // 响应格式(可选)
.build();
8.2 参数分类
| 采样控制 | temperature, topP, topK | 控制生成多样性 |
| 长度控制 | maxTokens | 限制输出长度 |
| 停止条件 | stop | 遇到指定序列停止生成 |
| 工具调用 | tools, toolChoice | 声明可用工具与调用策略 |
| 输出格式 | responseFormat | 强制 JSON 输出等 |
| 提供商特有 | extraParams | 透传提供商特有参数 |
九、ExecutionConfig:执行策略
9.1 职责
ExecutionConfig 控制模型调用的运行时行为:
ExecutionConfig config = ExecutionConfig.builder()
.timeout(Duration.ofSeconds(60)) // 单次调用超时
.maxRetries(3) // 最大重试次数
.retryBackoff(Duration.ofSeconds(2)) // 重试退避基数
.retryMultiplier(2.0) // 指数退避乘数
.build();
9.2 重试策略
第 1 次失败 → 等待 2s → 第 2 次重试
第 2 次失败 → 等待 4s → 第 3 次重试
第 3 次失败 → 抛出异常 / 触发 FallbackModel
十、ChatResponse 与 ChatUsage:响应与计量
10.1 ChatResponse
模型调用的统一响应结构:
public class ChatResponse {
private final String id; // 响应唯一 ID
private final Msg message; // 助手回复消息
private final ChatUsage usage; // Token 用量
private final String finishReason; // 结束原因
private final String model; // 实际使用的模型
private final Map<String, Object> metadata; // 扩展元数据
}
10.2 ChatUsage:Token 用量
public class ChatUsage {
private final int promptTokens; // 输入 Token 数
private final int completionTokens; // 输出 Token 数
private final int totalTokens; // 总 Token 数
}
生产意义:ChatUsage 是 Token 计费、成本核算、预算控制的数据基础。结合 Middleware 的 onModelCall 钩子,可以实现精确的用量追踪。
十一、FallbackModel:主备模型容错
11.1 设计动机
生产环境中,模型调用可能因以下原因失败:
- 网络超时
- 提供商限流(429)
- 服务暂时不可用(503)
- API Key 过期或无效
一次失败可能中断整条任务链。FallbackModel 解决的核心问题是:主模型挂了,任务不能断。
11.2 工作机制
FallbackModel fallbackModel = FallbackModel.builder()
.primary(dashscopeModel) // 主模型
.fallback(openaiModel) // 备用模型
.maxRetries(2) // 主模型最大重试次数
.retryableErrors( // 可重试的错误类型
TimeoutException.class,
RateLimitException.class,
ServiceUnavailableException.class
)
.build();
// 对 Agent 完全透明
ReActAgent agent = ReActAgent.builder()
.model(fallbackModel)
.build();
11.3 执行流程
Agent 发起模型调用
│
▼
FallbackModel.generate()
│
├── 尝试主模型(DashScope)
│ ├── 成功 → 返回结果
│ └── 失败(超时/限流/503)
│ ├── 重试次数未耗尽 → 重试主模型
│ └── 重试次数耗尽 → 切换备用模型
│
└── 尝试备用模型(OpenAI)
├── 成功 → 返回结果
└── 失败 → 抛出最终异常
11.4 多级 Fallback 链
FallbackModel model = FallbackModel.builder()
.primary(dashscopeModel) // 第一优先
.fallback(openaiModel) // 第二优先
.fallback(anthropicModel) // 第三优先
.build();
11.5 对上层透明
FallbackModel 是一个装饰器(Decorator),对 Agent 层完全透明。Agent 不知道也不关心底层是主模型还是备用模型在响应。
十二、模型认证层:CredentialBase
12.1 认证抽象
AgentScope 2.0 将模型认证抽象为独立的 CredentialBase 体系:
public abstract class CredentialBase {
public abstract String getType(); // 认证类型
public abstract Map<String, String> toHeaders(); // 转为 HTTP Headers
}
12.2 八种认证实现
| API Key | 最常见的 Bearer Token |
| OAuth 2.0 | 企业级 OAuth 流程 |
| AK/SK | 阿里云 AccessKey |
| JWT | JSON Web Token |
| mTLS | 双向 TLS 证书 |
| Custom Header | 自定义请求头 |
| No Auth | 本地模型(如 Ollama) |
| Managed | 托管认证 |
12.3 ModelCard:模型元数据
ModelCard card = ModelCard.builder()
.provider("dashscope")
.modelName("qwen-plus")
.maxContextLength(128000)
.supportsTools(true)
.supportsVision(true)
.supportsStreaming(true)
.build();
十三、与 Middleware 的协作:onModelCall
13.1 模型调用的中间件拦截
Middleware 的 onModelCall 钩子精确包裹每次底层模型 API 调用:
public class TokenBillingMiddleware extends MiddlewareBase {
@Override
public Mono<ModelCallResponse> onModelCall(
ModelCallRequest request, MiddlewareChain chain) {
long startTime = System.nanoTime();
return chain.next(request)
.doOnNext(response -> {
long duration = System.nanoTime() – startTime;
// 记录 Token 用量
billingService.record(BillingRecord.builder()
.modelName(request.getModelName())
.promptTokens(response.getUsage().getPromptTokens())
.completionTokens(response.getUsage().getCompletionTokens())
.durationMs(duration / 1_000_000)
.timestamp(Instant.now())
.build());
});
}
}
13.2 典型生产组合
// 模型调用链路上的 Middleware 叠加
.middleware(new OtelTracingMiddleware()) // 链路追踪
.middleware(new RateLimitMiddleware(200)) // 限流
.middleware(new TokenBillingMiddleware()) // 计费
.middleware(new ModelFallbackMiddleware()) // 降级策略
十四、Spring Boot 集成
14.1 Bean 注册方式
@Configuration
public class ModelConfig {
@Bean
public Model createModel() {
return DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen-max")
.build();
}
@Bean
public HarnessAgent createAgent(Model model) {
return HarnessAgent.builder()
.name("production-agent")
.model(model)
.workspace(Paths.get("/data/workspace"))
.build();
}
}
### 14.2 application.yml 配置
yaml
编辑
agentscope:
core:
model:
dashscope:
api–key: ${DASHSCOPE_API_KEY}
model–name: qwen–plus
timeout: 60s
max–retries: 3
## 十五、传输层:OkHttp / JDK HTTP / WebSocket
### 15.1 多传输协议支持
AgentScope 2.0 的模型层底层支持多种 HTTP 传输实现:
表格
传输层适用场景
OkHttp默认选择,连接池管理成熟
JDK HttpClient无额外依赖,JDK 11+ 原生
WebSocket长连接场景,低延迟流式
### 15.2 流式传输
文本
编辑
Client Model Provider
│ │
│── POST /chat/completions ──────→│
│ (stream: true) │
│ │
│←── SSE: data: {"delta":"你"} ──│
│←── SSE: data: {"delta":"好"} ──│
│←── SSE: data: {"delta":"!"} ──│
│←── SSE: data: [DONE] ──────────│
│ │
框架自动将 SSE 事件流转换为 Flux<ChatResponse>,上层通过 streamEvents() 消费。
十六、模型对凭证是无状态的
16.1 关键架构事实
模型对凭证是无状态的。
这意味着:
Model 实例可以被多个 Agent、多个用户安全共享
凭证(API Key)在构建时注入,运行时不可变
不需要为每个请求创建新的 Model 实例
天然支持多租户场景下的模型复用
16.2 生产部署模式
java
编辑
// 应用启动时创建一次(单例)
@Bean
public Model sharedModel() {
return DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen-plus")
.build();
}
// 所有 Agent 共享同一个 Model 实例
// 不同用户通过 RuntimeContext 隔离,而非 Model 隔离
十七、完整实战:多模型容错 + 流式输出
17.1 生产级模型配置
java
编辑
@Configuration
public class ProductionModelConfig {
@Bean
public Model productionModel() {
// 主模型:DashScope
Model primary = DashScopeChatModel.builder()
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.modelName("qwen-max")
.executionConfig(ExecutionConfig.builder()
.timeout(Duration.ofSeconds(60))
.maxRetries(2)
.build())
.build();
// 备用模型:OpenAI
Model backup = OpenAIChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-5.5")
.build();
// 组合为 FallbackModel
return FallbackModel.builder()
.primary(primary)
.fallback(backup)
.maxRetries(2)
.build();
}
@Bean
public HarnessAgent agent(Model model) {
return HarnessAgent.builder()
.name("customer-service")
.sysPrompt("你是企业客服助手。")
.model(model)
.workspace(Paths.get("/data/agentscope/workspace"))
.middleware(new OtelTracingMiddleware())
.middleware(new TokenBillingMiddleware())
.compaction(CompactionConfig.builder()
.triggerMessages(50)
.keepMessages(15)
.build())
.build();
}
}
17.2 流式调用 + 模型切换感知
java
编辑
@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<String>> chat(@RequestParam String message) {
RuntimeContext ctx = RuntimeContext.builder()
.sessionId(UUID.randomUUID().toString())
.userId("user-001")
.build();
return agent.streamEvents(new UserMessage(message), ctx)
.flatMap(event -> {
if (event instanceof TextBlockDeltaEvent delta) {
return Flux.just(ServerSentEvent.<String>builder()
.data(delta.getDelta())
.build());
}
if (event instanceof ModelCallEndEvent end) {
// 记录实际使用的模型(可能是备用模型)
log.info("Model used: {}, tokens: {}",
end.getModelName(), end.getUsage().getTotalTokens());
}
return Flux.empty();
});
}
十八、自定义模型适配器开发
18.1 实现步骤
当需要接入一个框架尚未内置的模型提供商时:
// 1. 实现 Formatter
public class MyProviderFormatter implements Formatter {
@Override
public Object formatRequest(List<Msg> messages, GenerateOptions options) {
// 将统一 Msg 转换为 MyProvider 的 JSON 格式
Map<String, Object> request = new HashMap<>();
request.put("model", "my-model-v1");
request.put("messages", messages.stream()
.map(this::convertMessage)
.toList());
return request;
}
@Override
public ChatResponse parseResponse(Object rawResponse) {
// 将 MyProvider 的响应解析为统一 ChatResponse
// …
}
@Override
public ChatResponse parseStreamChunk(Object rawChunk) {
// 解析流式 chunk
// …
}
}
// 2. 继承 ChatModelBase
public class MyProviderChatModel extends ChatModelBase {
private final String apiKey;
private final String baseUrl;
private final HttpClient httpClient;
public MyProviderChatModel(Builder builder) {
super(builder.modelName, new MyProviderFormatter(), builder.executionConfig);
this.apiKey = builder.apiKey;
this.baseUrl = builder.baseUrl;
this.httpClient = HttpClient.newHttpClient();
}
@Override
protected Mono<Object> doGenerate(Object formattedRequest) {
// 发送 HTTP 请求到 MyProvider API
return Mono.fromCallable(() -> {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/chat"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(
objectMapper.writeValueAsString(formattedRequest)))
.build();
HttpResponse<String> response = httpClient.send(
request, HttpResponse.BodyHandlers.ofString());
return objectMapper.readValue(response.body(), Map.class);
});
}
@Override
protected Flux<Object> doStreamGenerate(Object formattedRequest) {
// 实现 SSE 流式调用
// …
}
// Builder
public static Builder builder() { return new Builder(); }
public static class Builder {
String apiKey;
String baseUrl;
String modelName;
ExecutionConfig executionConfig;
// … 链式方法
}
}
// 3. 注册到 ModelRegistry
ModelRegistry.register("my-provider", (modelName, config) -> {
return MyProviderChatModel.builder()
.apiKey(config.getApiKey())
.baseUrl(config.getBaseUrl())
.modelName(modelName)
.build();
});
// 4. 使用
.model("my-provider:my-model-v1")
十九、与其他构建块的协作关系
┌─────────────────────────────────────────────────────────────────┐
│ Agent 层 │
│ ReActAgent / HarnessAgent │
│ 调用 model.generate() / model.streamGenerate() │
└──────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Middleware 层 │
│ onModelCall → 追踪 / 限流 / 计费 / 降级 │
└──────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Model 层 │
│ FallbackModel → ChatModelBase → Formatter → HTTP │
└──────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Event 层 │
│ ModelCallStartEvent → TextBlockDeltaEvent → ModelCallEndEvent │
└─────────────────────────────────────────────────────────────────┘
二十、设计哲学总结
20.1 三个核心原则
| 调用与治理分离 | Model + Formatter 解决"调用";Middleware + FallbackModel 解决"治理" |
| 模型对凭证无状态 | 单实例服务所有用户,通过 RuntimeContext 隔离 |
| 可插拔、可扩展 | 独立扩展包 + SPI 注册 + 自定义 Formatter |
20.2 与其他框架的对比
| 维度 | AgentScope 2.0 | Spring AI | LangChain4j |
| 模型抽象 | Model + Formatter 三层 | ChatModel 单层 | ChatLanguageModel 单层 |
| 格式适配 | 独立 Formatter,可替换 | 内置在各实现中 | 内置在各实现中 |
| 容错机制 | FallbackModel 原生支持 | 需自行实现 | 需自行实现 |
| 字符串解析 | ModelRegistry 全局注册 | 配置文件 | 无 |
| 流式支持 | Flux 原生 | Flux | TokenStream |
| 中间件拦截 | onModelCall 精确钩子 | Advisor 模式 | 有限 |
二十一、结语
AgentScope Java 2.0 的 Model 构建块,用三层抽象(Model → ChatModelBase → Formatter)实现了"换模型如换配置"的极致灵活性,用 ModelRegistry 实现了"字符串即模型"的极简开发体验,用 FallbackModel 实现了"主模型挂了任务不断"的生产级容错。
它的核心价值在于:
将"模型调用"这件看似简单的事情,拆解为调用、适配、容错、治理四个独立关注点,每个关注点都有清晰的抽象边界和扩展点。
对于 Java 开发者而言,这套设计完美契合了 SOLID 原则:
- S(单一职责):Formatter 只管格式,ChatModelBase 只管通用逻辑
- O(开闭原则):新增提供商只需新增扩展包,不改核心代码
- L(里氏替换):任何 Model 实现可无缝替换
- I(接口隔离):Agent 只依赖 Model 接口
- D(依赖倒置):高层 Agent 不依赖低层 HTTP 实现
模型是智能体的大脑,而 AgentScope 的 Model 层,是让这颗大脑稳定、可靠、可替换地跳动的"心血管系统"。
网硕互联帮助中心



评论前必须登录!
注册