Provider 与 Model 注册表系统:Cherry Studio 预设数据加载、归一化、播种与合并机制全解析

发布时间:2026/9/20 14:33:29
Provider 与 Model 注册表系统:Cherry Studio 预设数据加载、归一化、播种与合并机制全解析 人工智能大模型AI 应用交互助手本地部署【免费下载链接】cherry-studio Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端项目地址https://gitcode.com/CherryHQ/cherry-studio点击查看免费下载导读Cherry Studio 的 Provider 与 Model 数据采用预设注册表 用户增量的双层架构内置的cherrystudio/provider-registry包维护一套权威的预设目录能力、价格、模态、端点等启动时仅播种身份与认证骨架运行时将所有连接配置与模型元数据实时合并用户增量。本文以 docs/references/provider-model/provider-registry.md 为骨架结合 packages/provider-registry 包与 ProviderRegistryService.ts 等源码系统讲解注册表的三份 JSON 数据、RegistryLoader的索引与 TTL 缓存、模型 ID 归一化管线、三层合并函数、数据库表结构与零数据迁移的增量设计帮助读者理解预设数据如何在不冻结快照的前提下持续演进以及如何安全地为注册表新增字段。架构总览一份注册表包两处消费入口整个体系由两部分组成cherrystudio/provider-registry包packages/provider-registry纯数据与纯函数层负责注册表 JSON 的定义、校验Zod、加载RegistryLoader与查询索引化的纯函数。它不依赖 Node.js 的fsregistry-utils.ts明确注释Safe to import from browser/renderer contexts。主进程数据服务src/main/data负责把注册表数据播种进 SQLite、处理用户 CRUD并在每次读取时把注册表基线 用户增量合并成运行时对象。注册表包内部结构packages/provider-registry/ ├── data/ │ ├── models.json 预设模型能力、价格、模态、参数支持... │ ├── providers.json 预设提供商端点、apiFeatures、元数据 │ └── provider-models.json 按提供商定制的模型覆盖per-provider tweaks ├── src/ │ ├── registry-loader.ts RegistryLoader加载、校验、缓存、建索引、空闲 TTL │ ├── registry-utils.ts 纯函数lookupRegistryModel、buildPersistedEndpointConfigs、inferAdapterFamily │ ├── utils/normalize.ts normalizeModelId 及各类辅助聚合商前缀、变体后缀、参数规模... │ └── schemas/ Zod 校验 schemamodel/provider/provider-models/forwardCompat/enums... └── docs/ └── reasoning-control.md 推理格式的 schema、优先级与 UI→请求数据流主进程消费端src/main/data/ ├── db/seeding/ │ └── seeders/presetProviderSeeder.ts ISeeder仅插入的提供商身份/认证骨架播种 ├── services/ │ ├── ProviderRegistryService.ts 注册表查询与提供商/模型基线解析 │ ├── ModelService.ts 模型 CRUD 与用户增量叠加 │ └── ProviderService.ts 提供商 CRUD 与读取期合并 └── api/handlers/ ├── models.ts 模型 CRUD、对账、注册表解析路由 └── providers.ts 提供商 CRUD 与预设投影路由值得强调的是原文档刻意不在架构文档里重复目录条目数量因为 JSON 文件本身才是唯一事实来源source of truth其规模随发布独立变化。数据流三条主线1. 启动预设提供商播种仅插入数据库初始化时DbService.onInit()触发SeedRunner.runAll(seeders)其中PresetProviderSeeder只做一件事——把注册表里还不存在的提供商身份行插入user_providerDbService.onInit() → SeedRunner.runAll(seeders) → PresetProviderSeeder.run(db) → RegistryLoader.loadProviders() // 读取 providers.json → SELECT 已有 provider ID来自 user_provider → 仅 INSERT 新提供商的 identity/auth 行 → 绝不物化注册表拥有的连接配置关键设计见 presetProviderSeeder.ts 的头部注释与实现种子行是增量行DELTA rowendpointConfigs、defaultChatEndpoint这类注册表拥有的连接配置不会被持久化而是在每次读取时从注册表实时解析源码注释引用了 issue #17096。因此注册表更新无需对账即可到达既有安装。只播种用户可编辑的脚手架身份providerId、预设归属presetProviderId、显示名name以及必需的认证外壳authConfig。toDbRow中presetProviderId ?? p.id处理了别名/分组预设如zai→zhipu。SeedRunner在providers.json版本变化时重跑该 seeder但由于已有行跳过它保持幂等与仅插入语义。特殊认证外壳getSeedAuthConfig只为三个复用他人端点协议的提供商注入认证类型——vertexai用iam-gcp、azure-openai用iam-azure、aws-bedrock用iam-aws其余返回null。这是因为Azure/Vertex/Bedrock 复用其他厂商的端点协议authType是唯一可靠的判别器厂商 URL 路由由authType驱动iam-azure→ AI SDKcreateAzureiam-gcp→ Vertex SDK。保护语义规范预设提供商不可被用户删除。多数行满足providerId presetProviderId别名/分组预设也通过注册表查询获得保护。继承自预设的用户自建提供商则可以删除。2. 按需模型创建POST /models当用户添加模型时例如POST /models [{ providerId: openai, modelId: gpt-4o }]处理流程把注册表解析与用户增量入库分开POST /models [{ providerId: openai, modelId: gpt-4o }] → handler对每项调用 providerRegistryService.lookupModel(providerId, modelId) → RegistryLoader.findModel(gpt-4o) // O(1) 索引查询失败则归一化回退 → RegistryLoader.findOverride(openai, gpt-4o) // O(1) 索引查询 → 从注册表数据解析端点配置档仅主进程不持久化 → 返回 { presetModel, registryOverride, reasoningProfile } → handlermodelService.create(items) → mergePresetModel(preset, override, ...) → 将显式 DTO 字段与注册表基线比较 → 仅 INSERT 与基线不同的可空列到 user_model → list/get/mutation 响应 → 重建当前注册表基线 → 叠加每个非空稀疏列注意最后两步的精妙之处Create 阶段比较传入值与当前注册表基线只有不同才入库因此渲染层回显renderer echo不会把目录值冻结进数据库而读取阶段总是从当前注册表基线出发叠加非空列。两者结合保证了目录演进能自动到达既有行。3. 解析 SDK 模型列表resolveModelsGET /providers/:providerId/models:resolve?idsgpt-4oidso3 → providerRegistryService.resolveModels(providerId, modelIds) → 对每个 modelId → RegistryLoader.findModel(modelId) // O(1)归一化回退 → RegistryLoader.findOverride(providerId, modelId) // O(1) → mergePresetModel(...) 或 createCustomModel(...) → 返回合并后的 Model[]该路由服务于SDK 只提供模型 ID的场景——能力、价格、模态等其余全部数据来自注册表SDK 数据不会覆盖精选的注册表数据。三个合并函数与优先级源码在 ProviderRegistryService.ts 中为三种不同场景提供了三个独立函数见 L407-L519 附近函数使用场景合并层mergePresetModel注册表查询、resolveModelspreset → override两层不涉及用户数据applyUserOverlay带显式用户增量的模型读取合并后的注册表基线 → 用户createCustomModel注册表无匹配项仅 modelId最小化自定义模型公共逻辑被抽取为applyPresetAndOverride(presetModel, catalogOverride)对除推理外的所有字段做 preset → override 两层合并。从源码看它依次处理 capabilitiesapplyCapabilityOverride支持force/add语义、modalities、endpointTypes、name、contextWindow、maxOutputTokens/maxInputTokens、pricing浅展开叠加、parameterSupport 与replaceWith模型替换标记会生成providerId::replaceWith的唯一 ID。resolveReasoning(reasoningSupport, profile)把模型的推理声明如 effort 枚举、thinking token 预算、toggle结合端点推理格式 profile解析出运行时推理配置。优先级规则非空稀疏列用户增量 provider-models.json按提供商覆盖 models.json全局预设 最高 中间 最低对于预设支撑的行每个可空的模型配置列都是独立的归属标记null表示继承注册表任何非空值都是用户增量。自定义行则存储完整配置。这一设计使得目录变化无需数据迁移即可到达既有行——显式的空字符串与空数组仍然作为合法覆盖生效即空值覆盖不会被误判为继承。用户覆盖保护当用户修改某个可被注册表增强的字段例如name该值被直接存入对应的可空列读取时从当前注册表出发叠加所有非空列。Create/PATCH 会把传入值与当前注册表基线比较因此渲染层回显不会冻结目录值把值恢复为基线会清空该列重新回到继承语义。源码中的EndpointConfigOverrideSchema与 PATCH 归一化进一步保证写路径的增量性——等于基线的值在写入时被丢弃。未来新增字段的三种路径原文档的核心方法论场景做法是否迁移注册表拥有、用户不可编辑的字段加入注册表 schema、运行时Model类型与mergePresetModel不加user_model列零迁移既有预设行下次读取即获得用户可编辑的预设字段新增可空增量列纳入 create/PATCH 叠加映射与预设增量字段集需 schema 迁移加列但既有行无需数据回填null继承自定义模型字段自定义行拥有完整配置新增必填字段需运行时默认值或自定义行回填这是预设继承规则的刻意例外一个有趣的事实佐证一个被自定义行与预设行共享的列可以对自定义行是必填、对预设行保持 null例如capabilities与reasoning——userModel.ts 中的检查约束presetModelId IS NOT NULL OR (name IS NOT NULL AND capabilities IS NOT NULL AND supportsStreaming IS NOT NULL)正是这一语义的数据库级落地。RegistryLoader索引化缓存与 30 秒空闲 TTLregistry-loader.ts 实现了缓存 索引 空闲自动过期的注册表访问器。其生命周期设计懒加载Lazy load数据在首次访问时才从磁盘读取不在启动时加载loadModels/loadProviders/loadProviderModels内部先touch()再检查缓存。预计算索引首次加载后一次性构建全部索引使查询达到 O(1)。空闲 TTL默认 30 秒DEFAULT_IDLE_TTL_MS 30_000构造函数可注入覆盖。每次touch()重置定时器定时器触发invalidate()释放全部数据与索引下次访问重新加载。作用域隔离ProviderRegistryService在查询间共享同一个 loaderPresetProviderSeeder则创建自己的 loader见 presetProviderSeeder.ts 的getLoader()。索引矩阵索引键用途modelByIdmodel.id精确模型查询modelByNormIdnormalizeModelId(id)归一化回退modelBySizedNorm保留参数规模的归一化 ID解析带参数规模标签的变体如gpt-oss:20boverrideByKeyproviderId::modelId精确覆盖查询overrideByNormKeyproviderId::normalizeModelId(id)归一化回退overrideByApiKeyproviderId::apiModelId精确的提供商侧模型 ID 查询overrideByNormApiKeyproviderId::normalizeModelId(apiModelId)归一化的提供商侧回退overridesByProviderproviderId某提供商的全部覆盖查询 APIloader.findModel(modelId) // O(1)精确 → 归一化回退 loader.findOverride(providerId, modelId) // O(1)精确 → 归一化回退 loader.getOverridesForProvider(providerId) // O(1)按提供商分组 loader.invalidate() // 释放全部数据下次访问重新加载源码中findModel的查询顺序非常讲究这也是索引多达 8 张的原因先查modelById精确匹配若 ID 带冒号变体标签如gpt-oss:20b用colonVariantTagToHyphen重排为连字符拼写后走保留规模的modelBySizedNorm——确保:20b命中gpt-oss-20b而不是同家族的gpt-oss-120b兄弟行无标签时优先 size-preserving 键若目录里根本没有该规模如qwen2.5:7b目录只有qwen2-5-*-instruct返回 null 而非瞎猜——错误兄弟行的价格、限制与presetModelId比没有元数据更糟最后才回退到无规模的modelByNormId。findOverride同样有严格的顺序纪律见源码 L316-L335 的注释两个精确查询canonical modelId、provider apiModelId必须先于两个归一化回退。因为归一化会剥掉规模/日期后缀多个不同行会塌缩到同一个归一化键如google.gemma-3-27b-it与gemma-3-12b-it都 →gemma-3-it若归一化回退先于 apiModelId 精确查询一个精确的 SDK ID 就会解析到先被索引的同族行。此外overrideByKey建立时采用了self variant 优先规则当同一 canonical 键出现多个行如 tokenhub 带日期的原厂直供变体共享deepseek-v4-flash时apiModelId modelId的自身体变体优先占用槽位。远程目录与 schema 版本registry-loader.ts还导出与远程目录更新相关的契约常量REGISTRY_SCHEMA_VERSION 2远程更新器从v{version}/路径拉取同步 CI 发布到匹配目录保证应用只会收到其捆绑 schema 能解析的数据。v2 起 schema 采用丢弃未知键的向前兼容策略schemas/forwardCompat.ts枚举词表增长不再升级版本只有结构性变更字段改名/改型/必填移除才升级。REGISTRY_MIN_APP_VERSION 2.0.13能执行当前目录语义值的最老应用版本新 adapter family、端点类型或线行为需要升级它。REMOTE_REGISTRY_FILES [models.json, provider-models.json]可被未签名远端数据覆盖的文件providers.json提供商路由始终捆绑。模型 ID 归一化一份 ID 到目录规范 ID 的七步管线不同提供商暴露给用户的模型 ID 往往与注册表规范 ID 不同normalizeModelId()packages/provider-registry/src/utils/normalize.ts是单一事实来源用户看到注册表拥有归一化aihubmix-gpt-4ogpt-4o剥离聚合商前缀gpt-4o:freegpt-4o剥离变体后缀claude-3.5-sonnetclaude-3-5-sonnet归一化版本分隔符aihubmix-gpt-4o:freegpt-4o组合处理处理管线1. 剥离提供商前缀如 anthropic/claude-3 → claude-3 2. 转小写 3. 剥离聚合商前缀aihubmix-、zai-、siliconflow-、... 4. 展开已知缩写mm- → minimax- 5. 剥离变体后缀:free、-thinking、(beta)、... 6. 剥离参数规模-72b、-7b、... 7. 归一化版本分隔符3.5 → 3-5、3p5 → 3-5源码揭示了大量精心维护的细节常量聚合商前缀COMMON_AGGREGATOR_PREFIXESAIHubMix 系aihubmix-/aihub-/ahm-、云厂商路由alicloud-/azure-/baidu-/cbs-...、平台聚合商deepinfra-/groq-/nvidia-/sophnet-、下划线前缀dmxapi_/aistudio_。注意mm-故意不在其中——它是 MiniMax 简写由PREFIX_EXPANSIONS展开为minimax-若先作为聚合商前缀剥离会导致m2-1孤儿 ID。变体后缀冒号系:free/:nitro/:extended/:beta/:preview/:thinking/:exacto/:latest/:cloud、连字符系-free/-search/-online/-think/-reasoning/-classic/-low/-high/-minimal/-thinking/-aliyun...与括号系(free)/(beta)/(preview)/(thinking)。-medium同样故意不在连字符后缀列表——它是真实模型档位名mistral-medium、devstral-medium。保护复合前缀non/no/pre/anti/post——剥离-no-think前会检查前缀是否为独立词元避免误伤inferno-search这类本应剥离的 ID注释举例...-no-think保留volcano-free剥离。量化后缀-fp8/-fp16/-bf16/-awq/-int4/-int8/-gguf/-gptq——同一逻辑模型的不同精度拼写被折叠。日期快照DATE_SNAPSHOT_PATTERN剥离claude-sonnet-4-5-20250929、gpt-4o-2024-08-06、kimi-k2-250905等发布日戳要求合法月份01-12与日期01-31确保glm-4-9b这类规模/版本永不被误伤。该模式与构建期规范化器generate-catalog.ts共享同一定义。Bedrock 跨厂商 ARN剥离前导的[region.]vendor.点号段与vendor-连字符段us.anthropic.claude-sonnet-4-5-v1:0→claude-sonnet-4-5并剥离尾部修订号:0/-v1:0。归一化到不动点变体 → 量化 → 日期剥离需要迭代至稳定stripVariantQuantDateSuffixes循环因为尾部日期会屏蔽内部变体——...-thinking-2507只有在日期剥离后才暴露-thinking。keepParameterSize模式保留规模的关键字供modelBySizedNorm索引使用——先通过colonVariantTagToHyphen把:20b重排为-20bgpt-oss:20b→gpt-oss-20b使大小成为 ID 的连字符词元而不被stripParameterSize剥离。查找策略先精确匹配、后归一化回退。这保证若gpt-4o与aihubmix-gpt-4o同时作为独立条目存在精确匹配优先。从源码看findModel还追加了保留规模的归一化优先于无规模家族键以及无对应规模的目录条目时返回 null两条规则避免跨规模兄弟行的错误元数据污染。关键数据库表增量存储的两张表user_providersrc/main/data/db/schemas/userProvider.ts列用途providerId主键用户自定义的唯一 IDpresetProviderId关联 providers.json 条目null自定义提供商。双重职责标识来源预设并作为侧栏分组键——少数注册表行如zai→zhipu、minimax-global→minimax指向不同预设从而折叠到该分组下name用户拥有的显示名首次播种时从预设初始化endpointConfigsJSON 增量用户的baseUrl覆盖自定义提供商还可存adapterFamily路由提示defaultChatEndpoint可空用户覆盖null 继承注册表默认值apiKeysAPI 密钥条目 JSON 数组apiFeaturesJSON 增量仅存与注册表/应用默认值不同的标志null 继承全部默认值user_modelsrc/main/data/db/schemas/userModel.ts列用途id确定性主键providerId::modelIdproviderIdmodelId提供商内模型唯一身份有唯一约束user_model_provider_model_uniquepresetModelId关联 models.json 条目null自定义模型兼作追溯标记name/capabilities/supportsStreaming自定义行必填预设行可空增量inputModalities/outputModalities自定义行完整配置或预设行可空增量contextWindow/maxOutputTokens同上reasoning自定义行的内禀控制/token 限制预设行从注册表解析pricing自定义行完整配置或预设行可空增量parameters同上orderKey提供商模型列表中的分数排序键notes用户备注从 userModel.ts 源码看表还带presetModelId索引、(providerId, isEnabled)索引、按providerId作用域的orderKey索引以及前文提到的检查约束preset 行可空、custom 行必填。providerId通过外键级联删除ON DELETE CASCADE。提供商配置合并与模型相同的增量契约提供商连接配置采用与模型相同的分层、读取期合并。user_provider行本身是一个增量delta只存用户显式设置的内容键缺失即使用注册表值。合并发生在rowToRuntimeProviderProviderService中经由ProviderRegistryService.mergeEndpointConfigs/getProviderDisplayMetadatauser_provider (DB, delta) providers.json (registry) app defaults字段归属解析endpointConfigs[ep].baseUrl用户row registryendpointConfigs[ep].adapterFamily注册表registry row自定义提供商提示inferAdapterFamily(ep)endpointConfigs[ep].modelsApiUrls注册表仅注册表端点类型键集注册表 ∪ 用户注册表与行的键取并集apiFeatures混合{...DEFAULT_API_FEATURES, ...registry, ...row}defaultChatEndpoint混合row registryinferAdapterFamilyregistry-utils.ts是 seeder / migrator / UI 创建路径的单一事实来源目录adapterFamily优先编码厂商特定中继路由如 AiHubMix 上 anthropic-messages 的aihubmix→ 按端点类型默认值anthropic-messages→anthropic、google-generate-content→google、ollama-chat/ollama-generate→ollama、jina-rerank→jina-rerank、openai-responses→openai→ 最终回退openai-compatible。另一个推导细节endpointImpliedCapability从能力专属端点推导模型能力——jina-rerank只能重排、openai-embeddings只能嵌入、图像/音频/视频专用端点只能服务对应媒体任务。这是目录没有该条目如不透明网关/NewAPI 模型 ID时从端点推导能力的单一事实来源。为什么注册表更新零数据迁移因为注册表拥有的值从不被冻结进行内注册表更新新端点类型、adapter family 变更、baseUrl 变更、特性开关、默认端点变化以零数据迁移到达增量契约下创建的行issue #17096。写路径强制增量EndpointConfigOverride是唯一可持久化的端点形状PATCH 归一化丢弃等于注册表基线的值。例如一个未被触碰的预设baseUrl不出现在行中。若提供商在providers.json中更改该 URL下次读取即返回新 URL用户自定义的代理 URL 保留在行中并持续生效直到用户把它重置回当前注册表值。provider.name是刻意的例外它是用户拥有的完整值播种时初始化不是注册表增量——之后注册表改名不会替换它。若产品语义要改为改名之前继承必须先把name转换为显式增量表示。何时需要回填Backfill注册表内容更新在存储归属契约不变时不需要回填注册表专属字段在读取时直接解析混合字段baseUrl、apiFeatures、defaultChatEndpoint在其行增量缺失时继承既有用户覆盖刻意保持优先它们不是陈旧数据新增的注册表专属字段应加入读取期投影而非持久化。schema 迁移仍可能需要——当新增用户可编辑字段需要存储时但预设行在null/缺失继承语义下无需数据回填。只有两种情况必须回填完整自定义行新增无运行时默认值的必填字段或既有字段从完整快照改为增量、且需保留旧数据库。新增注册表字段的操作指南原文档的落地要点注册表拥有、用户不可编辑只加入读取期合并输出。端点配置字段不要加入EndpointConfigOverride——Zod 会自动从写 DTO 中剥掉它因为keyof集合是权威归属声明。零迁移。用户可编辑的端点字段混合归属加入EndpointConfigOverrideSchemakeyof集合即权威归属声明在合并中加row.x ?? registry.x规则可选地在写入时丢弃等于基线的值。零迁移——缺失键回退注册表。用户可编辑的提供商字段若属于既有 JSON 增量如apiFeatures扩展该 schema 与合并规则即零迁移否则选择显式持久化覆盖位置。新独立列属于 schema 变更但可空的预设增量列仍无需值回填。该设计不让任意顶层字段免迁移。永不把注册表拥有的值作为行快照持久化——那正是注册表更新变陈旧的确切原因。推理配置模型数据与提供商线协议的边界划分推理reasoning配置被刻意拆分到两个边界详见 packages/provider-registry/docs/reasoning-control.md模型数据声明内禀控制与 token 限制。主进程注册表增强把这些投影为仅运行时的selectableEfforts供渲染层控件消费。模型侧 schemaschemas/model.ts支持三种控制种类effort离散档位values是模型内禀词表none出现 ⇔ 推理可被禁用、budget数值型思考 token 预算min/max/default且mindefaultmax有 superRefine 校验、toggle仅开/关。提供商注册表数据声明一个封闭的reasoningFormat线协议 profile仅在主进程解析与解释从不复制进 SQLite、DataApi 或渲染层状态。请求路径从精确的提供商-模型 → 端点覆盖/默认 → 穷尽格式默认解析出一个 profile与提交时的规范选择组合最终发射为原生 AI SDK 提供商选项或通用兼容参数。推理的引入还伴随能力注入mergePresetModel中当传入reasoningSupport时MODEL_CAPABILITY.REASONING会被并入 capabilities见 ProviderRegistryService.ts。值得一提的createCustomModel细节无注册表匹配的模型仍会通过inferCustomModelReasoning(modelId, profile)在摄取期推断推理描述——只要 ID 可辨识为推理 SKU自定义行也像目录行一样拥有推理描述符issue #16598。synthesizePresetFromOverride则允许provider-models.json完全独立承载厂商独占模型ModelScope 的Tongyi-MAI/Z-Image-Turbo、PPIO 定制端点等无需全局目录条目。文件位置速查内容位置注册表 JSON 数据packages/provider-registry/data/Zod schemaspackages/provider-registry/src/schemas/RegistryLoader加载、索引、TTLpackages/provider-registry/src/registry-loader.ts纯查询/转换函数packages/provider-registry/src/registry-utils.ts归一化工具packages/provider-registry/src/utils/normalize.ts播种运行器src/main/data/db/seeding/SeedRunner.ts预设提供商播种src/main/data/db/seeding/seeders/presetProviderSeeder.ts服务合并查询src/main/data/services/ProviderRegistryService.ts模型服务用户增量叠加src/main/data/services/ModelService.ts提供商服务src/main/data/services/ProviderService.tsDB schemassrc/main/data/db/schemas/userModel.ts、src/main/data/db/schemas/userProvider.ts总结增量契约如何让目录持续演进Cherry Studio 的 Provider/Model 注册表系统本质上是三句话的架构目录即事实models.json、providers.json、provider-models.json是唯一事实来源RegistryLoader以 O(1) 索引 30 秒空闲 TTL 提供高速只读访问行即增量user_provider与user_model只存用户显式差异null/键缺失 继承注册表任何注册表更新零迁移到达既有行读取时合并mergePresetModelpreset→override、applyUserOverlay基线→用户、createCustomModel纯自定义三个合并函数按场景分工配合七步 ID 归一化管线让 SDK 的任意 ID 拼写都能落回目录规范行。理解这套契约后无论是排查为什么我的模型价格变了目录更新了你的行没有覆盖、还是规划如何给注册表加一个新字段按上文三种路径选择都有了清晰的决策依据。赞分享人工智能大模型AI 应用交互助手本地部署【免费下载链接】cherry-studio Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端项目地址https://gitcode.com/CherryHQ/cherry-studio点击查看免费下载相关推荐Cherry Studio Provider Model Registry 系统解析预设数据如何加载、归一化、播种并与用户数据合并Cherry Studio Provider Model Registry 系统解析预设数据如何加载、归一化、播种并与用户数据合并 本篇技术指南围绕 ChAI 应用大模型桌面应用本地部署RAGCherry Studio Provider Model 注册表系统预设数据加载、规范化、种子写入与用户数据合并全解析Cherry Studio Provider Model 注册表系统预设数据加载、规范化、种子写入与用户数据合并全解析 导读 Cherry StudioAI 应用大模型桌面应用本地部署RAGCherry Studio 工具注册表Tool Registry深度解析统一 AI SDK ToolEntry、MCP 同步与延迟暴露机制Cherry Studio 工具注册表Tool Registry深度解析统一 AI SDK ToolEntry、MCP 同步与延迟暴露机制 导读 本文围绕AI 应用大模型桌面应用本地部署RAG上一篇Friends基于Web的P2P聊天革命重新定义去中心化通信下一篇使用 Participle v2 在 Go 中构建声明式解析器从零编写 .ini 语法解析器的完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询