mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
- Introduced platform client documentation in `docs/v4/clients/platform.md` detailing methods for sending messages, images, and managing group members. - Added example plugins for LLM chat and database functionalities in `docs/v4/examples/README.md`, `docs/v4/examples/llm-chat/README.md`, and `docs/v4/examples/database/README.md`. - Enhanced quickstart guide with links to new documentation and example plugins. - Implemented runtime contract tests to ensure compatibility of public capabilities and hooks.
6.6 KiB
6.6 KiB
记忆客户端
记忆客户端提供 AI 记忆存储能力,支持语义搜索。
概述
from astrbot_sdk import Context
# 通过 Context 访问
ctx.memory # MemoryClient 实例
Memory vs DB 的区别
| 特性 | DBClient | MemoryClient |
|---|---|---|
| 存储方式 | 键值存储 | 语义向量存储 |
| 检索方式 | 精确匹配 | 语义搜索 |
| 适用场景 | 配置、计数器、简单数据 | AI 上下文、用户偏好、对话记忆 |
选择建议:
- 需要精确键查找 → 使用
db - 需要语义搜索 → 使用
memory
方法
save()
保存记忆项。
async def save(
self,
key: str,
value: dict[str, Any] | None = None,
**extra: Any,
) -> None
参数:
key: str- 记忆项的唯一标识键value: dict | None- 要存储的数据字典**extra: Any- 额外的键值对
示例:
# 保存用户偏好
await ctx.memory.save("user_pref", {
"theme": "dark",
"language": "zh",
"interests": ["游戏", "音乐"]
})
# 使用关键字参数
await ctx.memory.save(
"note:1",
None,
content="重要笔记",
tags=["work", "urgent"],
created_at="2024-01-01"
)
# 保存对话摘要
await ctx.memory.save("conversation:session_123", {
"summary": "用户询问了天气,推荐了晴天出行",
"topics": ["天气", "出行"],
"sentiment": "positive"
})
get()
精确获取单个记忆项。
async def get(self, key: str) -> dict[str, Any] | None
参数:
key: str- 记忆项的唯一键
返回:dict | None - 记忆内容,不存在则返回 None
示例:
# 获取用户偏好
pref = await ctx.memory.get("user_pref")
if pref:
print(f"用户偏好主题: {pref.get('theme')}")
print(f"用户兴趣: {pref.get('interests')}")
search()
语义搜索记忆项。
async def search(self, query: str) -> list[dict[str, Any]]
参数:
query: str- 搜索查询文本
返回:list[dict] - 匹配的记忆项列表,按相关度排序
示例:
# 搜索用户偏好相关记忆
results = await ctx.memory.search("用户喜欢什么颜色")
for item in results:
print(f"键: {item['key']}")
print(f"内容: {item['content']}")
print(f"相关度: {item.get('score', 0)}")
print("---")
# 搜索对话历史
results = await ctx.memory.search("之前讨论过天气吗")
if results:
await event.reply("是的,我们之前讨论过天气话题")
delete()
删除记忆项。
async def delete(self, key: str) -> None
示例:
# 删除过期记忆
await ctx.memory.delete("old_note")
# 删除用户数据
await ctx.memory.delete(f"user_data:{user_id}")
使用场景
场景 1:用户偏好记忆
@on_command("remember")
async def remember_preference(self, event: MessageEvent, ctx: Context):
"""记住用户偏好"""
preference = event.text.removeprefix("/remember").strip()
# 保存偏好
key = f"pref:{event.user_id}"
prefs = await ctx.memory.get(key) or {"items": []}
prefs["items"].append(preference)
await ctx.memory.save(key, prefs)
await event.reply(f"已记住:{preference}")
@on_command("what_do_i_like")
async def recall_preference(self, event: MessageEvent, ctx: Context):
"""回忆用户偏好"""
query = "用户偏好 喜欢"
results = await ctx.memory.search(query)
if results:
lines = ["您之前告诉过我:"]
for item in results[:3]:
lines.append(f"- {item.get('content', '未知')}")
await event.reply("\n".join(lines))
else:
await event.reply("我还没有记住您的偏好")
场景 2:对话上下文记忆
@on_message(keywords=["我"])
async def track_context(self, event: MessageEvent, ctx: Context):
"""跟踪用户提到的个人信息"""
# 保存到记忆
await ctx.memory.save(
f"user_info:{event.user_id}:{event.session_id}",
{
"message": event.text,
"timestamp": "2024-01-01",
"type": "personal_info"
}
)
@on_command("recall")
async def recall_context(self, event: MessageEvent, ctx: Context):
"""回忆对话内容"""
query = event.text.removeprefix("/recall").strip() or "用户说过什么"
results = await ctx.memory.search(query)
if results:
await event.reply(f"您之前提到:{results[0].get('message', '未知')}")
else:
await event.reply("我没有找到相关记忆")
场景 3:智能推荐
@on_command("recommend")
async def recommend(self, event: MessageEvent, ctx: Context):
"""基于记忆的智能推荐"""
# 搜索用户兴趣相关的记忆
interests = await ctx.memory.search(f"{event.user_id} 兴趣 爱好")
if not interests:
await event.reply("告诉我您的兴趣,我可以给您推荐内容!")
return
# 基于兴趣生成推荐
interest_text = ", ".join(
item.get("content", "")
for item in interests[:3]
)
prompt = f"用户喜欢 {interest_text},推荐一些相关内容"
recommendation = await ctx.llm.chat(prompt)
await event.reply(recommendation)
最佳实践
1. 使用结构化键名
# 推荐:有层次结构的键名
"user:{user_id}:preferences"
"user:{user_id}:history:{session_id}"
"conversation:{session_id}:summary"
# 避免:无组织的键名
"data"
"info"
"temp"
2. 为搜索优化内容
# 好:包含可搜索的描述性文本
await ctx.memory.save("user_pref", {
"description": "用户喜欢玩游戏和听音乐",
"interests": ["游戏", "音乐"],
"level": "advanced"
})
# 不好:过于抽象,难以语义搜索
await ctx.memory.save("user_pref", {
"a": ["x", "y"],
"b": 2
})
3. 结合 DB 和 Memory
# DB:存储精确配置
await ctx.db.set("config:theme", "dark")
# Memory:存储语义可搜索的内容
await ctx.memory.save("user_interests", {
"description": "用户对游戏开发感兴趣",
"tags": ["游戏", "开发", "Unity"]
})
注意事项
- 值必须是字典:
memory.save()的 value 参数必须是dict类型
# 正确
await ctx.memory.save("key", {"value": 123})
# 错误
await ctx.memory.save("key", 123) # TypeError
- 语义搜索依赖宿主实现:搜索质量取决于宿主的向量存储配置