AgentCore Java SDK 使用指南

更新时间:
复制 MD 格式

Java 应用调用 AgentCore 的模型、MCP、Skill、记忆和凭证时,需要自行处理连接地址、访问凭证和协议封装。AgentCore Java SDK 把这些云端资源统一到一个 AgentCore 客户端入口,并提供 Spring AI、LangChain4j、AgentScope Java 三个框架的适配模块,用于构建对外提供 AG-UI 与 OpenAI Chat Completions 服务的 Agent 应用。本文按安装、初始化客户端、调用云端与自定义资源、接入框架、部署并调用服务的顺序,给出从依赖引入到接口可用的完整实现路径。

前提条件

开始之前,确认以下条件已满足:

  1. 已开通 AgentCore,并在 AgentCore 控制台 创建 Workspace,操作方法参见管理 Workspace。

  2. 已按下表准备示例使用的资源,并确认 Agent 具有相应的访问权限。

  3. 构建环境为 JDK 17 及以上、Maven 3.9 及以上。

占位值

资源

要求

my-model-connection

模型连接

已创建,参见管理模型

my-model

模型

所选模型连接中已配置;框架工具示例要求模型支持工具调用

my-mcp

MCP 服务

已创建,参见管理 MCP 服务

my-skill

Skill

已启用且存在已发布版本,参见管理 Skill

my-memory

MemoryStore

已创建

my-api-key

凭证(API Key)

已创建

my-mcp-header

凭证(MCP Header)

已创建,且允许应用到目标 MCP 服务

本文示例的资源名称统一使用上表中的占位值,实际使用时替换为对应的资源名称。示例中以尖括号书写的部分(如 <工具名>、<参数名>)表示按实际调用填写的参数,以裸标识符书写的部分(如 name、baseUrl)取自所在章节的配置表。仅调用模型时,不需要准备 MCP 服务、Skill、MemoryStore 和额外凭证。

安装 SDK

SDK 发布在 Maven Central,不需要配置额外仓库。向 pom.xml 添加基础 SDK 依赖:

<dependency>
  <groupId>io.github.ai-agentcore</groupId>
  <artifactId>agentcore-sdk</artifactId>
  <version>0.1.0</version>
</dependency>

按需添加同一 groupId 与版本的其余模块。模块分三类:基础 SDK 提供资源接口,server 模块提供协议服务,框架适配模块把资源接入具体的 Agent 框架。

模块(artifactId)

提供的能力

对应框架版本(SDK 0.1.0)

agentcore-sdk

基础 SDK,包含 Model、MCP、Skill、Memory、Credential 资源接口

—

agentcore-sdk-server

AG-UI、OpenAI Chat Completions 与自定义协议服务

—

agentcore-sdk-spring-ai

Spring AI 适配

Spring AI 2.0.1

agentcore-sdk-langchain4j

LangChain4j 适配

LangChain4j 1.20.0

agentcore-sdk-agentscope

AgentScope Java 适配

AgentScope Java 2.0.3

框架模块会引入基础 SDK 和对应框架依赖,不需要重复声明;完整的构件坐标见 Maven Central。代码包名以 io.agentcore 开头,与 Maven groupId io.github.ai-agentcore 不同。

初始化客户端

云端资源的调用都从一个客户端实例发起。AgentCore.auto() 从 AgentCore 运行环境获取访问配置并创建该实例,业务代码中不需要填写平台访问密钥,因此云端资源示例运行在 AgentCore 托管环境内。自有模型、自有 MCP 服务和本地 Skill 不注册为平台资源,由应用提供连接配置,接入方式见接入自定义资源。

在应用生命周期内复用同一个实例,退出时调用 close() 或使用 try-with-resources;不要在单次 HTTP 请求结束后关闭共享的实例。本文后续示例统一以变量 core 指代该实例,模型、MCP、Skill、记忆与凭证的调用都在 core 的生命周期内完成,首个示例见调用云端模型。

基础 API 返回 Reactor 的 Mono 与 Flux,响应式调用必须被订阅才会执行,示例中的 block() 用于把响应式返回值取出到普通主线程。

重要

block() 仅用于普通主线程。WebFlux 等响应式请求应组合返回值,不阻塞事件循环。本文后续示例为突出资源调用本身统一使用 block(),该约束在所有章节同样适用。

代码示例聚焦调用结构本身,text、query、input 等变量与省略号 ... 均为占位,编写实际代码时需按上下文补全;各节末尾给出的完整示例可直接运行。

调用云端模型

