☰
openJiuwen 记忆作用域配置 MemoryScopeConfig 深度解析:字段模型、持久化加密与作用域覆盖机制
2026/10/14 16:40:04 网站建设 项目流程
  • 人工智能
  • AI Agent
  • Agent 框架
  • 工具调用
  • Agent 工作流
  • RAG
  • MCP Clients
  • 强化学习

【免费下载链接】agent-core-java

openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。

项目地址:https://gitcode.com/openJiuwen/agent-core-java
点击查看免费下载

本文围绕 openJiuwen agent-core-java 中com.openjiuwen.memory.config.MemoryScopeConfig展开:它是 Long-Term Memory(长期记忆)引擎按 scope(作用域)隔离记忆行为的核心配置载体,集中声明了作用域内使用的模型请求参数、模型客户端连接参数、Embedding 模型参数以及三类记忆的抽取定义。读完本文,你将掌握 MemoryScopeConfig 的全部公开字段与默认值、snake_case JSON 映射规则、作用域配置的读写/加密持久化链路,以及它在 scope 级 LLM/Embedding 覆盖和记忆抽取提示词注入中的实际生效方式,并能够直接写出可运行的配置代码。

一、MemoryScopeConfig 的定位:作用域级(Scope-specific)记忆配置

在 openJiuwen 的记忆体系中,全局系统级参数由MemoryEngineConfig承载(如默认模型配置defaultModelCfg、defaultModelClientCfg、cryptoKey校验,参见 MemoryEngineConfig.md),而MemoryScopeConfig则负责每个 scope 独立的记忆配置。

从源码注释可见,该类与 Python 版 openJiuwen Core 的MemoryScopeConfig(openjiuwen/core/memory/config/config.py)保持镜像对齐(见 MemoryScopeConfig.java)。其设计目标很明确:同一记忆引擎实例可以服务多个 scope(例如多租户、多业务线、多应用场景),每个 scope 可以拥有自己独立的模型、Embedding 与记忆定义,互不干扰。

LongTermMemory内部使用ConcurrentHashMap<String, MemoryScopeConfig> scopeConfig缓存各 scope 的配置,并以 scopeId 为键进行读写,印证了「一 scope 一配置」的隔离模型(见 LongTermMemory.java)。

二、字段全景:三类模型配置 + 三个记忆抽取定义

原 API 文档仅列出三个模型类字段,但查看 MemoryScopeConfig.java 的完整源码,该类实际拥有6 个公开字段,可分为两组:

2.1 模型与向量化配置字段

字段类型JSON 键作用
modelCfgModelRequestConfigmodel_cfg作用域内模型请求级生成参数(模型名、采样参数等)
modelClientCfgModelClientConfigmodel_client_cfg作用域内模型客户端连接参数(Provider、API Key、Base URL 等)
embeddingCfgEmbeddingConfigembedding_cfg作用域内 Embedding 模型配置(记忆向量化所用模型)

三个字段均允许为 null:MemoryScopeConfig上标注了@JsonInclude(JsonInclude.Include.NON_NULL),即 JSON 序列化时空字段不会输出。当某字段缺失时,运行时会回退到引擎级默认值(详见第五节)。

2.2 记忆抽取定义字段

字段类型JSON 键默认值
userProfileDefinitionStringuser_profile_definition「用户本人的肯定或否定表述(包含不限于基本身份、兴趣偏好、人际关系、资产状况)」
semanticMemoryDefinitionStringsemantic_memory_definition「用户对话中涉及的和时间无明确关系的事实性内容或概念」
episodicMemoryDefinitionStringepisodic_memory_definition「用户对话中涉及的和时间有明确关系的事实性内容或概念」

