- AI Agent
- 人工智能
- 大模型
- AI 应用
- 工具调用
- 本地部署
- MCP Clients
- Agent 记忆
【免费下载链接】Operit
The most powerful AI agent and AI chat software on Android/Operit是一款Android上能力最为强大、发展最久的AI Agent
导读
Operit 的长期记忆库原本只使用内置知识图谱提示词进行自动与手动 AI 整理,用户无法限定入库范围、分类偏好或文本写法。本文介绍"记忆提取附加规则"(Memory Extraction Custom Rules)功能的完整实现:它允许用户在每个记忆空间独立保存一段文本规则,由自动保存调度器与手动更新共用,在知识图谱提取提示词中以受控标签注入,同时保持内置长期价值筛选与严格 JSON 输出协议不变。读完本文,你将掌握该功能的存储结构、UI 入口、保存链路、提示词注入方式,以及如何编写一份高质量的记忆提取规则。
背景:旧实现的局限与意图修正
旧实现的限制
在引入附加规则之前,记忆库的设置链路存在明确的短板(见 01_settings_and_prompt_integration.md):
- 记忆库设置只保存检索权重(关键词 / 标签 / 向量 / 边权重)、自动保存间隔和嵌入模型配置三类内容;
- 自动保存与手动更新都会进入
MemoryLibrary.generateAnalysis生成知识图谱,但知识图谱提示词不接受用户规则。
其结果正如 index.md 所描述:长期记忆的自动与手动 AI 整理只使用内置知识图谱提示词,用户无法限定入库范围、分类偏好或文本写法。
意图修正
本次修改确立了三项目标:
- 在当前记忆空间的偏好中保存文本规则——规则按记忆空间(profileId)隔离存储;
- 在自动保存设置区的间隔说明下方提供多行编辑框——入口位于记忆库设置的"自动保存"分组内;
- 在知识图谱提取提示词中,将规则限定为入库范围、分类和表达偏好——规则只能细化这三个维度,继续要求严格 JSON 输出。
预期结果同时被明确为三条可验收标准:
- 切换记忆空间时显示各自独立的规则;
- 自动保存与手动更新使用相同规则;
- 恢复默认时清空该记忆空间的规则。
存储层:按记忆空间隔离的规则持久化
规则的持久化落在 MemorySearchSettingsPreferences.kt 中。该类以profileId为粒度创建 SharedPreferences 文件:
class MemorySearchSettingsPreferences(context: Context, profileId: String) { private val searchPrefs = context.applicationContext.getSharedPreferences( "memory_search_settings_$profileId", Context.MODE_PRIVATE ) // ... companion object { private const val KEY_MEMORY_EXTRACTION_CUSTOM_RULES = "memory_extraction_custom_rules" const val DEFAULT_MEMORY_EXTRACTION_CUSTOM_RULES = "" } }关键实现细节(MemorySearchSettingsPreferences.kt):
loadMemoryExtractionCustomRules():从 SharedPreferences 读取memory_extraction_custom_rules键,默认值为空字符串DEFAULT_MEMORY_EXTRACTION_CUSTOM_RULES = "";若取到 null 会抛出IllegalStateException以暴露异常状态;saveMemoryExtractionCustomRules(rules: String):以apply()异步落盘写入该键;- 键名与存储文件
memory_search_settings_$profileId均带 profileId 后缀,因此每个记忆空间的规则天然隔离,切换记忆空间时读取到的是各自独立的规则——这正是"切换记忆空间时显示各自的规则"这一预期结果的存储层保证。
值得注意的是,同文件中的自动保存间隔(KEY_AUTO_SAVE_INTERVAL_MINUTES,默认 5 分钟,允许范围 1~30 分钟)与规则共用一个搜索设置文件,这与"编辑入口放在自动保存设置分组中"的 UI 设计保持了一致。
UI 层:记忆库设置弹窗中的多行规则编辑入口
弹窗的输入承载
规则编辑入口位于记忆库设置的弹窗组件 MemorySearchSettingsDialog.kt 中。该弹窗新增了memoryExtractionCustomRules: String入参,并以本地状态承载编辑中的文本:
@Composable fun MemorySearchSettingsDialog( currentConfig: MemorySearchConfig, autoSaveIntervalMinutes: Int, memoryExtractionCustomRules: String, // ... onSave = { config, cloudConfig, autoSaveIntervalMinutes, memoryExtractionCustomRules -> ... } ) { var editedMemoryExtractionCustomRules by remember(memoryExtractionCustomRules) { mutableStateOf(memoryExtractionCustomRules) } // 自动保存分组内的多行编辑框(OutlinedTextField 多行形态) }按照 01_settings_and_prompt_integration.md 的定位,该编辑框以多行文本框形态置于自动保存设置的间隔说明下方,即"自动保存分组"内。
弹窗的挂载与保存回调
弹窗由记忆库主界面 MemoryScreen.kt 挂载,保存回调同时把规则文本交给 ViewModel:
if (uiState.isSearchSettingsDialogVisible) { MemorySearchSettingsDialog( memoryExtractionCustomRules = uiState.memoryExtractionCustomRules, onSave = { config, cloudConfig, autoSaveIntervalMinutes, memoryExtractionCustomRules -> viewModel.saveSearchSettings(config, cloudConfig, autoSaveIntervalMinutes, memoryExtractionCustomRules) viewModel.searchMemories() }, // ... ) }uiState.memoryExtractionCustomRules来自 ViewModel 的 UI 状态,切换记忆空间时由 ViewModel 重新加载,从而满足"切换记忆空间时显示各自的规则"。
保存链路:ViewModel 的读写与归一化
规则在 MemoryViewModel.kt 中完成读写闭环。
加载方向(loadSearchSettings,MemoryViewModel.kt):从searchSettingsPreferences.loadMemoryExtractionCustomRules()读取后写入_uiState,配合记忆空间切换即可在弹窗中展示当前空间规则。
保存方向(saveSearchSettings,MemoryViewModel.kt):一次保存同时落盘检索配置、自动保存间隔与附加规则:
fun saveSearchSettings( newConfig: MemorySearchConfig, newCloudConfig: CloudEmbeddingConfig, autoSaveIntervalMinutes: Int, memoryExtractionCustomRules: String ) { // 归一化检索配置与自动保存间隔(coerceIn 1..30 分钟) viewModelScope.launch(Dispatchers.IO) { searchSettingsPreferences.save(normalizedSearchConfig) searchSettingsPreferences.saveAutoSaveIntervalMinutes(normalizedInterval) searchSettingsPreferences.saveMemoryExtractionCustomRules(memoryExtractionCustomRules) repository.saveCloudEmbeddingConfig(normalizedCloudConfig) } }"恢复默认"的语义在 01_settings_and_prompt_integration.md 中被定义为"清空该记忆空间的规则":由于DEFAULT_MEMORY_EXTRACTION_CUSTOM_RULES = "",恢复默认即把空字符串写入该空间的 SharedPreferences,规则随之失效。
提示词接入:规则如何在知识图谱提取中生效
读取与注入
规则真正影响记忆提取的路径在 MemoryLibrary.kt 的generateAnalysis(MemoryLibrary.kt)。该函数在构建候选记忆检索后,读取当前记忆空间的规则并传入提示词构建器:
val memorySearchSettings = MemorySearchSettingsPreferences(context, profileId) val searchConfig = memorySearchSettings.load() val memoryExtractionCustomRules = memorySearchSettings.loadMemoryExtractionCustomRules() // ... val systemPrompt = FunctionalPrompts.buildKnowledgeGraphExtractionPrompt( duplicatesPromptPart = duplicatesPromptPart, existingMemoriesPrompt = existingMemoriesPrompt, existingFoldersPrompt = existingFoldersPrompt, useEnglish = useEnglish, profileDocument = profileDocument, profileUpdateEnabled = profileUpdateEnabled, memoryExtractionCustomRules = memoryExtractionCustomRules )这里可以清晰看到规则与既有检索机制的配合:本地混合检索策略(问题导向的紧凑查询 + 权重打分,取前 15 条候选记忆)先做粗筛,LLM 最终决策阶段才看到规则文本。规则不会改变本地检索打分,只作用于 AI 的知识图谱生成决策。
提示词中的受控注入格式
FunctionalPrompts.kt 的buildKnowledgeGraphExtractionPrompt(FunctionalPrompts.kt)将规则包裹在专用标签中注入提示词。中文版格式如下:
【用户指定的记忆提取附加规则】 <memory_extraction_custom_rules> $memoryExtractionCustomRules </memory_extraction_custom_rules> 使用这些规则细化记忆领域、入库重点、文件夹、标签或写法。写入前筛选、证据要求和严格 JSON 输出协议仍然必须遵守。英文版([User-specified memory extraction rules])语义一致:"Use these rules to refine the memory domain, retention focus, folder selection, tags, or writing style. The selection gate, evidence requirements, and strict JSON output contract remain mandatory."
这段指令被插入在"【标题与内容写法】"与"【连接关系规则】"之间,位于整个提示词中段的规则区。两条红线始终生效:
- **规则只能细化(refine)**记忆领域、入库重点、文件夹选择、标签或写法——即文档所言的"入库范围、分类和表达偏好";
- 内置的写入前筛选(Selection gate)、证据要求与严格 JSON 输出协议保持强制——用户规则不能关闭内置筛选项,也不能放松 JSON schema 要求。
JSON 输出协议不受影响
提示词后半段的严格输出 schema 保持完整(FunctionalPrompts.kt):除{}外必须输出main、new、update、merge、links(开启资料自动更新时含profile_markdown);credibility、importance、weight必须是 0.0~1.0 的 JSON 数字。规则的注入不改变这一协议,AI 仍需返回合法 JSON 对象。服务端解析侧 MemoryLibrary.kt 的parseAnalysisResult对缺失字段、空值、越界浮点数均做严格校验,任何不符合协议的输出都会在解析阶段被拒绝。
自动保存与手动更新共用同一规则
自动保存链路
自动保存由 MemoryAutoSaveScheduler.kt 驱动:轮询器每 60 秒 tick 一次,按记忆空间检查候选消息数量(不足 5 条时继续累计),达到门槛后把同一会话内的候选消息按时间排序、分批(每会话每轮最多 20 条候选、单批最多 48 条消息)组装成对话历史,最终调用:
MemoryLibrary.saveMemoryNow( context = context, toolHandler = toolHandler, conversationHistory = conversationHistory, content = memoryContent, aiService = memoryService, profileIdOverride = profileId )saveMemoryNow内部进入saveMemory→generateAnalysis,与手动更新走的是同一条提取函数。由于规则读取发生在generateAnalysis内部且以profileId为键,自动保存调度器无需任何额外改动即可复用当前记忆空间的规则——这正是"自动保存与手动更新使用相同规则"这一预期结果的实现原理。
手动更新链路
手动更新(如用户主动触发保存或记忆库工具的写入)同样调用MemoryLibrary.saveMemoryNow/saveMemoryWindowNow(后者支持自定义分析历史条数),因而也必然经过同一段规则读取与提示词注入逻辑。从源码结构看,任何进入generateAnalysis的路径——无论来源是自动调度器、手动保存还是窗口保存——都能获得一致的规则作用效果。
编写一份高质量的记忆提取规则
结合提示词注入段的措辞("细化记忆领域、入库重点、文件夹、标签或写法"),规则文本应围绕四个可控维度组织:
- 记忆领域(Domain):限定只关心哪些主题,例如"只记录与项目 A 相关的技术决策与依赖版本变化";
- 入库重点(Retention focus):说明高价值信号,例如"用户明确表达的偏好与约束优先入库;寒暄、天气、临时心情不入库";
- 分类偏好(Folder / tags):给出文件夹归属与标签习惯,例如"技术类记忆一律放入 folder_path 为
tech/的目录,标签统一使用中文小写"; - 表达偏好(Writing style):约束内容写法,例如"content 用 2~3 句客观陈述,不写第一人称"。
需要注意的约束边界:
- 规则不应试图关闭内置筛选(如"所有对话都入库"会被 Selection gate 拦截,常识性问答仍返回
{}); - 规则不应要求 AI 输出 JSON 以外的文本,输出协议强制为单一 JSON 对象;
- 规则不应包含未来计划或推测内容——内置策略要求 content 只写"已发生事实 + 当前已确认状态";
- 规则为空字符串时(默认状态),提示词注入段会插入空内容,功能退化为纯内置提示词行为,等价于旧实现。
验证与交付要点
依据 01_settings_and_prompt_integration.md 的验收清单,功能交付时需验证:
- 切换记忆空间:在多个记忆空间分别填写不同规则并切换,弹窗中应分别显示各自保存的文本(存储层由
memory_search_settings_$profileId文件隔离保证); - 自动保存与手动更新一致性:同一记忆空间下,观察自动保存调度器触发的入库结果与手动触发的入库结果在领域、分类、写法上符合同一份规则(两者共用
generateAnalysis); - 恢复默认:执行恢复默认操作后,该记忆空间的规则被清空,再次打开弹窗显示空文本,后续提取恢复内置提示词行为;
- 严格 JSON 协议:规则注入后,AI 输出仍必须符合
main/new/update/merge/links的 schema,解析层校验不应出现回归。
总结
"记忆提取附加规则"在 Operit 中形成了一条完整、可验证的功能链路:存储层(MemorySearchSettingsPreferences.kt)按记忆空间隔离持久化规则文本 → UI 层(MemorySearchSettingsDialog.kt 与 MemoryScreen.kt)提供多行编辑入口 → ViewModel(MemoryViewModel.kt)完成读写闭环 → 提取核心(MemoryLibrary.kt 的generateAnalysis)在每次自动或手动提取时读取规则并注入提示词(FunctionalPrompts.kt 的buildKnowledgeGraphExtractionPrompt)。
该设计在放开用户定制能力的同时,通过"规则只能细化、不能覆盖"的措辞、内置 Selection gate 与严格 JSON 协议,守住了记忆图谱的事实质量底线。对于希望让 Operit 长期记忆更贴合自身工作流与偏好的用户,这是一项可直接上手配置的能力。
- AI Agent
- 人工智能
- 大模型
- AI 应用
- 工具调用
- 本地部署
- MCP Clients
- Agent 记忆
【免费下载链接】Operit
The most powerful AI agent and AI chat software on Android/Operit是一款Android上能力最为强大、发展最久的AI Agent
相关推荐
为 AI 构建"长期记忆":gin-vue-admin 仓库中 aiDoc 记忆层的目录设计与写入规则
为 AI 构建"长期记忆":gin vue admin 仓库中 aiDoc 记忆层的目录设计与写入规则 长期记忆(long term memory)是 AI 协
后端前端认证鉴权低代码企业应用gin-vue-admin 的 aiDoc 长期记忆层:跨任务稳定偏好与协作规则的沉淀规范
gin vue admin 的 aiDoc 长期记忆层:跨任务稳定偏好与协作规则的沉淀规范 导读 aiDoc/memory/long term/ 是 gin v
后端前端认证鉴权低代码任务调度Agno 记忆优化实战:用 Summarize 与自定义策略压缩 Agent 长期记忆
Agno 记忆优化实战:用 Summarize 与自定义策略压缩 Agent 长期记忆 记忆是 Agent 长期会话能力的核心,但无限制累积的用户记忆会迅速膨胀
人工智能大模型AI AgentAgent 框架多智能体工具调用RAGAgent 工作流Agent 记忆
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考