agent-memory 记忆接口层实现全解:MemoryAPI、LocalMemoryAPI 与 PEP 鉴权装配策略 人工智能AI AgentAgent 记忆RAGMCP 服务【免费下载链接】agent-memoryMemory 是一款面向 AI 智能体的长期记忆模块为运行在 openJiuwen 框架上的智能体提供记忆提取、存储、检索与迁移能力。项目地址https://gitcode.com/openJiuwen/agent-memory点击查看免费下载本文基于 agent-memory 仓库中的接口层实现规约docs/features/api/F01-memory-api-impl-design.md展开系统讲解jiuwen_memory/api的记忆接口层设计MemoryAPI如何作为内核唯一对外入口、单进程实现LocalMemoryAPI如何以「鉴权PEP 入口审计 委派」三板斧薄封装控制层以及assembly.py如何通过 Producer.dep、默认上下文合并覆盖与 kv 注入把整套内核装配成一个可用的 API。读完后你将掌握该接口的完整方法语义、PEP 鉴权流程、同步/异步桥接边界、list数据面接口的存储下推契约以及 HTTP/CLI 与 API 签名对齐的 dispatch 机制并能直接复制示例完成装配与调用。一、背景MemoryAPI 是内核的唯一对外入口在 agent-memory 中MemoryAPI定义于 memory_api.py是内核的唯一对外入口形态无关——SDK/CLI/Skill/MCP/HTTP·gRPC 各接入形态最终都映射到这同一组语义。调用层只依赖jiuwen_memory.api这一个包即可触达全部能力与所需类型无需 import 内核其他包这是由 api/init.py 的重导出面保证的from jiuwen_memory.api import ( assemble, assemble_runtime, MemoryAPI, MemoryRuntime, # 入口 接口 Scope, Context, Modality, # 调用上下文 MemoryPatch, UpdateMode, # update DeleteSelector, DeleteMode, # delete FilterClause, FilterOp, # search 前置过滤 DisclosureLevel, EvolveMode, # search / evolve Grant, Action, Channel, # 授权 / 演进通道 SpaceSpec, SpaceInfo, SpacePolicy, # space 管理 ValidationError, Credentials, # Access 错误映射 / 凭据 legacy_request_context, # 过渡期安全上下文 )对照 memory_api.py 中的抽象类可以看到公开方法覆盖四组能力数据面add/add_async/batch_add/batch_add_async/search/list/get/update/delete/evolve/check_write/submit_ingest管理面job_status/job_cancel/admin_get/admin_set/admin_all治理面inspect/trace/audit/verify_audit/grant/revokeSpace 管理create_space/get_space/list_spaces/update_space/archive_space/delete_space/export_space/space_usage/get_space_policy/set_space_policy/list_space_members/add_space_member/remove_space_member。memory_api_impl/落两件事文件角色local_memory_api.py ·LocalMemoryAPI单进程下的MemoryAPI实现——鉴权PEP 入口审计 委派自身不含编排逻辑assembly.py ·assemble/assemble_runtime/_build_kernel公开装配只返回MemoryAPI或MemoryRuntime内部_Kernel才持有 KV/Storage接口层是控制层jiuwen_memory/control的薄封装从 local_memory_api.py 的类定义可以看到LocalMemoryAPI由WriteOpsMixin、QueryOpsMixin、AdminOpsMixin、SpaceOpsMixin、PepOpsMixin五个 mixin 组合而成构造时接收engine、permission、scheduler、policy、governor、audit_logger、space、ingest_jobs等控制端口。数据面经control.application的MemoryCommandService/MemoryQueryService委托MemoryEngine治理经GovernanceService委托Governordelete_space事务经SpaceLifecycleService任务/策略/space 普通 CRUD 仍直达对应控制算子。本层只做参数装配 鉴权 入口审计编排逻辑全在控制层。方法签名与参数语义以 S02 规约 为准本文聚焦「为什么这样实现」。二、决策 1PEP 在接口层——鉴权 审计 只透传已鉴权的 targetLocalMemoryAPI是策略执行点PEP也是整个系统中唯一的业务 PEP。每个涉及租户数据/治理的方法统一走两个私有公共点实现在 pep_ops.py_authorize(security.auth.actor, target, action)→ 最终调PermissionManager.decide(...)不通过抛PermissionDeniedError_log(security.auth.actor, action, target_id)→ 经_record_audit落一条layerapi的入口审计事件带认证 actor。通过后才委托引擎/控制算子且只下沉已鉴权的 targetscopesecurity 不下沉下游信任 target。常见「本人操作自己」场景是security.auth.actor scope。从源码看_authorize_with_context的完整流程是若装配了空间级判定且目标是空间级入口先做主体形态校验principal.require_principal_apply_space_policy_context装配判定输入入口名、条目作者标记、空间授权事实带 TTL 缓存的快照一次调用内判定与状态校验共用同一份避免跨快照漂移scope.require_space策略校验具体 target scope 缺space时拒绝并落 deny 审计PermissionManager.decide(identity, target, action, context...)拒绝则落 deny 审计并抛PermissionDeniedError通过则落 allow 审计含命中的 rule 与权限轴。这保证身份永远只来自security.auth.actor业务 payload 中不存在identity/actor_*/role之类的身份声明。三、决策 2security 一律 keyword-only每个方法的security都在*之后、必须具名传security...调用方身份只能从security.auth.actor取得。这样不会把安全上下文误当成 targetScope传入也避免调用方伪造 actor。check_write为兼容历史调用保留第二个位置参数但仍要求传入完整的RequestSecurityContext见 pep_ops.py 的check_write实现先_reject_non_scalar_metadata校验再镜像 add 的鉴权路径但不调 engine.write。四、决策 3Context 只活在接口层边界处拆包search收到的Context在边界即被拆开Context 对象本身不进内核。从 query_ops.py 的search实现可以看到拆包细节options dict(context.extensions) max_tokens _parse_max_tokens(options.pop(EXT_MAX_TOKENS, None)) # 约定 key披露预算 spaces _pop_spaces(options) # 约定 key跨空间检索开关 coords _pop_coords(options, enabledself._routing_enabled()) # 约定 key归属坐标context.scope→ 照旧作独立轴下推先鉴权、再作检索隔离轴context.extensions[max_tokens]→ API 边界解析为 int 后写入RetrievalQuery.max_tokens由披露阶段消费解析后从透传 extensions 中移除其余context.extensions→ 写入调用级 optionsRetrievalQuery.extensions顺 parser 透传给用户自定义的检索模块按约定 key 取用。extensions[max_tokens]是接口层解释的约定 key其余 extensions 保持内核不解释的不透明透传语义。注意max_tokens非整数会抛ValidationError见 local_support.py 的_parse_max_tokens。五、决策 4异步内核 同步桥接引擎是异步的。add_async是直通引擎的真协程供事件循环/高并发接入形态HTTP/MCP非阻塞调用同步add及 search/list/get/update/delete/evolve是它的同步桥接——内部asyncio.run(...)包一层供 CLI/脚本直接调用。从 write_ops.py 可见add就是asyncio.run(self.add_async(...))batch_add同理。一套语义两个入口避免同步/异步双实现漂移。由此带来一个使用约束规约「已知遗留」第 1 条同步方法不可在运行中的事件循环内调用。在已有 event loop 的环境如 async 框架内须改用add_async等协程入口否则asyncio.run会报错。六、决策 5–8数据面委托引擎管理面直达控制算子数据面add/search/list/get/update/delete/evolve →MemoryEngine经MemoryCommandService/MemoryQueryService管理面job_status/job_cancel →Scheduleradmin_* →PolicyManagerinspect/trace/audit →Governorgrant/revoke →PermissionManagercreate/get/list/update/archive/delete/export/usage/policy/member space 管理 →SpaceManager。接口层不替管理面做编排直达对应控制算子职责清晰。源码中 admin_ops.py 的job_status同时覆盖 evolve 任务Scheduler与长耗时 Ingest 任务INGEST_JOB_PREFIX前缀走ingest_jobs.status且 Ingest 任务必须显式传入 target scope。三个更细的闸门决策决策 6管理面闸门 根 scope 鉴权。admin运行时策略与全局 audit 查询没有具体 target scope统一以「根 scope」_ROOT Scope()为鉴权目标定义见 local_support.py。真实 RBAC 后端下「能对全局根 scope 行权」即等价于管理员闸门allow_all装配下为 no-op。租户数据/治理方法仍按各自 target scope 鉴权org 级create_space/list_spaces以Scope(org...)做管理面鉴权不受scope.require_space拦截。决策 7任务鉴权——先取任务、再按其 scope 判权。job_status/job_cancel先Scheduler.status(job_id)取到任务含其 scope再据 identity 对该 scope 判权status 为只读查询先取后判权不产生副作用cancel 按 WRITE与 evolve 触发一致——保证只能查/操作自身或已授权范围的任务。决策 8delete 的 scope 兜底。delete按selector.scope鉴权 DELETE未限定 scope纯按 id/标签的跨范围删除则退到_ROOT闸门要求更高权限——避免「不指定范围」绕过隔离。query_ops.py 中target selector.scope or _ROOT一行即此语义且命中条目还会经permission_contexts_for_delete逐条二次鉴权。七、决策 9装配assembly.py——Producer.dep 默认上下文 合并覆盖 kv 注入assemble/_build_kernel的串接策略实现见 assembly.py取依赖统一走depXProducer.dep(root, default...)按配置值分派——引用名str→build_named共享内联 dict →build匿名缺省None→ 按default匿名新建。字段名默认取各 Producer 的TOP_NAME。根组件经 ROOT_PARAMS 引用各命名空间下的default实例。默认装配无 config 时用内置默认上下文config/defaults.py——纯内存离线栈kv_store/vector_store/graph_store/fulltext_store全为 memory 目标llm为 echo、audit与permission为内存 sqlite用显式具名 引用复刻共享拓扑用户 config 经AssemblyContext.merged合并覆盖到其上只写要改动的部分。policies 便捷覆盖policies折进globals[policies]。真源 kv 注入kv入参经KvProducer.put(KV_DEFAULT_NAME, kv)预置进缓存覆盖配置的 kv_store 选择并被各处共享如传SQLiteKVStore即落盘。多次装配隔离组装前_register_all()各层 bootstrap 幂等自注册common 插件、storage 后端、retrieval 算子、ingest、construction、control、ConfigSourceFactory.reset_all()清空具名实例缓存。内部_Kernel持有统一 Storage 与控制句柄_build_kernel返回_Kernel{api, kv, storage, ingest_jobs, space, audit, config_source, scheduler}不从jiuwen_memory.api导出assemble只返回 apiassemble_runtime只返回api closeMemoryRuntimeProtocolclose 时依次关闭 ingest jobs、停止 Scheduler、释放 dreaming leader 锁。普通数据面能力应走MemoryAPI。公开用法即规约给出的三行示例from jiuwen_memory.api import assemble from jiuwen_memory.config import Config api assemble() # 默认纯内存离线栈 api assemble(configConfig(...), policies{rerank_enabled: true}) api assemble(kvSQLiteKVStore(mem.db)) # 注入落盘真源装配顺序有一条铁律ConfigSource→store_manager.defaultcomposite 再 dep 各 Store含kv_store.default→_Kernel.kv manager.kv(端口名)。此外_build_kernel还做装配期一致性校验例如配置了 schema target 但未开globals.schema_enabled会抛ValidationError配置了 router 判定表但判定实现不读空间事实的组合也会被拒绝见 assembly.py 的_reject_routing_without_space_authorization理由是「内容按坐标分流进协作空间而协作空间没有任何权限边界」。完整可运行的装配与调用演示见 examples/quickstart.pyConfig.from_yaml(examples/config.yml)解析后assemble配置写法注释见 examples/config.yml。八、决策 10HTTP/多 surface 的结构化 dispatch 边界HTTP 与 CLI 不再经过 MCP 使用的 legacy handler稳定边界均为MemoryAPI本身POST /v1/method_name的 JSON 字段直接对应同名方法参数反射 API 签名取得字段集合、必填/默认关系和类型注解再机械构造Scope、Context、MemoryPatch等公开对象。服务端拒绝未知字段以及target、item_id、k等历史 HTTP 别名避免 DTO 与 API 再次独立演进。这一机制的实现是 jiuwen_memory_entry/core/api_contract.pymethod_contract(verb)通过inspect.signature(MemoryAPI, verb)与类型注解构建传输契约request_parameters显式排除self与security_RESERVED_SECURITY_FIELDS集合security/identity/actor/acting_user/principal 等保证请求体无法携带身份字段。认证 actor 仍只来自RequestSecurityContext.auth.actor。security不接收请求体输入HTTP 认证中间件生成可信上下文后以关键字参数注入同名 APIAPI 再以公开参数中的scope、selector.scope、spec.org/space等业务目标完成鉴权与审计。成功返回值不再转换成{ok, op, ...}而是按数据类字段、枚举值和 ISO 8601 时间递归序列化。同步 API 直接调用add_async/batch_add_async按协程契约等待完成并序列化原返回值不转成新的任务模型。evolve/submit_ingest保留任务语义是因为 API 本身就返回任务标识或提交结果而不是 HTTP 根据同步/异步重新解释。CLI 命令和--参数名直接从 API 签名生成所有对象使用与 HTTP 相同的 JSON 结构本地 CLI 经受控认证入口直接调用 API远程 CLI 原样发送同名 HTTP 请求两者共用core/api_contract.py以及core/error_response.py的领域错误映射。本地开发认证须显式使用--auth-mode dev不会根据业务 scope 推导身份。MCP 和旧调用方的 flat 输入仍可经 legacy_request_adapter.py 与 shared handler详细取舍见 F05。九、决策 11list 升级为正式数据面接口bootstrap表面已有listverb但此前接口层没有正式MemoryAPI.list(...)容易让不同接入形态各自实现枚举逻辑甚至把「surface 直扫 KV」误读成长期架构。参考 mem1.0list_memories(user_id, scope_id, offset, limit, mem_types)的核心语义本层把 list 收口到统一 API抽象签名见 memory_api.pydef list( self, scope: Scope, *, security: RequestSecurityContext, offset: int 0, limit: int 100, memory_types: list[str] | None None, extensions: dict[str, Any] | None None, filters: FilterExpr | list[FilterClause] | dict | None None, ) - MemoryListResult: ...当前默认实现的职责链是MemoryAPI.list - MemoryEngine.list_with_permission_contexts - KVStore.list。KVStore.list契约定义见 storage/kv.py在完整Scope内完成/memory/MemoryUnit 的类型/FilterExpr 过滤、精确计数、稳定排序和分页Engine 只反序列化当前页并生成权限上下文engine.py 的list/list_with_permission_contexts。9.1 API 层职责与设计目标MemoryAPI.list做 READ 鉴权、入口审计和参数委托实现见 query_ops.pyMemoryEngine.list校验分页参数并把查询参数完整委托KVStore.listHTTP / CLI 直接调用MemoryAPI.listMCP 等旧调用方的handler._list仍委托srv.api.list(...)不再直连 KV返回范围只包含/memory/前缀的已建索引MemoryUnit不返回/messages/下的 infer 原文缓存list 是范围枚举不走MemoryPipelinepipeline 仍只负责构建/查询组件绑定。API 层权限上下文未传memory_types构造一次PermissionContext(resource_typememory_list)按普通 READ 鉴权显式传一个或多个类型按清洗去重后的类型列表逐个构造PermissionContext(resource_typememory_list, memory_typetype)全部通过才委托 Engine这样RoutingPermissionManager(route_keymemory_type)可以让不同记忆类型使用不同权限逻辑且多类型请求不会绕过更严格的类型策略。鉴权通过后 API 还会把权限路由值回注为系统等值过滤条件并与用户 filters 做外层ANDlist 与 search 一样注入第一族系统谓词个体空间隔离最后对当前页每条实际MemoryUnit再逐条 READ 鉴权。9.2 List 自定义参数、过滤与结果总数增量设计已实现List 需要在「按 Scope 枚举」基础上支持调用方自定义参数和结构化过滤同时返回过滤后的结果总数dataclass class MemoryListResult: items: list[MemoryUnit] field(default_factorylist) count: int 0Python API 使用filters作为规范参数名与search保持一致bootstrap payload 以filters为规范字段同时兼容调用方使用单数filter。两者同时出现时拒绝请求避免静默选择其中一份条件。extensions契约与RetrievalQuery.extensions一致类型为dict[str, Any]API 边界只复制外层字典并原样透传值避免调用方后续修改原字典影响正在执行的请求内核不得隐式调用str()内核默认实现不解释业务 key必须沿MemoryAPI - MemoryEngine - KVStore.list完整透传自定义 Engine 或 KV 后端可按约定消费未知 key 不报错extensions不得改变scope、绕过权限或覆盖系统过滤谓词。权限上下文构建只解释PermissionManager.routing_fields()声明的路由键extensions 优先、filter 等值兜底与 search 同一口径其余扩展值对权限层不透明——既不进PermissionContext.metadata也不被str()调用方无法借扩展键向鉴权入参塞入任意判定依据。参与权限路由的键API 必须像 search 一样把对应路由值回注为系统等值过滤条件并与用户 filters 做外层AND确保「按什么条件授权就只列出什么范围的数据」None与空字典都表示没有自定义参数。非字典输入在 API/handler 边界抛ValidationError不静默丢弃。filters复用 retrieval 的完整过滤契约接受单个FilterClause、FilterExpr树、旧式list[FilterClause]和 dict DSL在 API 边界统一通过normalize转成FilterExpr | None支持EQ/NE/IN/NOT_IN/GT/GTE/LT/LTE/CONTAINS以及AND/OR/NOTScope 是独立的强隔离轴org/space/user/agent/session不允许放入 filters用户过滤只能进一步收窄已鉴权的 target Scope不能扩大查询范围memory_types保留为兼容快捷参数与 filters 是AND关系类型匹配仍优先读取unit.system_metadata[memory_type]缺省退回unit.tier.value规范化后的 filters、memory_types、extensions、offset和limit必须由 Engine 原样下推 KV 查询契约过滤必须在存储适配器内部先于排序、offset和limit执行禁止 Engine 先取一页再做后置过滤。9.3 KV 层契约KVStore.list通用KVStore.scan(scope, prefix)是无业务语义的字节扫描能力供 lifecycle、offboarding 和兼容代码使用不能直接在该方法上堆叠 MemoryUnit 过滤参数。KV 契约因此新增面向/memory/真源的结构化查询storage/types.py 中定义KVMemoryListResultdataclass class KVMemoryListResult: entries: list[tuple[str, bytes]] field(default_factorylist) count: int 0 class KVStore: def list( self, scope: Scope, *, offset: int 0, limit: int 100, memory_types: list[str] | None None, filters: FilterExpr | None None, extensions: dict[str, str] | None None, ) - KVMemoryListResult: ...参数传递规则API 对extensions做防御性复制和字符串值规范化对 filters 做 AST 规范化Engine 校验分页参数后以同名 keyword 参数直接调用KVStore.listKV 实现将memory_types/filters/extensions视为只读参数需要异步保存或跨请求缓存时自行复制KVMemoryListResult由同一次存储查询返回当前页 entries 和分页前 count保证两者基于相同的数据状态。KVStore.list只查询MEMORY_KEY_PREFIX下由memory_codec.dumps写入的 MemoryUnit不包含/messages/或其他普通 KV 记录。各 KV 实现必须保证在完整 Scope 内执行查询不能跨 Scope/Space返回的entries已完成 filters、memory_types、稳定排序和分页count是同一查询条件下的分页前精确总数extensions完整到达后端默认后端可以不解释未知 key但不能在 Engine 层提前丢弃原生支持 JSON/metadata 查询和 count 的后端可直接下推不支持的内存、加密或简单 key-value 后端在自身适配器内执行「枚举、解码、过滤、计数、排序、分页」兼容回退EncryptedKVStore不能把 MemoryUnit filters 直接下推到密文 raw KV它必须先解密再执行兼容回退或者依赖不泄露敏感值的独立可查询 metadata sidecar。无 sidecar 时不能用密文条数近似过滤后 count。新增KVStore.list是抽象接口变更当前所有 KV 实现都必须同步修改不能只在默认memory后端实现KV 实现list首版策略约束InMemoryKVStore在目标 Scope 的/memory/entries 上解码并使用公共 MemoryUnit filter evaluator再精确计数、排序、分页不得依赖 dict 遍历顺序SQLiteKVStore当前 bytes schema 使用公共 evaluator 回退先按 Scope 和/memory/前缀取值再解码、过滤、计数、排序、分页不拼接 FilterExpr SQL后续 schema 支持 JSON 查询后再单独增加原生下推RedisKVStore普通 Redis bytes 模式没有通用 metadata query首版按 namespaced/memory/key 扫描并使用公共 evaluator将来启用 RedisJSON/搜索索引时可增加方言编译器不得把不同 Scope 的 key 混入候选EncryptedKVStore先取得并解密目标 Scope 的/memory/entries再使用公共 evaluator若未来有安全 metadata sidecar 才允许原生下推filters/extensions 不能直接委托给看不到明文的 raw KV9.4 FilterExpr 到 KV 可执行条件的三层复用边界FilterExpr 到「KV 可执行条件」的转换不能是一份固定查询字符串因为各后端没有共同查询语言。可复用边界分成三层公共 AST 与校验继续由common.type_def.filter.normalize负责把单 clause、旧 list 和 dict DSL 收口成合法的FilterExpr | None公共树遍历复用common.type_def.filter.evaluate递归处理AND/OR/NOT公共 MemoryUnit 求值matches_memory_unit(unit, expr)统一字段投影和叶子比较当前 memory/sqlite/redis/encrypted 四个实现都用该兼容路径。后续后端如需原生下推由各自方言编译 FilterExpr不改变KVStore.list契约。公共matches_memory_unit已从 retrieval UnitReader 的字段投影和叶子比较逻辑中提取统一tags/tier/source/lifecycle/unit_id/t_event/t_valid/t_invalid/metadata.*的取值、缺值、集合和类型比较语义。Retrieval 真源复核与 KV 扫描回退都调用它禁止各自复制一套比较逻辑。「树形结构遍历」和「MemoryUnit 过滤语义」可以通用「如何表达为 SQL、Milvus 字符串或 Elasticsearch DSL」必须由方言适配不能伪装成跨后端通用查询语句。9.5 CloudEngine 与 InMemoryEngine 对齐、默认执行顺序CloudEngine与InMemoryEngine的 List 能力必须对齐list、list_with_permission_contexts接受完全相同的offset/limit/memory_types/extensions/filters返回相同的 items/count 语义两个 Engine 都直接调用同一个KVStore.list契约不允许一个下推 KV、另一个在 Engine 内全量扫描两者都只反序列化 KV 返回的当前页 entries并从同一批 MemoryUnit 构造逐项 PermissionContext避免 items 与鉴权上下文来自两次查询offset/limit校验、空 filters/extensions、稳定排序、count 和异常语义完全一致公共逻辑提取到 Engine 共享 helper两个实现不复制_list_page唯一允许的能力差异是既有部署边界InMemoryEngine继续拒绝非空scope.spaceCloudEngine支持命名 Space。该差异不改变 List 查询、过滤和返回协议。默认执行顺序固定为MemoryAPI - 规范化 extensions/filters完成请求级 READ 鉴权 - MemoryEngine 校验分页参数不解释、复制或丢弃查询参数 - KVStore.list( scope, offsetoffset, limitlimit, memory_typesmemory_types, filtersfilters, extensionsextensions, ) - memory_types AND filters - count len(全部匹配结果) - t_ingest DESC, id DESC 稳定排序 - entries matches[offset:offset limit] - Engine 只反序列化当前页 entries生成 MemoryUnit PermissionContext - API 对当前页实际 MemoryUnit 二次 READ 鉴权 - MemoryListResult(items, count)MemoryListResult.count表示同一 Scope 下同时满足memory_types和filters的分页前总数不受offset/limit影响本页数量由len(result.items)得到。bootstrap 响应中的count同步改为该总数items仍只包含当前页。请求级鉴权未通过时不得执行枚举或返回 count实际资源二次鉴权未通过时整个请求失败不返回部分 items 或可推断未授权数据规模的 count。这一阶段继续以 KV 真源查询保证语义正确不复用 searchlist 是确定性范围枚举不应受相关性、召回通道、阈值、top-k 或披露策略影响。简单 KV 后端的兼容回退仍需扫描 Scope 下全部/memory/记录复杂度为 O(N)但扫描职责封装在 KV 适配器内Engine 始终使用同一个list契约。生产后端应在分页前完整下推 FilterExpr 并使用原生 count不能用「先取 limit 条再过滤/计数」的近似实现替代精确语义。9.6 list 相关的 legacy payload 兼容与拒绝方案legacy handler payload 兼容仅 MCP 和旧调用方不适用于 HTTP / CLI字段语义tenant_idscopetarget scopeactor_*HTTP / CLI 拒绝仅保留为 legacy dispatch 调用的兼容输入不能作为新入口的身份来源offset非负整数默认 0limit正整数默认 100memory_types/mem_types/memory_type记忆类型过滤可为字符串列表或逗号分隔字符串list 相关的拒绝方案handler 继续直扫 KV绕开 API 鉴权/审计也会让 SDK/MCP/HTTP 的 list 语义分裂复用 search 返回全量会混淆「相关性检索」和「范围枚举」并受到召回通道、top_k、阈值和披露策略影响list 支持跨 scope枚举多个 scope 属于治理/管理能力不放进普通数据面读接口只用 tier 命名过滤参数mem1.0 是mem_types本层选择更中性的memory_typeshandler 接受mem_types与memory_type作为兼容别名。十、全局拒绝的方案接口层总览规约在「拒绝的方案」一节汇总了接口层的取舍值得完整保留security作为位置参数被拒。安全上下文必须与 targetscope保持不同的类型和参数角色除check_write的历史兼容位置外统一强制 keyword-only避免调用处误传或丢失认证信息。Context 对象下沉进内核被拒。Context 是接口层的打包容器下沉会让内核耦合「调用形态」改为边界拆包scope 独立下推extensions 中的约定 key 由 API 边界解释其余 extensions 透传。接口层承担编排被拒。api 层只做 PEP 参数装配 审计所有编排add 的规约/索引、search 的多路召回/融合/披露、evolve 的阶段调度留在jiuwen_memory/control与各算子层保证入口薄、可替换接入形态。管理面也走 MemoryEngine被拒。engine 聚焦数据面任务/策略/治理/授权直达对应控制算子避免 engine 变成「什么都转发」的上帝对象。同步实现整套内核被拒。内核选异步适配 HTTP/MCP 高并发同步入口用asyncio.run桥接避免维护同步/异步两份实现导致语义漂移。admin/全局 audit 按调用方自身 scope 鉴权被拒。这类操作无具体 target scope按自身 scope 判权会让任意用户都「对自己有权」从而绕过管理面改用根 scope 闸门统一表达管理员权限。隐式按字段名共享装配依赖被拒随 config/factory 重构。共享改为「显式具名 引用」build_kernel用默认上下文复刻共享拓扑用户只覆盖差异。十一、验证与测试基线历史基线pytest tests/unit/api全绿。test_build_kernel_config.py装配路径——默认上下文、用户 config 合并覆盖、build_named具名共享、顶层名校验、kv 注入test_memory_api_list.py分页、memory_types过滤、scope 隔离、/messages/不外泄、非法 offset/limit、单一/多值 memory_type 权限路由以及 extensions 逐层透传、非字典输入拒绝、count为分页前精确总数、超出 offset 时 items 为空但 count 保持不变等增量用例鉴权/审计语义随控制层tests/unit/control/一并回归PEP 在接口层闸门行为在allow_all与真实 PermissionManager 下分别覆盖HTTP / CLI 同名契约test_api_contract.py、test_http_server_security.py、test_cli.py覆盖全部方法与参数、嵌套对象和默认值、原返回值、未知/身份字段拒绝、认证上下文清理及本地/HTTP 调用legacy dispatch 的target归一化、space 别名冲突与DispatchRequest边界由 test_handler.py 保留覆盖不再描述为 HTTP 兼容契约。十二、已知遗留与使用限制同步方法不可在运行中的事件循环内调用add/search/… 内部asyncio.run在已有 event loop 的环境如 async 框架内须改用add_async等协程入口否则asyncio.run报错。security 不下沉 下游信任 target鉴权只在接口层做一次下游算子信任传入的 target scope若未来出现「下游需二次校验」的场景需要显式传递鉴权上下文。默认装配是本地 SQLite owner-only ACLassemble()默认permissionsqlite(db_path:memory:)owner 访问自己的 target scope 默认放行同租户跨 scope 默认拒绝测试或开发若要完全放行需显式装配allow_all。管理面闸门粒度粗admin/全局 audit 统一走根 scope尚无更细的「按策略键/按 layer」分权待真实 RBAC 后端细化。小结agent-memory 的记忆接口层用一份抽象MemoryAPI、一个单进程实现LocalMemoryAPI和一套装配函数assemble/assemble_runtime把「形态无关的语义、接口层的 PEP 鉴权与审计、控制层的编排」三者切得干干净净调用方只 importjiuwen_memory.apiSDK/CLI/MCP/HTTP 各自只做协议转换而权限上下文、空间事实快照、同步/异步桥接、KV 真源注入等敏感决策全部收口在接口层边界上。理解本文的十一项决策与拒绝清单基本就能读懂该仓库jiuwen_memory/api与jiuwen_memory_entry之间所有的契约约束也为自定义 Engine/KV 后端如原生下推 FilterExpr提供了明确的扩展边界。赞分享人工智能AI AgentAgent 记忆RAGMCP 服务【免费下载链接】agent-memoryMemory 是一款面向 AI 智能体的长期记忆模块为运行在 openJiuwen 框架上的智能体提供记忆提取、存储、检索与迁移能力。项目地址https://gitcode.com/openJiuwen/agent-memory点击查看免费下载相关推荐Midway 角色鉴权Casbin接入实战模型策略配置、装饰器鉴权与分布式存储Midway 角色鉴权Casbin接入实战模型策略配置、装饰器鉴权与分布式存储 本文基于 Midway 官方文档「角色鉴权」与仓库源码整理。Midway后端微服务云原生ECC 研究报告解读ai-memory 与 Agent 编排系统的记忆层对照与可借鉴的治理思路ECC 研究报告解读ai memory 与 Agent 编排系统的记忆层对照与可借鉴的治理思路 导读 本文基于仓库内 docs/research ecc.md人工智能AI 应用Agent 记忆MCP 服务ChatDev 2.0 多 Agent 记忆体系实战Memory Store、向量检索与 Mem0 云端记忆配置全解ChatDev 2.0 多 Agent 记忆体系实战Memory Store、向量检索与 Mem0 云端记忆配置全解 本篇指南系统讲解 ChatDev 2.0AI AgentAgent 框架Agent 工作流低代码工作流自动化OpenBMB上一篇PyPTO Tile 计算 API 实战指南逐元素运算、归约、选择与类型转换全解析下一篇CANN ops-nn 算子开发指南aclnnConvDepthwise2d 二维深度卷积算子深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考