这三个默认值分别对应三条常量(DEFAULT_USER_PROFILE_DEFINITION、DEFAULT_SEMANTIC_MEMORY_DEFINITION、DEFAULT_EPISODIC_MEMORY_DEFINITION,见 MemoryScopeConfig.java)。它们的语义指向 Long-Term Memory 的三大类记忆:用户画像(User Profile)、语义记忆(Semantic Memory,与时间无明确关系的事实/概念)、情景记忆(Episodic Memory,与时间有明确关系的事实/概念)。

重要行为:三个 setter 均做了空值兜底——传入null时会被替换为对应默认常量,因此不会出现 definition 为 null 的情况(见 MemoryScopeConfig.java)。该行为被测试 MemoryConfigModelsTest.java 与 CustomPromptDefinitionPythonParityTest.java 明确锁定,确保与 Python 版行为一致。

三、三类子配置的完整参数解读

3.1 ModelRequestConfig:模型请求级生成参数

modelCfg的类型定义于 ModelRequestConfig.java,控制每次模型调用的生成行为:

参数默认值说明
model(JSON 键model)""模型名称
temperature0.95采样温度
top_p(JSON 键top_p)0.1核采样概率阈值
max_tokens(JSON 键max_tokens)null最大生成 token 数,缺省由服务端决定
usernull可选的用户标识透传
seednull随机种子(可复现采样)
stopnull停止符
extraFieldsLinkedHashMap透传的任意扩展字段(@JsonAnyGetter/@JsonAnySetter)

3.2 ModelClientConfig:模型客户端连接参数

modelClientCfg的类型定义于 ModelClientConfig.java,控制连接行为:

参数JSON 键默认值说明
clientIdclient_id随机 UUID客户端实例标识
clientProviderclient_providernull模型 Provider(如DashScope),传入时会经normalizeClientProvider归一化校验
apiKeyapi_keynullAPI 密钥
apiBaseapi_basenullAPI 基础地址
timeouttimeout60.0超时秒数,必须为正数(validatePositiveTimeout校验)
maxRetriesmax_retries3最大重试次数
verifySslverify_ssltrue是否校验 SSL
sslCertssl_certnull自定义 SSL 证书
customHeaderscustom_headers空 Map自定义请求头
httpVersionhttp_versionnullHTTP 协议版本枚举ModelHttpVersion

Provider 校验值得一提:normalizeClientProvider会先按ProviderType枚举成员名/小写值归一化,再检查ClientRegistry注册的llm_前缀客户端,若两者都不匹配且不在延迟对齐列表中,将抛出MODEL_PROVIDER_INVALID错误(见 ModelClientConfig.java)。

3.3 EmbeddingConfig:记忆向量化模型配置

embeddingCfg的类型定义于 EmbeddingConfig.java,只有三个参数:

参数必填说明
modelName是模型名,缺失抛IllegalArgumentException("model_name is required")
baseUrl是API 基础地址,缺失抛IllegalArgumentException("base_url is required")
apiKey否API 密钥,可为 null

在序列化到MemoryScopeConfig时,embeddingCfg上还带有@JsonIgnoreProperties({"verify_ssl", "verifySsl", "ssl_cert", "sslCert"}),用于反序列化时忽略可能混入的 SSL 相关冗余键(见 MemoryScopeConfig.java)。

四、JSON 序列化:snake_case 键名映射

MemoryScopeConfig的六个字段均通过@JsonProperty映射为 snake_case JSON 键,序列化格式如下:

{ "model_cfg": { "model": "qwen-max", "temperature": 0.95, "top_p": 0.1 }, "model_client_cfg": { "client_provider": "DashScope", "api_key": "sk-xxx", "api_base": "https://dashscope.aliyuncs.com/api/v1", "timeout": 60.0, "max_retries": 3 }, "embedding_cfg": { "model_name": "text-embedding-v3", "base_url": "https://dashscope.aliyuncs.com/api/v1", "api_key": "sk-xxx" }, "user_profile_definition": "用户本人的肯定或否定表述(包含不限于基本身份、兴趣偏好、人际关系、资产状况)", "semantic_memory_definition": "用户对话中涉及的和时间无明确关系的事实性内容或概念", "episodic_memory_definition": "用户对话中涉及的和时间有明确关系的事实性内容或概念" }

