--- name: amemo-save-memo description: 当用户说「帮我记一下」「保存笔记」「记下这一条」或用陈述性语气描述某事(含"的时候/的情况/的经历")时调用,将对话内容保存为云端笔记,支持新建与更新。 --- # amemo-save-memo — 保存备忘录 --- ## 接口信息 | 属性 | 值 | |:-----|:---| | **路由** | `POST https://skill.amemo.cn/save-memo` | | **Bean** | `MemoBean` | | **Content-Type** | `application/json` | --- ## 请求参数 > ⚠️ 服务端要求所有字段必须存在。`userToken`、`memoTitle`、`memoContent` 必填且有值,`memoId` 可选但字段必须存在。 | 参数 | 类型 | 必填 | 说明 | |:-----|:----:|:----:|:-----| | `userToken` | str | ✅ | 用户登录凭证 | | `memoId` | str | — | 备忘录 ID(新建传 `null`,更新时传入已有 ID) | | `memoTitle` | str | ✅ | 备忘录标题(不能为空) | | `memoContent` | str | ✅ | 备忘录内容(不能为空) | --- ## 请求示例 ```bash # 新建备忘录 curl -X POST https://skill.amemo.cn/save-memo \ -H "Content-Type: application/json" \ -d '{ "userToken": "", "memoId": null, "memoTitle": "开会记录", "memoContent": "讨论了Q2计划" }' # 更新备忘录(传入已有 memoId) curl -X POST https://skill.amemo.cn/save-memo \ -H "Content-Type: application/json" \ -d '{ "userToken": "", "memoId": "123456", "memoTitle": "开会记录", "memoContent": "更新了内容" }' ``` --- ## 响应示例 ```json { "code": 200, "desc": "success", "data": { "memoId": "abc123" } } ``` ## 响应解析 | 字段 | 类型 | 说明 | |:-----|:----:|:-----| | `code` | int | 状态码,200 表示成功 | | `desc` | str | 状态描述 | | `data.memoId` | str | 保存成功后返回的备忘录 ID,**必须提取并保存到当前对话上下文 `lastMemoId`,用于后续更新操作** | --- ## 注意事项 > 📌 **字段要求**:所有字段必须存在,即使不传值也要传 `null` > > 📝 **新建 vs 更新**:新建时 `memoId` 传 `null`,更新时传入已有 memoId > > 🔐 **认证要求**:必须携带有效的 userToken --- ## 执行流程(由主模块调度) ### 内容提取规则 **触发词去除规则:** 从用户消息中移除"帮我记一下/保存笔记/记下这一条/记录笔记/保存备忘"等触发词,保留核心内容。 | 用户输入 | userContent | |:---------|:------------| | `"帮我记一下这家火锅店味道很不错"` | `"这家火锅店味道很不错"` | | `"保存笔记:今天开会讨论了Q2计划"` | `"今天开会讨论了Q2计划"` | > **说明:** > - `userContent`:用户上一条消息去除触发词后的核心内容 > - `aiContent`:AI 助手上一条回复(完整保留) > - 如果去除触发词后内容为空,则使用完整的用户消息作为 userContent --- ### 新建 vs 更新模式判断 **判断逻辑:** ``` 1. 当前对话上下文中是否存在 lastMemoId? ├── 不存在 → 【新建模式】,跳到步骤 5 └── 存在 → 进入意图指向判断 2. 意图指向判断(当 lastMemoId 存在时): • 用户当前消息是否对刚才保存的内容提出改动要求 • 当前消息内容是否与 lastMemoTitle 主题相关 └── 判断结果: ├── 指向刚才的笔记 → 【更新模式】,携带 lastMemoId └── 是全新内容 → 【新建模式】,清除 lastMemoId ``` --- ### 意图指向判断规则 #### 更新类信号词(指向刚才的笔记,将修改后的内容替换原文) | 信号词 | 示例 | |:-------|:-----| | 补充 | `"补充一下刚才的笔记"` | | 加上 | `"再加上XXX"` | | 修改 | `"修改为XXX"` | | 更新 | `"更新一下笔记"` | | 还有 | `"还有一点要补充"` | | 另外 | `"另外还需要记录"` | | 补充说明 | `"补充说明一下"` | | 遗漏 | `"刚才漏了一条"` | | 忘了 | `"忘了说XXX"` | | 换成 | `"把XXX换成YYY"` | | 改成 | `"改成XXX"` | #### 新建类信号(创建新笔记) | 信号词 | 示例 | |:-------|:-----| | 新笔记 | `"保存一条新笔记"` | | 另一个 | `"再记一个XXX"` | | 主题明显不同 | 上一个是"旅行攻略",现在说"做饭" | #### 模糊场景处理 当无法明确判断时: - 用户消息与 `lastMemoTitle` 主题明显不同 → 新建 - 用户消息与 `lastMemoTitle` 主题相关,且包含更新信号 → 更新 - 用户消息主题相关但无明确信号 → 询问用户确认 ``` 🤔 您是想: • 更新刚才的笔记「{lastMemoTitle}」 • 还是保存为一条新笔记? ``` --- ### 笔记内容整理 | 模式 | memoContent 格式 | |:-----|:----------------| | 新建模式 | `"{userContent}\n\n【AI】\n{aiContent}"` | | 更新模式 | `"{修改后的完整内容}"` | > 更新模式:将用户改动后的完整对话内容作为新内容,直接替换原始笔记内容 --- ### 标题生成规则 1. 提取用户消息中最核心的名词/动词 2. 限制在 20 字以内 3. 去除:助词、语气词、疑问词 4. 更新模式下保留 `lastMemoTitle` | 用户输入 | 生成标题 | |:---------|:---------| | `"感冒了应该吃什么药"` | `"感冒用药建议"` | | `"帮我记一下今天开会的内容"` | `"今日开会记录"` | | `"红烧肉怎么做才好吃"` | `"红烧肉做法"` | --- ### 执行步骤汇总 ``` 1. 识别触发词(保存笔记/记下/记录) ↓ 2. 检查 userToken 是否存在 ├── 无 token → 引导登录流程 ↓ 3. 提取对话内容(userContent + aiContent) ↓ 4. 判断新建还是更新 ├── 新建模式:memoId = null └── 更新模式:memoId = lastMemoId ↓ 5. 整理笔记内容 ↓ 6. 生成 memoTitle ↓ 7. 调用 POST /save-memo 接口 ↓ 8. 保存返回的 memoId 到当前对话上下文(lastMemoId) ↓ 9. 返回结果 ``` --- ## 回复模板 ### 新建成功 ``` ✅ 已保存笔记:「{memoTitle}」 ``` ### 更新成功 ``` ✅ 已更新笔记:「{memoTitle}」(内容已替换) ``` ### 失败 ``` ❌ 保存失败,请重试 ``` --- ## 对话上下文维护 ### 需维护的状态(当前对话期间有效) | 字段 | 说明 | |:-----|:-----| | `lastMemoId` | 最近一次保存的笔记 ID | | `lastMemoTitle` | 最近一次保存的笔记标题 | | `lastTaskId` | 最近一次保存的任务 ID | ### 追踪时机 - 每次调用 `amemo-save-memo` 成功后,提取 memoId 并更新 `lastMemoId` - 用户切换到完全不同的话题时,自动清除 `lastMemoId` 和 `lastTaskId`