先说工具全貌:hmharness 是一个开源的 HarmonyOS/OpenHarmony 开发智能体框架,把工程创建、检查、构建、签名、安装、启动、日志读取和结果验证接成本地工具链,让 AI 不只是生成代码,还要用本机环境证明结果;自进化行为受审批、预算、canary 和回滚约束。它不是 DevEco Studio 的替代品,而是开发智能体和鸿蒙工具链之间的验证层。本文只展开其中一环:计分式记忆检索。
开发智能体最尴尬的一类失败,不是没记过坑,而是后来检索不到。昨天明明写过“hvigor 构建在 Windows 路径含空格时会失败”,今天用户问 hvigor build windows,系统却返回空列表。记忆存在,但检索条件把旧经验挡在外面,智能体就只能重新踩坑。
hmharness 的 Memory 2.0 检索把这个问题拆成两层:先做不可放松的结构化过滤,再用“逐词部分命中”计算 lexical 分,并和置信度、时间新鲜度合成排序分。本文对应公开提交 0c111fe89cd200ae9efb7bd2b3f980ee202042db。
1. 旧问题:一个连续子串把有用记忆全挡掉
这次变更前的测试注释记录了旧行为:查询 hvigor build 作为连续子串去匹配时,命不了 hvigor 构建失败 或 build doctor 这类内容,结果直接掉进“AND-substring wall”。
这对开发工具很致命,因为真实经验不会永远按同一个语言、同一个顺序、同一个连续片段出现:
- 同一件事可能是中文、英文或中英混合;
- 标题写
hvigor,正文写build doctor; - 查询里多一个系统名,例如
windows,旧逻辑就更容易失配。
新逻辑不要求所有查询词连成一个完整子串,而是先把查询拆成词,再逐个看 content + tags 是否包含它。命中 2 个词比命中 1 个词得分高,完全命不中的候选会被排除。
2. 新机制:硬过滤之后才计分
CognitiveMemory.retrieve 的顺序很重要:
排除 supersededBy
-> layer / environment / tags 硬过滤
-> 查询文本切词
-> 逐词计算 lexical score
-> confidence + recency + lexical 加权排序
查询切分规则是按空白、英文逗号、中文逗号、英文分号、中文分号切开,长度小于 2 的词会被忽略。每个候选记忆的 lexical 分是:
命中的查询词数量 / 查询词总数
最终排序分是:
confidence * 0.4 + recency * 0.2 + lexical * 0.4
这三个权重表达的是一种取舍:相关性仍然最重要,但高置信、更近期的经验也会影响同分候选的排序。它不是把相关性丢掉只看“新”,也不是只看文本命中率而忽略记忆质量。
3. 测试里的三条记忆:谁排第一?
公开测试 memory2.test.ts 构造了三条语义记忆:
hvigor 构建在 Windows 路径含空格时失败,需引号包裹,confidence0.8;build doctor classifies seven failure signatures,confidence0.6;unrelated gardening note about roses,confidence0.9。
查询 hvigor build windows 后,期望结果是:
- hvigor/Windows 路径坑排第一,因为它命中 2 个查询词;
- build doctor 排第二,因为它至少命中
build; - gardening/roses 不出现,因为它一个查询词都没命中。
这个测试还专门检查了一个细节:命中更多词的记忆,可以排在置信度更高但命中更少的记忆前面。相关性不是 confidence 的装饰品,而是检索阶段的第一等问题。
中文查询也能工作,但前提是词已经按空格或标点分开,例如 构建 失败。这不是通用中文分词,更不是语义向量检索。
4. 能力边界:不要把它宣传成向量记忆
这个实现解决的是“多词部分命中”和“排序”问题,不是所有语义理解问题。公开实现里有几个硬边界:
layer、environment、tags是硬过滤,不参与加权放松;- 已经
supersededBy的记忆不进入候选池; - 中文不会自动分词,查询要写成
构建 失败这类自然切分形式; - 同义词、意图理解和向量语义检索不在这次提交的能力范围内;
- lexical 分只在
content + tags上计算,查询词长度小于 2 时会被忽略。
这些边界并不削弱功能价值。对本地开发智能体来说,先把可解释的词级命中做正确,比把检索黑盒化成“向量语义搜索”更容易审计,也更容易排查为什么某条经验没被召回。
5. 怎么复现证据
源码口径钉在公开提交:
git clone https://github.com/swsgbl/hmharness.git
cd hmharness
git checkout 0c111fe89cd200ae9efb7bd2b3f980ee202042db
npm install
node --import tsx --test packages/cognitive/src/__tests__/memory2.test.ts
本地 targeted test 输出为 1 test / 1 pass / 0 fail,证据保存在本文附带运营记录中。GitHub Actions 上没有对应可引用的绿色 run,因此本文不声称该提交 CI 绿色。
如果要按当前 npm 安装口径试用:
npm install -g @hmharness/cli@0.23.16
截至本文发布,npm latest 是 0.23.16,其 npm gitHead 是 8ce67e4cc593dfde3b971ca00ee417daedb89755;GitHub Release 仍是 v0.18.12。源码复现、npm latest 和 GitHub Release 是三个不同边界,不能混着说。
6. 结论
计分式记忆检索的价值很直接:让开发智能体能把“踩过的坑”变成下次可召回的经验,而不是存进一个检索不到的日记本。
它做到的事情是可解释的:结构化条件硬过滤,查询词逐个计分,confidence、recency 和 lexical 共同排序;没做到的事情也说清楚:不是中文自动分词,不是语义向量检索。对要长期在真实工具链里工作的 agent 来说,这种边界明确的记忆系统比“全靠语义搜索”更可信。
欢迎在 GitHub Discussions 反馈你的查询样例、环境差异和召回结果,尤其是 DevEco/OpenHarmony SDK 版本、Windows/macOS/Linux 差异,以及真实构建失败经验的召回表现。
参考: