IngestEvents API는 메모리 뱅크에서 이벤트 수집과 메모리 생성을 분리합니다. 콘텐츠를 메모리 뱅크로 지속적으로 스트리밍할 수 있으며, 트리거 기준이 충족되면 생성이 자동으로 실행됩니다.
이 가이드에 설명된 단계를 완료하려면 먼저 메모리 뱅크 설정의 단계를 수행해야 합니다.
이 페이지의 예에서는 최신 IngestEvents 구성 옵션을 제공하는 agentplatform SDK를 사용합니다. agentplatform로 클라이언트를 초기화합니다.
import agentplatform
client = agentplatform.Client(
project="PROJECT_ID",
location="LOCATION",
)
이벤트 수집 이해하기
GenerateMemories API를 사용하면 메모리 생성이 즉시 트리거됩니다. 이 메서드를 사용하면 메모리 생성이 발생하는 시점을 직접 제어할 수 있습니다. IngestEvents는 메모리 생성에서 이벤트 수집을 분리하는 스트리밍 패턴을 제공합니다.
- 연속 수집: 새 데이터를 사용할 수 있을 때마다 컨텍스트를 메모리 뱅크로 지속적으로 스트리밍할 수 있습니다.
- 중복 삭제: 메모리 뱅크는 공유 이벤트 ID를 기반으로 중복되는 대화 기록을 자동으로 감지하고 무시합니다.
- 자동 트리거: 이벤트 수 기준점 또는 유휴 시간과 같은 특정 조건이 충족될 때만 생성이 자동으로 트리거됩니다.
- 비동기 생성: 이벤트가 백그라운드에서 처리됩니다. API는 트리거 조건이 충족되고 메모리가 생성될 때까지 폴링하거나 모니터링할 수 있는 장기 실행 작업 (LRO)을 즉시 반환합니다.
스트림 및 장기 실행 작업 (LRO)
스트림은 여러 요청에서 이벤트를 누적하는 격리된 버퍼 역할을 합니다. 각 스트림은 scope와 stream_id의 조합으로 고유하게 정의됩니다. 스트림 ID를 제공하지 않으면 메모리 뱅크는 default를 ID로 사용합니다. 이벤트는 정확히 동일한 범위와 ID를 공유하는 경우에만 함께 스테이징되고 '플러시'되어 메모리 생성 중에 엄격한 격리를 보장합니다.
동일한 스트림에 대한 여러 수집 호출은 메모리 생성이 트리거되고 완료될 때까지 동일한 LRO를 반환합니다. 완료되면 이 IngestEvents LRO에는 GenerateMemories API 호출의 다운스트림 LRO가 포함됩니다. 이후 스트림에 대한 인제스트 요청은 새 LRO를 반환합니다.
메모리 생성 트리거
트리거 조건이 충족되지 않으면 마지막 이벤트가 수집된 후 24시간이 지나 스트림의 모든 대기 중 이벤트가 자동으로 플러시됩니다. 이 한도를 통해 메모리 뱅크는 포기된 이벤트를 포함한 모든 이벤트를 처리할 수 있습니다.
generation_trigger_config은 수집된 이벤트가 플러시되고 메모리 생성을 위해 처리되는 시점을 결정합니다. 다음 트리거 조건을 구성할 수 있습니다.
- 이벤트 수 (
event_count): 누적된 고유 이벤트 수가 한도에 도달하면 생성이 트리거됩니다. - 비활성 시간 (
idle_duration, 분 단위로 초 단위, 즉 60의 배수를 지정해야 함): 지정된 기간 (예:"300s")이 지난 후 스트림에서 새 이벤트를 수신하지 않으면 생성이 트리거됩니다. - 고정 간격 (
fixed_interval, 분 단위로 초 단위, 즉 60의 배수를 지정해야 함): 지정된 기간 (예:"300s")이 지난 후 델타 이벤트를 폴링하여 고정된 리듬으로 생성이 실행됩니다. - 강제 플러시 (
force_flush): 대기 중인 모든 이벤트를 즉시 플러시합니다.
동일한 generation_rule에서 이벤트 수 규칙과 시간 기반 규칙을 결합할 수 있습니다. 예를 들어 event_count를 idle_duration와 함께 설정할 수 있습니다. 두 개 이상의 조건이 구성된 경우 먼저 충족되는 조건이 있으면 바로 생성이 트리거됩니다. 두 시간 기반 조건은 상호 배타적입니다. 단일 규칙은 idle_duration 또는 fixed_interval 중 하나를 지정할 수 있지만 둘 다 지정할 수는 없습니다. force_flush 필드는 이러한 규칙과 독립적이며 항상 대기 중인 이벤트를 즉시 플러시합니다.
API는 event_id를 사용하여 데이터를 자동으로 중복 삭제합니다. 각 이벤트에 고유 ID를 제공하면 새 이벤트만 버퍼에 추가됩니다.
생성 창 간에 컨텍스트 유지
기본적으로 각 생성 윈도우는 이전 플러시 이후 누적된 이벤트만 처리합니다. 연속된 생성 창에서 메모리가 일관되게 유지되도록 하려면 generation_rule에서 overlap_event_count를 설정하여 한 창에서 다음 창으로 컨텍스트를 전달하면 됩니다. 이렇게 하면 이미 처리된 마지막 N개의 이벤트가 다음 윈도우의 시작 부분에 다시 포함됩니다.
이월된 이벤트는 트리거 조건에 포함되지 않습니다. overlap_event_count 값은 event_count보다 작은 양의 정수여야 하며 event_count 또는 시간 기반 규칙 (idle_duration 또는 fixed_interval)이 필요합니다.
데이터 소스
IngestEvents를 사용하면 직접 페이로드에서 direct_contents_source를 사용하여 애플리케이션 요청 내에서 직접 이벤트를 제출하여 콘텐츠를 제공합니다.
다음 예에서는 다양한 트리거를 보여줍니다.
예: 이벤트 수 트리거
이 예에서는 맞춤 스트림을 사용하고 스트림에 고유 이벤트가 10개 누적되면 생성을 트리거합니다.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "My favorite color is blue."}]
},
"event_id": "event-1" # Optional, used for deduplication.
}
]
},
generation_trigger_config={
"generation_rule": {
"event_count": 10
}
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="My favorite color is blue.")]
),
event_id="event-1" # Optional, used for deduplication.
)
]
),
generation_trigger_config=types.MemoryGenerationTriggerConfig(
generation_rule=types.MemoryGenerationTriggerConfigGenerationTriggerRule(
event_count=10
)
),
scope={"user_id": "123"}
)
예: 시간 기반 유휴 기간 트리거
이 예에서는 스트림이 5분 (300s) 동안 새 이벤트를 수신하지 않으면 생성을 트리거합니다. 또한 맞춤 stream_id를 설정합니다.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "I will be back in a bit."}]
},
"event_id": "event-2" # Optional, used for deduplication.
}
]
},
generation_trigger_config={
"generation_rule": {
"idle_duration": "300s"
}
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="I will be back in a bit.")]
),
event_id="event-2" # Optional, used for deduplication.
)
]
),
generation_trigger_config=types.MemoryGenerationTriggerConfig(
generation_rule=types.MemoryGenerationTriggerConfigGenerationTriggerRule(
idle_duration="300s"
)
),
scope={"user_id": "123"}
)
예: 이벤트 기반 트리거와 시간 기반 트리거 결합
이 예에서는 동일한 요청에서 두 가지 트리거 조건을 구성합니다. 생성은 순 이벤트가 10개 누적되거나 스트림이 5분 (300s) 동안 유휴 상태가 되는 경우 중 먼저 발생하는 경우에 실행됩니다.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "Let's keep this conversation going."}]
},
"event_id": "event-3" # Optional, used for deduplication.
}
]
},
generation_trigger_config={
"generation_rule": {
"event_count": 10,
"idle_duration": "300s"
}
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="Let's keep this conversation going.")]
),
event_id="event-3" # Optional, used for deduplication.
)
]
),
generation_trigger_config=types.MemoryGenerationTriggerConfig(
generation_rule=types.MemoryGenerationTriggerConfigGenerationTriggerRule(
event_count=10,
idle_duration="300s"
)
),
scope={"user_id": "123"}
)
예: 이벤트 강제 플러시
이 예에서는 트리거 조건을 무조건 우회하고 스트림의 대기 중인 모든 이벤트를 즉시 플러시하고 처리하도록 강제합니다.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "That's all for today!"}]
},
}
]
},
config={
"force_flush": True
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="That's all for today!")]
),
)
]
),
config=types.IngestEventsConfig(
force_flush=True
),
scope={"user_id": "123"}
)
예: 창 간에 컨텍스트 전달
이 예에서는 고유한 이벤트가 10개 발생할 때마다 생성을 트리거하고 이미 처리된 마지막 2개 이벤트를 다음 창에 다시 포함하여 창 간에 추억이 일관되게 유지되도록 합니다.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "Let's continue where we left off."}]
},
}
]
},
generation_trigger_config={
"generation_rule": {
"event_count": 10,
"overlap_event_count": 2
}
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="Let's continue where we left off.")]
),
)
]
),
generation_trigger_config=types.MemoryGenerationTriggerConfig(
generation_rule=types.MemoryGenerationTriggerConfigGenerationTriggerRule(
event_count=10,
overlap_event_count=2
)
),
scope={"user_id": "123"}
)
메모리 버전 구성
GenerateMemories와 마찬가지로 IngestEvents은 생성하는 메모리의 메모리 버전을 만듭니다. config에서 다음 필드를 설정하여 수집 요청으로 생성되는 버전을 구성할 수 있습니다.
- 버전 라벨 (
revision_labels): 생성된 메모리 버전에 적용되는 키-값 쌍입니다. 예를 들어 데이터 소스로 버전에 라벨을 지정한 후 나중에 해당 라벨로 버전을 필터링할 수 있습니다. - 버전 만료 (
revision_expire_time또는revision_ttl): 생성된 메모리 버전이 만료되는 시점을 제어합니다. 만료를 설정하지 않으면 메모리 뱅크는 인스턴스 구성 또는 기본 TTL인 365일을 사용합니다. - 수정 사용 중지 (
disable_memory_revisions):True인 경우 메모리 뱅크는 이 요청에서 생성된 메모리에 대해 수정을 생성하지 않습니다.
다음 예에서는 생성된 수정사항에 데이터 소스 라벨을 지정하고 30일 동안 보관합니다.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "My favorite color is blue."}]
},
}
]
},
generation_trigger_config={
"generation_rule": {
"event_count": 10
}
},
config={
"revision_labels": {"data_source": "321"},
# Persist memory revisions for 30 days after they're created.
"revision_ttl": f"{30 * 60 * 60 * 24}s"
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="My favorite color is blue.")]
),
)
]
),
generation_trigger_config=types.MemoryGenerationTriggerConfig(
generation_rule=types.MemoryGenerationTriggerConfigGenerationTriggerRule(
event_count=10
)
),
config=types.IngestEventsConfig(
revision_labels={"data_source": "321"},
# Persist memory revisions for 30 days after they're created.
revision_ttl=f"{30 * 60 * 60 * 24}s"
),
scope={"user_id": "123"}
)
생성된 추억에 메타데이터 첨부
수집된 이벤트에서 생성된 추억에 메타데이터를 첨부할 수 있습니다. 메타데이터를 사용하면 메모리 사실과 함께 구조화된 정보 (문자열, double, 불리언 또는 타임스탬프)를 저장할 수 있으며, 이는 기억의 수명 주기를 필터링하거나 관리하는 데 유용합니다.
metadata_merge_strategy를 사용하여 통합 중에 메타데이터가 기존 메모리와 상호작용하는 방식을 제어합니다. OVERWRITE (설정되지 않은 경우 기본값), MERGE 또는 REQUIRE_EXACT_MATCH로 설정할 수 있습니다. 자세한 내용은 통합 중에 메타데이터 사용을 참고하세요.
딕셔너리
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source={
"events": [
{
"content": {
"role": "user",
"parts": [{"text": "My favorite color is blue."}]
},
}
]
},
generation_trigger_config={
"generation_rule": {
"event_count": 10
}
},
config={
"metadata": {
"my_string_key": {"string_value": "my_string_value"},
"my_boolean_key": {"bool_value": True}
},
"metadata_merge_strategy": "MERGE"
},
scope={"user_id": "123"}
)
클래스 기반
from google import genai
from agentplatform import types
client.agent_engines.memories.ingest_events(
name=memory_bank.api_resource.name,
stream_id="my-custom-stream",
direct_contents_source=types.IngestionDirectContentsSource(
events=[
types.IngestionDirectContentsSourceEvent(
content=genai.types.Content(
role="user",
parts=[genai.types.Part.from_text(text="My favorite color is blue.")]
),
)
]
),
generation_trigger_config=types.MemoryGenerationTriggerConfig(
generation_rule=types.MemoryGenerationTriggerConfigGenerationTriggerRule(
event_count=10
)
),
config=types.IngestEventsConfig(
metadata={
"my_string_key": types.MemoryMetadataValue(string_value="my_string_value"),
"my_boolean_key": types.MemoryMetadataValue(bool_value=True)
},
metadata_merge_strategy=types.MemoryMetadataMergeStrategy.MERGE
),
scope={"user_id": "123"}
)