IngestEvents API 可将事件提取与记忆库中的记忆生成分离开来。您可以持续向记忆库流式传输内容,当满足触发条件时,系统会自动运行生成过程。
如需完成本指南中演示的步骤,您必须先按照设置记忆库中的步骤操作。
本页中的示例使用 agentplatform SDK,该 SDK 提供最新的 IngestEvents 配置选项。使用 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"}
)
将元数据附加到生成的记忆
您可以将元数据附加到根据已提取的事件生成的记忆中。借助元数据,您可以将结构化信息(字符串、双精度浮点数、布尔值或时间戳)与记忆事实一起存储,这对于过滤或管理记忆的生命周期非常有用。
使用 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"}
)