调用云端模型时分别指定模型连接名和模型名,不需要手动拼接服务地址。

try (var core = AgentCore.auto()) {
    var model = core.model("my-model-connection", "my-model").block();
    var response = model.completion(
            List.of(Map.of("role", "user", "content", "用一句话介绍杭州。")),
            Map.of("temperature", 0.2)).block();
}

流式输出使用 stream:

model.stream(messages).doOnNext(System.out::println).blockLast();

普通调用与流式调用是两次独立请求,响应结构由模型协议决定,OpenAI 与 Anthropic 协议返回的字段不同。使用 OpenAI 协议时还可以调用 responses(input, parameters) 与 responsesStream(input, parameters),前提是模型支持 Responses API。

重要

Responses 调用失败时,SDK 不会自动改为 Chat Completions,失败直接返回给调用方。模型不支持 Responses API 时,使用 completion 与 stream 调用。

托管模型客户端不提供 Embedding 能力。直连 OpenAI 兼容客户端的 embedding(input, parameters) 仅适用于支持向量生成的服务。

使用 MCP 工具

MCP 客户端在 core 的生命周期内使用:

var mcp = core.mcp("my-mcp").block();
mcp.listTools().block();
mcp.callTool("<工具名>", Map.of("<参数名>", "<参数值>")).block();

listTools() 只发现工具,不执行工具;callTool() 按工具名和参数发起调用。

需要模型自行选择并执行工具时,把工具注册到 Agent 框架,具体见使用 LangChain4j 构建 Agent 服务和集成其他框架。单独调用模型不会自动执行 MCP 工具。

使用 Skill

加载平台 Skill 并取出其工具:

var skill = core.skills().load("my-skill", "1.0.0").block();
skill.tools();

版本号 1.0.0 必须是已发布版本;省略版本号时解析为最新版本。同一个 core 实例会固定首次成功加载的版本,建议显式指定版本号。

本地 Skill 从目录加载:

core.skills().local(Path.of("./skills")).block();

每个 Skill 包含 SKILL.md 及其引用文件。加载多个 Skill 时,使用 io.agentcore.skill.Skill.tools(skills, workingDirectory) 统一生成工具。

重要

加载 Skill 不等于执行 Skill,运行环境需要预先安装脚本依赖。Skill 脚本的执行权限与命令执行开关见安全约束。

使用记忆

本文用“记忆”指代长期记忆的保存与检索能力,承载该能力的资源实例统一称 MemoryStore。MemoryStore 不替代 Agent 框架的对话历史,检索结果由业务代码或框架适配器提供给模型。

写入与检索记忆:

var store = core.memory("my-memory");

var writeScope = new MemoryScope("example-user", "example-agent", "example-session");
store.addMemories(text, writeScope).block();

var readScope = new MemoryScope("example-user", "example-agent", null);
store.searchMemories(query, readScope, 5).block();

检索时把 sessionId 传为 null,表示跨会话检索。

参数

说明

userId

业务用户的逻辑标识

agentId

Agent 的逻辑标识

sessionId

会话标识;检索时指定则限制到该会话

topK

返回结果数量上限

Workspace 来自 core 的资源上下文,不需要重复传入。多用户场景必须显式设置范围,范围字段的可信来源要求见安全约束。

除写入与检索外,MemoryStore 还支持 listMemories、getMemory、updateMemory、deleteMemory、listMemorySessions 和 listMemorySessionMessages。查询会话消息需要提供会话 ID,并至少提供 userId 或 agentId。

说明

新写入的记忆可能需要一定时间才能被检索到。首次检索为空时,先确认写入调用是否成功,再核对读写两次使用的 userId、agentId 与 sessionId 是否一致,不要反复写入。

在框架中使用记忆

三个框架都先构造 MemoryContext,再按各自方式注册:

new MemoryContext(core.memory("my-memory"), readScope, writeScope, 5);

框架

接入方式

Spring AI

为 ChatClient 注册 MemoryAdvisor

LangChain4j

注册 MemoryAdapter.retriever(),并使用 call() 或 stream()

AgentScope Java

为 ReActAgent 注册 MemoryMiddleware

自动回写默认关闭。LangChain4j 通过 MemoryAdapter 构造函数的第二个参数开启,示例中为 new MemoryAdapter(memory, true);上例的 MemoryContext 为四参数构造形式,不含布尔开关。回写只保存本轮用户输入和正常完成的最终文本答案,不重复写入历史消息和工具结果;开启自动回写后不要再手动写回同一轮内容。仅注册 retriever() 时只检索、不回写。

LangChain4j 接入示例:

