目录
- 摘要
- 1. 引言 - 为什么需要语义搜索?
- 1.1 传统搜索的局限
- 1.2 语义搜索的优势
- 1.3 memory_search 核心能力
- 2. memory_search 工具详解
- 2.1 工具签名
- 2.2 参数详解
- 2.3 返回格式
- 2.4 相关性分数解读
- 3. 搜索策略优化
- 3.1 查询优化技巧
- 3.2 参数调优策略
- 3.3 搜索场景与参数建议
- 4. 实战应用场景
- 4.1 场景一:用户偏好查询
- 4.2 场景二:历史决策追溯
- 4.3 场景三:问题解决方案检索
- 4.4 场景四:任务进度查询
- 5. 高级搜索技巧
- 5.1 组合查询
- 5.2 时间范围限定
- 5.3 多轮搜索
- 5.4 搜索结果后处理
- 6. 搜索性能优化
- 6.1 索引优化
- 6.2 查询优化
- 6.3 结果优化
- 7. 常见问题与解决
- Q1:搜索结果不准确怎么办?
- Q2:搜索结果太多怎么办?
- Q3:搜索结果太少怎么办?
- Q4:搜索速度慢怎么办?
- 8. 最佳实践总结
- 8.1 搜索策略清单
- 8.2 参数配置建议
- 8.3 下一步
- 参考资料
摘要
本文深入探讨 OpenClaw 框架中的 memory_search 语义搜索功能。从向量搜索原理、工具参数详解、搜索策略优化到实战应用场景,全面解析如何高效检索记忆内容。通过实际案例演示用户偏好查询、历史决策追溯、问题解决方案检索等典型场景,帮助开发者构建具有智能记忆检索能力的 AI 应用,实现"过目不忘"的效果。🔍
1. 引言 - 为什么需要语义搜索?
1.1 传统搜索的局限
| 问题 | 说明 | 示例 |
|---|---|---|
| 关键词匹配 | 只能匹配精确词 | 搜"偏好"找不到"喜好" |
| 无语义理解 | 不理解查询意图 | 搜"怎么解决"找不到"解决方案" |
| 结果排序差 | 无法按相关性排序 | 最相关的结果排在后面 |
| 上下文缺失 | 无法关联相关内容 | 找不到上下文相关的信息 |
1.2 语义搜索的优势
1.3 memory_search 核心能力
| 能力 | 说明 | 效果 |
|---|---|---|
| 语义理解 | 理解查询的真实意图 | 搜"不喜欢"能找到"偏好" |
| 模糊匹配 | 容忍拼写和表达差异 | 搜"飞书"能找到"Feishu" |
| 相关性排序 | 按相似度排序结果 | 最相关的排在最前 |
| 多源检索 | 同时搜索多个记忆文件 | 一次查询所有日志 |
2. memory_search 工具详解
2.1 工具签名
memory_search(query:str,# 搜索查询文本maxResults:int=5,# 最大返回结果数minScore:float=0.5# 最小相关性分数阈值)2.2 参数详解
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| query | string | 必填 | 搜索查询文本 |
| maxResults | int | 5 | 返回的最大结果数量 |
| minScore | float | 0.5 | 最小相关性分数(0-1) |
2.3 返回格式
{"results":[{"path":"MEMORY.md","lines":"10-15","content":"用户偏好:简洁表达风格","score":0.95},{"path":"memory/2026-04-10.md","lines":"20-25","content":"用户要求文章不要太长","score":0.82}],"provider":"none","citations":"auto","mode":"fts-only"}2.4 相关性分数解读
| 分数范围 | 含义 | 建议 |
|---|---|---|
| 0.9-1.0 | 高度相关 | 直接使用 |
| 0.7-0.9 | 相关 | 可参考使用 |
| 0.5-0.7 | 弱相关 | 需要进一步判断 |
| < 0.5 | 不相关 | 通常不返回 |
3. 搜索策略优化
3.1 查询优化技巧
| 技巧 | 说明 | 示例 |
|---|---|---|
| 使用关键词 | 提取核心关键词 | “用户偏好” 而非 “用户有什么偏好” |
| 组合查询 | 组合多个关键词 | “文章 结构 决策” |
| 使用同义词 | 尝试不同表达 | “偏好” 或 “喜好” 或 “倾向” |
| 添加上下文 | 提供更多上下文 | “Gateway 启动失败 解决方案” |
3.2 参数调优策略
3.3 搜索场景与参数建议
| 场景 | maxResults | minScore | 说明 |
|---|---|---|---|
| 精确查找 | 3 | 0.7 | 只需要最相关的结果 |
| 广泛搜索 | 10 | 0.4 | 需要尽可能多的结果 |
| 决策追溯 | 5 | 0.6 | 查找历史决策 |
| 问题检索 | 5 | 0.5 | 查找类似问题 |
4. 实战应用场景
4.1 场景一:用户偏好查询
用户问题:
我之前说过喜欢什么样的文章风格?AI 内部调用:
memory_search(query="用户 文章 风格 偏好",maxResults=5,minScore=0.5)返回结果:
{"results":[{"path":"MEMORY.md","lines":"15-18","content":"## 沟通偏好\n- 表达风格:简洁直接,不喜欢啰嗦\n- 文章格式:表格 + 代码块 + 图表","score":0.92},{"path":"memory/2026-04-10.md","lines":"5-8","content":"用户反馈:文章太长了,希望更简洁","score":0.78}]}AI 回复:
根据记忆,你喜欢简洁直接的文章风格,不喜欢啰嗦。文章格式方面,你偏好表格 + 代码块 + 图表的组合形式。之前你也提过文章不要太长。
4.2 场景二:历史决策追溯
用户问题:
我们为什么选择 5 阶段的文章结构?AI 内部调用:
memory_search(query="文章结构 阶段 决策 原因",maxResults=3,minScore=0.6)返回结果:
{"results":[{"path":"memory/2026-03-14.md","lines":"20-30","content":"## 重要决策\n### 决策:文章采用 5 阶段结构\n- 选择:方案 B\n- 原因:\n 1. 由浅入深更符合学习曲线\n 2. 读者可以按阶段学习\n 3. 便于后续扩展","score":0.89}]}AI 回复:
根据 2026-03-14 的决策记录,选择 5 阶段结构的原因是:
- 由浅入深更符合学习曲线- 读者可以循序渐进
- 读者可以按阶段学习- 不同水平的读者找到适合自己的阶段
- 便于后续扩展- 可以方便地增加新阶段
4.3 场景三:问题解决方案检索
用户问题:
之前 Gateway 启动失败是怎么解决的?AI 内部调用:
memory_search(query="Gateway 启动失败 解决",maxResults=5,minScore=0.5)返回结果:
{"results":[{"path":"memory/2026-04-05.md","lines":"10-20","content":"## 遇到的问题\n### 问题:Gateway 启动失败\n- 原因:端口 18800 被占用\n- 解决:kill -9 <PID> 后重启","score":0.91},{"path":"memory/2026-03-20.md","lines":"15-18","content":"Gateway 启动报错:检查配置文件路径","score":0.65}]}AI 回复:
根据历史记录,Gateway 启动失败有两种情况:
情况一(最相关):
- 原因:端口 18800 被占用
- 解决方案:
- 检查端口占用:
lsof -i :18800 - 终止占用进程:
kill -9 <PID> - 重新启动:
openclaw gateway start
- 检查端口占用:
情况二:
- 原因:配置文件路径错误
- 解决方案:检查 openclaw.yaml 路径是否正确
4.4 场景四:任务进度查询
用户问题:
我们的文章项目进度怎么样了?AI 内部调用:
memory_search(query="文章 项目 进度 完成",maxResults=3,minScore=0.5)返回结果:
{"results":[{"path":"MEMORY.md","lines":"10-12","content":"## 项目上下文\n- 目标:完成100篇技术文章\n- 已完成:42篇\n- 完成率:42%","score":0.88},{"path":"memory/2026-04-13.md","lines":"5-10","content":"## 项目进度\n- 总目标:100篇文章\n- 已完成:42篇\n- 今日完成:第41、42篇","score":0.82}]}AI 回复:
根据最新记录,文章项目进度如下:
| 项目 | 数值 |
|---|---|
| 总目标 | 100 篇文章 |
| 已完成 | 42 篇 |
| 完成率 | 42% |
| 今日完成 | 第41、42篇 |
5. 高级搜索技巧
5.1 组合查询
# 搜索用户关于文章的所有反馈memory_search(query="用户 文章 反馈 意见 建议",maxResults=10,minScore=0.4)5.2 时间范围限定
# 先确定日期范围,再搜索# 搜索最近7天的记录foriinrange(7):date=today-timedelta(days=i)# 可以先读取文件再进行本地搜索content=read(f"memory/{date}.md")# 或使用 memory_search 自动覆盖所有文件5.3 多轮搜索
5.4 搜索结果后处理
defprocess_search_results(results):"""对搜索结果进行后处理"""processed=[]forresultinresults:# 提取关键信息item={"source":result["path"],"content":result["content"],"relevance":result["score"],"date":extract_date(result["path"])}processed.append(item)# 按相关性排序processed.sort(key=lambdax:x["relevance"],reverse=True)returnprocessed6. 搜索性能优化
6.1 索引优化
| 优化项 | 说明 | 效果 |
|---|---|---|
| 定期重建索引 | 更新向量索引 | 提高搜索准确性 |
| 分块存储 | 大文件分块索引 | 减少搜索范围 |
| 缓存热点 | 缓存常用查询 | 加快响应速度 |
6.2 查询优化
| 优化项 | 说明 | 效果 |
|---|---|---|
| 精简查询 | 使用关键词而非长句 | 提高匹配精度 |
| 避免重复 | 缓存查询结果 | 减少重复计算 |
| 批量查询 | 合并多个查询 | 减少API调用 |
6.3 结果优化
| 优化项 | 说明 | 效果 |
|---|---|---|
| 结果去重 | 合并重复内容 | 减少冗余 |
| 智能摘要 | 提取关键信息 | 提高可读性 |
| 上下文补充 | 补充前后文 | 提高理解度 |
7. 常见问题与解决
Q1:搜索结果不准确怎么办?
解决方案:
- 优化查询关键词
- 调整 minScore 阈值
- 尝试不同的表达方式
- 使用更具体的查询
Q2:搜索结果太多怎么办?
解决方案:
- 提高 minScore 阈值
- 减少 maxResults
- 使用更精确的查询
- 添加更多关键词
Q3:搜索结果太少怎么办?
解决方案:
- 降低 minScore 阈值
- 增加 maxResults
- 使用更宽泛的查询
- 尝试同义词
Q4:搜索速度慢怎么办?
解决方案:
- 减少搜索范围
- 使用缓存
- 优化查询复杂度
- 定期清理旧日志
8. 最佳实践总结
8.1 搜索策略清单
- 使用关键词而非长句
- 根据场景调整参数
- 多轮搜索逐步优化
- 对结果进行后处理
- 缓存常用查询结果
8.2 参数配置建议
| 场景 | maxResults | minScore | 查询策略 |
|---|---|---|---|
| 精确查找 | 3 | 0.7 | 关键词组合 |
| 广泛搜索 | 10 | 0.4 | 单个关键词 |
| 决策追溯 | 5 | 0.6 | 决策相关词 |
| 问题检索 | 5 | 0.5 | 问题+解决 |
8.3 下一步
- 第44篇:OpenClaw 记忆维护:自动整理与归档
- 第45篇:OpenClaw 上下文管理:Token 优化策略
参考资料
- OpenClaw 官方文档
- OpenClaw GitHub
- 向量搜索原理