big-AGI 的 AIX 单调版本号滚动(Roll AIX)实践指南:从命令到模型定义版本化体系
【免费下载链接】big-AGIAI suite powered by state-of-the-art models and providing advanced AI/AGI functions. Includes AI personas, AGI functions, world-class Beam multi-model chats, text-to-image, voice, response streaming, code highlighting and execution, PDF import, presets for developers, much more. Deploy on-prem or in the cloud.项目地址: https://gitcode.com/GitHub_Trending/bi/big-AGI
Monotonics.Aix是 big-AGI 用于触发全量客户端数据重新校验的单调递增版本号,其"滚动"动作通过仓库内置的 Claude Code 命令roll-aix一键完成。本文以该命令文档为主体,结合src/common/app.release.ts、src/modules/llms/版本化体系与引导期重配置源码,完整讲解 AIX 的含义、滚动步骤、前置检查,以及它与按厂商(per-vendor)模型定义版本化(LLM-defs-refresh)的分工边界——读完你既能安全执行一次 AIX 滚动,也能理解"何时该滚 AIX、何时该滚 epoch"的决策依据。
一、AIX 单调版本号是什么
在 app.release.ts 中,big-AGI 集中维护着一组"单调计数器":
// this is here to trigger revalidation of data, e.g. models refresh Monotonics: { Aix: 92, NewsVersion: 210, },Monotonics.Aix:当前值为92,是 AIX(AI eXperience / 协议能力层)的单调版本号。每次滚动加 1,会强制刷新每一个客户端上的每一个 LLM 服务商。Monotonics.NewsVersion:用于新闻/公告数据的重新校验,与 AIX 相互独立。
按 roll-aix.md 的说明,AIX 滚动属于"协议级变更"(protocol-level change)的保留动作:Aix被折叠进每个服务商的模型定义版本(见下文llmsDefsVersionFor),因此滚一次 AIX 等价于对全量客户端广播"所有定义已更新"。
二、什么时候该滚 AIX,什么时候不该滚
这是理解该命令的核心边界,原文档给出了明确的决策规则:
- 需要滚 AIX:发生了协议级(protocol-level)变更,需要让所有客户端、所有服务商重新校验并刷新。
- 不再需要为模型定义更新滚 AIX:模型定义更新已改为按厂商自动滚动(详见 kb/modules/LLM-defs-refresh.md),每个厂商有独立的版本,客户端只在对应厂商定义变化时单独刷新,无需全局滚动。
- 只想强制滚动单个厂商:在 llms.defs.manifest.ts 中 bump 该厂商的
epoch字段;_shared.epoch则用于强制滚动所有厂商。 - AIX 滚动必须保留给协议级变更:不要把它当成模型列表更新的日常手段。
从源码上看,这一"折叠"关系由 llm.client.defs.ts 的llmsDefsVersionFor实现:
export function llmsDefsVersionFor(vendorId: ModelVendorId, serviceSetup: Record<string, any> | undefined): string { const bucket = (vendorId === 'openai' && !llmsIsNativeOpenAIHost(serviceSetup?.oaiHost || undefined)) ? '_openaiCompat' : vendorId; return `${LLMS_DEFS_VERSIONS[bucket]}-a${Release.Monotonics.Aix}`; }即每个服务的有效版本 =内容哈希版本 + "-a" + Monotonics.Aix。因此无论内容哈希是否变化,Aix一旦 +1,所有服务的版本字符串都会变化,从而全部进入刷新队列——这正是"AIX 滚动刷新所有厂商"的底层机制。
三、执行 Roll AIX 的标准操作流程
roll-aix.md是仓库内置的 Claude Code 命令(位于 .claude/commands/aix/roll-aix.md),被声明为disable-model-invocation: true,即仅允许显式调用,且约束了工具权限(仅Bash(git add:*)、Bash(git status:*)、Bash(git commit:*)、Edit、Write)与模型档位(model: sonnet)。完整流程如下:
1. 前置检查(MUST pass or abort,不满足必须中止)
# 检查 1:必须位于 main 分支 git branch --show-current # 检查 2:目标文件必须无本地改动 git status src/common/app.release.ts- 若当前不在
main分支,中止; - 若
src/common/app.release.ts存在未提交改动,中止(防止把无关改动混入本次提交,也保证"只改一行"的提交是干净的)。
2. 执行滚动
- 读取 app.release.ts 中当前的
Monotonics.Aix值(示例中为92); - 将其递增 1(示例中改为
93); - 只更新那一行,不得顺带改动文件内其他内容;
- 提交:
git add src/common/app.release.ts && git commit -m "Roll AIX"3. 确认
提交完成后,重新读取Monotonics.Aix,向调用方确认新版本号。
为什么前置检查如此严格
从 app.release.ts 的头部注释可以看到,该文件"同时被前端与后端引入,取决于构建时刻,两端的值可能不同",是所有版本信息(TenantSlug、Features、TechLevels、AiFunctions、buildInfo等)的集中配置面。它被前端 bundle 与后端共同读取,任何无关改动混入 AIX 提交,都可能造成构建期不一致的版本信息。因此"只改一行 + 干净提交"是硬性纪律。
四、按厂商模型定义版本化:AIX 的"分工伙伴"
为了让读者理解"为什么模型定义更新不再需要滚 AIX",这里展开 LLM-defs-refresh.md 描述的核心机制——它与 AIX 滚动共同构成 big-AGI 的版本刷新体系:
| 文件 | 角色 |
|---|---|
| llms.defs.manifest.ts | 手维护的清单:声明每个厂商的定义文件归属。satisfies Record<ModelVendorId, ...>让新增/删除厂商在清单与生成映射未同步时直接编译报错 |
| generate-llms-defs.mjs | 生成器:对声明文件做语义哈希、执行完整性门禁、写出映射;支持--check只算不写 |
| llms.defs.versions.ts | 生成并提交的映射:每个 bucket 一个 12 位十六进制版本(如openai: '970f492bca59') |
| llm.client.defs.ts | llmsDefsVersionFor(vendorId, setup):服务对比使用的有效版本(折叠 AIX,含自定义主机 OpenAI 特例) |
| reconfigureBackendModels.ts | 引导期选择性刷新:逐一比对服务戳记与版本,只重列不匹配者 |
| package.json | predev/predev-debug/prebuild串联生成器;完整性失败即构建失败 |
版本如何推导(什么会滚、什么不会滚)
每个被声明的文件都会经过ts.transpileModule归一化(删除注释、擦除类型、统一 LF 换行)再做 sha256 哈希;一个 bucket 的版本对其文件加epoch做哈希,且每个非_sharedbucket 都会把_shared的摘要折叠进来。运行期再追加-a<Monotonics.Aix>(即上文llmsDefsVersionFor的实现)。
- 会滚动:模型表、标签、定价、zod wiretype schema、过滤/排序/变体代码、共享映射等任何"运行时语义"变化;
- 不会滚动:注释、JSDoc、格式、空白、纯类型编辑(interface、注解、
import type);局部变量重命名会滚(可接受的误报:代价仅是一次多余重列); - 官方强制滚动手段:bump 厂商
epoch(滚单厂商)或_shared.epoch(滚全部);SCHEME_REV在哈希方案变化时强制滚动所有 bucket; - 确定性:哈希是"源码 + 锁定的 typescript 版本"的纯函数,任意机器都能逐位复现提交的映射。
启动期刷新流程
ProviderBootstrapLogic→ sherpa →reconfigureBackendModels,每会话一次,在 capabilities 提供者确认前后端构建匹配之后执行(reconfigureBackendModels.ts):
- 为后端配置的厂商幂等创建服务(
hasLlm*能力标志); - 服务在"刚创建"或"其
defsV戳记与llmsDefsVersionFor(vId, setup)不一致"时刷新;未知厂商(来自更新版本 App 的数据)保持不变; - 失配服务通过一个小型并发池(4 个在途)重列;戳记在每次尝试之前写入,因此离线 Ollama、失效 LocalAI、吊销的 key 不会每次启动都被重试,而是等版本滚动或手动刷新;
- 若有任何刷新:LLMs 按服务顺序重新排序,并运行领域自动分配。
值得注意的行为差异:API key 轮换不再触发刷新(旧哈希包含 env 值,但定义并未变化);刷新从"全有或全无"变成"按服务"(同一厂商的所有实例一起刷新)。
五、实操:从命令行验证 AIX 与版本体系
验证当前 AIX 值并确认生成映射是否过期:
# 查看当前 AIX 值(期望 92) grep -n "Aix" src/common/app.release.ts # 只校验(不写入)生成映射是否过期;过期时退出码为 2 node tools/develop/gen-llms-defs/generate-llms-defs.mjs --check对一次标准 Roll AIX,最终形态应是一行 diff 与一条Roll AIX提交:
git diff HEAD~1 -- src/common/app.release.ts # 期望输出形如:- Aix: 92, / + Aix: 93, git log --oneline -1 # Roll AIX发布侧注意事项(来自 LLM-defs-refresh.md 的部署说明):Vercel 与 Docker 构建走npm run build,prebuild会自动再生成映射,因此即使提交的生成文件滞后,部署产物也始终携带与编译定义一致的哈希;next start不会运行生成器(Docker 运行阶段已被裁剪)。静态导出与无 key 构建不受影响。
六、小结:Roll AIX 决策速查
| 场景 | 手段 |
|---|---|
| 协议级变更,需要全量客户端刷新所有厂商 | 执行 Roll AIX(Monotonics.Aix+1) |
| 单个厂商模型定义变更 | 正常合入对应*.models.ts,版本自动滚动,无需干预 |
| 强制滚动单个厂商(注释/类型改动也想滚) | bump 该厂商epoch |
| 强制滚动所有厂商 | bump_shared.epoch |
| 哈希方案本身变化 | 提升生成器SCHEME_REV |
在 big-AGI 的工程实践中,Roll AIX从"高频日常操作"被收敛为"协议级保留动作",日常模型更新由按厂商哈希版本自动完成。理解二者的分工,既能避免滥用全局刷新,也能在真正需要协议级失效时,用一条命令、一行 diff、一次干净提交,安全地完成全局版本推进。
【免费下载链接】big-AGIAI suite powered by state-of-the-art models and providing advanced AI/AGI functions. Includes AI personas, AGI functions, world-class Beam multi-model chats, text-to-image, voice, response streaming, code highlighting and execution, PDF import, presets for developers, much more. Deploy on-prem or in the cloud.项目地址: https://gitcode.com/GitHub_Trending/bi/big-AGI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考