您可以使用 Memory Bank 生成結構化設定檔,這類資料結構會使用 LLM 填入及更新靜態結構定義。定義固定結構定義後,代理程式就能立即存取不斷變化的資訊,且延遲時間很短,不必在工作階段期間執行耗費資源的搜尋作業。
如要完成本指南中示範的步驟,請先按照「設定 Memory Bank」中的步驟操作。
總覽
在代理程式中使用結構化設定檔,可確保快速、簡潔地以一致的格式提供擷取的資訊,例如使用者的技術堆疊或偏好設定。舉例來說,您可以擷取包含下列內容的設定檔:
MemoryProfile(
profile={
"technical_stacks": "ADK, Python",
"preferred_language": "Python",
"tone_preference": "Succinct"
},
schema_id="user-profile"
)
結構化設定檔經過最佳化調整,可縮短擷取延遲時間,因為資訊的策劃工作是在生成時完成。非常適合用來啟動代理程式與使用者之間的互動。
瞭解結構化記憶體設定檔
系統會使用與自然語言記憶相同的生成方法 (GenerateMemories 和 IngestEvents) 生成結構化設定檔。定義結構定義後,Memory Bank 會使用提供的資料來源,自動產生符合結構定義的設定檔。
使用結構化設定檔時,Memory Bank 會在記憶生成期間執行下列作業:
- 擷取:從資料來源擷取符合結構定義的資訊和脈絡。系統只會擷取符合結構定義的資訊。您可以使用記憶體修訂版本檢查擷取的資訊和脈絡。
- 合併:視需要更新商家檔案中的現有欄位。LLM 會根據新擷取的資訊和脈絡,判斷如何更新現有內容。如果設定檔中沒有這個欄位,系統會略過合併程序,直接以擷取的資訊更新欄位。
系統會根據您將資料擷取至 Memory Bank 時提供的 scope (例如 {"user_id": "123"}) 隔離設定檔。針對每個結構定義和範圍,Memory Bank 會維護單一設定檔做為可靠資料來源。產生的設定檔包含一或多個 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={...}
)
結構定義
Memory Bank 生成的設定檔會與建立或更新 Agent Platform 執行個體時定義的結構定義保持一致。您可以使用 pydantic 模型定義要讓 Memory Bank 擷取及維護的欄位。例如:
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 執行個體時,請將結構定義上傳至 Memory Bank。您可以定義多個獨立的設定檔結構定義,每個結構定義都必須有專屬 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 一律會嘗試擷取自然語言記憶。如果您只希望 Memory Bank 生成設定檔,可以停用自然語言記憶生成功能:
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 方法提供對話記錄 (事件),觸發產生結構化記憶。與自然語言記憶體一樣,Memory Bank 會使用 LLM 從資料來源擷取有意義的資訊,並與現有記憶體合併。
範例
以下範例逐步說明如何使用先前定義的結構定義產生記憶體設定檔。
在傳送至 Memory Bank 的第一組範圍 {"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?"}]}}]
}
)
Memory Bank 會為結構定義中的「ADK」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'
)
}
)
"""
在下一組傳送至 Memory Bank 的事件中,使用者表示自己是學生,主要使用 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?"}]}}]
}
)
Memory Bank 會從互動中擷取「Python」和「學生」狀態。系統會合併 technical_stack 片段,並在現有的「ADK」項目中附加「Python」。系統會以「student」列舉填入先前空白的 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'
}
)]
"""