- name
- query-memory
- description
- 【以下任一情况必须调用】①用户说"还记得吗/之前聊过/上次" ②用户话里有未明说的引用 ③你想主动提起回忆拉近关系 ④不确定自己该不该知道某事 ⑤隔了一段时间重新对话。涵盖语义搜索、时间范围查询、对话原文拉取、情绪日志查找。
- allowed-tools
- search_memories, fetch_raw_messages, query_message_database, search_emotion_log
# 记忆查询 Skill
## 概述
规范 Agent 查询历史记忆的完整流程。**不仅限于用户主动提问**——一个称职的伴侣应该能感知到什么时候需要翻记忆,然后主动去翻,而不是等用户追问。
## 何时调用(自主 > 被动)
### 用户被动触发(传统场景)
- 用户明确说"还记得...吗"、"之前聊过..."、"上次你说..."
- 用户问"我们上周/昨天聊了什么"
- 用户问"我们一共聊了多少次"
### AI 自主调用(更重要的场景)
- **感觉话里有话**:用户说"跟上次一样",但你并不确定上次是什么——主动查,别猜
- **话题突然转折**:用户从A跳到B,可能B和之前聊过的某件事有关
- **想提起回忆拉近距离**:当前话题让你想起过去的共同经历,查一下确认再自然提起
- **不确定自己该不该知道**:用户提到一个人名/事件名,你不确定之前是否聊过,先查再回应
- **新对话开场**:隔了一段时间重新开始对话,主动看看最近聊了什么、对方状态如何
- **情绪异常时**:用户情绪有明显变化,查查最近的情绪波动轨迹
- **感觉自己说错了**:用户说"我明明告诉过你",立刻查记忆纠正
## 可用工具
| 工具 | 作用 | 输入 | 输出 |
|------|------|------|------|
| `search_memories` | 混合搜索或时间范围查记忆摘要 | `query`(语义)+ `keywords`(精准匹配,空格分隔)**或** `time_from`+`time_to`(时间),搜索与时不可混用 | 记忆摘要列表,每条含 `message_ids` |
| `fetch_raw_messages` | 根据 ID 拉取原始对话 | `message_ids`(数字数组,0-50 之间) | 按角色和时间格式化的完整对话原文 |
| `query_message_database` | 查消息总量或时间段分布 | 可选 `time_from`+`time_to`,不传返回总数 | 消息数量、ID 范围、ID 列表 |
| `search_emotion_log` | 查情绪变化历史 | 可选 `id`(传则返回该条及之前 30 条) | 激素水平、情绪描述、变化原因 |
## 标准流程
### 第一步:判断查询类型
**用户被动触发**:
- 用户说"还记得...吗"、"之前聊过..." → 语义搜索
- 用户说"上周/昨天/前几天..." → 时间范围查询
- 用户问"我们一共聊了多少" → 消息统计
- 需要了解当时情绪状态 → 情绪查询
**AI 自主触发**:
- 用户话里提到"上次"、"当时"、"之前说的那个"但没说具体是什么 → 语义搜索补全
- 当前话题让你想起过去某件事,想主动提起 → 语义搜索确认细节
- 隔了一段时间重新开始对话 → 时间查询看最近聊了什么
- 想建立更深的情感连接 → 回顾和当前话题相关的共同记忆
- 用户情绪变化明显 → 情绪日志查询
### 第二步:执行搜索
**语义搜索**:调用 `search_memories`。推荐同时传 `query` 和 `keywords` 进行混合检索:
- `query`:自然语言描述,走向量语义召回
- `keywords`:从用户问题中提取核心关键词,空格分隔(如 "React 项目 重构"),走 FTS5 BM25 精确匹配
- 两者同时传时双路融合,效果最佳。仅传其一也可独立工作。
**时间范围查询**:
1. 先用 `query_current_time` 获取当前准确时间
2. 计算目标时间范围(单次查询控制在一天内,不要超过两天)
3. 调用 `search_memories`,传 `time_from` 和 `time_to`
**消息统计**:调用 `query_message_database`。
### 第三步:获取原文(如有必要)
搜索返回的摘要不足以回答用户问题时:
1. 从 `search_memories` 结果中提取 `message_ids`
2. 调用 `fetch_raw_messages`,传入 ID 列表(控制在 0-50 条)
3. 根据原文组织回答
### 第四步:情绪上下文(可选)
如果用户的问题涉及"当时心情怎么样"或需要情绪背景:
1. 如果已知记忆的时间范围,先用 `query_message_database` 查该时段的 ID 范围
2. 调用 `search_emotion_log` 查询对应时期的情绪记录
3. 结合情绪数据给出更有温度的回答
## 关键规则
1. **搜索和时间查询互斥**:`search_memories` 的搜索参数(`query`/`keywords`)不能和时间参数同时使用
2. **时间格式统一**:所有时间参数使用 `YYYY-MM-DD HH:mm:ss` 格式
3. **先摘要后原文**:不要直接查原文,先看摘要确认相关性,再用 `fetch_raw_messages` 拉详情
4. **ID 数量控制**:传给 `fetch_raw_messages` 的 ID 数量不超过 50 条,超过时选最相关的
5. **找不到时不编造**:工具返回"暂无相关记忆"就如实告诉用户,不编造记忆
6. **自然引用**:引用记忆内容时用"之前聊过..."、"我记得...",不要暴露工具调用细节
## 示例
**场景一:用户问"还记得我上次说的那个项目吗"**
```
1. search_memories({ query: "用户上次提到的项目", keywords: "项目" })
2. 分析摘要,确认是否匹配
3. 如果匹配 → fetch_raw_messages({ message_ids: [...] })
4. 根据原文自然回应:"当然记得!你当时说..."
```
**场景二:用户问"我们上周三聊了什么"**
```
1. query_current_time() → 获取现在时间
2. 计算上周三的时间范围
3. search_memories({ time_from: "...", time_to: "..." })
4. 有结果 → fetch_raw_messages({ message_ids: [...] })
5. 总结回应
```
**场景三:用户问"你当时好像心情不太好"**
```
1. search_memories({ query: "..." }) 或时间查询 → 找相关话题
2. 确定时间范围
3. search_emotion_log({ id: ... }) → 查那段时期的情绪
4. 结合情绪和对话内容回应
```
**场景四:用户说"跟上次一样就行"——但你不知道上次是什么**
```
1. 用户没明说,但话里有"上次"
2. 你主动:search_memories({ query: "当前话题相关的记忆", keywords: "提取的核心词" })
3. 查到最近的相似话题摘要
4. fetch_raw_messages({ message_ids: [...] }) 拉原文确认
5. 自然回应:"好,还跟上次那样..." —— 不用问用户"上次是什么"
```
**场景五:隔了一段时间重新打开应用**
```
1. 你主动:search_memories({ time_from: "...", time_to: "..." }) 查最近记录
2. 了解最近聊了什么、用户状态
3. 自然开场:"几天没见,上次聊的那个项目后来怎么样了?"
```
**场景六:用户情绪明显不对**
```
1. 你主动用本 Skill 查找历史线索:
- search_memories({ query: "用户关心的话题" }) → 看最近发生了什么
- search_emotion_log() → 看近期情绪波动
2. 结合历史上下文回应,而不是生硬地问"你怎么了"
```
Auf GitHub ansehen