1. Claude Code CLI 语义召回机制解析
1.1 语义召回的必要性
在开发Claude Code CLI的过程中,我们面临一个关键挑战:随着时间推移,系统积累的记忆文件会越来越多(可能达到数百个),但直接加载所有记忆会带来两个严重问题:
- Token消耗过高:每个记忆文件都会占用宝贵的上下文窗口空间,导致实际对话可用的token减少
- 信息质量下降:大量不相关的记忆会稀释上下文质量,使AI难以聚焦于真正重要的信息
传统解决方案如关键词匹配对自然语言描述的记忆效果不佳,而仅依赖索引又无法获取足够细节。为此,我们设计了语义召回机制——让另一个AI(Sonnet)来判断哪些记忆与当前查询真正相关。
1.2 记忆扫描实现细节
语义召回的第一步是高效扫描所有记忆文件。我们采用以下优化策略:
typescript复制const MAX_MEMORY_FILES = 200
const FRONTMATTER_MAX_LINES = 30 // 只读取文件前30行
async function scanMemoryFiles(memoryDir) {
const entries = await readdir(memoryDir, { recursive: true })
const mdFiles = entries.filter(
f => f.endsWith('.md') && basename(f) !== 'MEMORY.md'
)
// 单次读取同时获取内容和修改时间
const headers = await Promise.all(
mdFiles.map(async file => {
const { content, mtimeMs } = await readFileInRange(file, 0, FRONTMATTER_MAX_LINES)
return { filename: file, mtimeMs, ...parseFrontmatter(content) }
})
)
return headers
.sort((a,b) => b.mtimeMs - a.mti