var adapter = new MemoryAdapter(memory, true);
var assistant = AiServices.builder(Assistant.class)
        .streamingChatModel(AgentCoreLangChain4j.streamingModel(model))
        .contentRetriever(adapter.retriever())
        .build();
adapter.stream(input, () -> assistant.chat(input));

adapter.stream(...) 返回事件流。Spring AI 的 MemoryAdvisor 作用于 ChatClient 调用链,不作用于直接调用 SpringAIEvents.stream 的独立流程。记忆适配的完整示例见 Java SDK 示例 中的 MemoryAdapters.java。

使用凭证和 MCP Header

获取托管凭证:

core.credentials().get("my-api-key").block().value();
core.credentials().get("my-mcp-header").block().asHeaders();

value() 用于获取 API Key,asHeaders() 用于获取 MCP Header。凭证值的保存与输出约束见安全约束。

为 MCP 服务绑定凭证:

core.mcp("my-mcp", "my-mcp-header", Map.of("X-Business-Id", "my-app")).block();

绑定的 Header 凭证必须允许应用到该 MCP 服务。不需要凭证时使用 core.mcp("my-mcp");只固定 Header、不绑定凭证时,第二个参数传 null。

Header 是客户端级别的固定配置,作用于握手、工具发现和工具调用,不是每个请求的用户身份。使用时注意以下限制:

  • Header 名称大小写不敏感;出现冲突时报错,不会静默覆盖。

  • 不能覆盖 Authorization、平台 Header 和 MCP 保留字段。

  • SDK 不会自动复制入站请求的 Header,不要修改共享客户端以切换用户身份。

接入自定义资源

自有模型、自有 MCP 服务和本地 Skill 不需要注册为平台资源,由应用提供连接配置。

core.directModel(name, URI.create(baseUrl), ModelClient.Protocol.OPENAI, headerProvider);
core.directMcp(URI.create(url), MCPClient.Transport.STREAMABLE_HTTP, headerProvider);

示例使用以下环境变量提供连接配置,上例中的 name、baseUrl 与 url 即取自该表:

环境变量

说明

CUSTOM_MODEL_NAME

自有模型名称

CUSTOM_MODEL_BASE_URL

OpenAI 兼容服务的 Base URL,通常以 /v1 结尾

CUSTOM_MODEL_API_KEY

自有模型的 API Key,由运行环境或密钥管理服务提供,不硬编码

CUSTOM_MCP_URL

自有 MCP 服务的完整 Streamable HTTP 地址

直连模型同样支持 Protocol.ANTHROPIC:Base URL 不含末尾的 /v1,请求需要指定 max_tokens,认证方式按服务要求配置。直连 MCP 还支持 SSE 与 stdio 传输,其中 stdio 不承载 HTTP Header。

需要同时接入多个供应商时,可以继续使用三个框架的原生 Provider,并复用 AgentCore 的工具与记忆适配。

选择 Agent 框架

三个框架的适配模块能力范围一致,都覆盖模型、工具、执行事件与记忆适配,因此框架选择取决于应用已有的技术栈与 Agent 编排方式,而不是 SDK 侧的功能差异。已有 ChatClient 的项目可以直接注册 MemoryAdvisor 与工具回调;已有原生模型时也可以继续使用框架原生 Provider,并复用 AgentCore 的工具与记忆适配。本文的端到端流程以 LangChain4j 为例展开,其他框架的差异集中在事件转换器与记忆注册方式上。

框架

入口类

工具注册方式

记忆接入

编排特点

Spring AI

AgentCoreSpringAI、SpringAIEvents、MemoryAdvisor

转换为 ToolCallback[],通过 ToolCallingChatOptions 绑定

为 ChatClient 注册 MemoryAdvisor

资源在初始化时加载,Prompt 在每次调用时按请求构造

LangChain4j

AgentCoreLangChain4j、LangChain4jEvents、MemoryAdapter

通过 AgentCoreLangChain4j.tools(...) 注册到 AiServices

注册 MemoryAdapter.retriever(),并使用 call() 或 stream()

由 LangChain4jEvents.from 启动 TokenStream 并转换为服务事件

AgentScope Java

AgentCoreAgentScope、AgentScopeEvents、MemoryMiddleware

通过 toolkit.registerAgentTool(...) 注册

为 ReActAgent 注册 MemoryMiddleware

每个请求创建独立的 ReActAgent

各适配模块对应的框架版本见安装 SDK。完整的端到端步骤见使用 LangChain4j 构建 Agent 服务,Spring AI 与 AgentScope Java 的入口类与差异点见集成其他框架。

