Ohhnews

分类导航

$ cd ..
foojay原文

探索 Spring AI SDK:Amazon Bedrock AgentCore 实战指南(第二部分)

#spring ai#amazon bedrock#人工智能#内存管理#开发指南

目录

如果您是从第 1 部分阅读而来,或者需要快速回顾架构,请收听这段关于 Spring AI 和 Amazon Bedrock 如何协同工作的简要概述。 使用 Notebook LLM 为我之前的文章生成。

在本文中,我们将探讨 AgentCore 的功能之一,即内存 (Memory)

[LOADING...] 来源:Amazon

首先,为您之前构建的代理启用 AgentCore 内存

[LOADING...]

第 1 步:添加 AI 模型和 AgentCore 内存依赖

$ xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-model</artifactId>
</dependency>
<dependency>
    <groupId>org.springaicommunity</groupId>
    <artifactId>spring-ai-agentcore-memory</artifactId>
</dependency>

第 2 步:在 AWS 管理控制台中创建短期/长期记忆

导航至 Amazon Bedrock AgentCore > Memory 以创建短期或长期记忆。

[LOADING...] AgentCore 内存

第 3 步:添加以下与内存相关的属性

application.yml

$ config
agentcore:
  memory:
    memory_id: memory_27vql-Vl7nIoHdf6
    total-events-limit: 100
    default-session: default
    page-size: 50
    ignore-unknown-roles: false

application.properties

$ properties
agentcore.memory.memory_id=memory_27vql-Vl7nIoHdf6
agentcore.memory.total-events-limit=100
agentcore.memory.default-session=default
agentcore.memory.page-size=50
agentcore.memory.ignore-unknown-roles=false

第 4 步:添加下面的 MemoryConfig

$ java
package com.bsmlabs.springai.config;

import org.springaicommunity.agentcore.memory.longterm.AgentCoreMemory;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
public class MemoryConfig {

    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .maxMessages(20) // 保留最后 20 条消息
                .build();
    }

    @Bean
    public MessageChatMemoryAdvisor messageChatMemoryAdvisor(ChatMemory chatMemory) {
        return MessageChatMemoryAdvisor.builder(chatMemory).build();
    }

    @Bean
    public AgentCoreMemory agentCoreMemory(MessageChatMemoryAdvisor advisor) {
        return new AgentCoreMemory(advisor, List.of());
    }
}

让我们剖析上述 configuration 类中定义的 Bean 结构。

4.1. ChatMemory Bean -- 核心

$ java
@Bean
public ChatMemory chatMemory() {
   return MessageWindowChatMemory.builder()
                .maxMessages(20) 
                .build();
}

这创建了一个滑动窗口内存,仅保留最后 20 条消息。其优点包括:

  • 防止内存无限增长
  • 在保留近期上下文的同时丢弃陈旧、无关的消息
  • 降低调用 LLM 时的 Token 使用量,从而具有成本效益
  • 保持对话的相关性

4.2. MessageChatMemoryAdvisor -- 包装器

$ java
@Bean
public MessageChatMemoryAdvisor messageChatMemoryAdvisor(ChatMemory chatMemory) {
   return MessageChatMemoryAdvisor.builder(chatMemory).build();
}

此 Advisor 充当中间件,功能如下:

  • ChatMemory 集成到 Spring AI 的 Advisor 链中
  • 自动将对话历史记录注入到聊天请求中
  • 管理何时以及如何将内存应用于提示词 (Prompt)

4.3. AgentCoreMemory -- 编排器

$ java
@Bean
public AgentCoreMemory agentCoreMemory(MessageChatMemoryAdvisor advisor) {
   return new AgentCoreMemory(advisor, List.of());
}

它将 Advisor 与一组额外的策略相结合,功能如下:

  • 协调代理操作中的内存使用
  • 为长期记忆管理提供统一接口
  • 允许扩展(List.of() 可以包含自定义的内存策略)

第 5 步:创建 ChatRequestChatResponse

将以下类添加到 models 文件夹中。我们将在下一个 REST 控制器中使用它们。

$ java
package com.bsmlabs.springai.models;

public record ChatRequest(String message) {
}
$ java
package com.bsmlabs.springai.models;

public record ChatResponse(String response) {
}

第 6 步:添加下面的 ShortTermController

为现有代理添加内存有助于提高响应延迟和相关性。代理可以将之前的对话存储在短期记忆 (STM) 中,也可以利用长期记忆 (LTM) 随时间保留学习到的信息。

SDK 通过 Spring AI 的 Advisor 模式与 AgentCore Memory 集成。这些 Advisor 充当拦截器,在将提示词发送给模型之前,使用相关上下文对其进行丰富。

