如何提取情景记忆¶
需要您的智能体从经验中学习?以下是如何使用 LangMem 进行经验回放——不仅捕获发生了什么,还捕获了导致成功的完整思维链。虽然语义记忆构建知识(“是什么”),但情景记忆捕获专业知识(“如何做”)。
无存储¶
以下是使用 LangMem 提取情景记忆且不使用存储的示例。您可以随意根据您的需求进行调整和修改代码。
from langmem import create_memory_manager
from pydantic import BaseModel, Field
class Episode(BaseModel): # (1)!
"""Write the episode from the perspective of the agent within it. Use the benefit of hindsight to record the memory, saving the agent's key internal thought process so it can learn over time."""
observation: str = Field(..., description="The context and setup - what happened")
thoughts: str = Field(
...,
description="Internal reasoning process and observations of the agent in the episode that let it arrive"
' at the correct action and result. "I ..."',
)
action: str = Field(
...,
description="What was done, how, and in what format. (Include whatever is salient to the success of the action). I ..",
)
result: str = Field(
...,
description="Outcome and retrospective. What did you do well? What could you do better next time? I ...",
)
manager = create_memory_manager(
"anthropic:claude-3-5-sonnet-latest",
schemas=[Episode], # (2)!
instructions="Extract examples of successful explanations, capturing the full chain of reasoning. Be concise in your explanations and precise in the logic of your reasoning.",
enable_inserts=True,
)
- 与存储事实的语义三元组不同,情景捕获成功交互的完整上下文
- 情景模式成为记忆管理器提示的一部分,帮助它提取完整的推理链,以指导未来的响应。管理器提取完整的情景,而不仅仅是单个事实。
成功解释后
conversation = [
{
"role": "user",
"content": "What's a binary tree? I work with family trees if that helps",
},
{
"role": "assistant",
"content": "A binary tree is like a family tree, but each parent has at most 2 children. Here's a simple example:\n Bob\n / \\\nAmy Carl\n\nJust like in family trees, we call Bob the 'parent' and Amy and Carl the 'children'.",
},
{
"role": "user",
"content": "Oh that makes sense! So in a binary search tree, would it be like organizing a family by age?",
},
]
episodes = manager.invoke({"messages": conversation})
print(episodes[0])
# ExtractedMemory(
# id="2e5c551f-58a7-40c2-96b3-cabdfa5ccb31",
# content=Episode(
# observation="In a teaching interaction, I used a family tree analogy to explain binary trees, which led to a successful understanding. The student then made an insightful connection to binary search trees and age ordering.",
# thoughts="I noticed that connecting abstract data structures to familiar concepts like family relationships made the concept more accessible. The student's quick grasp and ability to extend the analogy to binary search trees showed the effectiveness of this approach. Using relatable examples helps bridge the gap between technical concepts and everyday understanding.",
# action='I explained binary trees using a family tree metaphor, drawing a simple diagram with "Bob" as parent and "Amy" and "Carl" as children. This visualization provided a concrete, relatable example that built on the student\'s existing knowledge of family trees.',
# result="The explanation was highly successful, evidenced by the student's immediate comprehension (\"Oh that makes sense!\") and their ability to make the cognitive leap to understanding binary search trees' ordering property. For future explanations, I should continue using familiar analogies while being prepared to build upon them for more complex concepts. The family tree analogy proved particularly effective for explaining hierarchical structures.",
# ),
# )
带存储¶
让我们扩展我们的示例,使用 LangGraph 的存储系统来存储和检索情景
API: init_chat_model | entrypoint | create_memory_store_manager
from langchain.chat_models import init_chat_model
from langgraph.func import entrypoint
from langgraph.store.memory import InMemoryStore
from langmem import create_memory_store_manager
# Set up vector store for similarity search
store = InMemoryStore(
index={
"dims": 1536,
"embed": "openai:text-embedding-3-small",
}
)
# Configure memory manager with storage
manager = create_memory_store_manager(
"anthropic:claude-3-5-sonnet-latest",
namespace=("memories", "episodes"),
schemas=[Episode],
instructions="Extract exceptional examples of noteworthy problem-solving scenarios, including what made them effective.",
enable_inserts=True,
)
llm = init_chat_model("anthropic:claude-3-5-sonnet-latest")
@entrypoint(store=store)
def app(messages: list):
# Step 1: Find similar past episodes
similar = store.search(
("memories", "episodes"),
query=messages[-1]["content"],
limit=1,
)
# Step 2: Build system message with relevant experience
system_message = "You are a helpful assistant."
if similar:
system_message += "\n\n### EPISODIC MEMORY:"
for i, item in enumerate(similar, start=1):
episode = item.value["content"]
system_message += f"""
Episode {i}:
When: {episode['observation']}
Thought: {episode['thoughts']}
Did: {episode['action']}
Result: {episode['result']}
"""
# Step 3: Generate response using past experience
response = llm.invoke([{"role": "system", "content": system_message}, *messages])
# Step 4: Store this interaction if successful
manager.invoke({"messages": messages})
return response
app.invoke(
[
{
"role": "user",
"content": "What's a binary tree? I work with family trees if that helps",
},
],
)
print(store.search(("memories", "episodes"), query="Trees"))
# [
# Item(
# namespace=["memories", "episodes"],
# key="57f6005b-00f3-4f81-b384-961cb6e6bf97",
# value={
# "kind": "Episode",
# "content": {
# "observation": "User asked about binary trees and mentioned familiarity with family trees. This presented an opportunity to explain a technical concept using a relatable analogy.",
# "thoughts": "I recognized this as an excellent opportunity to bridge understanding by connecting a computer science concept (binary trees) to something the user already knows (family trees). The key was to use their existing mental model of hierarchical relationships in families to explain binary tree structures.",
# "action": "Used family tree analogy to explain binary trees: Each person (node) in a binary tree can have at most two children (left and right), unlike family trees where people can have multiple children. Drew parallel between parent-child relationships in both structures while highlighting the key difference of the two-child limitation in binary trees.",
# "result": "Successfully translated a technical computer science concept into familiar terms. This approach demonstrated effective teaching through analogical reasoning - taking advantage of existing knowledge structures to build new understanding. For future similar scenarios, this reinforces the value of finding relatable real-world analogies when explaining technical concepts. The family tree comparison was particularly effective because it maintained the core concept of hierarchical relationships while clearly highlighting the key distinguishing feature (binary limitation).",
# },
# },
# created_at="2025-02-09T03:40:11.832614+00:00",
# updated_at="2025-02-09T03:40:11.832624+00:00",
# score=0.30178054939692683,
# )
# ]
- 对于生产环境,请使用持久存储,例如
AsyncPostgresStore
让我们分解一下正在发生的事情
- 设置: 我们为相似性搜索创建一个向量存储,并配置具有存储支持的记忆管理器
- 搜索: 处理消息时,我们首先搜索相似的过去情景
- 应用: 如果找到相关情景,我们会将其学习内容包含在系统消息中
- 学习: 生成响应后,我们将此交互存储为新情景
这创建了一个学习循环,智能体通过借鉴过去的经验不断改进。
何时使用情景记忆¶
情景记忆驱动自适应学习。语义记忆构建事实的知识库(“Python 是一种编程语言”),而情景记忆捕获如何有效应用该知识的专业知识(“用蛇类比解释 Python 让用户感到困惑,但将其与食谱步骤进行比较效果很好”)。
这种经验回放有助于智能体: - 根据有效的方法调整教学风格 - 从成功的解决问题方法中学习 - 构建经验证的技术库 - 不仅理解做什么,还理解为什么有效
有关记忆类型及其作用的更多信息,请参阅记忆类型。