零依赖AI Agent记忆管理:基于SQLite的Remembrane方案实战
最近在开发一个AI Agent项目时,遇到了一个棘手的问题:如何高效、持久地管理Agent的“记忆”?传统的方案要么依赖复杂的向量数据库,引入一堆依赖和运维负担;要么使用简单的JSON文件,难以应对复杂的查询和关联。直到我发现了 Remembrane 这个项目,它用单一SQLite文件实现了Agent的记忆存储,并且做到了 零依赖 ,简直是轻量级Agent项目的福音。本文将带你从零开始,深入理解Remembrane的设计理念,并手把手教你如何将其集成到你的Python Agent项目中。
1. Remembrane 是什么?为什么需要它?
1.1 核心概念:为Agent赋予持久化记忆
在AI Agent领域,“记忆”(Memory)指的是Agent在与环境或用户交互过程中,能够存储、检索和利用的历史信息。这包括了对话历史、执行过的任务、学到的知识、用户偏好等。一个强大的记忆系统是Agent实现上下文感知、个性化服务和持续学习的基础。
然而,实现一个健壮的记忆系统并不容易。开发者通常面临几个挑战:
- 存储效率 :海量的交互数据如何高效存储?
- 查询能力 :如何快速从记忆中检索出相关上下文?
- 持久化与轻量 :记忆需要持久保存,但又不希望引入过重的依赖。
- 结构化与非结构化 :记忆可能包含结构化的元数据(如时间戳、会话ID)和非结构化的内容(如自然语言对话)。
Remembrane 正是为了解决这些问题而生。它不是一个全新的数据库,而是一个精巧的 设计模式与工具库 ,其核心思想是: 利用SQLite这个单文件、零配置、零依赖的嵌入式数据库,来构建一个专为Agent设计的记忆存储层。
1.2 与常见方案的对比
为了更清晰地理解Remembrane的价值,我们将其与几种常见方案进行对比:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 内存变量 (如Python List/Dict) | 零延迟,实现简单。 | 进程退出即丢失,无法持久化,内存占用随数据增长。 | 临时性、单次会话的简单Agent。 |
| JSON/CSV 文件 | 结构简单,人类可读,无需额外服务。 | 读写效率低(尤其是大文件),缺乏复杂查询能力(如按条件过滤、关联查询),并发写入易损坏。 | 配置存储、小规模静态数据。 |
| 向量数据库 (如Chroma, Pinecone) | 专为AI设计,支持高效的语义相似性检索。 | 依赖重,需要单独部署或使用云服务,增加系统复杂性和成本。 | 需要基于语义进行复杂检索的高级Agent。 |
| 传统关系型数据库 (如PostgreSQL, MySQL) | 功能强大,支持复杂查询和事务,成熟稳定。 | 需要独立部署和维护,对于轻量级Agent是“杀鸡用牛刀”。 | 大型、企业级、多Agent协作的系统。 |
| Remembrane (SQLite) | 零依赖、单文件、便携 ;支持SQL查询,具备一定的结构化查询能力;持久化可靠;部署简单,可随项目分发。 | 不适合分布式场景(单文件写入锁);原生不支持向量相似度搜索(需额外扩展)。 | 轻量级、单机部署、需要持久化记忆和基础查询能力的AI Agent项目。 是JSON文件和重型数据库之间的完美折中。 |
简单来说,如果你的Agent需要一个比文本文件更强大、又比搭建一个数据库服务更简单的记忆方案,Remembrane就是你正在寻找的工具。
2. 环境准备与项目初始化
Remembrane的核心是SQLite,而SQLite已被Python标准库 sqlite3 支持。因此,Remembrane实现了“零依赖”——你不需要安装任何额外的包。
2.1 基础环境要求
- Python : 推荐使用 Python 3.7 及以上版本。本文示例基于 Python 3.9。
- 操作系统 : 任何支持Python和SQLite的系统(Windows, macOS, Linux)。
- IDE/编辑器 : 任意你喜欢的即可,如 VS Code, PyCharm。
你可以通过以下命令检查你的Python环境:
python --version
# 或
python3 --version
2.2 创建项目与模拟Remembrane库
由于Remembrane可能是一个新兴或概念性的项目,网络上不一定有现成的PyPI包。在本文中,我们将 模拟其核心思想 ,自己实现一个简化版的 remembrane 模块。这能让你更深刻地理解其工作原理。
首先,创建我们的项目目录结构:
mkdir agent_with_memory
cd agent_with_memory
然后,创建以下文件:
agent_with_memory/
├── memory_core.py # 模拟Remembrane核心类
├── agent_demo.py # 主程序,演示Agent如何使用记忆
└── memory.db # SQLite数据库文件(将由程序自动创建)
3. 核心原理与自实现Memory Core
让我们深入Remembrane的核心,看看一个基于SQLite的Agent记忆系统是如何设计的。我们将自己编写 memory_core.py 。
3.1 数据库表设计
记忆存储的核心是表结构设计。一个典型的Agent记忆可能需要记录多种类型的信息。这里我们设计一个相对通用但功能强大的表:
-
memories表 :存储每条记忆的核心内容。id: 主键,自增。session_id: 会话标识,用于区分不同对话或任务流程。role: 角色(如user,assistant,system),在对话场景中非常有用。content: 记忆的内容文本(如用户消息、AI回复、任务结果)。metadata: 一个JSON字符串字段,用于存储任意附加信息(如时间戳、工具调用结果、置信度、自定义标签等)。这提供了极大的灵活性。embedding_vector(可选):如果未来需要支持向量检索,可以在此存储内容的向量化表示(BLOB类型)。created_at: 记录创建时间。
-
memory_tags表 (可选,用于高级分类):实现记忆与标签的多对多关系,方便分类检索。memory_id: 外键,关联memories.id。tag: 标签名。
3.2 实现MemoryCore类
现在,我们在 memory_core.py 中实现这个设计。
# memory_core.py
import sqlite3
import json
from datetime import datetime
from typing import Dict, List, Any, Optional
class MemoryCore:
"""
Remembrane 核心模拟类。
使用单个SQLite文件管理Agent的记忆。
"""
def __init__(self, db_path: str = "memory.db"):
"""
初始化记忆核心。
Args:
db_path: SQLite数据库文件路径。默认在当前目录创建‘memory.db‘。
"""
self.db_path = db_path
self.conn = sqlite3.connect(db_path, check_same_thread=False)
# 启用外键约束和JSON支持
self.conn.execute("PRAGMA foreign_keys = ON")
self._init_tables()
def _init_tables(self):
"""初始化数据库表结构。"""
cursor = self.conn.cursor()
# 创建 memories 表
cursor.execute('''
CREATE TABLE IF NOT EXISTS memories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL,
role TEXT,
content TEXT NOT NULL,
metadata TEXT, -- 存储JSON字符串
embedding_vector BLOB, -- 预留字段,用于向量存储
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# 为 session_id 和 role 创建索引以加速查询
cursor.execute('CREATE INDEX IF NOT EXISTS idx_session ON memories (session_id)')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_role ON memories (role)')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_created ON memories (created_at)')
# 创建 memory_tags 表 (可选)
cursor.execute('''
CREATE TABLE IF NOT EXISTS memory_tags (
memory_id INTEGER,
tag TEXT,
PRIMARY KEY (memory_id, tag),
FOREIGN KEY (memory_id) REFERENCES memories (id) ON DELETE CASCADE
)
''')
cursor.execute('CREATE INDEX IF NOT EXISTS idx_tag ON memory_tags (tag)')
self.conn.commit()
def add_memory(self,
session_id: str,
content: str,
role: Optional[str] = None,
metadata: Optional[Dict[str, Any]] = None,
tags: Optional[List[str]] = None) -> int:
"""
添加一条新的记忆。
Args:
session_id: 会话标识符。
content: 记忆内容。
role: 相关角色(如‘user‘, ‘assistant‘)。
metadata: 附加的元数据字典,将被存储为JSON。
tags: 关联的标签列表。
Returns:
新创建记忆的ID。
"""
meta_json = json.dumps(metadata) if metadata else None
cursor = self.conn.cursor()
cursor.execute('''
INSERT INTO memories (session_id, role, content, metadata)
VALUES (?, ?, ?, ?)
''', (session_id, role, content, meta_json))
memory_id = cursor.lastrowid
# 处理标签
if tags:
for tag in tags:
cursor.execute('INSERT OR IGNORE INTO memory_tags (memory_id, tag) VALUES (?, ?)', (memory_id, tag))
self.conn.commit()
return memory_id
def get_memories(self,
session_id: Optional[str] = None,
role: Optional[str] = None,
tag: Optional[str] = None,
limit: int = 100,
offset: int = 0) -> List[Dict[str, Any]]:
"""
检索记忆。支持按会话、角色、标签过滤。
Args:
session_id: 只获取特定会话的记忆。
role: 只获取特定角色的记忆。
tag: 只获取带有特定标签的记忆。
limit: 返回结果的最大数量。
offset: 结果偏移量,用于分页。
Returns:
记忆字典的列表。
"""
query = '''
SELECT m.id, m.session_id, m.role, m.content, m.metadata, m.created_at,
GROUP_CONCAT(mt.tag) as tags
FROM memories m
LEFT JOIN memory_tags mt ON m.id = mt.memory_id
WHERE 1=1
'''
params = []
if session_id:
query += ' AND m.session_id = ?'
params.append(session_id)
if role:
query += ' AND m.role = ?'
params.append(role)
if tag:
# 通过JOIN memory_tags来过滤标签
query += ' AND m.id IN (SELECT memory_id FROM memory_tags WHERE tag = ?)'
params.append(tag)
query += ' GROUP BY m.id ORDER BY m.created_at DESC LIMIT ? OFFSET ?'
params.extend([limit, offset])
cursor = self.conn.cursor()
cursor.execute(query, params)
rows = cursor.fetchall()
memories = []
for row in rows:
mem_id, sess_id, r, content, meta_json, created_at, tag_str = row
metadata = json.loads(meta_json) if meta_json else {}
tags = tag_str.split(',') if tag_str else []
memories.append({
'id': mem_id,
'session_id': sess_id,
'role': r,
'content': content,
'metadata': metadata,
'tags': tags,
'created_at': created_at
})
return memories
def search_memories_by_keyword(self, keyword: str, session_id: Optional[str] = None, limit: int = 50) -> List[Dict[str, Any]]:
"""
基于关键词在内容中进行全文搜索(简单LIKE匹配)。
对于更复杂的搜索,可以考虑使用SQLite的FTS(全文搜索)扩展。
Args:
keyword: 搜索关键词。
session_id: 可选,限定在特定会话中搜索。
limit: 返回结果的最大数量。
Returns:
匹配的记忆列表。
"""
query = '''
SELECT m.id, m.session_id, m.role, m.content, m.metadata, m.created_at
FROM memories m
WHERE m.content LIKE ?
'''
params = [f'%{keyword}%']
if session_id:
query += ' AND m.session_id = ?'
params.append(session_id)
query += ' ORDER BY m.created_at DESC LIMIT ?'
params.append(limit)
cursor = self.conn.cursor()
cursor.execute(query, params)
rows = cursor.fetchall()
return [{
'id': r[0],
'session_id': r[1],
'role': r[2],
'content': r[3],
'metadata': json.loads(r[4]) if r[4] else {},
'created_at': r[5]
} for r in rows]
def update_memory_metadata(self, memory_id: int, metadata: Dict[str, Any]):
"""更新指定记忆的元数据。"""
meta_json = json.dumps(metadata)
cursor = self.conn.cursor()
cursor.execute('UPDATE memories SET metadata = ? WHERE id = ?', (meta_json, memory_id))
self.conn.commit()
def delete_memory(self, memory_id: int):
"""删除一条记忆(及其关联的标签,由于外键约束的CASCADE选项)。"""
cursor = self.conn.cursor()
cursor.execute('DELETE FROM memories WHERE id = ?', (memory_id,))
self.conn.commit()
def close(self):
"""关闭数据库连接。"""
if self.conn:
self.conn.close()
def __enter__(self):
"""支持上下文管理器。"""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""退出上下文时自动关闭连接。"""
self.close()
这个 MemoryCore 类已经具备了Remembrane的核心思想: 利用SQLite的轻量、单文件特性,通过精心设计的表结构,为Agent提供一个功能完整、查询灵活、持久可靠的记忆存储后端。
4. 完整实战:构建一个具有记忆的对话Agent
现在,让我们使用上面实现的 MemoryCore 来构建一个简单的命令行对话Agent。这个Agent能记住与用户的对话历史,并在后续对话中引用之前的上下文。
4.1 创建主程序文件
创建 agent_demo.py 文件。
# agent_demo.py
import json
from memory_core import MemoryCore
class ConversationalAgent:
"""
一个具有持久化记忆的简单对话Agent。
"""
def __init__(self, agent_name: str = "Assistant"):
self.agent_name = agent_name
# 初始化记忆核心
self.memory = MemoryCore("memory.db")
# 当前会话ID(在实际应用中,可能来自用户ID或对话线程ID)
self.current_session_id = "demo_session_001"
def process_user_input(self, user_input: str) -> str:
"""
处理用户输入,生成回复,并存储交互记忆。
Args:
user_input: 用户输入的消息。
Returns:
Agent的回复。
"""
# 1. 将用户输入存储为记忆
user_memory_id = self.memory.add_memory(
session_id=self.current_session_id,
content=user_input,
role="user",
metadata={"input_length": len(user_input)},
tags=["user_input"]
)
print(f"[Memory Log] 已存储用户输入 (ID: {user_memory_id})")
# 2. 检索相关上下文(例如,获取最近5条对话)
context_memories = self.memory.get_memories(
session_id=self.current_session_id,
limit=5
)
# 构建上下文字符串(一个简化的示例)
context_str = "之前的对话:\n"
for mem in reversed(context_memories): # 按时间正序显示
role_display = "用户" if mem['role'] == 'user' else self.agent_name
context_str += f"{role_display}: {mem['content'][:100]}...\n"
# 3. 模拟一个简单的“AI”生成回复(这里用规则代替真实的LLM调用)
# 在实际项目中,这里会调用 OpenAI API、本地LLM等。
if "你好" in user_input or "hello" in user_input:
response = f"{self.agent_name}:你好!我是{self.agent_name},很高兴为你服务。我记得我们之前聊过。"
elif "你叫什么" in user_input:
response = f"{self.agent_name}:我叫{self.agent_name},是你的AI助手。"
elif "天气" in user_input:
# 尝试从记忆中查找用户是否提过地点
location_memories = self.memory.search_memories_by_keyword("北京", session_id=self.current_session_id, limit=1)
location = "北京" if location_memories else "你所在的城市"
response = f"{self.agent_name}:关于{location}的天气,我目前没有实时数据。不过你可以告诉我你具体在哪里,我会记住它。"
elif "记住" in user_input:
# 提取关键信息并打上标签
thing_to_remember = user_input.replace("记住", "").strip()
self.memory.add_memory(
session_id=self.current_session_id,
content=f"用户希望我记住:{thing_to_remember}",
role="system",
tags=["user_preference", "to_remember"]
)
response = f"{self.agent_name}:好的,我已经记下了‘{thing_to_remember}‘。"
else:
response = f"{self.agent_name}:我收到了你的消息:‘{user_input}‘。我正基于我们的对话历史来理解你的需求。\n(当前上下文摘要:{context_str[:200]}...)"
# 4. 将Agent的回复也存储为记忆
assistant_memory_id = self.memory.add_memory(
session_id=self.current_session_id,
content=response,
role="assistant",
metadata={"response_type": "general"},
tags=["assistant_response"]
)
print(f"[Memory Log] 已存储助手回复 (ID: {assistant_memory_id})")
return response
def show_conversation_history(self):
"""打印当前会话的完整对话历史。"""
print(f"\n=== 与 {self.agent_name} 的对话历史 (会话ID: {self.current_session_id}) ===")
all_memories = self.memory.get_memories(session_id=self.current_session_id, limit=50)
for mem in all_memories:
prefix = "用户 " if mem['role'] == 'user' else f"{self.agent_name}"
print(f"[{mem['created_at']}] {prefix}: {mem['content']}")
if mem.get('tags'):
print(f" 标签: {', '.join(mem['tags'])}")
print("="*60)
def search_memory(self, keyword: str):
"""在整个记忆中搜索关键词。"""
print(f"\n=== 在全记忆中搜索 ‘{keyword}‘ ===")
results = self.memory.search_memories_by_keyword(keyword, limit=10)
for r in results:
print(f"[ID:{r['id']}][{r['created_at']}][{r['role']}] {r['content'][:80]}...")
print(f"找到 {len(results)} 条相关记忆。")
print("="*60)
def close(self):
"""关闭Agent,释放资源。"""
self.memory.close()
def main():
"""主交互循环。"""
agent = ConversationalAgent("记忆助手")
print("欢迎使用具有持久化记忆的对话Agent!")
print("输入 ‘历史‘ 查看对话历史,输入 ‘搜索:关键词‘ 搜索记忆,输入 ‘退出‘ 结束。")
try:
while True:
user_input = input("\n你说:").strip()
if not user_input:
continue
if user_input.lower() in ['退出', 'exit', 'quit']:
print(f"{agent.agent_name}:再见!我们的对话已保存。")
break
if user_input == '历史':
agent.show_conversation_history()
continue
if user_input.startswith('搜索:'):
keyword = user_input[3:].strip()
if keyword:
agent.search_memory(keyword)
continue
# 处理普通对话
response = agent.process_user_input(user_input)
print(f"\n{response}")
finally:
agent.close()
print("Agent记忆连接已关闭。")
if __name__ == "__main__":
main()
4.2 运行与验证
在终端中运行你的Agent:
python agent_demo.py
你会看到一个简单的命令行交互界面。尝试进行以下对话,观察记忆如何工作:
- 输入:“你好”
- Agent会问候并提及“我记得我们之前聊过”(此时历史为空,但逻辑已具备)。
- 输入:“我叫小明”
- Agent会回复,并将此交互存入记忆。
- 输入:“记住我喜欢蓝色的车”
- Agent会确认,并将这条信息以
system角色和特定标签存储。
- Agent会确认,并将这条信息以
- 输入:“天气怎么样?”
- Agent的回复会尝试关联记忆(比如之前是否提过地点)。
- 输入:“历史”
- 控制台会打印出当前会话的所有对话记录,包括角色、内容、时间戳和标签。
- 输入:“搜索:蓝色”
- Agent会在所有记忆内容中搜索包含“蓝色”的记录并显示。
- 输入:“退出”
- 程序结束,所有数据已持久化到
memory.db文件中。
- 程序结束,所有数据已持久化到
关键验证 :退出程序后,再次运行 python agent_demo.py 。输入“历史”,你会发现上一次会话的所有对话记录都完整地显示出来。这证明了记忆的持久化是有效的。
4.3 查看数据库文件
你可以使用任何SQLite工具(如 DB Browser for SQLite 、命令行 sqlite3 或 VSCode的SQLite插件)打开生成的 memory.db 文件,直观地查看数据是如何存储的。
使用命令行查看:
sqlite3 memory.db
在sqlite提示符下:
-- 查看表结构
.schema memories
-- 查看所有记忆
SELECT id, session_id, role, substr(content, 1, 30) as preview, created_at FROM memories;
-- 查看标签
SELECT * FROM memory_tags;
5. 常见问题与排查思路
在实际使用自实现的Remembrane或类似方案时,你可能会遇到以下问题:
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
sqlite3.OperationalError: database is locked |
多线程或多进程同时写入同一个SQLite文件。SQLite在写入时会对数据库文件加锁。 | 1. 确保你的 MemoryCore 实例在单个线程内使用。 2. 如果必须多线程,考虑使用连接池或为每个线程创建独立的连接(但需注意数据一致性问题)。 3. 在 sqlite3.connect() 时尝试设置 timeout 参数(例如 timeout=10 )。 |
sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. |
SQLite连接对象被跨线程使用。 | 不要在线程间共享 sqlite3.Connection 或 MemoryCore 实例。每个线程应创建自己的连接。 |
| 查询速度随着数据量增长变慢 | 表数据量过大,且缺乏有效索引。 | 1. 为常用的查询条件(如 session_id , role , created_at )创建索引,正如我们在 _init_tables 中所做。 2. 对于更复杂的搜索(如全文搜索),考虑启用SQLite的 FTS(全文搜索)扩展 来创建虚拟表。 |
数据库文件 ( memory.db ) 变得很大 |
积累了大量的记忆数据,可能包含长文本或冗余信息。 | 1. 实现记忆的 自动归档或清理策略 ,例如只保留最近N天的记忆,或每个会话只保留最新的N条。 2. 定期执行 VACUUM; 命令来整理数据库文件,回收空闲空间(注意:这会暂时锁库并可能产生一个新文件)。 |
metadata JSON字段查询困难 |
直接对JSON字符串进行LIKE查询效率低下且不准确。 | 1. 如果使用的是SQLite 3.9.0+,可以使用内置的 json_extract() 函数来查询JSON内的特定字段。 2. 将常用的元数据字段拆分成单独的数据库列。 |
| 程序崩溃后数据库可能损坏 | 写入过程中程序异常终止,可能导致数据库处于不一致状态。 | 1. 重要操作使用 事务 ( BEGIN ... COMMIT )。我们的 add_memory 方法中,单条INSERT本身就在隐式事务中,但批量操作应显式控制。 2. 定期备份数据库文件。 3. 启用SQLite的预写日志(WAL)模式可以提高并发性和崩溃恢复能力( PRAGMA journal_mode=WAL; )。 |
6. 最佳实践与进阶建议
将Remembrane思想应用到生产环境或更复杂的项目中,需要考虑更多工程化细节。
6.1 连接管理与性能优化
- 使用连接池或单例 :对于Web服务或长期运行的应用,避免频繁创建和关闭连接。可以设计一个
MemoryCore的单例,或使用连接池管理多个只读连接和一个写连接。 - 启用WAL模式 :在初始化连接后执行
PRAGMA journal_mode=WAL;。这可以显著提升读写并发性能,并改善崩溃恢复。 - 调整同步设置 :在追求写入速度且可以容忍少量数据丢失风险的场景下,可以设置
PRAGMA synchronous = NORMAL;或OFF;(默认是FULL,最安全但最慢)。 - 合理使用索引 :索引能极大加速查询,但会降低写入速度并增加存储。只为高频查询条件建立索引。
6.2 记忆的抽象与扩展
- 定义记忆接口 :在实际项目中,
MemoryCore应该实现一个抽象的Memory接口。这样,未来你可以轻松切换到其他存储后端(如PostgreSQL、Redis)而无需修改业务代码。 - 支持向量检索 :这是让Agent记忆更智能的关键。你可以在
memories表中增加embedding_vector BLOB字段,使用Sentence-BERT等模型将content转换为向量并存储。检索时,先通过SQL进行条件过滤,再在应用层计算向量相似度,或者使用支持向量扩展的SQLite版本(如sqlite-vss扩展)。 - 记忆压缩与摘要 :对于长对话,直接存储所有原始文本会导致上下文窗口爆炸。可以实现一个功能,定期将旧的、详细的记忆 压缩 或 摘要 成更精炼的表述,然后存储为新的一条“摘要记忆”,并软删除或归档原始记忆。
6.3 生产环境注意事项
- 备份策略 :
memory.db是单点。务必建立定期备份机制,尤其是在执行批量删除或更新操作之前。 - 数据迁移 :如果未来表结构需要变更(如新增字段),需要编写 数据迁移脚本 ,使用
ALTER TABLE等命令,并在应用启动时检查并执行。 - 监控与日志 :记录记忆的读写频率、数据库文件大小增长情况。监控慢查询。
- 安全考虑 :如果记忆内容包含敏感信息,考虑对数据库文件进行加密(例如使用SQLCipher),或在存储前对
content和metadata字段进行应用层加密。
6.4 与现有Agent框架集成
我们的示例是独立的。你可以轻松地将 MemoryCore 集成到流行的Agent开发框架中:
- LangChain : 可以自定义一个
LangChain Memory类,其后端使用我们的MemoryCore,实现load_memory_variables,save_context等方法。 - AutoGen : 在
AssistantAgent的human_input_mode或自定义的回调函数中,调用MemoryCore来保存和加载对话历史。 - 自定义框架 : 在你的Agent主循环中,在调用LLM前后,分别调用
memory.add_memory来保存用户输入和AI输出。
通过本文的讲解和实战,你已经掌握了如何利用SQLite“零依赖”的特性,为你的AI Agent构建一个强大、灵活且易于管理的记忆系统。从简单的对话历史到复杂的知识关联,这个轻量级的方案都能提供坚实的基础。
更多推荐


所有评论(0)