概述
模型层把共享契约和具体模型提供商实现分开。agentscope-core 只保留通用 API(Model、ChatModelBase、Formatter、ModelRegistry 和 ModelProvider SPI);OpenAI、DashScope、Gemini、Anthropic、Ollama 的具体实现分别位于各自的模型扩展模块中。
运行时模型层采用两层结构:上层是 Credential(基于 io.agentscope.core.credential 中的通用基类),承载某个提供商的 API 鉴权字段;下层是 Chat Model,即在该凭证基础上对接的具体推理模型实现。
apiKey、baseUrl 等)。从一个凭证出发,可以通过 listModels() 获取该提供商支持的模型列表(List<ModelCard>)。
这种分层与前端的自然交互流程一致 —— 先注册凭证,再从凭证下挑选模型 —— 让界面只需鉴权一次,就能展示该提供商支持的所有模型。
模型扩展模块
特定模型提供商的实现已经从agentscope-core 迁移到独立扩展模块中。每个模型适配模块自己维护 chat model、credential、formatter、DTO、异常、SDK/API client 等。
迁移步骤
- 增加对应模型提供商扩展模块依赖。以 DashScope 为例:
agentscope-extensions-model-openai、agentscope-extensions-model-gemini、agentscope-extensions-model-anthropic、agentscope-extensions-model-ollama。
- 将模型提供商实现的 import 从
io.agentscope.core.model.*改为io.agentscope.extensions.model.<provider>.*。 - 将模型提供商 formatter import 从
io.agentscope.core.formatter.<provider>.*改为io.agentscope.extensions.model.<provider>.formatter.*。 - Spring Boot 应用中,改用对应提供商 starter 和
agentscope.<provider>.*配置:
选择模型创建方式
字符串 model id
简单的非 Spring 应用可以使用dashscope:qwen-plus、openai:gpt-4.1-mini、deepseek:deepseek-v4-flash 这样的字符串 id。引入对应模型扩展模块,设置模型提供商的标准环境变量,例如 DASHSCOPE_API_KEY、OPENAI_API_KEY 或 DEEPSEEK_API_KEY,然后直接把 id 传给 agent:
DASHSCOPE_API_KEY、OPENAI_API_KEY、GLM_API_KEY、DEEPSEEK_API_KEY、ANTHROPIC_API_KEY、GEMINI_API_KEY。Ollama 会在存在时读取 OLLAMA_BASE_URL,否则默认使用本地 Ollama endpoint。
显式 Model builder
需要自定义 API key、base URL、formatter、transport、timeout、生成参数或其他提供商专属配置时,推荐显式构造模型,再把Model 实例传给 agent:
Spring Boot 应用
Spring Boot 场景下,优先使用特定模型提供商的 starter,例如agentscope-openai-spring-boot-starter、agentscope-dashscope-spring-boot-starter、agentscope-gemini-spring-boot-starter、agentscope-anthropic-spring-boot-starter、agentscope-ollama-spring-boot-starter。这些 starter 直接依赖对应模型扩展模块,创建 Spring 管理的 Model bean,通用的 agentscope-spring-boot-starter 继续负责 AgentScope 的公共基础设施。它们不会通过静态 ModelRegistry 创建模型;高级用户始终可以自定义 Model bean。
OpenAI 示例:
Builder customizer
各模型提供商的 Spring Boot starter 还提供了有序的 builder customizer bean。它适合用于application.yml 已覆盖常见配置、但仍需要设置 builder 专属能力的场景,例如自定义
formatter、默认生成参数、代理/client 配置,或其他提供商专属开关。
这些 customizer 会在 starter 属性绑定之后、调用
builder.build() 之前执行。可以注册多个
customizer,并通过 Spring 的 @Order 或 Ordered 控制执行顺序。
ModelRegistry 与 ModelCreationContext
ModelRegistry 是一个用于模型实例创建与查找的全局注册中心,支持多种解析策略。解析时按优先级依次尝试:通过 ModelRegistry.register(name, model) 直接注册的命名模型实例、通过 registerFactory(regex, factory) 注册的自定义工厂,以及通过 Java SPI 机制自动发现的扩展模块提供的 ModelProvider 实现。
简单场景推荐使用 provider:model 格式的 id 和模型提供商的标准环境变量;需要精细控制时,优先使用显式的模型 Builder。ModelCreationContext 主要面向需要动态解析模型的集成层代码。
高级集成上下文
ModelCreationContext 面向需要动态创建模型、但不方便直接依赖具体提供商 builder 的集成层代码,例如多租户网关、插件系统或框架适配层。它可以把 API key、base URL、endpoint path、stream 模式,以及扩展模块定义的 options/components 传给 SPI 提供商实现:
缓存策略
ModelRegistry 会缓存简单provider:model解析出的模型。带 context(ModelCreationContext)解析出的模型默认不缓存,避免不同租户的 API key、base URL 或 stream 配置复用到同一个模型实例。
如果
CachePolicy.ENABLED 搭配 option(...) 或 component(...) 使用,用户必须提供 cacheId。
ModelProvider SPI
模型提供商扩展模块通过 Java SPI 暴露META-INF/services/io.agentscope.core.model.spi.ModelProvider,由 ModelRegistry 自动发现。新的模型提供商可以实现 supports(String, ModelCreationContext) 和 create(String, ModelCreationContext) 来消费 context。简单模型提供商仍可只实现原有的 supports(String) 和 create(String),因为 context-aware 方法提供了兼容默认实现。
Chat Model
Chat Model 是驱动 agent 对话与工具调用的 LLM,输入输出可以是文本之外的多模态内容。AgentScope Java 当前提供以下 Chat Model 类:
模型提供商凭证类随对应模型扩展模块提供,例如
OpenAICredential、AnthropicCredential、DashScopeCredential、GeminiCredential、OllamaCredential。OpenAI 兼容提供商的 DeepSeekCredential、KimiCredential、XAICredential 仍在 core 模块中可用。
创建 Chat Model
每个 Chat Model 通过 builder 构造,最常见的字段是apiKey、modelName、stream、formatter、defaultOptions。下面三个 tab 分别展示流式、工具调用与推理三种典型初始化场景:
- Streaming
- Tools
- Reasoning
调用 Chat Model
Model 接口暴露统一的 stream(messages, tools, options),返回 Flux<ChatResponse>:
ChatResponse 包含若干 content block(TextBlock、ThinkingBlock、ToolUseBlock、DataBlock)以及记录 token 数与耗时的 ChatUsage。
实际开发中通常不需要直接调模型,而是通过 ReActAgent 调度;要直连模型做轻量调用时,推荐参考 agentscope-examples/documentation/.../model/ModelRegistryExample.java。
生成结构化输出
Agent 层提供把模型输出绑定到 Java POJO 的便捷重载,由ReActAgent.call(msgs, structuredOutputClass, runtimeContext) 暴露:
Msg.metadata 的 structured_output 字段,供 getStructuredData(Class) 直接反序列化。完整示例:agentscope-examples/documentation/.../structuredoutput/StructuredOutputExample.java。
结构化输出路径选择
框架提供两条结构化输出路径:
当 native 路径失败(如模型返回 400),框架会自动降级到 fallback 路径,无需用户干预。
各模型提供商默认行为
DashScope 用户注意:DashScope 的思考模式(enableThinking(true))不支持结构化输出,框架会强制走 fallback 路径。
显式配置
如果确认你的模型/端点支持json_schema,可以通过 builder 开启 native 路径:
结构化输出与工具调用共存
当 Agent 同时注册了工具并请求结构化输出时,部分 OpenAI 兼容 API(如 Kimi、Deepseek 等)会优先遵循response_format 约束而跳过工具调用。设置 nativeStructuredOutputWithTools(false) 可解决此问题:
DashScopeChatModel 同样支持此配置。对于 OpenAI 原生模型(GPT-4o 等)无需设置。
Formatter
Formatter 负责把 AgentScope 的Msg 对象转换为各提供商 API 期望的请求载荷。它通过 Chat Model builder 的 formatter(...) 字段配置。每个提供商内置两种 formatter:
切换到多 agent 模式只需传入 MultiAgent 变体,无需修改 agent 代码:
如果提供商的载荷格式不属于以上几种,开发者可以实现
Formatter<TReq, TResp, TParams> 接口(位于 io.agentscope.core.formatter),并通过同一个 formatter(...) 字段传入。
自定义模型提供商
接入自定义模型提供商的最小路径是:实现一个CredentialBase 子类与一个 ChatModelBase 子类。
步骤 1:定义 Credential
继承CredentialBase,实现 getChatModelClass():
步骤 2:实现 Chat Model
继承ChatModelBase,实现 doStream:
步骤 3:注册到 ModelRegistry(可选)
ModelRegistry 可以让 ReActAgent.builder().model("provider:model-name") 字符串化解析模型:
前端集成
什么是 ModelCard
ModelCard(credential/ModelCard.java)是对模型能力与约束的声明式描述,用于驱动前端 —— 模型选择器、参数表单、能力开关都可以基于它动态渲染,无需在前端硬编码任何提供商相关的逻辑。
当前 ModelCard 是一个最小化的 record,包含:
ModelCard 字段当前最小化;能力标记(输入/输出 MIME 类型)与参数 schema 将随模型发现基础设施完善而扩展。
获取 ModelCard
通过CredentialBase#listModels() 获取 Model Card,返回 Mono<List<ModelCard>>:
getChatModelClass() 返回对应的 ChatModelBase 子类,可用于反向构造默认 model: