从无状态 prompt 演进到有状态 agent,探讨记忆机制在长期工程任务中的设计和应用。
这篇文章的定位:本文连接两个系列。它结束了《The Backyard Quarry》中引入的主题——一个以物理对象为教学领域的数据工程探索——并为《Sovereign Synapse》系列奠定基础,该系列即将探讨自主的、具有内存感知的智能体系统。你可以独立开始任一系列,但按顺序阅读会获得更好的学习效果。
八篇文章之前,我们从一堆石头开始。
到那个系列结束时,这些石头已经演变成了一个可识别的系统——一个采集层、一个摄取管道、结构化的记录、索引化的资产,最后是其上的应用程序。新兴的架构与远超后花园范畴的系统惊人一致:制造业、档案管理、AI。
但这个架构留下了一些未解决的问题。
数据流入。数据被索引。应用程序查询它。系统没有做到的——也无法做到的——是跨越时间进行记忆。每个查询都是无状态的。每个会话都从头开始。
对石头来说没什么问题。石头不会改变。在十月编目的花岗岩样本在三月仍然是同一块花岗岩样本。
但 AI 智能体不同。
它们无处不在。但大多数共享相同的架构限制:
这不是因为 AI 模型不够能力或存在缺陷。而是因为封装它们的应用程序是无状态的。作为开发者,我们多年来一直在设计系统,通过数据库、缓存、队列、事件日志等有意地持久化状态。然而,许多 AI 系统仍然依赖最简单的内存机制:
将之前的消息追加到提示中,并希望它能放进去。
在演示、示例应用程序和演讲的世界里,这可行。但它不能扩展到生产环境。
有几种技术用于克服这个架构限制,Oracle 的人员有一些有趣的例子。他们的 GitHub 仓库 oracle-ai-developer-hub 展示了一些不同的方法。通过像 memory_context_engineering_agents.ipynb 这样的 Jupyter 笔记本和 RAG 示例,Agent 内存不再是一项功能,而是变成了一门工程学科。
让我们深入了解为什么向 Agent 内存的转变很重要,以及开发者如何在真实系统中应用这些模式。
大多数大型语言模型(LLM)API 以无状态的方式运作,如下所示:
response = llm.generate(
prompt = "User: What did I ask earlier? \n Assistant:"
)
如果应用程序不明确包含来自前一次交互的上下文,模型就不知道它。一个常见的变通办法可能是:
conversation_history.append(user_message)
response = llm.generate(
prompt="\n".join(conversation_history)
)
这似乎是一个合理的方法,但有一些需要考虑的因素。当发生什么情况时:
对话超过 token 限制?
检索变得过度昂贵?
跨会话的持久化变得复杂?
无关的历史污染推理?
问题不在提示大小。问题在于缺乏结构化的内存架构。
Oracle AI 开发者中心关于内存工程的笔记本展示了一个关键转变:
内存应该有意地被存储、索引和检索。
我们不是存储所有内容,而是提取和持久化重要内容。
如果我们用数据库术语和架构来思考:
我们不会索引每一列。
我们根据查询模式进行索引。
我们根据访问需求进行规范化。
Agent 内存需要类似的思考。
在过渡到智能体内存架构时,设计和考虑不同的内存类别是关键。
工作内存(短期)
范围:当前执行周期
语义内存(长期知识)
范围:跨会话持久化
情景记忆(历史经验)
范围:先前的行动和结果
Oracle AI 开发者中心仓库的笔记本展示了如何将这些结合到一个集成的 agent 内存系统中,而不是一个简单的平面记录。
让我们看看一个受笔记本中演示的模式启发的简化示例。
步骤 1:提取值得保存的内存
与其存储所有内容,不如总结和结构化
def extract_memory(interaction):
return {
"type": "preference",
"content": interaction["assistant_summary"],
"metadata": {
"user_id": interaction["user_id"],
"timestamp": interaction["timestamp"]
}
}
步骤 2:嵌入和存储
embedding = embed_model.encode(memory["content"])
vector_store.add(
id=uuid4(),
vector=embedding,
metadata=memory["metadata"]
)
现在内存是可搜索的,这使得它对 LLM 更加有用。虽然这个例子使用了一个通用的向量存储,但 Oracle Database 26ai 使用 VECTOR 数据类型本地支持这种存储和索引。
步骤 3:在相关时检索
query_vector = embed_model.encode(current_query)
relevant_memories = vector_store.search(
vector=query_vector,
top_k=3
)
步骤 4:有意地注入上下文
memory_context = "\n".join(
[m["content"] for m in relevant_memories]
)
prompt = f"""
Relevant prior context:
{memory_context}
User query:
{current_query}
"""
注意这个架构设计发生了什么:
我们不是在重放历史。
我们在检索相关性。
内存变成了可查询的状态。
这是一个基础性的转变。
从架构上讲,这是发生的事情:
flowchart LR
%% --- User Interaction ---
U[User Input]
%% --- Retrieval Layer ---
subgraph Retrieval Layer
E[Generate Embedding]
R[Retrieve Relevant Memory]
end
%% --- Reasoning Layer ---
subgraph Reasoning Layer
LLM[LLM Processing]
X[Extract New Memory]
end
%% --- Persistence Layer ---
subgraph Persistence Layer
V[(Vector Store / Database)]
end
%% --- Flow ---
U --> E
E --> R
R --> LLM
LLM --> X
X --> V
%% --- Feedback Loop
V --> R
这变成了一个生命周期,而不是一个静态系统,数据库不是管道的终点,而是推理循环的一部分。
Oracle AI 开发者中心还提供了几个检索增强生成(RAG)的例子。许多开发者将 RAG 视为"文档问答"。然而,RAG 与我们概述的 Agent 内存架构有许多架构相似之处。RAG 是语义内存。
有意地使用时,RAG 可以成为:
Oracle AI 开发者中心仓库有一些优秀的示例展示了如何:
开发者的关键启示:
RAG 不是一个功能。它是一个内存原语。
到目前为止,我们从架构的角度考察了内存。但架构只有在能够在生产现实中生存下来时才重要——规模、并发、安全性和治理。这是基础设施选择开始重要的地方。
从笔记本过渡到生产需要一个将向量视为一等公民的数据库。Oracle Database 26ai 通过 AI 向量搜索充当这个架构的支撑。通过利用本地 VECTOR 数据类型和专门的索引如 HNSW,开发者可以在数百万个"记忆"中执行相似性搜索,耗时仅需几毫秒——同时保持企业数据库的安全性和 ACID 合规性。一个示例可能如下所示:
CREATE TABLE agent_memory (
id NUMBER GENERATED BY DEFAULT AS IDENTITY,
user_id VARCHAR2(100),
content CLOB,
embedding VECTOR(1536),
created_at TIMESTAMP
)
在企业环境中,"遗忘"不是唯一的风险。"记忆过多"或"为错误的用户记忆错误的事情"是一个关键的安全问题。当智能体从隔离的演示转向多用户生产系统时,内存治理成为数据完整性的守门员。
使用行级安全(RLS)的权限回忆
智能体架构中的主要挑战之一是确保 agent 的语义记忆不会成为未授权数据访问的后门。Oracle AI Database 26ai 通过本地行级安全(RLS)解决这个问题。
通过将安全策略直接应用于 VECTOR 表,数据库确保当 agent 查询"相关记忆"时,结果集根据当前用户的身份自动过滤。agent 永远不会"看到"它无权检索的内存片段,防止在提示级别的权限提升。
审计"思维过程"
治理也需要可问责性。因为 Oracle 26ai 将内存视为可查询的状态,每个检索操作都可以使用标准数据库工具进行记录和审计。开发者可以精确追踪哪些内存片段被注入到提示中以及何时被注入,为合规和调试提供透明的审计跟踪。
抗量子保护
当我们展望计算的未来时,存储嵌入的安全性至关重要。Oracle 26ai 结合了抗量子算法来保护静态和传输中的数据,确保即使解密技术演变,agent 的语义记忆中存储的专有知识仍然安全。
如同系统架构中的大多数事物一样,有权衡。让我们看看开发者在 Agent 内存系统中必须考虑的一些真实情况。
检索精确度 vs 召回率
如果检索过多:
如果检索过少:
就像提示工程一样,内存工程需要调整。
更好的方法可能是:
听起来很熟悉吗?它反映了传统系统中许多日志保留策略。
随着多智能体系统变得更加普遍和精细,内存在多智能体工作流中变得更加关键:
Agent A: Research
Agent B: Plan
Agent C: Execute
没有共享内存系统的情况下:
有了结构化的内存架构:
Oracle AI 开发者中心仓库的模式通过将内存视为基础设施使这成为可能。
让我们看看一个示例内存生命周期:
stateDiagram-v2
[*] --> Input: User Query
Input --> Retrieval: Vector Search (User-Scoped Semantic Memory)
Retrieval --> Audit: Log Retrieval Event
Audit --> Reasoning: LLM Processing
Reasoning --> Response: Deliver Answer
Response --> Extraction: Extract Structured Memory
Extraction --> Persistence: Store in Oracle 26ai
Persistence --> Retrieval: Future Similarity Search
这个生命周期强化了内存的迭代、演变本质。
作为开发者或开发团队构建 AI 应用程序,应该从哪里开始?通常,进程类似于:
如果我们重新访问 Oracle AI 开发者中心,我们会看到它特别好地支持步骤 2-4。
这加快了从好奇心到能力的路径。
随着我们进入更多智能体的世界,并发现自己越来越多地利用智能体和 LLM 进行更多任务,我们正在发现 Agent 内存不能是表面化的。它变成了至关重要的,并能够实现:
没有内存,智能体仍然是令人印象深刻的演示。
有了内存,它们变成了系统。
作为开发者,我们长期以来一直知道耐久的系统需要,除其他外:
Agent 内存值得同样的严谨性,实际上,需要它。
Oracle AI 开发者中心证明了具有内存感知的智能体不是研究奇想。它们今天可以使用结构化模式构建。软件开发者多年来一直在使用的模式。
准备好构建一个具有内存感知的智能体了吗?
探索代码:前往 Oracle AI 开发者中心查看这些模式的实际应用。
运行笔记本:使用内存上下文工程笔记本立即开始体验结构化检索。
实施 RAG:学习如何使用 Oracle 的 RAG 实现示例将 RAG 视为"内存原语"。
实施 RAG:学习如何使用 Oracle 的 RAG 实现示例将 RAG 视为"内存原语"。
对于探索 AI 架构下一阶段的开发者,内存不是可选的。
而工程化它的工具已经可用。
Agent 内存不是一个功能。它是区分令人印象深刻的演示与实际跨越时间工作的系统的基础。
我们在本系列中花费了相当多的时间思考如何将数据输入系统——采集、转换、索引、检索。具有内存感知的智能体翻转了这个问题:现在系统本身需要累积、选择和检索重要的内容。这个架构看起来很熟悉,因为它就是熟悉的。相同的本能,新的领域。
这种本能——将智能视为基础设施——指向下一个值得探索的东西。当智能体不仅有内存感知,而且是主权的时会发生什么?当它们不仅回忆上下文,而且维持持久的目标、与其他智能体协调,并以某种程度的自主性运作,这看起来不再像一个工具,而更像一个合作者时?
这就是我们的方向。
在 LinkedIn 上分享(在新窗口中打开)LinkedIn
给朋友发送链接(在新窗口中打开)电子邮件
打印(在新窗口中打开)打印