下面的 RestController 演示了如何利用前一个示例中的内存配置构建一个有状态的聊天 API,通过维护对话历史记录来提供持续的对话上下文。

$ java
package com.bsmlabs.springai.agents;

import com.bsmlabs.springai.models.ChatRequest;
import com.bsmlabs.springai.models.ChatResponse;
import org.springaicommunity.agentcore.memory.longterm.AgentCoreMemory;
import org.springaicommunity.agentcore.memory.shorttem.AgentCoreShortTermMemoryRepository;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.web.bind.annotation.*;
import java.util.UUID;
import java.util.List;

@RestController
public class ShortTermMemoryController {

    private final ChatClient chatClient;
    private final ChatMemory chatMemory;
    private final AgentCoreMemory agentCoreMemory;
    private static final String CONVERSATION_ID = UUID.randomUUID().toString();

    public ShortTermMemoryController(ChatClient.Builder chatClientBuilder,
                                     ChatMemory chatMemory,
                                     AgentCoreMemory agentCoreMemory,
                                     AgentCoreShortTermMemoryRepository shortTermMemoryRepository) {
        this.chatClient = chatClientBuilder.build();
        this.chatMemory = chatMemory;
        this.agentCoreMemory = agentCoreMemory;
    }

    @PostMapping("/api/short")
    public ChatResponse shortTermChat(@RequestBody ChatRequest chatRequest) {
        String response = chatClient.prompt()
                .user(chatRequest.message())
                .advisors(agentCoreMemory.advisors)
                .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, CONVERSATION_ID))
                .call()
                .content();
        return new ChatResponse(response);
    }

    @GetMapping("/api/history")
    public List<Message> getHistory() {
        return chatMemory.get(CONVERSATION_ID);
    }

    @DeleteMapping("/api/history")
    public void clearHistory() {
        chatMemory.clear(CONVERSATION_ID);
    }
}
  • ChatClient: 向 LLM 发送提示词
  • ChatMemory: 管理对话窗口/滑动窗口(20 条消息)
  • AgentCoreMemory: 编排跨操作的内存

POST /api/short -- 聊天端点

处理流程:

  1. ChatRequest 中接收用户消息
  2. 调用 agentCoreMemory.advisors 以注入 MessageChatMemoryAdvisor
  3. 将 CONVERSATION_ID 传递给 Advisor,以便其确定检索哪个对话的历史记录
  4. ChatClient 自动:
    • 为此对话检索最后 20 条消息
    • 将它们附加到当前用户消息中
    • 将完整上下文发送给 LLM
    • 将用户消息 + 响应存储在 ChatMemory 中
  5. 将 LLM 的响应返回给客户端

GET /api/history -- 检索对话历史记录

该方法返回给定对话 ID 的所有消息(最多 20 条)。它适用于:

  • 在 UI 中显示聊天历史
  • 调试对话上下文
  • 审计交互

DELETE /api/history -- 清除历史记录

用于清除指定对话 ID 的历史记录。

第 7 步:验证

$ http
### Tell name - STM
POST http://localhost:8080/api/short
Content-Type: application/json

{
  "message": "Mahendra is writing an article to Foojay on Spring AI SDK with Amazon Bedrock Agentcore"
}

### Ask name - STM
POST http://localhost:8080/api/short
Content-Type: application/json

{
  "message": "What is my name?"
}

### Get history
GET http://localhost:8080/api/history

### Clear history
DELETE http://localhost:8080/api/history

使用 curl 命令:

$ bash
# --- 短期记忆 (STM) ---
# 告诉你的名字和你正在谈论的内容
curl -X POST http://localhost:8080/api/short \
    -H "Content-Type: application/json" \
    -d '{"message": "Mahendra is writing an article to Foojay on Spring AI SDK with Amazon Bedrock Agentcore"}'

# 询问你的名字(记忆召回)
curl -X POST http://localhost:8080/api/short \
    -H "Content-Type: application/json" \
    -d '{"message": "What is my name?"}'

# 获取对话历史
curl http://localhost:8080/api/history

# 清除对话
curl -X DELETE http://localhost:8080/api/history

端到端流程

用户请求
[/api/short 端点]
ChatMemory 检索 CONVERSATION_ID 的最后 20 条消息
消息 + 当前用户输入发送给 LLM
LLM 生成响应
交换存储在 ChatMemory 中(滑动窗口)
响应返回给用户

在下一部分中,我将讨论如何包含其余的 AgentCore 服务,添加内置工具(如浏览器、代码解释器)以及部署到 Amazon Bedrock AgentCore 运行时。

所有内容均来自配套的 GitHub 仓库,其中包含了每个示例的完整工作实现。

祝您学习 Spring AI 愉快

参考资料