使用 LangChain4j 构建 Agent 服务

本节把云端模型、MCP 和 Skill 接入 LangChain4j,并使用 AgentCoreServer 对外提供 AG-UI 与 OpenAI Chat Completions 服务。示例服务每次只处理最新一条用户文本。AgentCoreServer 自身不持久化对话历史,本文示例也未配置 ChatMemory,因此不保存跨请求历史,多轮对话由应用或框架管理。示例未接入记忆,需要长期记忆时按使用记忆显式接入。

步骤一:创建 Maven 项目

向 pom.xml 添加 agentcore-sdk-langchain4j 与 agentcore-sdk-server 依赖,版本均为 0.1.0,并将 maven-compiler-plugin 的 release 设为 17。完整 pom.xml 见 Java SDK 示例。

步骤二:编写应用入口

以下片段为结构示意,省略了变量来源与异常处理,不能直接编译;完整可运行代码见 Java SDK 示例 中的 LangChainAgent.java。

var model = AgentCoreLangChain4j.streamingModel(core.model(...).block());
var tools = core.mcp(...).listTools() + core.skills().load(...).tools();
var assistant = AiServices.builder(Assistant.class)
        .streamingChatModel(model)
        .tools(AgentCoreLangChain4j.tools(tools))
        .build();
new AgentCoreServer(request -> ... LangChain4jEvents.from(() -> assistant.chat(input))).start(9000);

示例把 MCP 工具与 Skill 工具合并后注册到 AiServices;不使用 MCP 或 Skill 时,移除对应的加载与注册代码。

LangChain4jEvents.from 负责启动 TokenStream,并把文本、工具调用、工具结果和消息边界转换为服务事件。不要再手动调用 start(),也不要只转发文本回调,否则会丢失工具执行过程。

步骤三:构建并启动应用

构建应用:

mvn -B -ntp package

构建产物需要同时包含编译结果与运行期依赖。使用 maven-dependency-plugin 的 copy-dependencies 目标(-DincludeScope=runtime)导出运行期依赖,把 target/classes 与 target/dependency 一并放入镜像,并在托管环境的 Linux 容器内启动应用:

java -cp 'target/classes:target/dependency/*' App

命令中的 App 为主类占位,替换为实际的应用主类名。平台侧的运行时、端口、探针与镜像要求和框架无关,见部署 Agent 服务。

集成其他框架

本章给出 Spring AI 与 AgentScope Java 适配的入口类与差异点,不作为端到端流程,完整步骤见各框架的集成指南。构建产物和平台侧部署配置与框架无关,见部署 Agent 服务。

Spring AI

入口类为 io.agentcore.springai.AgentCoreSpringAI、SpringAIEvents 和 MemoryAdvisor。

var model = AgentCoreSpringAI.model(core.model(...).block());
var callbacks = mcp.listTools().stream().map(AgentCoreSpringAI::tool).toArray(ToolCallback[]::new);
var options = ToolCallingChatOptions.mutate().toolCallbacks(callbacks);
var events = SpringAIEvents.stream(model, new Prompt(prompt, options));

资源初始化时加载,Prompt 每次调用时按请求构造。Skill 工具按相同方式注册。已有 ChatClient 可以注册 MemoryAdvisor。集成指南见 spring-ai.md,完整示例见 Java SDK 示例 中的 SpringAIAgent.java。

AgentScope Java

入口类为 io.agentcore.agentscope.AgentCoreAgentScope、AgentScopeEvents 和 MemoryMiddleware。

var model = AgentCoreAgentScope.model(...);
toolkit.registerAgentTool(AgentCoreAgentScope.tool(tool));

每个请求创建独立的 ReActAgent,完成、失败或取消后释放,可使用 Flux.using 包装。需要记忆时注册对应的 MemoryMiddleware。集成指南见 agentscope.md,完整示例见 Java SDK 示例 中的 AgentScopeAgent.java。

复用框架原生 Provider

已有原生模型时,可以直接使用框架原生 Provider,并继续注册 AgentCore 的工具与记忆适配,完整示例见 Java SDK 示例 中的 NativeFrameworkAgents.java。

部署 Agent 服务

以下配置与框架无关,使用 Spring AI、LangChain4j 或 AgentScope Java 部署时同样适用。平台侧的部署配置需要与代码保持一致:

配置项

值

运行时

JRE 17 及以上

监听地址

0.0.0.0

端口

9000,由 start(9000) 显式指定

AG-UI 接口

POST /agui

