Skip to content

feat(harness): 为记忆与会话检索增加可选多关键词匹配模式 - #3062

Open
wzq-xzwj wants to merge 1 commit into
agentscope-ai:mainfrom
wzq-xzwj:codex/memory-search-match-modes
Open

feat(harness): 为记忆与会话检索增加可选多关键词匹配模式#3062
wzq-xzwj wants to merge 1 commit into
agentscope-ai:mainfrom
wzq-xzwj:codex/memory-search-match-modes

Conversation

@wzq-xzwj

@wzq-xzwj wzq-xzwj commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Closes #3054

背景

模型有时会传入空格分隔的多个关键词,例如 query="部署 蓝鲸"。当前两个检索工具都把完整 query 当作字面短语,因此无法命中 部署决定:使用蓝鲸方案

这个 PR 提供一个可选的多关键词匹配方案。默认行为保持不变,具体参数和语义可以根据评审意见调整。

方案

memory_searchsession_search 增加可选字符串参数 matchMode

语义
phrase(默认) 按完整 query 做字面子串匹配,保留原有空白和顺序
all 按 Unicode 空白拆分,所有关键词都要出现在同一条记录中,顺序不限
any 按 Unicode 空白拆分,同一条记录包含至少一个关键词即可

调用示例:

{"query": "部署 蓝鲸", "matchMode": "all"}

session_search 仍可同时传入 agentIdmaxResults

边界与兼容性

  • Memory 仍按行匹配,Session 仍按 entry 匹配,不跨记录组合关键词。
  • 省略 matchMode 或传入 null 时使用 phrase。值区分大小写;非法值(包括空字符串)返回明确错误,不静默切换模式。
  • 多关键词模式忽略多余空白、去重相同关键词;空查询不会因为 allMatch 的空集合语义而匹配所有记录。
  • 关键词按字面值匹配,正则特殊字符不作为表达式执行。
  • 保留两个工具各自现有的大小写匹配实现,避免在这个 PR 中额外改变 Unicode/Locale 行为。
  • 保留旧 Java 方法签名,由旧方法转调新重载;只有新重载带 @Tool,避免重复注册。
  • 保留查询范围、结果格式、顺序和数量限制;不新增相关性排序。

实现

  • 新增包内辅助类 KeywordMatcher,共用模式校验、空白拆词和 all/any 组合逻辑;每次查询创建匹配器,不在每条记录上重新拆词或编译正则。
  • MemorySearchToolSessionSearchTool 接入匹配器,并补充工具参数描述。
  • 更新中英文 Memory 文档,包含调用示例、默认值、记录边界和限制。
  • 新增 KeywordSearchModesTest,同时验证两个工具的实际文件检索及 Toolkit 注册/调用。

测试

本地使用 JDK 21、Java release 17 编译,以下定向测试共 83 项通过,0 失败、0 错误、0 跳过,其中新增多关键词测试 18 项:

mvn -pl agentscope-harness -am test \
  -Dtest=KeywordSearchModesTest,SessionTranscriptWriterTest,SessionTreeMirrorTest,MemoryConsolidatorFilesystemTest,HarnessAgentTest \
  -Dsurefire.failIfNoSpecifiedTests=false -Dspotless.skip=true

另行对本次修改的四个 Java 文件执行 Spotless 格式化与检查,通过:

mvn -pl agentscope-harness spotless:check \
  '-DspotlessFiles=.*KeywordMatcher.java,.*MemorySearchTool.java,.*SessionSearchTool.java,.*KeywordSearchModesTest.java'

git diff --cached --check 通过。以上为定向回归,不是全仓测试,也没有调用真实 LLM 验证模型选择模式的概率。

覆盖:默认/旧 Java 入口、完整短语空白保留、中文关键词、英文大小写、不相邻及乱序关键词、all/any 无匹配、正则特殊字符、Unicode 空白、重复词、空查询、无效模式、不跨行/entry、daily ledger、agentId 过滤、maxResults,以及新参数的 schema 和反射调用。

不在本次范围内

  • 连续中文句子的自动分词、同义词和语义检索。
  • “昨天”等时间表达式解析。
  • 历史内容截断、数据源迁移或记忆提取流程。
  • 自动决定何时从 Memory 回退到 Session 检索。

没有增加第三方依赖,也没有改默认模式为 OR 匹配。该改动改善显式多关键词查询,不代表模型一定会选择新模式。

@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.36842% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...entscope/harness/agent/tool/SessionSearchTool.java 90.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@dailingtao dailingtao left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

matchMode,
term -> {
String lowerTerm = term.toLowerCase();
return text -> text.toLowerCase().contains(lowerTerm);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: each term predicate lowercases the full session entry independently, so an all/any query with N terms can allocate N lowercase copies per entry. Could we normalize content once per entry (while preserving the existing locale behavior) and run the predicates against that normalized string?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 建议为 memory_search / session_search 增加可选的多关键词匹配模式

2 participants