DeepSeek-Reasonix 模型能力元数据解析指南:多模态输入判定、能力缓存与图片输入配置
【免费下载链接】DeepSeek-ReasonixDeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Reasonix
本文基于 DeepSeek-Reasonix 仓库中的 docs/MODEL_CAPABILITIES.md 及其配套源码,系统讲解 AI 编码代理如何逐模型解析输入能力(text/image/text + image)、如何通过 OpenAI 兼容/models接口与内置本地目录获取能力事实、如何持久化动态元数据缓存,以及如何在桌面端为自定义中继模型手动声明图片输入能力。读完本文,你将理解能力判定的完整优先级链、缓存 V2 的设计约束,并掌握在 Settings → Models 中配置「Image input」的完整操作流程。
一、能力元数据模型:模态声明与三态判定
Reasonix 通过 provider adapter 为每一个精确模型解析输入能力。Adapter 遵循deepseek-harness模型契约,返回inputModalities字段,其取值语义如下:
text:模型接受文本输入;image:模型接受原生图片输入;text + image:模型支持原生多模态请求,无需再配置VisionModels设置。
在内部实现中,模态类型定义于 internal/provider/model_info.go:
type ModelModality string const ( ModalityText ModelModality = "text" ModalityImage ModelModality = "image" )该类型被设计为开放枚举(未来可扩展 audio/video/file),但当前实现只路由 text 与 image 两种输入。
三态语义:Supported / Unsupported / Unknown
能力状态由 internal/config/model_capabilities.go 中的枚举定义:
type CapabilityState string const ( CapabilitySupported CapabilityState = "supported" CapabilityUnsupported CapabilityState = "unsupported" CapabilityUnknown CapabilityState = "unknown" )关键规则:
- 缺失(nil 模态列表):adapter 无法确定能力 → 状态为
unknown(内部为nil,桌面端视图显示为[]); - 显式文本声明(
["text"]):这是故意否定声明 → 状态为unsupported; - 含图片声明(
["text","image"]):状态为supported。
这一三态设计在 internal/config/model_capabilities.go 的capabilityFromModalities中直接体现:modalities == nil时状态为 Unknown,含 image 时状态为 Supported,否则为 Unsupported。
能力来源枚举
每次判定都会记录其来源(CapabilitySource),用于 UI 展示与调试,见 internal/config/model_capabilities.go:
const ( CapabilitySourceOverride CapabilitySource = "override" // 用户显式声明 CapabilitySourcePreset CapabilitySource = "preset" // 未改动的内置预设 CapabilitySourceLegacy CapabilitySource = "legacy" // 旧版 vision / vision_models 配置 CapabilitySourceAdapter CapabilitySource = "adapter" // adapter 在线目录结果 CapabilitySourceCache CapabilitySource = "cache" // 能力缓存命中 CapabilitySourceDefault CapabilitySource = "adapter_default" CapabilitySourceUnknown CapabilitySource = "unknown" CapabilitySourceProtocol CapabilitySource = "protocol" // 官方协议硬性限制 )二、OpenAI 兼容/models响应的字段解析
Reasonix 通过GET /models获取模型级能力元数据。解析逻辑位于 internal/provider/openai/fetch_models.go 的FetchModelCatalogWithOptions:请求携带与聊天请求相同的传输策略(代理、超时等),响应体限制为 2 MiB(fetchModelsMaxBody),HTTP 超时 10 秒。
字段优先级:规范字段 > 兼容别名
在 internal/provider/openai/fetch_models.go 的parseModalities中,字段按以下顺序解析:
- 规范字段
input_modalities(数组形式,如["text","image"]); - 兼容别名
modalities.input(嵌套对象); - 兼容别名
capabilities.input_modalities; - 兼容别名
capabilities.vision(布尔); - 兼容别名
supports_vision、vision(布尔)。
规范字段优先级高于别名,即使规范字段的值无效也是如此——例如input_modalities存在但值非法时,直接判定为 unknown,不再回退到别名字段。
值解析的严格校验
internal/provider/openai/fetch_models.go 对值的校验规则:
decodeModalities:数组中的每个值必须小写化、去空格后恰好是text或image,否则整个声明判为无效(unknown);数组会去重,并固定为text, image的稳定顺序(若原顺序为image, text会交换),使重复合并与顺序无关;decodeVisionBool:true→["text","image"],false→["text"];非布尔值判为无效;- 同一响应内同一模型 ID 出现相互矛盾的声明(如一次
["text"]一次["text","image"]),该模型在整个响应中保持unknown——缺失元数据永远不会被当作否定事实。
注释也明确了设计原则(见 internal/provider/openai/fetch_models.go):端点省略能力字段时,adapter 故意返回 unknown,调用方绝不允许根据模型名称猜测图片支持。
三、动态能力缓存:model-capabilities-v2.json
动态元数据存储在 Reasonix 缓存目录下的一次性缓存model-capabilities-v2.json中,不会写入config.toml。缓存文件格式见 internal/config/model_capabilities.go:
type ModelCapabilityCacheFile struct { Version int `json:"version"` Entries []ModelCapabilityCacheEntry `json:"entries"` } type ModelCapabilityCacheEntry struct { ProviderFingerprint string `json:"providerFingerprint"` ModelID string `json:"modelID"` InputModalities []provider.ModelModality `json:"inputModalities"` Source CapabilitySource `json:"source"` FetchedAt time.Time `json:"fetchedAt"` ExpiresAt time.Time `json:"expiresAt"` }关键设计约束
- TTL 与容量上限:条目 24 小时后过期(
modelCapabilityCacheTTL = 24 * time.Hour);文件最大 2 MiB(modelCapabilityCacheMaxSize = 2 << 20),最多 4096 条(modelCapabilityCacheMaxItems),见 internal/config/model_capabilities.go; - 失败不覆盖成功:失败的请求不会替换已有的成功条目;而一次成功的仅 ID 响应(无能力字段)会记录为
unknown; - 指纹隔离:每条缓存以
ProviderFingerprint标识 provider 身份,由 HMAC-SHA256 对 provider 名称、类型、BaseURL、ChatURL、RequestURL、ModelsURL、API 密钥环境变量、认证头模式、代理设置、请求头及凭据修订号计算得到(见 internal/config/model_capabilities.go)。路由或凭据一旦变化,缓存自动隔离失效; - 并发安全与原子写:写入使用跨进程文件锁(
acquireCapabilityFileLock,见 internal/config/model_capabilities.go),并合并磁盘上最新快照,保证多个设置刷新进程不会互相覆盖;最终通过fileutil.AtomicWriteFileStrict以 0o600 权限原子替换文件; - 不含凭据:测试
TestModelCapabilityResolverLoadsIndependentCache(internal/config/model_capabilities_test.go)明确断言缓存文件不得包含 API 密钥或 Authorization 头; - V2 不读取也不修改 V1:旧版
model-capabilities-v1.json无法区分「元数据缺失」与「否定声明」。仅依赖 V1 正向元数据的自定义模型,需要一次模型列表刷新或手动覆盖。
四、内置本地目录:无需请求即可判定
对于未改动过的策展 provider 预设,内置 adapter 还携带了经过验证的本地目录(local catalogs),即使不发起模型列表请求也能完成判定。目录覆盖范围包括:
- 官方 OpenCode Go 各路由(Chat / Anthropic / Responses);
- DeepSeek 视觉 SKU(
deepseek-v4-flash-vision-exp); - ModelScope Qwen3.5 SKU;
- 其余预设模型的模型列表。
本地目录的实现位于 internal/provider/opencode_go.go 的BuiltinModelInfo:它先查 OpenCode Go 本地目录,再查 ModelScope 目录,最后检查官方 DeepSeek 端点(api.deepseek.com),命中 internal/provider/deepseek_models.go 中的officialDeepSeekImageModels列表则返回["text","image"]。
判定边界
- 自定义端点、被编辑过的预设、不在本地目录中的模型,除非有其他有效来源,否则保持 unknown;
- 本地目录是精确匹配(
PiCatalogModelInfoForProvider要求 provider ID、kind、baseURL 与目录条目完全一致,见 internal/provider/pi_catalog.go),自定义网关永远不会意外继承其他厂商的元数据。
五、为中继模型开启图片输入(实操)
如果你的中继(relay)模型支持图片但无法被自动探测到,按以下步骤在桌面端手动声明:
- 进入Settings → Models,添加或编辑 provider,并抓取其模型列表;
- 选中该模型。若显示「Image capability unknown」,请与服务提供商确认其图片支持情况,然后选择Image input → On;
- 点击保存,等待运行时重建(runtime rebuild)成功后发送图片。刷新模型列表或重启应用都会保留该选择。
Auto / On / Off 三态语义
Provider 编辑器与刷新后的模型选择器均提供Auto / On / Off三态:
- On:你对该模型图片支持的声明(declaration),不是付费客户端的探测(probe);声明后该模型直接获得
text + image能力; - Off:即使模型在本地目录中登记为视觉模型,也强制禁用原生图片输入;
- Auto:仅移除该模型的
vision覆盖;上下文、输出、推理(reasoning)设置保持不变。若存在旧版vision/vision_models值生效,Auto 可能显示「Using legacy configuration」。
对应的config.toml配置形式(摘录自原文档):
[providers.model_overrides.example-model] vision = true # false 表示禁用;删除此字段即恢复 Auto最终优先级链
能力判定的最终优先级(从高到低)为:
- 官方协议限制(official protocol restriction);
- 单模型覆盖(per-model override,即上面的
model_overrides); - 既有自动链:策展预设 → 旧版配置 → 精确本地目录 → 有效在线缓存;
- unknown。
官方 DeepSeek 文本模型(如deepseek-v4-pro,见 internal/provider/deepseek_models.go)被协议硬性阻止图片输入(ImageInputEnableAllowed = false,block reason 为official_deepseek_text_model,见 internal/config/model_capabilities.go);而 DeepSeek 视觉模型可以被显式禁用。
能力变化保留目录上下文、输出、API 与推理元数据;UI 提供的(手动声明的)能力永远不会作为事实被保存进发现缓存——即 discovery 不会将用户手动选择写回在线缓存。
优先级链的源码验证
internal/config/model_capabilities_test.go 的TestModelCapabilityResolverHonorsExplicitConfigBeforeCache验证了核心优先级:adapter 目录判定supported之后,旧版vision_models会以legacy来源覆盖;而单模型visionOverride=false再以override来源覆盖为unsupported。
六、运行时重建与会话语义
- 空闲的活动会话在保存设置后立即重建;其他打开的会话在下一轮(turn)开始前检查;正在飞行中的请求保留其冻结的能力与载荷,不会中途变更;
- 失败或被推迟的重建必须先完成,设置才会生效;composer 读取的是运行中 Controller 的快照;
- 不会自动重发任何失败的请求或历史图片;发送消息永远不会触发
/models请求(能力判定不阻塞普通对话); - 系统提示词、工具 schema 与纯文本序列化保持不变。但改变图片能力可能改变含图片历史的投影方式,因此此类会话在重建后的缓存命中不保证。
桌面端的可见性门控在 desktop/settings_app.go 的selectableDesktopVisionModelRef中实现:选择视觉模型前会依次校验 provider 可访问、已配置 API 密钥,最后通过config.EffectiveVision(entry)判断模型是否支持图片输入。
七、底层目录来源:sky-valley/pi 与依赖治理
更广泛的 provider/model 目录来自 MIT 许可的github.com/sky-valley/pi/aiGo 移植版 Pi。Reasonix仅使用其嵌入的模型数据(GetModels/Model.Input及相关事实),不运行其 Agent 或 Provider 运行时。该依赖在 go.mod 中锁定版本;目录更新必须作为数据与许可证变更进行审查。
依赖治理有两项保障:
- Dependabot 每周单独开启
sky-valley/pi更新 PR,不与无关的 Go 升级捆绑,便于独立评审; - 目录契约测试位于 internal/provider/opencode_go_test.go,当重要模型能力漂移时测试会失败(例如
TestPiCatalogContractKeepsKnownCapabilityFacts、TestBuiltinModelInfoIncludesDeepSeekVisionSKU、TestOpenCodeGoChatModelsMatchPinnedLimits等)。只有 provider/API/端点差异被审查通过后,更新才会被合并。
八、文本与未知模型的回退路径
纯文本与能力未知的模型沿用既有的Agent.VisionModel、OCR 与 MCP vision 回退链路。原始图片载荷绝不会发送给这些模型——这保证了即使能力判定为 unknown,也不会意外把图片塞进不支持多模态的模型。
结语
DeepSeek-Reasonix 的模型能力解析是一套「显式声明优先、自动探测兜底、严格区分缺失与否定」的确定性系统:/models响应字段按规范字段→别名解析,矛盾与非法声明一律回落 unknown;24 小时 TTL 的能力缓存 V2 以 provider 指纹隔离、失败不覆盖成功、绝不写入config.toml;内置本地目录让官方路由零请求即可判定;手动vision覆盖则赋予用户对中继模型的最终裁决权。结合 internal/config/model_capabilities.go 与 internal/provider/openai/fetch_models.go 的源码,你可以精确预判任意模型在对话、历史投影与多模态发送链路中的实际行为。
【免费下载链接】DeepSeek-ReasonixDeepSeek-native AI coding agent for your terminal. Engineered around prefix-cache stability — leave it running.项目地址: https://gitcode.com/GitHub_Trending/de/DeepSeek-Reasonix
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考