OpenAI Chat Completions 接口

POST /openai/v1/chat/completions

存活探针

GET /healthz

就绪探针

GET /readyz

重要

Java SDK 0.1.0 的默认 AG-UI 路径为 /agui,不要照搬其他语言 SDK 示例中的路径。容器镜像必须为 Linux amd64,包含 /bin/bash 与 /bin/sh,且镜像仓库可达、可拉取;仅构建出 JAR 不代表镜像已包含这些组件。

需要自定义就绪判断时使用 AgentCoreServer 的 readiness 回调。代码上传、镜像构建和部署不由 SDK 负责,需要在平台侧完成。

验证部署结果

服务启动后按以下顺序确认部署结果:

  1. 请求存活探针 GET /healthz,确认进程已启动。/healthz 不判断下游资源状态,返回正常不代表模型、MCP 或 Skill 已就绪。

  2. 请求就绪探针 GET /readyz,确认资源初始化完成。示例服务在完成资源初始化后才启动。

  3. 按调用 Agent 服务发起一次实际请求,确认返回正常结束事件而不是 RUN_ERROR。

调用 Agent 服务

把 https://<agent-endpoint> 替换为应用的实际地址,并按需补充认证信息。该地址是 Agent 应用的地址,不是模型供应商的地址。

选择协议

对比项

AG-UI

OpenAI Chat Completions

文本输出

支持

支持

消息边界

保留消息开始、内容与结束事件

聚合为一条 assistant 消息

工具调用

保留工具调用 ID 与参数

以 tool_calls 返回

工具结果

以独立事件返回

不提供

适用场景

展示多步执行过程

对接现有 Chat Completions 客户端

框架服务已在服务端执行工具,客户端不要再执行收到的工具调用轨迹;需要完整展示执行过程时,使用 AG-UI 协议配合框架事件转换器。

说明

两个 SSE 接口在空闲 15 秒时发送心跳注释。心跳不是模型输出,也不表示生成完成。

AG-UI

POST /agui 的请求体包含 threadId、runId、messages、state、tools、context 和 forwardedProps,其中:

  • threadId 与 runId 必须非空,每次运行使用新的 runId。

  • 同一对话可以复用 threadId,但服务不会自动恢复历史。

  • tools 为空不会禁用代码中已注册的工具。

正常响应以 RUN_STARTED 开始、RUN_FINISHED 结束,失败时返回 RUN_ERROR。工具调用与工具结果通过 toolCallId 关联。

OpenAI Chat Completions

POST /openai/v1/chat/completions 的请求体包含 model、messages 和 stream。流式响应以 data: [DONE] 结束;stream=false 返回普通 JSON;model 字段不会自动切换下游模型。

安全约束

以下约束适用于本文全部示例,应用上线前逐条确认:

  • 凭证保护:凭证值不写入源码、日志或对外响应;自有模型的 API Key 由运行环境或密钥管理服务提供,不硬编码。

  • Skill 脚本执行:Skill 中的脚本以应用进程权限执行,仅加载可信来源的 Skill;不需要命令执行能力时,设置 ALLOW_EXECUTE_COMMAND=false。

  • 记忆范围字段:范围字段由可信的业务上下文提供,不应由模型任意指定,也不替代访问控制。

  • 日志内容:不记录密钥和敏感对话内容。

常见问题

必须使用 AgentCoreServer 吗?

不必。现有 Web 服务或执行器可以直接调用资源接口;使用 AgentCoreServer 是为了复用协议封装。

已加载 MCP 或 Skill,模型仍不调用工具?

加载只完成准备工作,还需要把工具注册到框架,并选择支持工具调用的模型。对于简单问题,模型也可能判断不需要调用工具。

相同的会话 ID 会自动恢复历史吗?

不会。AgentCoreServer 不持久化对话历史,本文示例也未配置 ChatMemory;多轮对话由应用或框架管理,记忆不替代完整对话历史。

自动记忆会写入全部历史吗?

不会。回写默认关闭;开启后只保存本轮用户输入和最终文本答案。显式调用 MemoryStore 失败时由调用方处理。

需要手动关闭客户端吗?

应用退出时调用 close() 或使用 try-with-resources 释放实例。在应用生命周期内复用 core,不要在单次 HTTP 请求结束后关闭共享的实例,调用约定见初始化客户端。

日志与浏览器跨域访问如何处理?

SDK 使用 SLF4J,由应用配置 Logback 等日志实现;跨域访问由应用或网关按来源配置 CORS。日志内容的脱敏要求见安全约束。

相关文档