gbrain 嵌入迁移完全指南:用gbrain migrate embeddings安全切换 Embedding 供应商
【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain
导读
gbrain migrate embeddings是 gbrain 将整个大脑(brain)重新嵌入到另一个 embedding 供应商/模型的官方正向迁移路径,它安全、可中断续跑,并同时处理 schema 维度切换、reranker 联动、查询缓存与锁。本文以该命令为核心,完整讲解它的规划、执行、恢复、状态检查与自托管替代方案,并深入其命令编排层与核心原语实现,帮助你在一家托管 API 停止服务(如 ZeroEntropy 于 2026-09-04 关停)时,用一条命令把语义检索完整迁移到新供应商。
一、命令是什么:一次迁移,解决的不只是换模型
gbrain migrate embeddings --to <provider:model>会把整颗大脑重新嵌入到任意已配置的 embedding 供应商/模型上。它虽然是为"供应商下线"场景设计的正向迁移路径(例如 ZeroEntropy 的托管 API 在 2026-09-04 关停,且它至今仍是那些从未显式选择过模型的存量大脑的无配置运行时回退项;新安装默认voyage:voyage-4),但与具体供应商无关:任何配置好的provider:model都可以作为迁移目标。
该命令同时可通过别名gbrain retrieval-upgrade访问——这是gbrain doctor修复提示与 README 指向的别名。
快速上手
# 预览工作量与费用,不做任何改动 gbrain migrate embeddings --to voyage:voyage-4 --dim 1024 --dry-run # 正式执行(交互式确认会先显示 chunk 数量与美元估算) gbrain migrate embeddings --to voyage:voyage-4 --dim 1024 # 非交互(cron / 脚本):必须带 --yes,否则退出码 2 gbrain migrate embeddings --to voyage:voyage-4 --dim 1024 --yes--dim <N>覆盖目标宽度:默认取供应商配方(recipe)声明的宽度;对于未声明宽度的配方(litellm、llama-server 等自带模型供应商)则必须显式传入。
对已宣布关停的供应商做目标会被拒绝(花真金白银重嵌入到一个濒死 API 会让大脑搁浅)。如果你在provider_base_urls覆盖后自托管了一个线协议兼容的端点,--force-sunset-target是显式的逃生舱口。
从命令层源码看(src/commands/migrate-embeddings.ts),该文件是编排器(planMigrationFlow+executeMigrationFlow),所有重量级原语都在 src/core/embedding-migration.ts,并被migrate_embeddings管理操作、doctor 与--status共享(详见 src/core/ops/embedding-migration.ts)。
完整参数一览
| 参数 | 说明 | 默认值/约束 |
|---|---|---|
--to <provider:model> | 目标嵌入模型,如openai:text-embedding-3-small | 必填 |
--dim <N> | 目标维度 | 默认取供应商配方声明宽度;配方未声明时必填 |
--dry-run | 只输出计划与费用估算,不改任何东西 | 无 |
--yes | 跳过确认提示(非交互环境必填) | 等价于--non-interactive |
--json | stdout 输出机器可读信封;人类可读计划走 stderr | 无 |
--no-embed | 只做 schema + 配置 + 失效标记,跳过重嵌入 | 之后需自己跑gbrain embed --stale --include-null-signature |
--batch-size <N> | 重嵌入的过期 chunk 批大小 | 默认 2000,上限 10000(源码见parseMigrateEmbeddingsFlags) |
--pace[=mode] | 重嵌入阶段的数据库争用节流(off/gentle/balanced/aggressive) | 无 |
--ignore-env-override | 即使GBRAIN_EMBEDDING_*环境变量与目标冲突也继续 | 无 |
--force-sunset-target | 允许迁移到已宣布关停的供应商(如自托管线兼容端点) | 无 |
--retarget | 放弃另一个进行中的迁移目标并启动本次迁移 | 被放弃目标会记入 marker 历史 |
--reranker <v> | 联动动作:auto(默认)/off/keep/ 显式provider:model | auto |
--status | 只读状态:各配置平面、列宽、NULL 普查、签名普查、in-flight marker 与恢复命令、上次完成记录与冒烟检查结果 | 只读、零花费 |
推荐目标
voyage:voyage-4 --dim 1024(新安装默认):一个VOYAGE_API_KEY同时覆盖嵌入、rerank-2.5重排器与多模态模型;voyage-4 系列共享同一嵌入空间,因此之后无需重索引即可把查询模型指向voyage-4-large或voyage-4-lite。注意:1280 不是合法的 Voyage 宽度(合法值:256/512/1024/2048),所以旧的 1280 维大脑会做一次性 schema/HNSW 索引重建到 1024——命令会自动处理,且被杀死后可以续跑。openai:text-embedding-3-small --dim 1280(保持宽度的替代方案):OpenAI 的 text-embedding-3 系列支持弹性维度,因此 1280 维大脑可以保留原列(无需 schema 重建)。但 OpenAI 密钥不覆盖重排器。
目标 API Key 的设置方式:export VOYAGE_API_KEY=...、gbrain config set voyage_api_key ...(API Key 会被路由到文件平面,供应商管线从那里读取),或直接编辑~/.gbrain/config.json。
选择--dim的黄金法则:当目标支持时,选用大脑当前列的实际宽度。不同宽度会触发破坏性的 schema 迁移(三张维度钉扎表全部重建列 + 索引);相同宽度则完全跳过。gbrain doctor的provider_sunset检查(针对有已宣布关停的供应商)会打印目标感知、可直接粘贴的命令——Voyage 使用其合法 1024 宽度,OpenAI 使用你的实际宽度(若该宽度在那边合法)的保宽替代命令——而且它读取的是真实的vector(N)列,不是可能漂移的配置值。
二、受影响大脑如何获知(供应商下线场景)
以下三个界面会标记那些 embedding 模型、重排器或自定义 embedding 列位于已宣布托管 API 关停的供应商(如 ZeroEntropy 2026-09-04)的大脑:
gbrain doctor:provider_sunset检查在每次运行时都告警,直到大脑离开该供应商。关停日期之后,仅当死供应商上确实存在已嵌入的向量(检索真正不可用)时才升级为fail;零向量大脑的配置只是解析到死默认值则保持warn——这样 doctor-as-CI-gate 的部署不会在该日期开始以退出码 1 失败。重排器一侧通过与实际重排所用相同的平面解析(模式包 +search.reranker.*覆盖),ZE 支撑的自定义embedding_columns条目也会被标记。消息携带目标感知的粘贴式迁移命令。若接受风险:gbrain config set doctor.suppress_provider_sunset true可静默。gbrain upgrade:一次性横幅(由ze_sunset_notice_shown门控),给出同样的两个修复方案,外加每个大脑的阶段二横幅。v0_46_3版本迁移(经gbrain upgrade/gbrain apply-migrations运行)——只检测和通知:检查宿主大脑的暴露面(embedding、reranker、自定义列),打印 ACTION REQUIRED 块,并把指向skills/migrations/v0.46.3.0.md的 agent 行动项归档到~/.gbrain/migrations/pending-host-work.jsonl(该技能文件在仓库中的位置见 skills/migrations/v0.46.3.0.md)。它从不改配置,也从不替你花钱。
三者都会完整陈述后果:关停后,存量向量变得不可查询——查询嵌入与摄取使用同一端点——不只是新内容。
从实现看,doctor 的provider_sunset与embedding_migration_state检查都复用同一套迁移原语,保证"告知"与"执行"对状态的判断完全一致(见 src/core/embedding-migration.ts 中的readMigrationState、verifyMigrationComplete等)。
三、执行流程:逐步做什么
命令按以下顺序执行(与 src/commands/migrate-embeddings.ts 中executeMigrationFlow的注释顺序一一对应):
1. 规划(Plan)
统计所有尚未处于目标嵌入空间的 chunk——包括那些页面没有记录嵌入签名的 chunk(这些页面的 chunk 是未打来源戳嵌入的)。根据定价表估算重嵌入费用;未知供应商打印 "estimate unavailable" 而不是编造一个数字。
计划输出会揭示一些数据库真实情况(以下字段均来自EmbeddingMigrationPlan,见 src/core/embedding-migration.ts):
- Page signatures:页面上实际盖的签名普查(env 变量可以谎报 From,普查不能);
- False stamps:被错误盖上目标签名、但 chunk 实际由其他模型嵌入的 chunk——运行时会清除这些戳并重嵌入(chunk 模型是事实来源,而非页面戳);
- Context tier:当前以
per_chunk_synopsis层嵌入的页面会降级为 TITLE 层重嵌入(已知质量降级,分层保持的重嵌入是已记录的后续工作); - 并发写者警告:检测到活跃 minion worker 或等待/运行中的 embed 作业时给出提示(它们的写会被最终普查计为过期并重嵌入,导致二次付费)。
2. 同意门(Consent gate)
打印计划;要求交互式y或--yes。非 TTY 环境无--yes时以退出码 2 拒绝(与 docs/operations/spend-controls.md 中的reindex-code门一致)。与那里的纯费用门不同,spend.posture=tokenmax不会绕过此门:posture 只豁免费用上限,而此门还守卫破坏性 schema 重建。在tokenmax下美元数字被标记为仅供参考,确认仍会被询问。--yes是唯一的脚本化绕过。
3. 实时探测(Live probe)
在任何变更之前,对目标供应商做一次微型嵌入——一次调用同时验证 API Key、模型 id 与维度支持。坏 Key 在这里失败,什么都不会被改动。源码实现见probeTargetProvider:如果返回的向量维度与--dim不符,直接以"Target provider returned X-dim vectors, expected Y"拒绝(src/commands/migrate-embeddings.ts)。
4. 环境变量覆盖门(Env-override gate)
当GBRAIN_EMBEDDING_MODEL/GBRAIN_EMBEDDING_DIMENSIONS被设置且与目标不一致时,正式运行会拒绝(配置说新 / 运行时嵌入旧的会静默地把一颗大脑劈成两个嵌入空间);--ignore-env-override用于有意的实验。当它们与目标一致时,运行在响亮提示下继续(env-first 部署是合法的;请在 gbrain 运行的每个地方保持 env 同步)。
这个门源自一次真实事故:v0.41.2.1 的 env-override 安全门就是为 PR #1421 的 71.6 万 chunk 损坏事故而建——那次ze-switch写了 DB 配置,但 env 覆盖在嵌入时静默保持旧模型活跃,schema 已迁到 2560 维而嵌入仍产出 1536 维向量。detectEnvOverride是process.env的纯读取(见 src/core/embedding-migration.ts),formatEnvOverrideWarning渲染 ASCII 框警告并给出unset命令。
关键:没有任何承载性逻辑信任 env——"nothing to migrate" 的判定验证的是数据库(列宽、NULL 普查、签名普查、未合并的文件平面),所以预置的 env 变量无法伪造一次已完成的迁移。
5. 应用(Apply)
当目标宽度与实际列宽不同时,在一个事务内执行由embedding-migration.ts拥有的原子 schema 迁移。它重建全部三张维度钉扎的文本嵌入空间列——content_chunks.embedding、query_cache.embedding、facts.embedding——到新宽度,保留每列的类型(vectorvshalfvec)并重建其 HNSW 索引。
三列缺一即静默损坏:窄的query_cache.embedding会让每次缓存写入与读取按设计失败(缓存吞错,永不破坏搜索)从而永久 0% 命中率;窄的facts.embedding会让每次按事实的嵌入写入失败。图像/多模态列被刻意不动——它们使用独立于文本嵌入模型的模型,维度与之无关(源码注释明确记载了这个 v0.41 修复:此前切换文本嵌入会顺带把embedding_image从 1024 维改到 1280 维,使 voyage-multimodal-3 无法写入)。
应用步骤还做三件事:
- 把
embedding_model+embedding_dimensions写入两个配置平面(文件平面给运行时网关、DB 平面给 doctor); - 使仍处于旧空间的所有 chunk 失效——包括 NULL 签名页面;
- 清空语义查询缓存,防止切换后仍被陈旧缓存结果命中。
两处源码级细节值得注意:
- 索引依赖重放(#4252):
DROP COLUMN会级联删除依赖该列的所有索引——包括embed --stale依赖的embedding IS NULL部分 btree 索引(迁移 v66 的idx_chunks_embedding_null、v103 的content_chunks_stale_idx)。runSchemaTransition通过pg_depend捕获将被级联删除的每一份索引定义,重建后重放;CREATE INDEX IF NOT EXISTS让操作在--resume期间可安全重跑(src/core/embedding-migration.ts)。 - HNSW 维度上限:pgvector 的 HNSW 索引上限 2000 维;对合法的 2048 维目标(如 Voyage 4 Large),跳过索引、依赖精确扫描(搜索只会变慢,不会坏)。策略单一来源在
vector-index.ts的hnswIndexExpected。
6. 重嵌入(Re-embed)
标准嵌入管线(embed --stale --catch-up),带每来源单飞锁、限速退避、stderr 进度,以及可选的数据库争用节流(--pace[=mode])。重嵌入在已持有的锁(heldLocks)下运行并用心跳续期,锁丢失即中止。
四、重建会删除什么
维度变更会删除大脑中存储的每一个嵌入向量——它们位于旧模型的空间、无法使用,且不可恢复:回到旧供应商意味着为第二次全量重嵌入再付一次钱。content_chunks向量由重嵌入趟次重建,查询缓存在下次查询时重新填充,事实嵌入在下一次写入(或gbrain extract趟次)时重写。
由于 HNSW 上界策略与索引重放在同一事务内处理,中途失败会整体回滚,不会出现"列已改、索引没了"的中间态。
五、被杀死后如何续跑
NULL 嵌入列就是检查点。如果运行被杀死(或部分页面嵌入失败),重跑同一条命令:已在目标上嵌入的 chunk 永不重嵌入,schema/配置步骤空转,运行从停止处继续。
一个进行中的标记(DB 配置中的embedding_migration.state)记录目标;只有当积压排空到零时才清除。进行中若用不同的--to目标重跑会被拒绝,并指出两个选项:原目标的精确续跑命令,或带--retarget的同命令以有意放弃(marker 在历史中记录被取代的目标)。marker v2 还会在相同目标续跑时保留started_at(--status与 doctor 报告的是迁移的真实年龄,而非最新一次重试),并记录force_sunset_target(续跑命令也必须带它)——见MigrationState与renderResumeCommand(src/core/embedding-migration.ts)。
硬杀(SIGKILL、崩溃、断电——不是 Ctrl-C)后的一个坑:运行的每来源单飞嵌入锁会遗留,立即重跑会跳过重嵌入并报告迁移暂停。命令会明确说明(--json中的lock_skipped);锁最多 60 分钟后自行过期,届时同命令重跑即正常续跑。源码中incomplete分支对lock_skipped有专门的措辞:"re-run to resume" 在锁过期前是谎言,所以它如实说明(src/commands/migrate-embeddings.ts)。
横跨两个过期批次的页面:其 chunk 被正确嵌入,但嵌入循环不会盖戳(嵌入循环按批全有或全无地盖章),因此迁移在排空后运行一趟调和(reconcile)趟次,给每个完全嵌入的页面盖戳。没有它,大型大脑会报告 "incomplete",重跑会为这些页面再付一次钱。--batch-size N可调批次(默认 2000)。
--no-embed只应用 schema + 配置 + 失效后停止,让你稍后或后台运行(可能很长的)重嵌入:
gbrain migrate embeddings --to openai:text-embedding-3-small --yes --no-embed gbrain embed --stale --catch-up --include-null-signature --background六、迁移期间与迁移后的运行状态
迁移期间
重嵌入运行期间,语义搜索对尚未重嵌入的内容返回**降级(仅词法臂)**结果。大脑袋请选安静窗口,或用--pace保持数据库响应。
完成后的冒烟检查
排空到零后,命令执行一次自检索冒烟检查(verifySearchRoundTrip,3 个样本)——注意源码措辞:这是冒烟检查(self-retrieval),不是召回率评估,BrainBench 才负责检索质量。结果(pass/warn/skipped 及其原因码)被写入完成标记,--status之后可直接读取,无需再次花费实时探测费用。warn不会阻塞迁移完成,但会列出未命中的页面与原因码供调查。
七、无嵌入签名的页面
嵌入时未打来源戳的页面embedding_signature IS NULL,会被例行的过期清扫(stale sweep)豁免(因此升级永远不会意外地全量重嵌入语料库)。但在供应商切换后,这个豁免条款会静默地把这些页面留在旧嵌入空间——同一索引内混合向量空间,检索质量下降且日志无痕。
gbrain migrate embeddings总是包含它们。- 普通
gbrain embed --stale在模型切换留下 NULL 签名页面时会告警,gbrain embed --stale --include-null-signature会重嵌入它们。
相关实现散布在embedding-invalidation.ts(守卫式过期签名失效、假目标戳计数与清除)与迁移计划(null_signature_chunks计入工作量并纳入chunks_to_embed)中。
八、Reranker 联动
迁移在同一次运行中处理重排器(--reranker auto为默认):当活跃重排器——经模式包解析,所以常见的无显式配置情况也计入——在离开的供应商或关停供应商上,且目标供应商提供重排器时,运行先实时探测,再在同一同意门下切换search.reranker.model(配置写入 + 查询缓存清除在一个事务内)。覆盖项:
--reranker off # 直接禁用重排 --reranker keep # 保持原样 --reranker voyage:rerank-2.5 # 显式模型(运行任何动作前先验证)目标供应商没有重排器(如 OpenAI)时,运行打印带精确命令的 ACTION 行,而不是静默启用第三方供应商:gbrain config set search.reranker.model voyage:rerank-2.5(需VOYAGE_API_KEY)或gbrain config set search.reranker.enabled false。
重排器探测失败会保留原配置并报告为switch_failed——永不静默、永不让迁移致命。源码层面,probeTargetReranker在配置写入前做一次实时重排调用(8 秒超时):嵌入迁移绝不能启用一个答不了话的重排器,否则每次搜索都会付出 fail-open 超时(src/commands/migrate-embeddings.ts)。
平面不对称性值得记住:embedding 配置在文件/env 平面(它决定 schema 尺寸,必须在引擎连接间稳定——绝不要gbrain config set embedding_model);reranker 配置在 DB 平面(gbrain config set search.reranker.*正确)。迁移把两者各写各的正确平面;你只需在手工操作时知道这点。
九、状态检查(只读、零花费)
gbrain migrate embeddings --status [--json]报告每个配置平面(env 存在性、文件、DB——API Key 只显示存在布尔值)、实际列宽(包括facts/query_cache)、NULL 与无 chunk 普查、页面签名普查、带精确续跑命令的 in-flight marker,以及上次完成记录(含其冒烟检查结果)。它是事故中途的"我在哪?"界面;gbrain doctor的embedding_migration_state检查在每次 doctor 运行时呈现同一 marker。
--json输出的结构化字段(源码可见)包括:identity(引擎 + 经脱敏的数据库目标,绝不打印裸连接串)、env、keys(四个供应商 Key 的存在布尔)、file_plane、db_plane、column_dims、pinned_widths、各普查计数、marker(live/corrupt/none)与resume_command。
十、自定义嵌入列
自定义embedding_columns条目没有自动化出口:migrate embeddings只覆盖主列。需要在新的供应商上重新声明每个自定义列的配置并重嵌入其内容,或删除列配置。计划输出在配置了非默认search_embedding_column时也会告警:本次迁移只重建默认的embedding列,读取路径仍在使用那个自定义列。
十一、自托管而非迁移
如果离开的模型权重可用(zembed-1 是 Apache-2.0),自托管可以保留现有向量——完全无需重嵌入——但仅当嵌入签名不变化时:保持相同的模型 id(zeroentropyai:zembed-1),用gbrain config set provider_base_urls.zeroentropyai <url>把其 base URL 指向你的端点。
两个诚实的限制:
- 端点必须说ZeroEntropy 的线协议方言(
/models/embed、{results: [...]}响应)——模型 id 走 ZE 专用的兼容 fetch,因此通用的 OpenAI 兼容 llama-server 或 Ollama 端点不工作,除非前面有兼容代理。 - 该路径只在
zeroentropyai配方被删除前有效(计划于 2026 年 9 月版本)。若依赖此路径,请跟进 TODOS.md 中的自托管连续性条目。
切换供应商 id(如llama-server:zembed-1)会改变pages.embedding_signature,下一次过期嵌入趟次会重嵌入一切——那是全量重嵌入,不是零成本迁移。注意gbrain migrate embeddings默认拒绝--to zeroentropyai:*(保护大家不把钱再投到垂死的托管 API 上);base-URL 覆盖就位后传--force-sunset-target才能继续。
十二、验证与收尾
# 信任数据库,不信任 env gbrain migrate embeddings --status # 关停检查转绿 gbrain doctor --json | jq '.checks[] | select(.name=="provider_sunset") | .status' # → "ok" # 冒烟:搜一条你确定大脑里有的内容 gbrain search "anything you know is in the brain"收敛的样子:列处于目标宽度、0 个 chunk 缺失、签名普查全部落在目标上、无进行中的迁移。事实(facts)向量会在下一次写入 /gbrain extract趟次时再生——--status显示的 pending 数量不是故障。
然后把手动归档的0.46.3行动项在~/.gbrain/migrations/pending-host-work.jsonl中标记为"status": "done"(目前无 CLI,已登记后续工作)。
退出码约定:0= 完成(或已验证无事可做);1= 未完成 / 拒绝 / 失败(消息说明原因);2= 非 TTY 且无--yes。故障排查速查表见 skills/migrations/v0.46.3.0.md 的 Recovery 一节:被杀死就重跑同命令、lock_skipped等 60 分钟锁过期、refused: a migration to X is still in flight就续跑 X 或带--retarget有意放弃、首趟--dim错了就带正确值重跑(错误宽度向量不可用,这笔重付费不可避免)。
十三、底层手册附录:手动切换维度(gbrain migrate embeddings之外的路径)
作为"使用命令而非配方"的对照,docs/embedding-migrations.md 保留了一套手动配方,供异常场景使用(也是维度不匹配错误信息所指向的附录):
- 同维度模型互换(自动):同维度切换不需要
ALTER/清空配方。gbrain 会在页面 chunk 嵌入时盖上嵌入来源签名(<provider:model>:<dims>);指向新模型后签名不一致,gbrain embed --stale会重访这些页面。已匹配目标模型、当前文本哈希与向量宽度的 chunk 保留嵌入。维度变化仍需清空重建或列变更配方。 - 为什么不做自动:需依次完成——丢弃 HNSW 索引(pgvector 无法在
ALTER COLUMN TYPE下存活)、清空所有旧向量(跨维度拒绝 cast,必须先清)、变更列类型(仅 Postgres;PGLite 不行)、全量重嵌入(50K 页面大脑可能数小时,API 费用 $1–100)、按维度上限条件重建索引。这是刻意、昂贵的操作。 - PGLite(默认安装):无法
ALTER COLUMN TYPE vector(N)(pgvector 以 WASM 嵌入,could not access file "$libdir/vector")。可用一键包装gbrain reinit-pglite --embedding-model voyage:voyage-4 --embedding-dimensions 1024(备份到.bak、用新标志重跑gbrain init、重同步大脑仓库;--no-sync跳过重同步、--yes跳过 TTY 确认、--json结构化输出),或手工四步:备份 pglite 文件 →gbrain init --pglite重初始化 →gbrain sync重导入 →gbrain embed --stale重嵌入。 - Postgres(Supabase / 自托管):支持原地列变更。先
DROP INDEX IF EXISTS idx_chunks_embedding,再先清空UPDATE content_chunks SET embedding = NULL, embedded_at = NULL(必须在列变更前:pgvector 拒绝跨维度 cast,仍含旧宽度向量的列会让事务中止;NULL 可以 cast),再ALTER TABLE ... TYPE vector(<NEW_DIMS>),最后仅当dims <= 2000时重建 HNSW(2048 维 Voyage 4 Large 跳过、依赖精确扫描)。随后gbrain init --supabase --embedding-model ... --embedding-dimensions ...并gbrain embed --stale。 gbrain config set的边界:config set embedding_model X无法切换模型——它写 DB 平面,而嵌入网关读文件平面(~/.gbrain/config.json),那样写对嵌入管线是空操作。因此gbrain config set embedding_model与embedding_dimensions会拒绝并打印清空重建配方。- 验证:
gbrain doctor --fast应全绿,embedding_width_consistency检查通过:✓ embedding_width_consistency dim parity: config 1280 / column vector(1280)。
小结
gbrain migrate embeddings把"换 embedding 供应商"从一段危险的手工 SQL 与配置舞蹈,压缩成一条可预览、可同意、可探测、可恢复、可验证的命令。无论你是因 ZeroEntropy 关停被迫离开,还是主动想迁移到voyage:voyage-4或保宽的 OpenAI 方案,其执行顺序(规划 → 同意 → 实时探测 → env 门 → 原子 schema 迁移 → 重嵌入 → 调和 → 冒烟检查)都确保:任何失败点都可安全重跑同命令,数据库而非配置是"完成"的唯一裁判。结合--status的只读体检与 doctor 的双检查面,你可以把这次迁移当作一次可观测、可审计的日常运维操作,而不是一次赌博。
【免费下载链接】gbrainGarry's Opinionated OpenClaw/Hermes Agent Brain项目地址: https://gitcode.com/gh_mirrors/gb/gbrain
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考