LongTermMemory使用共享ObjectMapper对该结构进行读写序列化(readConfig/writeJson,见 LongTermMemory.java)。外部集成方若通过配置 Map 下发(见 OpenJiuwenMemoryProvider.java),MAPPER.convertValue(values, MemoryScopeConfig.class)同样遵循上述键名。

五、作用域配置的读写链路与 API Key 加密

MemoryScopeConfig不是静态声明类,它通过LongTermMemory的三个公开方法进入实际运行:

  • setScopeConfig(String scopeId, MemoryScopeConfig memoryScopeConfig):校验 scopeId 格式后,写入内存缓存,并将配置持久化到 KV Store,键为SCOPE_CONFIG_KEY + "/" + scopeId(经多租户键解析TenantKVStoreKeyResolver.resolveKey),随后关闭该 scope 旧的 Embedding 实例(见 LongTermMemory.java)。
  • getScopeConfig(String scopeId):从 KV Store 读取并反序列化,返回异步封装类型FutureMemoryScopeConfig(见 LongTermMemory.java)。
  • deleteScopeConfig(String scopeId):删除 KV Store 中的配置并清理缓存与 scope 级 Embedding(见 LongTermMemory.java)。

其中API Key 加密是安全关键点:写入前调用encodeApiKeys,对modelClientCfg.apiKey与embeddingCfg.apiKey使用storageCodec加密后再落库;读取时通过decodeApiKeys解密还原(见 LongTermMemory.java)。这意味着落盘/入库的配置文件中不会出现明文 API Key,开发者应配合MemoryEngineConfig.cryptoKey使用。FutureMemoryScopeConfig(FutureMemoryScopeConfig.java)则提供了join()与toCompletableFuture()两种取数方式,延续了该模块的 CompletableFuture 异步风格。

六、作用域覆盖机制:scope 级 LLM 与 Embedding 的生效顺序

配置的最终价值体现在运行期的覆盖逻辑上。LongTermMemory在写入记忆(addMessages)等入口会调用internalScopeConfig(scopeId)获取当前生效的 scope 配置(先查缓存、再落库,见 LongTermMemory.java),然后驱动两类覆盖:

scope 级 LLM(getScopeLlm,见 LongTermMemory.java):

  1. 若 scope 配置同时提供modelCfg与modelClientCfg,则以二者构造该 scope 专属Model实例;
  2. 否则回退到引擎默认配置sysMemConfig.defaultModelCfg + defaultModelClientCfg;
  3. 再否则回退到baseLlm。

scope 级 Embedding(getScopeEmbeddingModel / applyScopeEmbedding,见 LongTermMemory.java):

  • 若 scope 配置提供embeddingCfg,则用new APIEmbedding(embeddingCfg)创建 scope 专属 Embedding,并注入记忆索引(setEmbeddingModel,通过反射完成以兼容不同索引实现);每次setScopeConfig/deleteScopeConfig后旧实例会被closeAndRemoveScopeEmbedding关闭释放。
  • 无 scope 级配置时回退到baseEmbed。

这种「scope 配置 > 引擎默认 > 基础兜底」的三级覆盖链,正是多租户/多场景下各自使用独立模型与向量服务的核心实现。

七、Builder 使用与完整代码示例

MemoryScopeConfig同时提供无参构造、全参构造与Builder(见 MemoryScopeConfig.java),Builder 的六个方法分别对应六个字段。以下示例完整配置了一个 scope 并写入记忆引擎:

MemoryScopeConfig scopeConfig = MemoryScopeConfig.builder() .modelCfg(ModelRequestConfig.builder() .modelName("qwen-max") .temperature(0.95) .topP(0.1) .build()) .modelClientCfg(ModelClientConfig.builder() .clientProvider("DashScope") .apiKey("sk-your-api-key") .apiBase("https://dashscope.aliyuncs.com/api/v1") .timeout(60.0) .maxRetries(3) .build()) .embeddingCfg(new EmbeddingConfig( "text-embedding-v3", "https://dashscope.aliyuncs.com/api/v1", "sk-your-embedding-key")) .userProfileDefinition("用户本人陈述的身份、兴趣、偏好与资产信息") .semanticMemoryDefinition("对话中与时间无明确关系的概念与事实") .episodicMemoryDefinition("对话中与具体时间节点明确绑定的事实") .build(); LongTermMemory.getInstance().setScopeConfig("scope_001", scopeConfig).join();

上述模式与集成层OpenJiuwenMemoryRuntime.configureScope(OpenJiuwenMemoryRuntime.java)一致——它通过setScopeConfig(scopeId, new MemoryScopeConfig())为 scope 建立默认配置。若只设置默认配置,也可以在后续通过getScopeConfig读取、setScopeConfig覆盖、deleteScopeConfig删除。

八、测试验证与使用注意事项

仓库测试从多个角度锁定了 MemoryScopeConfig 的行为:

  • 默认值与空值兜底:scopeDefaultsIncludeZeroOneFourDefinitions断言三个 definition 的默认常量(MemoryConfigModelsTest.java)。
  • 持久化与解密:setScopeConfigPersistsAndDecryptsConfiguration覆盖了「构造带三个模型配置的 scope 配置 → 写入 → 读取解密」全链路(LongTermMemoryTest.java)。
  • 自定义定义与 Python 对齐:CustomPromptDefinitionPythonParityTest校验自定义 definition 的默认值与替换行为。
  • 配置缺失回退:LongTermMemoryScopeConfigMissingTest验证 scope 配置缺失时的降级路径。

实践中的关键注意事项可总结为四条:

  1. scopeId 有格式约束:setScopeConfig/getScopeConfig/deleteScopeConfig均会校验 scopeId,非法格式将分别抛出MEMORY_SET_CONFIG_EXECUTION_ERROR或MEMORY_GET_MEMORY_EXECUTION_ERROR。
  2. API Key 必须配合 cryptoKey:只有设置了MemoryEngineConfig.cryptoKey,API Key 加密存储才会生效;未设置时按源码逻辑(storageCodec == null)直接跳过编码。
  3. 覆盖是「整体或回退」而非「字段级合并」:scope 级 LLM 要求modelCfg与modelClientCfg同时存在才生效,缺一即回退到引擎默认;Embedding 则只看embeddingCfg是否存在。
  4. definition 影响抽取质量:三个 definition 会被注入fragment_memory_prompt模板(见 LongTermMemoryExtractor.java),直接决定 LLM 如何区分用户画像、语义记忆与情景记忆,建议按业务场景定制而非沿用默认文案。

参考资料

  • 关联 API 文档:MemoryScopeConfig.md
  • 配置类源码:MemoryScopeConfig.java
  • 子配置类型:ModelRequestConfig.java、ModelClientConfig.java、EmbeddingConfig.java
  • 记忆引擎读写/覆盖实现:LongTermMemory.java
  • 抽取链路:LongTermMemoryExtractor.java、Generator.java
  • 集成与外部适配:OpenJiuwenMemoryRuntime.java、OpenJiuwenMemoryProvider.java
  • 测试用例:MemoryConfigModelsTest.java、LongTermMemoryTest.java
  • 人工智能
  • AI Agent
  • Agent 框架
  • 工具调用
  • Agent 工作流
  • RAG
  • MCP Clients
  • 强化学习

【免费下载链接】agent-core-java

openJiuwen agent core Java是 openJiuwen Core的 Java版本,提供AI Agent开发、运行、调优与演进相关的全套SDK能力。

项目地址:https://gitcode.com/openJiuwen/agent-core-java
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询