统一 Memory 门面针对三个后端之一运行。两个HTTP后端(托管网关、本地操作环境)股票一个由端点配置文件(功能数据,而不是运行时子类型)参数化的运行时,而 auth 是一个独立的标头(api 密钥,或无)。以下各列是后端,而不是身份验证模式:身份验证并不能决定后端可以执行哪些操作。如果某项功能不可用,则调用会引发类型化错误,而不是静默失败或显示原始HTTP错误。这些每个后端的间隙是过渡性的;它们像后端一样收敛,点配置文件会缩减为一个。
SDK 从 project_id 状态中选择后端路由结构,与身份验证无关。 Set 表示项目范围的网关路由 (/api/v1/projects/{id}/memory/*)。空表示固定 OE 路由 (/api/v1/memory/*)。因此,下面的 Gateway 列表示“project_id 设立”,OE 列表示“project_id empty”。
Memory.search(query, sources=[...]) 是对下面每种类型搜索的客户端扇出,将结果合并到一个 list[MemoryChunk](按 similarity_score 排序)。它继承每个源的每个后端可用性:请求端点间隙的源会引发 MemoryNotSupportedError。默认[semantic, episodic] 适用于所有三个后端。
功能 | 网关(托管) | OE(本地) | 应用程序绑定(平台) |
|---|---|---|---|
运行时操作(record_turn、build_context) | ✓ | ✓ | ✓(见注释) |
每个源上下文 ( | ✓ | ✓ | ✓ (TenantRuntime) |
语义/情节相似度搜索 | ✓ | ✓ | ✓ |
程序搜索( | ✓ | ✓ | ✓ |
特定于类型的增删改查 ( | ✓ | ✓ | ✓ 有间隙(见注释) |
自定义类型 | ✓ 标志门控(参见注释) | ✗ 没有执行上下文(请参阅注释) | ✓ 标志门控(参见注释) |
分类搜索 | ✓ | ✓ | ✓ (TenantRuntime) |
工具调用/模型打开元数据 | ✓ | ✓ | ✗ |
| ✓ | ✓ | ✗ |
| ✓ | ✓ | ✗ |
创建 | ✓ | ✓ | 部分(仅限 bool/doc-id;通常为空 id) |
重试/幂等性 | shared | shared | 通过 |
身份源 | 调用/绑定 | 调用/绑定 | 调用/绑定/ contextvars |
租户来源 | api-key + 项目范围的路径(网关将密钥固定到其项目) | 执行范围(OE 从执行上下文推断组织/项目) |
|
应用程序绑定列位于平台包(agent-engine-sdk-langgraph) 中,该包封装了 TenantRuntime;将应用程序绑定的重试和幂等性委托给该运行时,而不是共享的 _HttpTransport 重试循环。该委托是一种故意的分歧,而不是奇偶校验失败 — 平台运行时拥有应用程序绑定路径的请求韧性。
分类搜索是在每个后端上进行的排名向量搜索,可以选择按 domain 进行筛选,与其他长期类型相同。路由因路径而异: HTTP运行时(网关和 OE)通过共享的 /search 路由 (type=taxonomic) 进行调度,而应用程序绑定则通过 TenantRuntime/MemoryClient,直接发布到 /retrieval/taxonomic。二者达到相同的搜索排名。
绑定应用程序的 record_turn 记录普通转弯;每轮工具调用/模型元数据被拒绝并显示 MemoryNotSupportedError,因为根本的TenantRuntime.write_turn_async 仅携带 (message, result_messages),不能表示这些字段。返回的 WriteTurnResult 使用合成的空 id / 零 turn_seq,并且仅当写入排队(存在内存写入器、可解析的用户/会话身份、非空内容)时,acknowledged 才是 True — 而不是全面成功声明。调用者提供的 idempotency_key 和 agent_id 不会在此路径上进行转发。
Per-source context (build_context_from_sources) reaches all three backends. The hosted Gateway route (POST /api/v1/projects/{id}/memory/retrieval/context-from-sources) proxies to the same OE retrieval/context-from-sources handler, stamping org/project from the API-key session. On app-bound it flows TenantRuntime → MemoryClient.build_context2 → OE’s retrieval/context-from-sources proxy, returning the full ContextResponse (unlike build_context, which the app-bound path flattens to a string) so ranking_strategy and source_outcomes survive. The runtime stamps org/project; each source’s top_k is honored (it is the caller’s explicit intent, unlike the runtime-owned top_k on build_context); session_id is required only when the stm source is requested. The read runs inside the durable memory activity, so the response round-trips as JSON across a checkpoint.
应用程序绑定的增删改查也会在 TenantRuntime 无法列出的地方发散:get_taxonomic(term=None) 和 get_procedural(procedure=None) 引发 MemoryNotSupportedError(改用类型化列表/搜索方法)。语义/情景/分类的创建结果通常带有空的 id 和 has_embedding=False,因为租户写入API 仅返回 bool 或文档 ID。
自定义类型 save / retrieve 对项目内存配置中声明的内存类型进行操作,并由部署功能标志控制。请求不包含身份或租户字段:平台会在服务器端标记 org、 项目和 user,因此操作仅在存在标记的位置才有效 — 项目范围的网关路由或执行范围的运行时(应用程序绑定或执行上下文中的平面 OE 调用)。没有执行上下文的平面 OE 调用或内存与服务器的直接连接无法标记身份,因而会在服务器端失败。客户端验证仅限于语法(内置类型名称被拒绝,标签语法检查);声明的标签模式由平台强制执行。不提供服务自定义类型路由(裸 404/405)或关闭此功能标记的平台会引发 MemoryNotSupportedError;服务器的结构化未知类型 404 会引发 MemoryBadRequestError。
对于应用程序绑定的读取,contextvars 标识是每次调用的默认,但前提是该读取未请求更广泛的可见性:传递显式 visibility(例如 "org")的读取正在请求跨用户范围,因此环境主体不会替换 user_id — 除非调用方(或 bind)提供主体,否则它保持未设置状态,从而防止可见性范围的读取被默默地缩小到主体范围。
session_id is resolved per operation, not uniformly. It scopes conversation I/O — record_turn and the short-term-memory leg of build_context inherit it from bind/contextvars. It does not scope episodic or semantic search: search_episodes, list_episodes, and the episodic leg of search() resolve session_id from the call argument only and never inherit a bound or ambient session. Episodic memory is stored session-unscoped (consolidated episodes carry session_id: null), so inheriting a conversation’s session as a filter would silently drop every durable memory. A caller that genuinely wants a session-scoped episodic read still passes session_id= explicitly. This matches the platform (agent-engine-sdk-langgraph / TenantRuntime) path, which already requires an explicit session_id on episodic search — the core SDK and the app-bound path now agree. org/ project tenancy is a separate axis (see the tenancy-source row) and is applied to every operation, search included.
另外两个需要注意的应用绑定不对称性:save_procedure(update_existing=True) 仅在应用绑定模式下有效(TenantRuntime 执行先查找后更新)。 HTTP后端仅提供服务创建路由,而不提供更新现有语义,因此网关和 OE 模式会引发 MemoryNotSupportedError,而不是静默创建而不更新。
公共 Memory.build_context 接受可选的 max_tokens 上下文构建毛预算(TypeScript:匹配的公共和应用程序绑定界面上的 maxTokens)。它不是获取费用或承诺的输出大小。在检索和排名后,服务器减去 500-token 格式保留,然后贪心地选择适合余数的整个内存块。等于或低于 500 的正值不会留下内存预算。当没有适合的数据块时,高于 500 的值仍可能产生空上下文。 metadata.token_count 仅报告格式化输出,不包括保留。省略该选项以保持服务器默认。该选项适用于每种连接模式,包括应用程序绑定模式。另外,公共 Memory.build_context 不会公开检索计数大小调整 (top_k) — 该参数位于较低级别的 MemoryRuntime.build_context 接缝上,并且在应用程序绑定模式下,TenantRuntime 完全拥有它(调用者无法设立top_k 到应用程序绑定)。在每种连接模式下,省略的 enabled_sources 默认为 episodic 和 semantic;为最近的轮次传递一个显式设立,其中包括 stm。
Memory.build_context 和 Memory.build_context_from_sources 还接受两个响应调整选项。 format_style("openai"、"claude" 或 "jinja2")选择 formatted_context 的格式;无效值会在本地被 ValueError 拒绝。省略,服务器从其配置的模型中推断格式。请注意,当显式值与其默认模型类型匹配时,服务器当前会重新推断,因此仅在配置了 OpenAI 系列模型的服务器上才会逐字遵循显式 "openai"; "claude" 和 "jinja2" 始终受到尊重。 include_memories=True 使用预算后 MemoryChunk 列表填充响应的 selected_memories,因此调用者可以准确检查选择了哪些内存。这两个选项都适用于网关和 OE HTTP模式。当设立以下任一条件时,应用程序绑定模式会引发 MemoryNotSupportedError:应用程序绑定 build_context 会将响应展平为格式化字符串,并且按源路径尚未将选项线程化通过 TenantRuntime。