使用 Firestore 的会话状态管理¶
Google Cloud Firestore 是一个灵活、可扩展的 NoSQL 云数据库,用于客户端和服务端开发中的数据存储和同步。ADK 提供了使用 Firestore 管理持久化智能体会话状态的原生集成,支持持续的多轮对话而不会丢失对话历史。
使用场景¶
- 客户支持智能体:在长期支持工单中维护上下文,使智能体能够在多个会话中记住过去的故障排查步骤和偏好。
- 个性化助手:构建随时间积累用户知识的智能体,基于历史对话个性化未来交互。
- 多模态工作流:无缝处理涉及图像、视频和音频以及文本对话的复杂用例,利用内置的 GCS 制品存储。
- 企业级聊天机器人:部署具有生产级持久性的高可靠性对话 AI 应用程序,适用于大规模企业环境。
前置条件¶
- 一个已启用 Firestore 的 Google Cloud 项目
- 你的 Google Cloud 项目中的 Firestore 数据库
- 在你的环境中配置的适当 Google Cloud 凭据
安装依赖项¶
Note
请为 google-adk 和 google-adk-firestore-session-service
使用相同的版本以确保兼容性。以下示例使用 1.6.0;请检查最新的 ADK 版本并在两个依赖项中使用相同的版本。
将以下依赖项添加到你的 pom.xml (Maven) 或 build.gradle (Gradle) 中:
Maven¶
<dependencies>
<!-- ADK 核心 -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk</artifactId>
<version>1.6.0</version>
</dependency>
<!-- Firestore 会话服务 -->
<dependency>
<groupId>com.google.adk</groupId>
<artifactId>google-adk-firestore-session-service</artifactId>
<version>1.6.0</version>
</dependency>
</dependencies>
Gradle¶
dependencies {
// ADK 核心
implementation 'com.google.adk:google-adk:1.6.0'
// Firestore 会话服务
implementation 'com.google.adk:google-adk-firestore-session-service:1.6.0'
}
示例:使用 Firestore 会话管理的智能体¶
使用 FirestoreDatabaseRunner 来封装你的智能体和基于 Firestore 的会话管理。以下是一个完整的示例,展示了如何使用自定义会话 ID 设置一个简单的助手智能体,使其能够在多轮对话中记住会话上下文。
import com.google.adk.agents.BaseAgent;
import com.google.adk.agents.LlmAgent;
import com.google.adk.agents.RunConfig;
import com.google.adk.runner.FirestoreDatabaseRunner;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreOptions;
import io.reactivex.rxjava3.core.Flowable;
import java.util.Map;
import com.google.adk.sessions.FirestoreSessionService;
import com.google.adk.sessions.Session;
import com.google.adk.tools.Annotations.Schema;
import com.google.adk.tools.FunctionTool;
import com.google.genai.types.Content;
import com.google.genai.types.Part;
import com.google.adk.events.Event;
import java.util.Scanner;
import static java.nio.charset.StandardCharsets.UTF_8;
public class YourAgentApplication {
public static void main(String[] args) {
System.out.println("正在启动 YourAgentApplication...");
RunConfig runConfig = RunConfig.builder().build();
String appName = "hello-time-agent";
BaseAgent timeAgent = initAgent();
// 初始化 Firestore
FirestoreOptions firestoreOptions = FirestoreOptions.getDefaultInstance();
Firestore firestore = firestoreOptions.getService();
// 使用 FirestoreDatabaseRunner 持久化会话状态
FirestoreDatabaseRunner runner = new FirestoreDatabaseRunner(
timeAgent,
appName,
firestore
);
// 创建新会话或加载已有会话
Session session = new FirestoreSessionService(firestore)
.createSession(appName, "user1234", null, "12345")
.blockingGet();
// 启动交互式 CLI
try (Scanner scanner = new Scanner(System.in, UTF_8)) {
while (true) {
System.out.print("\\nYou > ");
String userInput = scanner.nextLine();
if ("quit".equalsIgnoreCase(userInput)) {
break;
}
Content userMsg = Content.fromParts(Part.fromText(userInput));
Flowable<Event> events = runner.runAsync(session.userId(), session.id(), userMsg, runConfig);
System.out.print("\\nAgent > ");
events.blockingForEach(event -> {
if (event.finalResponse()) {
System.out.println(event.stringifyContent());
}
});
}
}
}
/** 模拟工具实现 */
@Schema(description = "获取指定城市的当前时间")
public static Map<String, String> getCurrentTime(
@Schema(name = "city", description = "要获取时间的城市名称") String city) {
return Map.of(
"city", city,
"time", "The time is 10:30am."
);
}
private static BaseAgent initAgent() {
return LlmAgent.builder()
.name("hello-time-agent")
.description("告知指定城市的当前时间")
.instruction(\"""
You are a helpful assistant that tells the current time in a city.
Use the 'getCurrentTime' tool for this purpose.
\""")
.model("gemini-flash-latest")
.tools(FunctionTool.create(YourAgentApplication.class, "getCurrentTime"))
.build();
}
}
配置¶
Note
Firestore 会话服务支持属性文件配置。这使你可以轻松地指定专用的 Firestore 数据库,并为存储智能体会话数据定义自定义集合名称。
你可以通过提供自己的 Firestore 属性设置来自定义 ADK 应用程序以使用 Firestore 会话服务,否则库将使用默认设置。
特定环境配置¶
该库使用以下解析顺序,优先使用特定环境的属性文件而非默认设置:
- 环境变量覆盖:它首先检查名为
env的环境变量。如果设置了该变量(例如env=dev),它将尝试加载与模板匹配的属性文件:adk-firestore-{env}.properties(例如adk-firestore-dev.properties)。 - 默认回退:如果未设置
env变量,或者找不到特定环境的文件,该库默认加载adk-firestore.properties。
属性设置示例:
# Firestore 存储会话数据的集合名称
firebase.root.collection.name=adk-session
# Google Cloud Storage 存储制品的桶名称
gcs.adk.bucket.name=your-gcs-bucket-name
# 关键词提取的停用词
keyword.extraction.stopwords=a,about,above,after,again,against,all,am,an,and,any,are,aren't,as,at,be,because,been,before,being,below,between,both,but,by,can't,cannot,could,couldn't,did,didn't,do,does,doesn't,doing,don't,down,during,each,few,for,from,further,had,hadn't,has,hasn't,have,haven't,having,he,he'd,he'll,he's,her,here,here's,hers,herself,him,himself,his,how,i,i'd,i'll,i'm,i've,if,in,into,is
Important
FirestoreDatabaseRunner 需要定义 gcs.adk.bucket.name 属性。这是因为该运行器内部会初始化 GcsArtifactService 来处理多模态制品存储。如果此属性缺失或为空,应用程序将在启动时抛出 RuntimeException。该属性用于存储由智能体生成或处理的图像、视频、音频文件等制品。
资源¶
- Firestore 会话服务: Firestore 会话服务的源代码。
- Spring Boot Google ADK + Firestore 示例: 一个示例项目,演示如何使用 Cloud Firestore 构建基于 Java 的 Google ADK 智能体应用程序进行会话管理。
- Firestore 会话服务 - DeepWiki: Google ADK for Java 中 Firestore 集成的详细描述。