尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Friend 通用记忆(Universal Memory)运维手册:控制开关、部署顺序与故障演练

Friend 通用记忆(Universal Memory)运维手册:控制开关、部署顺序与故障演练 Friend 通用记忆Universal Memory运维手册控制开关、部署顺序与故障演练【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend本指南面向 backend on-call完整讲解 Friend 后端通用记忆体系的运维控制面统一规范写入器universal canonical writer、双格式读取器dual-format reader、历史兼容适配层historical compatibility adapter以及 Short-term 维护任务memory-maintenance-job的部署、观测、故障处置与回滚演练。读完本文你将掌握全部运维开关的语义与取值、7 步部署顺序、无内容观测指标Prometheus counters、6 步故障动作以及强制回滚演练要求并能直接定位到对应源码与运行时环境清单。一、运营边界一套权威不做产品分群Friend 的记忆体系遵循一条核心原则每一个已认证用户都遵循同一套 memory/task 权威逻辑。仓库中不存在产品级 UID 注册product UID enrollment、dogfood 激活dogfood activation或通用账户回填general account backfill。开发环境中的 drain 操作 allowlist 只是安全围栏safety fence不是产品 enroll 机制。所有新写入统一落入 canonicalmemory_items既有的users/{uid}/memories历史行保持原样可读read in place仅在该条记忆被变更时才惰性物化materialized为 canonical 表示读取侧通过 backend/utils/memory/memory_service.py 合并 canonical 条目权威 历史行适配为发布响应模型不原地修改 持久化的 override/tombstone抑制已物化或已删除的历史副本。这一边界在架构文档 backend/docs/canonical_memory_architecture.md 中有完整生命周期图与模块切面说明。二、控制开关总览全局就绪/事故/成本开关绝不作为用户选择器运维手册给出了一张权威控制表。以下逐一展开每个开关的语义、取值与源码佐证控制项Owner含义MEMORY_MODEbackend maintenance manifests全局就绪/事故声明绝不是用户选择器MEMORY_V3_GET_ENABLEDbackend manifests已废弃、非权威的声明等待 manifest 清理绝不是用户选择器MEMORY_CANONICAL_MAINTENANCE_ENABLED仅memory-maintenance-job启用计划性 Short-term 归一化、TTL 审计、consolidation 与 outbox drainMEMORY_CANONICAL_CONSOLIDATION_ENABLEDmaintenance job全局 L2 成本/事故开关必需处理、TTL 审计与 outbox 所有权保持独立consolidation batch/candidate capsmaintenance job限定单次 L2 调用与单轮 pass 的上界KNOWLEDGE_LEDGER_DRAIN_ENABLEDknowledge-ledger-drain-job显式运维门开发与生产 manifest 默认关闭。一次性开发执行仅在只读预检 直接用户 ledger 写入证明之后才可覆盖门KNOWLEDGE_LEDGER_DRAIN_UID_ALLOWLISTknowledge-ledger-drain-job开发环境保留一名具名 QA 负责人用于显式覆盖生产环境为空。属于安全围栏而非产品 enroll默认关门的配置防止计划性变更共享 JIT admission kill switchknowledge-ledger-drain-job迁移前对每个账户和每行重新授权授权不可用时 fail closedledger drain page cap/cursorknowledge-ledger-drain-job全局滚动扫描每轮最多处理 20 个 apply-control 文档仅当整页所有账户全部成功无错后才推进光标dev allowlist 只读其具名 controls不产生全局光标副作用cursor secret/version/TTLbackend活跃路由未使用移除前需确认没有独立消费者占用该绑定2.1MEMORY_MODE与MEMORY_V3_GET_ENABLED遗留别名勿再写入新 overlay从 backend/config/memory_rollout.py 可以看到真正的产品开关只有一个MEMORY_ENABLEDon|off未设置时 fail-closes 到off。MEMORY_MODE与MEMORY_V3_GET_ENABLED仅作为单部署别名保留目的是让旧版本不爆炸未设置MEMORY_ENABLED时MEMORY_MODEwrite|read→ 视为onoff|shadow→ 视为off实时GET /v3/memories路由不会调用MEMORY_V3_GET_ENABLED列表 503 来自MEMORY_V3_CURSOR_SECRET/read_page与该标志无关MemoryRolloutMode枚举包含off / shadow / write / read四个值其中MEMORY_ENABLEDon语义是 write-mode 摄入create list不是Gate 3 只读。在 backend/.env.template 中同样注明MEMORY_MODEandMEMORY_V3_GET_ENABLEDare legacy one-deploy aliases并给出示例值MEMORY_MODEoff。2.2MEMORY_CANONICAL_MAINTENANCE_ENABLED仅memory-maintenance-job可置 true实现位于 backend/utils/memory/canonical_short_term_maintenance_cron.pydef canonical_maintenance_enabled() - bool: Whether *this process* hosts the ST→LT cron. raw os.getenv(MEMORY_CANONICAL_MAINTENANCE_ENABLED_ENV, false) return raw.lower() true默认值是false这是刻意的 per-deployable 路由设计只有memory-maintenance-job将其置为 true且 backend/scripts/runtime_env_validation/manifest.py 会在任何其他 job 或请求路径 surface上设置该值时报构建失败。基础运行时环境清单 backend/deploy/runtime_env/_base.yaml 中该变量为value: false、category: memory_rollout。2.3MEMORY_CANONICAL_CONSOLIDATION_ENABLED全局 L2 成本/事故开关定义于 backend/utils/memory/canonical_consolidation.pyMEMORY_CANONICAL_CONSOLIDATION_ENABLED_ENV MEMORY_CANONICAL_CONSOLIDATION_ENABLED ... raw os.getenv(MEMORY_CANONICAL_CONSOLIDATION_ENABLED_ENV, true)它只控制 consolidationLong-term 路由中的 L2 决策必需处理required processing、TTL 审计、outbox 所有权保持独立——关闭它不会停掉其余维护管道。同一文件还定义了 consolidation 的上下文与重试上界常量例如CONSOLIDATION_CONTEXT_CANDIDATES_PER_ANCHOR_MAX_COUNT 20、CONSOLIDATION_CONTEXT_ARGUMENTS_MAX_CHARS 2_000、CONSOLIDATION_CONTEXT_REDACTED_TEXT [REDACTED: restricted sensitivity]这些即手册所述consolidation batch/candidate caps 限定一次 L2 调用和一轮 pass的具体来源。重试状态由ConsolidationRetryState承载retryable / in_progress / quarantined / terminal_review四种状态 lease 字段支撑修订级尝试、租约、有界重试、review quarantine的防毒行机制。2.4 ledger drain 两个开关显式门 安全围栏backend/modal/knowledge_ledger_drain_job.py 的入口首先检查ledger_drain_enabled_from_environment()未开启直接return打印knowledge-ledger-drain-job disabled若开启但 allowlist 为空则抛错knowledge-ledger-drain-job requires an explicit UID allowlist。backend/utils/memory/knowledge_ledger_drain.py 定义了MAX_LEDGER_DRAIN_UIDS_PER_RUN 20、MAX_LEDGER_DRAIN_ERRORS 16、LEDGER_ROW_AUTHORIZATION_TIMEOUT_SECONDS 15.0以及LEDGER_DRAIN_CURSOR_PATH knowledge_ledger_migration_control/inventory_cursor。它刻意不依赖Short-term 维护模块使用自己 generation-fenced 的持久光标因此慢维护不会饿死 ledger 迁移。allowlist 解析ledger_drain_uid_allowlist_from_environment()会拒绝含/或空白字符的 UID且解析结果不出现在日志中。生产与开发的差异可直接对照生产 overlay backend/deploy/runtime_env/prod.overlay.yamlKNOWLEDGE_LEDGER_DRAIN_UID_ALLOWLIST: value: 空无 QA 围栏开发 overlay backend/deploy/runtime_env/dev.overlay.yaml保留一个具名 UID9OqYLlKJv4hmeYpIhwJcHBR975i2即开发保留一名具名 QA 负责人的实际落地。2.5 已退役的控制MEMORY_ENABLED_USERS与代码内 UID 清单MEMORY_ENABLED_USERS以及代码中自带的 product UID 列表均已退役。运行时校验backend/scripts/runtime_env_validation/manifest.py 及 backend/scripts/runtime_env_validation/common.py会拒绝任何按用户细分的内存清单重新引入。这与架构文档 backend/docs/canonical_memory_architecture.md 中没有MEMORY_ENABLED_USERS运行时绑定、没有产品 enroll 命令的声明一致。三、部署顺序7 步上线清单运维手册给出了精确的 7 步部署顺序每一步对应可验证的契约或观测点跑 hermetic 契约对精确 SHA 运行 hermetic memory pipeline、universal service/mutation、task no-drop/no-duplicate、privacy/export、runtime-env 与 OpenAPI 兼容性契约对应测试见 backend/tests/unit/test_universal_memory_service.py、backend/tests/unit/test_memory_apply_store.py。非生产项目部署该 SHA准备 ≥2 个合成认证用户覆盖三种数据形态historical-only、canonical-only、mixed rows。验证逻辑一致性在 REST、chat、MCP、tools、developer 各 surface 上比对逻辑 ID、排序、lifecycle/device/visibility 策略、重复抑制与跨 UID 隔离完全一致。验证维护任务专用 maintenance job 与 Scheduler identity/cadence 正确job 必须推进有界、无内容的账户注册表光标bounded content-free account-registry cursor不得扫描 users collection也不得重复同一固定页。验证knowledge-ledger-drain-job与knowledge-ledger-drain-hourly与 maintenance 相互独立Scheduler 主账户对 job 持有run.invoker权限确认其无内容计数器展示有界光标推进与 compatibility→ledger cutover。演练全局停止与恢复路径记录 revision、镜像 digest、project/database 身份、Scheduler/job 结果与无内容计数器。先部署 universal reader 再开 canonical 摄入在启用生产 canonical intake 或 maintenance之前先部署同一 universal reader不要添加 canary UID 或 enroll 文档。关于第 4、5 步中的 Scheduler 身份可参考 backend/scripts/provision_daily_memory_sweep_scheduler.py它保留了一份来源派生的契约映射EXPECTED_TARGETS {EXPECTED_SCHEDULER_JOB: EXPECTED_CLOUD_RUN_JOB, knowledge-ledger-drain-hourly: knowledge-ledger-drain-job}使用gcloud scheduler jobs create|update --http-methodPOST --urihttps://run.googleapis.com/v2/projects/{project}/locations/{region}/jobs/{job}:run --oauth-service-account-email{service_account}每小时触发0 * * * *时区Etc/UTCupdate 后还会显式resume以保证触发处于启用态。四、无内容观测只记计数绝不记录内容运维手册强调观测只记录计数——canonical 行返回数、historical 行返回数、canonical-over-historical 抑制数、override/tombstone 抑制数、malformed historical 行数、cursor 失败数、pending/terminal 维护行数、outbox lag/dead letter 数、historical 清理失败数。不得记录memory 内容、embeddings 或 provider payload。仓库通过 backend/utils/metrics.py 导出三个低基数的 Prometheus 计数器文档原文直接可用作告警与仪表盘表达式memory_universal_read_origin_total{origincanonical|historical}——universal repository 按物理来源纳入的逻辑行数memory_historical_suppression_total{reasoncanonical_identity|canonical_state}——被 canonical 身份或 canonical 状态抑制的历史行数memory_historical_materialization_total{outcomenot_needed|committed}——惰性物化的结果分布无需物化 / 已提交。这三个计数器在 backend/utils/metrics.py 中定义并完成 label 预注册。维护收据maintenance receipts额外上报可重试的 outbox 失败数、dead letter 数、ack 失败数、已处理账户数、光标进度告警聚合这些字段时禁止带 UID、memory ID 或内容标签。此外架构中还有一条文本无关的canonical_memory_decision_path.v1日志只输出分类决策字段与计数绝不输出 transcript、quote、memory 或模型 rationale 文本。五、故障处置6 步标准动作当 incident 发生时按以下顺序执行不可跳步保持 universal dual-format reader 部署在位。回滚到 legacy-only reader 会隐藏新的 canonical 数据明令禁止。停 L2 成本或错误 consolidation置MEMORY_CANONICAL_CONSOLIDATION_ENABLEDfalse。停计划性变更置MEMORY_CANONICAL_MAINTENANCE_ENABLEDfalse同时继续权威读取。若新摄入本身不安全使用部署方拥有的全局 memory incident mode对应MEMORY_ENABLED关闭路径绝不要把选定 UID 路由到 legacy writer。保全数据preserve canonical items、historical rows、overrides、tombstones、journals、outbox 状态物理删除需单独审批。修复后全局恢复先运行一次有界维护执行gcloud run jobs execute memory-maintenance-job --wait确认成功后再确认后续一次 Scheduler 执行与 provider lag 恢复。其中第 3 步继续权威读取的支撑在于维护任务设计为幂等required normalization、TTL、全量 L2 路由、带租约的 projection-outbox 投递。memory-maintenance-job的 Cloud Run Job 入口 backend/modal/memory_maintenance_job.py 会把outbox_delivery_failed与cursor_persist:标记为致命错误_FATAL_ERROR_MARKERS其余错误在 Flex 停止时视为非致命避免重试整页这正对应手册restore globally, run one bounded maintenance execution with --wait, then confirm a later Scheduler execution的恢复节奏。5.1 维护任务的一次 pass 做了什么从 backend/utils/memory/canonical_short_term_maintenance_cron.py 的run_universal_short_term_maintenance可看到单次执行的完整内部顺序通过到期优先库存expiry_ordered_maintenance_uid_inventory只查未来 24h TTL 内的 lifecycle 元数据与有界注册表库存bounded_canonical_memory_uid_inventory按持久化 UID 光标分页MAX_MAINTENANCE_UIDS_PER_RUN 400到尾自动回绕合并出本轮 UID 页逐 UID 跳过无 active Short-term 的账户、recently_dreamed冷却DREAMING_MIN_INTERVAL 20h但 overflow 10 条或到期紧急可绕过与 ledger writer 模式账户依次执行 required 归一化、TTL 过期结算、consolidation 路由promote / archive / review / reject、canonical apply 提交、outbox drain仅在整页无错误时用 generation 校验CAS推进注册表光标persist_cursorFalse与完成一个 UID 才提交的设计确保 Flex 预算停止不会跳过后续账户。对应测试覆盖见 backend/tests/unit/test_canonical_short_term_maintenance_cron.py包括全局开关关闭时不解析库存test_disabled_global_switch_does_not_resolve_inventory、库存缺失 fail closedtest_missing_inventory_fails_closed_with_operational_dependency、光标推进与回绕不饿死test_registry_cursor_progresses_and_wraps_without_starvation、Flex 停止不越过当前 UIDtest_flex_deferral_stops_the_page_without_advancing_past_the_uid、失败不启动冷却test_failed_consolidation_does_not_start_dream_cooldown等。5.2 ledger drain 的独立光标与重授权backend/utils/memory/knowledge_ledger_drain.py 展示 drain 的整页提交语义run_knowledge_ledger_drain每轮经bounded_ledger_drain_inventory读取一页≤20 个 apply-control 文档按__name__排序 start_after游标对每个 UID 先做共享 JIT rollout 授权resolve_jit_rollout(uid, stageJITDecisionStage.INGRESS, force_refreshTrue)15 秒超时失败视为拒绝授权通过才执行run_ledger_migration_sweep与publish_ledger_migration_cutover任何账户级失败都不推进页面光标且仅当not summary.errors时才commit_ledger_drain_inventory。这解释了手册中页面推进仅发生在整页全部成功之后以及kill 掉的执行不会推进光标的保证。六、必需的回滚演练Required rollback rehearsal部署任何版本前都必须完成回滚演练演练需证明以下三点同时成立停止新的 canonical 处理不会隐藏历史或 canonical 数据universal reader 保持读取两种格式不会恢复 legacy writer不存在 UID 级回退通道task intelligence 不会不可用记忆权威缺失不连带影响任务智能。另外在 provider如向量库排空期间跨来源删除仍由 canonical tombstones/overrides 抑制——即删除/覆盖记录先于物理清理提交确保重试、崩溃或 provider 中断期间不会出现重复读取或复活读取backend/docs/canonical_memory_architecture.md 的 Lazy historical mutation 一节对此有完整描述先校验历史行与请求 → 以相同 public ID 写 canonical 表示 → 提交 active override 或 tombstone → best-effort 清理历史行/向量抑制记录提交先于清理。七、关键实现切面速查Primary seams运维手册聚焦操作面以下是其背后可直接查阅的实现切面来自 backend/docs/canonical_memory_architecture.md关注点代码通用服务universal servicebackend/utils/memory/memory_service.pyCanonical 适配器backend/utils/memory/canonical_memory_adapter.py历史 override 路径backend/database/memory_collections.py原子持久化backend/database/memory_apply_store.py必需处理backend/utils/memory/canonical_required_processing.py终态路由backend/utils/memory/canonical_consolidation.py计划编排backend/utils/memory/canonical_short_term_maintenance_cron.pyOutbox 投递backend/database/memory_outbox_worker.py公共 APIbackend/routers/memories.py维护任务入口backend/modal/memory_maintenance_job.pyLedger drain 入口backend/modal/knowledge_ledger_drain_job.py八、操作速查小结想停 L2 成本MEMORY_CANONICAL_CONSOLIDATION_ENABLEDfalse默认 true仅维护任务生效。想停计划性变更MEMORY_CANONICAL_MAINTENANCE_ENABLEDfalse默认 false仅memory-maintenance-job可置 true其他 surface 设置会构建失败。想全局停新摄入关闭MEMORY_ENABLED产品唯一开关或使用部署方 incident mode禁止按 UID 回退到 legacy writer。想跑 ledger cutover开发环境在只读预检与直写证明后可临时置KNOWLEDGE_LEDGER_DRAIN_ENABLEDtrue 具名 allowlist 执行一次性 drain生产 allowlist 必须为空。回滚底线universal dual-format reader 永不回退历史行物理删除必须单独审批。观测纪律只用无内容计数器与canonical_memory_decision_path.v1分类字段任何告警不得携带 UID、memory ID、embedding 或 provider 内容。以上所有开关与步骤均可在 backend/docs/runbooks/universal-memory-operations.md 及其引用的源码、运行时环境清单backend/deploy/runtime_env.yaml、backend/deploy/runtime_env/_base.yaml、dev/prod overlay中交叉验证适合直接用于 incident 排障与发布前 checklist。【免费下载链接】FriendAI that sees your screen, listens to your conversations and tells you what to do项目地址: https://gitcode.com/GitHub_Trending/fr/Friend创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表