您可以使用记忆库生成结构化配置文件,这些配置文件是使用 LLM 填充和更新的具有静态架构的数据结构。通过定义固定架构,您可以确保智能体能够立即以低延迟访问不断变化的信息,而无需在会话期间执行代价高昂的搜索操作。
如需完成本指南中演示的步骤,您必须先按照 设置记忆库中的步骤操作。
概览
将结构化配置文件与智能体搭配使用,可确保快速、简洁地以一致的格式提供提取的信息(例如用户的技术堆栈或偏好设置)。例如,您可以检索包含以下内容的配置文件:
MemoryProfile(
profile={
"technical_stacks": "ADK, Python",
"preferred_language": "Python",
"tone_preference": "Succinct"
},
schema_id="user-profile"
)
结构化配置文件经过优化,可实现低延迟检索,因为整理信息的工作是在生成时完成的。它们非常适合初始化智能体与用户之间的互动。
了解结构化记忆配置文件
结构化配置文件是通过与自然语言记忆相同的方法(GenerateMemories 和 IngestEvents)生成的。定义架构后,记忆库将自动尝试使用提供的数据源生成符合您架构的配置文件。
使用结构化配置文件时,记忆库会在记忆生成期间执行以下操作:
- 提取:从数据源中提取符合架构的信息和上下文。系统只会提取符合架构的信息。您可以使用记忆修订版本检查提取了哪些信息和上下文。
- 整合:更新(如有必要)配置文件中的现有字段。LLM 将根据新提取的信息和上下文判断如何更新现有内容。如果配置文件中尚不存在该字段,系统将跳过整合,并使用提取的信息直接更新该字段。
配置文件会根据您在将数据注入记忆库时提供的 scope(例如 {"user_id": "123"})进行隔离。对于每个架构和范围,记忆库都会维护一个配置文件作为可靠来源。生成的配置文件由一个或多个 Memory 实例组成。每个 Memory 实例都代表配置文件中的单个字段,您可以使用该实例检查字段的元数据和修订历史记录,例如:
Memory(
create_time=datetime.datetime(...),
memory_type=<MemoryType.STRUCTURED_PROFILE: 'STRUCTURED_PROFILE'>,
name='projects/.../locations/.../reasoningEngines/.../memories/...',
scope={
'user_id': '123'
},
structured_content=MemoryStructuredContent(
data={
'language_preference': 'Java'
},
schema_id='user-profile'
),
update_time=datetime.datetime(...),
expire_time=datetime.datetime(...),
metadata={...}
)
架构定义
记忆库生成的配置文件与创建或更新 Agent Platform 实例时定义的架构一致。您可以使用 pydantic 模型定义您希望记忆库提取和维护的字段。例如:
from pydantic import BaseModel, Field
from typing import Literal
class UserProfile(BaseModel):
name: str = Field(
description="Name of the user.")
technical_stack: str = Field(
description="Comma-separated list tools or languages used by the user.")
primary_goal: str = Field(
description="The main objective the user is pursuing.")
expertise_level: str = Field(
description="Current skill level (e.g., Junior, Senior).")
job_status: Literal['unemployed', 'part_time', 'full_time', 'student'] = Field(
description="The job status of the individual")
创建或更新 Agent Platform 实例时,将架构上传到记忆库。您可以定义多个独立的配置文件架构;每个架构都必须使用唯一的 ID 进行标识:
schema_config = {
"id": "user-profile",
"memory_schema": UserProfile.model_json_schema()
}
memory_bank = client.agent_engines.create(
config={
"context_spec": {
"memory_bank_config": {
"structured_memory_configs": [
{
"schema_configs": [schema_config]
}
]
}
}
}
)
默认情况下,记忆库始终会尝试提取自然语言记忆。如果您只希望记忆库生成配置文件,可以停用自然语言记忆生成:
memory_bank = client.agent_engines.create(
config={
"context_spec": {
"memory_bank_config": {
"structured_memory_configs": [
{
"schema_configs": [schema_config]
}
],
# Optional: Disable natural language memories.
"customization_configs": [
{"disable_natural_language_memories": True}
]
}
}
}
)
配置文件生成
您可以通过向 GenerateMemories 或 IngestEvents 方法提供对话历史记录(事件)来触发结构化记忆的生成。与自然语言记忆一样,记忆库使用 LLM 从数据源中提取有意义的信息,并将其与现有记忆整合。
示例
以下示例演示了如何使用之前定义的架构生成记忆配置文件。
在发送给记忆库的第一组事件中,范围为 {"user_id": "123"} 的用户表示他们使用 ADK 智能体:
client.agent_engines.memories.generate(
name=memory_bank.api_resource.name,
scope={"user_id": "123"},
direct_contents_source={
"events": [
{"content": {
"parts": [{
"text": "Can you help me build an ADK agent that organizes my daily tasks?"}]}}]
}
)
记忆库会为架构中的 technical_stack 字段提取“ADK”。由于注入的事件不包含架构其余部分的相关信息,因此不会填充其他字段。由于这是此范围的首次互动,系统会跳过整合,并使用此初始值初始化配置文件。
result = client.agent_engines.memories.retrieve_profiles(
name=memory_bank.api_resource.name,
scope={"user_id": "123"},
)
"""
Returns:
RetrieveProfilesResponse(
profiles={
'user-profile': MemoryProfile(
profile={
'technical_stack': 'ADK'
},
schema_id='user-profile'
)
}
)
"""
在发送给记忆库的下一组事件中,用户表示他们是学生,主要使用 Python 进行编码:
client.agent_engines.memories.generate(
name=memory_bank.api_resource.name,
scope={"user_id": "123"},
direct_contents_source={
"events": [
{"content": {
"parts": [
{"text": "Do you have any career recommendations for students that specialize in Python?"}]}}]
}
)
记忆库会从互动中提取“Python”和“学生”状态。系统会整合 technical_stack 片段,将“Python”附加到现有的“ADK”条目。系统会使用“学生”枚举填充之前为空的 job_status 字段,并跳过整合步骤。
result = client.agent_engines.memories.retrieve_profiles(
name=memory_bank.api_resource.name,
scope=scope
)
"""
Returns:
RetrieveProfilesResponse(
profiles={
'user-profile': MemoryProfile(
profile={
'technical_stack': 'ADK, Python',
'job_status': 'student'
},
schema_id='user-profile'
)
}
)
"""
配置文件检索
生成后,您可以使用 RetrieveProfiles 方法检索特定范围的整合配置文件。此方法会返回映射到您架构的最新数据。
result = client.agent_engines.memories.retrieve_profiles(
name=memory_bank.api_resource.name,
scope={"user_id": "123"},
)
# Accessing the data
for profile in result.profiles.values():
print(profile)
# Output: {'technical_stack': 'ADK, Python', 'job_status': 'student', ...}
配置文件检查
在底层,配置文件由类型为 STRUCTURED_PROFILE 的各个记忆组成。架构中的每个字段都会映射到每个范围的单个记忆,从而实现精细的可观测性。
虽然 RetrieveProfiles 是用于在生产环境中检索配置文件的主要方法,但您可以检查各个记忆来审核配置文件的演变过程。这样您就可以访问:
- 字段级元数据:查看和更新配置文件中各个字段的特定存留时间 (TTL) 和
Memory.metadata。 - 修订历史记录:跟踪字段的沿袭,查看历史值以及触发每次更改的具体对话上下文。
例如,您可以使用 RetrieveMemories 检索包含用户配置文件片段的所有记忆。默认情况下,RetrieveMemories 仅检索自然语言记忆,因此您需要明确请求 STRUCTURED_PROFILE 记忆:
client.agent_engines.memories.retrieve(
name="...",
scope={"user_id": "123"},
config={
"memory_types": ["STRUCTURED_PROFILE"]
}
)
"""
Returns:
[RetrieveMemoriesResponseRetrievedMemory(
memory=Memory(
create_time=datetime.datetime(...),
memory_type=<MemoryType.STRUCTURED_PROFILE: 'STRUCTURED_PROFILE'>,
name='projects/.../locations/.../reasoningEngines/.../memories/...',
scope={
'user_id': '1'
},
structured_content=MemoryStructuredContent(
data={
'technical_stack': 'ADK, Python'
},
schema_id='user'
),
update_time=datetime.datetime(...)
)
)]
"""
然后,您可以检索此结构化配置文件片段的修订历史记录,以检查配置文件字段随时间的变化情况以及每次更改的相关上下文:
for retrieved_memory in list(results):
list(client.agent_engines.memories.revisions.list(
name=retrieved_memory.memory.name
))
"""
Returns:
[MemoryRevision(
create_time=datetime.datetime(...),
expire_time=datetime.datetime(...),
extracted_memories=[
IntermediateExtractedMemory(
context='The user indicated that they have expertise in Python when asking about career options.',
structured_data={
'technical_stack': 'Python'
}
),
],
name='projects/.../locations/.../reasoningEngines/.../memories/.../revisions/...',
structured_data={
'technical_stack': 'ADK, Python'
}
),
MemoryRevision(
create_time=datetime.datetime(...),
expire_time=datetime.datetime(...),
extracted_memories=[
IntermediateExtractedMemory(
context='The user indicated that they need help building an ADK agent',
structured_data={
'technical_stack': 'ADK'
}
),
],
name='projects/.../locations/.../reasoningEngines/.../memories/.../revisions/...',
structured_data={
'technical_stack': 'ADK'
}
)]
"""