概要
Koogは、AIAgentStorageを使用してデータを保存および受け渡す方法を提供します。これは、異なるノード間やサブグラフ間でもデータを渡すための型安全な方法として設計されたキーバリューストレージ(key-value storage)システムです。
ストレージは、エージェントノードで使用可能なstorageプロパティ(storage: AIAgentStorage)を介してアクセスでき、AIエージェントシステムの異なるコンポーネント間でシームレスなデータ共有を可能にします。
キーと値の構造
キーバリューデータのストレージ構造は、AIAgentStorageKeyデータクラスに依存しています。AIAgentStorageKeyの詳細については、以下のセクションを参照してください。
AIAgentStorageKey
ストレージは、データの保存と取得時に型安全性を確保するために、型指定されたキーシステムを使用します。
AIAgentStorageKey<T>クラスは、データの識別とアクセスに使用されるストレージキーを表します。このクラスの主な特徴は以下の通りです。
ジェネリック型パラメータ
Tは、このキーに関連付けられたデータの型を指定し、型安全性を確保します。各キーには、識別やデバッグを容易にするための文字列識別子である
nameプロパティがあります。各キーインスタンスは一意です。
nameは一意性を判断するためには使用されないため、同じ名前のキーを複数持つことができます。これにより、ストレージ内のデータを誤って上書きするリスクなく、既存のストラテジー(Strategy)コンポーネントを再利用できます。
使用例
以下のセクションでは、ストレージキーを作成し、それを使用してデータを保存および取得する実際の例を示します。
データを表すクラスの定義
データを保存して受け渡すための最初のステップは、そのデータを表すクラスを作成することです。以下は、基本的なユーザーデータを持つ単純なクラスの例です。
class UserData(
val name: String,
val age: Int
)<!--- KNIT example-data-transfer-between-nodes-01.kt -->
record UserData(
String name,
int age
) {}<!--- KNIT exampleDataTransferBetweenNodesJava01.java -->
定義が完了したら、以下で説明するように、このクラスを使用してストレージキーを作成します。
ストレージキーの作成
定義したデータ構造に対して、型指定されたストレージキーを作成します。
=== "Kotlin"
<!--- INCLUDE
import ai.koog.agents.core.agent.entity.createStorageKey
class UserData(
val name: String,
val age: Int
)
-->
```kotlin
val userDataKey = createStorageKey<UserData>("user-data")
```
<!--- KNIT example-data-transfer-between-nodes-02.kt -->
=== "Java"
<!--- INCLUDE
import ai.koog.agents.core.agent.entity.AIAgentStorage;
import ai.koog.agents.core.agent.entity.AIAgentStorageKey;
import ai.koog.serialization.TypeToken;
class exampleDataTransferBetweenNodesJava02 {
record UserData(
String name,
int age
) {}
public static void main(String[] args) {
-->
<!--- SUFFIX
}
}
-->
```java
AIAgentStorageKey<UserData> userDataKey = AIAgentStorage.createStorageKey("user-data", TypeToken.of(UserData.class));
```
<!--- KNIT exampleDataTransferBetweenNodesJava02.java -->
createStorageKey関数は、識別やデバッグの目的で使用される文字列パラメータと、値の型を表すTypeTokenを受け取ります(Javaの場合。Kotlinでは自動的に具現化された型パラメータ(reified generics)が使用されます)。
データの保存
作成したストレージキーを使用してデータを保存するには、ノード内でstorage.set(key: AIAgentStorageKey<T>, value: T)メソッドを使用します。
=== "Kotlin"
<!--- INCLUDE
import ai.koog.agents.core.dsl.builder.strategy
import ai.koog.agents.core.dsl.builder.node
import ai.koog.agents.core.agent.entity.createStorageKey
class UserData(
val name: String,
val age: Int
)
val userDataKey = createStorageKey<UserData>("user-data")
-->
```kotlin
val nodeSaveData by node<Unit, Unit> {
storage.set(userDataKey, UserData("John", 26))
}
```
<!--- KNIT example-data-transfer-between-nodes-03.kt -->
=== "Java"
<!--- INCLUDE
import ai.koog.agents.core.agent.entity.AIAgentNode;
import ai.koog.agents.core.agent.entity.AIAgentStorage;
import ai.koog.agents.core.agent.entity.AIAgentStorageKey;
import ai.koog.serialization.TypeToken;
public class exampleDataTransferBetweenNodesJava03 {
record UserData(
String name,
int age
) {}
public static void main(String[] args) {
AIAgentStorageKey<UserData> userDataKey = AIAgentStorage.createStorageKey("user-data", TypeToken.of(UserData.class));
-->
<!--- SUFFIX
}
}
-->
```java
var nodeSaveData = AIAgentNode.builder("nodeSaveData")
.withInput(String.class)
.withOutput(String.class)
.withAction((input, ctx) -> {
ctx.getStorage().set(userDataKey, new UserData("John", 26));
return "";
})
.build();
```
<!--- KNIT exampleDataTransferBetweenNodesJava03.java -->
データの取得
データを取得するには、ノード内でstorage.getメソッドを使用します。
=== "Kotlin"
<!--- INCLUDE
import ai.koog.agents.core.agent.entity.createStorageKey
import ai.koog.agents.core.dsl.builder.strategy
import ai.koog.agents.core.dsl.builder.node
class UserData(
val name: String,
val age: Int
)
fun main() {
val userDataKey = createStorageKey<UserData>("user-data")
val str = strategy<String, Unit>("my-strategy") {
-->
<!--- SUFFIX
}
}
-->
```kotlin
val nodeRetrieveData by node<String, Unit> { message ->
storage.get(userDataKey)?.let { userFromStorage ->
println("Hello dear $userFromStorage, here's a message for you: $message")
}
}
```
<!--- KNIT example-data-transfer-between-nodes-04.kt -->
=== "Java"
<!--- INCLUDE
import ai.koog.agents.core.agent.entity.AIAgentNode;
import ai.koog.agents.core.agent.entity.AIAgentStorage;
import ai.koog.agents.core.agent.entity.AIAgentStorageKey;
import ai.koog.serialization.TypeToken;
public class exampleDataTransferBetweenNodesJava04 {
record UserData(
String name,
int age
) {}
public static void main(String[] args) {
AIAgentStorageKey<UserData> userDataKey = AIAgentStorage.createStorageKey("user-data", TypeToken.of(UserData.class));
-->
<!--- SUFFIX
}
}
-->
```java
var nodeRetrieveData = AIAgentNode.builder("nodeRetrieveData")
.withInput(String.class)
.withOutput(String.class)
.withAction((message, ctx) -> {
var userData = ctx.getStorage().get(userDataKey);
System.out.println("Hello dear %s, here's a message for you: %s".formatted(userData, message));
return "";
})
.build();
```
<!--- KNIT exampleDataTransferBetweenNodesJava04.java -->
APIドキュメント
AIAgentStorageクラスに関する完全なリファレンスについては、AIAgentStorageを参照してください。
AIAgentStorageクラスで使用可能な個々の関数については、以下のAPIリファレンスを参照してください。
追加情報
AIAgentStorageはスレッドセーフであり、同時アクセスが適切に処理されるようにMutex(ミューテックス)を使用しています。- 値を取得する際、型キャストは自動的に処理され、アプリケーション全体で型安全性が確保されます。
- 値への非nullアクセスには、キーが存在しない場合に例外をスローする
getValueメソッドを使用します。 clearメソッドを使用すると、ストレージを完全にクリアし、保存されているすべてのキーと値のペアを削除できます。
