ollama v0.30.9更新详解:Cohere2Moe支持落地,LFM2思维链解析修复,超长上下文报错机制上线 2026年6月17日ollama 发布了 v0.30.9 最新版本。从这次发布信息来看虽然版本号只是一次常规迭代但实际改动并不小覆盖了模型架构支持、LFM2 解析与渲染修复、ollama 在启动 Claude 及其他 coding agent 或 assistant 场景下只输出一个 token 的问题修复以及单条消息超过当前上下文窗口时直接返回错误的新机制。从变更规模来看本次版本一共包含 3 次提交涉及 16 个文件1 位贡献者总代码层面为 280 行新增、103 行删除。如果从工程角度看这不是一次简单的 bugfix而是一轮围绕兼容层、解析器、渲染器、调度器以及 llama-server 行为约束的系统性修订。一、本次版本官方变更摘要v0.30.9 的核心更新点可以概括为四项支持 Cohere2Moe 架构修复 LFM2 在未输出 thinking 时的 parser 和 renderer 行为修复 ollama 在 launch Claude 以及其他 coding agent、assistant 使用场景下只输出一个 token 的问题当单条消息大于当前上下文窗口时ollama 现在会直接返回错误这四项看起来很简短但背后实际牵涉到了多个模块llama.cpp 兼容层补丁组织方式调整LFM2 parser 状态机重构LFM2 renderer 对 thinking 字段的重建逻辑完善prompt 超长时不再截断而是显式报错context shift 的默认策略发生变化针对大于 8k 上下文窗口的 context shift 处理做了调整二、提交与改动规模概览本次发布对应的提交时间集中在 2026年6月15日 和 2026年6月16日。提交内容主要包括更新 llama.cpp 到新版本更新 lfm2 parser 和 renderer使 thinking 变为可选行为时也能正确处理调整 server 侧 context shift 策略并新增上下文窗口超限错误处理从 diff 信息看本次更新共涉及这些方向版本号调整compat 补丁文件重命名和新增compat 文档说明更新patch 自动应用逻辑增强laguna 架构兼容层修正llama server prompt 长度处理逻辑变化llama server 测试从“截断成功”改为“超限报错”LFM2 parser 状态与流式解析行为大幅增强LFM2 renderer 能够根据 Thinking 字段重建 think 标签调度器 context shift 默认决策逻辑改动多处测试同步更新可以说这个版本虽然改动文件数量不算夸张但大部分都落在底层逻辑与边界行为上因此对稳定性和兼容性影响非常直接。三、支持 Cohere2Moe 架构版本能力边界继续扩大官方 changelog 的第一条就是Support for Cohere2Moe architecture这说明 v0.30.9 新增了对 Cohere2Moe 架构的支持。虽然在用户给出的 diff 片段中没有展开 Cohere2Moe 具体实现文件的完整细节但这项支持已经明确列入本次版本变更说明意味着在模型架构适配层面ollama 的兼容能力又向前推进了一步。结合本次 compat 层的组织方式调整可以看出新增架构支持并不是零散加入而是继续沿用“补丁加兼容实现”的方式推进。这一点从 compat 目录的变更就很明显。四、llama.cpp 版本更新底层依赖继续前进本次有一个很基础但很重要的变化就是LLAMA_CPP_VERSION从b9509更新为b9626也就是说ollama v0.30.9 所依赖的 llama.cpp 版本进一步推进了。这类变更的重要性在于很多上层能力其实并不完全由 ollama 自己独立实现尤其是模型加载、架构识别、UI 辅助工具、服务行为等都会受到底层 llama.cpp 版本的直接影响。因此兼容层补丁、架构注册、工具链修复、上下文行为调整往往都需要围绕这个版本基线同步演进。这也是为什么本次更新里compat 层相关文件变更这么集中。五、compat 层补丁命名方式调整从单补丁走向有序补丁集本次一个非常明显的工程化调整是补丁文件命名发生了变化。原来的llama/compat/llama-cpp-hooks.patch现在重命名为llama/compat/001-llama-cpp-hooks.patch同时新增了一个补丁文件llama/compat/002-llama-cpp-ui-empty-assets.patch此外原来的llama/compat/models/llama-cpp-laguna.patch也重命名为了llama/compat/models/003-llama-cpp-laguna.patch这说明 compat 层已经从“某个单一补丁文件”的思路转向“按数字顺序执行的一组补丁”的思路。这个变化在文档和 CMake 逻辑中也有完整呼应。原本 README 中对 patch 的说明还是强调某一个 hooks patch。更新后则明确指出使用数字文件名顺序来应用补丁该目录下的所有*.patch都会按数值顺序执行包括 hooks patch 和各个 models 架构 patch这个变化的重要性非常高因为它让 compat 层从“零散 patch”变成“可维护的 patch pipeline”。也就是说后续新增架构、修补 UI 工具、加 loader hooks不需要继续把所有修改塞进一个 patch 文件里而是可以按顺序拆分成多个补丁既方便维护也方便判断哪一步出问题。六、新增 UI 空资源补丁没有前端资源时也能生成空资产表新增补丁002-llama-cpp-ui-empty-assets.patch的内容比较明确修改的是tools/ui/embed.cpp改动核心有两点asset_dir不再强制要求必须传入第三个参数而是当argc 4时才使用argv[3]否则设为空字符串use_gzip的判断增加了asset_dir非空校验也就是原来逻辑默认认为一定存在资源目录。现在则允许资源目录为空并在这种情况下依然正常执行只是不会去寻找_gzip目录。这与 README 中新增的描述完全一致让 llama.cpp UI embed helper 在没有 UI assets 的情况下也能生成一个空的 asset table这个改动的实际意义是在某些构建环境下如果没有准备 UI 静态资源以前可能会因为 embed 流程强依赖 asset 目录而出错。而现在构建过程可以在“无 UI 资源”条件下继续进行自动生成空资源表增强了构建兼容性和可移植性。七、compat 文档更新清楚界定补丁层与新架构层llama/compat/README.md的更新不只是名称替换而是对整个 compat 设计意图进行了更清晰的说明。几个关键信息包括001-llama-cpp-hooks.patch是在 llama.cpp 文件中增加小范围、附加式调用点的补丁002-llama-cpp-ui-empty-assets.patch用于在没有 UI assets 时生成空资产表compat.cmake和apply-patch.cmake用来按数字顺序应用当前目录下所有 patchmodels/目录是“新增架构层”用于补充 llama.cpp 暂不支持的新架构上层 compat 文件主要负责“翻译和适配”而 models 目录里的文件主要负责“新增架构”这个描述非常关键因为它帮助开发者理解哪些 patch 是 llama.cpp 钩子层的哪些 patch 是架构扩展层的为什么要按顺序应用哪些文件是 Ollama 自己持有的 compat 逻辑从工程维护角度说这类文档更新的价值不低因为它减少了后续继续迭代时的理解成本。八、补丁应用脚本增强按文件名排序日志更清晰失败信息更精准llama/compat/apply-patch.cmake这次修改非常值得关注。核心变化包括明确所有 patch 会按数字文件名顺序应用而不仅仅是简单遍历先构造_patch_entries每个元素包含“文件名和完整路径”对_patch_entries排序后再逐个提取PATCH_FILE日志输出从笼统的“patch already applied, skipping”变为显示具体相对路径应用成功日志从“applied patch”变为“applied 某个具体 patch”出错日志也从输出完整路径变成输出相对路径信息更聚焦这几个调整看似细碎实际对构建调试帮助很大。以前如果目录里 patch 变多单看“已跳过”或者“已应用”很难知道是哪一个。现在会明确显示具体的 patch 相对路径问题定位成本明显下降。另外原逻辑虽然也能处理*.patch但现在进一步强调并落实了“按数字文件名顺序执行”的机制这和补丁重命名成001、002、003形成了严格配套。九、compat.cmake 同步更新补丁文件路径改为新的编号名称llama/compat/compat.cmake的改动不多但作用很明确注释从“单个小 patch file”改成“小型有序 patch 集”OLLAMA_LLAMA_CPP_COMPAT_PATCH_FILE指向的新路径由llama-cpp-hooks.patch改成001-llama-cpp-hooks.patch这意味着整个构建系统已经正式接受新的补丁命名规则旧文件名不再是主路径。十、laguna 兼容层修正调用参数从成员变量改为方法llama/compat/models/003-llama-cpp-laguna.patch与llama/compat/models/laguna.cpp也有更新。在laguna.cpp中这一行发生了变化原来使用hparams.n_layer现在改为hparams.n_layer()也就是ml.get_key_or_arr(laguna.attention.layer_types, hparams.is_swa_impl, hparams.n_layer(), false);这通常意味着n_layer的访问方式发生了接口层调整或者是需要通过方法而不是直接成员访问来获得层数。虽然只是单行改动但这种变化往往是为了适配底层结构定义变更避免编译或运行时不一致。同时patch 文件重命名到003也说明 laguna 架构 patch 现在纳入统一的顺序补丁集管理。十一、llama server prompt 处理逻辑变化从自动截断改为直接报错这次更新中最值得用户关注的改动之一就是llm/llama_server.go的 prompt 长度处理策略变了。此前逻辑是这样的llama-server 拒绝恰好填满整个 slot context 的 prompt为尽量兼容旧 runner 行为会预留 1 个 token 空间如果 token 数超过限制就按NumKeep保留前部再丢弃中间一段拼接尾部最终生成一个被截断后的 token 序列并记录 truncating input prompt 的 warning 日志而在 v0.30.9 中这套逻辑被彻底删除改为以s.options.NumCtx作为当前 runner 的有效上下文长度这个值在 launch 阶段已经被模型训练上下文长度所限制如果len(tokens) s.options.NumCtx则直接返回一个api.StatusError错误码是http.StatusBadRequest错误信息是the prompt is longer than the context length currently available to the model; shorten the prompt or adjust the context length in settings也就是说现在不再偷偷帮你截断输入而是明确拒绝超限 prompt。这个变化非常重要因为它代表设计思路发生了变化旧逻辑强调“尽量兼容并兜底”新逻辑强调“明确边界并主动报错”这样做的优点是用户不会在不知情的情况下丢失部分 prompt tokencoding agent、assistant 这类对上下文完整性敏感的场景更稳定调试 prompt 失败原因时更直观避免被截断后模型行为异常却难以察觉这也与 changelog 中“当单条消息大于当前上下文窗口时会返回错误”完全一致。十二、对应测试同步改变不再测试截断而是测试拒绝请求llm/llama_server_test.go的测试名称也直接改了从TestLlamaServerCompletionTruncatesPromptAsTokens改为TestLlamaServerCompletionRejectsPromptOverContext这说明测试意图已经完全变化。新的测试重点验证超长 prompt 会返回指定错误错误类型必须是api.StatusError状态码必须是400 Bad Request错误消息必须与预期完全一致/completion接口不应该被调用也就是说当 tokenized prompt 已经超过上下文长度时流程会在进入 completion 前就被拦截掉。旧测试里还会检查被截断后的 token 数组是否符合预期例如保留哪些 token。这些检查现在全部删除因为新的行为已经不再是“截断后继续生成”而是“直接拒绝”。这个改动对使用者来说非常关键特别是依赖长 prompt、长 system message 或长上下文拼接的应用要开始适应“超限显式报错”的新规则。十三、修复 ollama 启动 Claude 等 coding agent 只输出一个 token 的问题官方 changelog 中还有一条非常关键Fixed issue where ollama launch claude and other coding agent or assistant use cases would only output one token虽然用户给出的 diff 片段没有单独展开这条问题在某个具体文件中的完整上下文说明但结合本次上下文处理与 context shift 策略调整可以看到该问题已经作为本版本核心修复项之一被明确列出。也就是说这次更新除了提升稳定性和兼容性还直接修复了某些 assistant、coding agent 典型场景下输出异常短、只生成一个 token 的问题。对于依赖这类场景的用户这个修复价值非常直接。十四、LFM2 parser 重大修复thinking 现在是真正“可选”的了本次版本中LFM2 parser 的修复是最系统的一部分之一。核心目标就是修复“模型没有输出 thinking 时”的解析行为。以前逻辑中的初始状态是LFM2CollectingThinking这意味着一旦 thinking 功能开启parser 会默认认为模型会进入 thinking 采集模式。但现实问题在于LFM2 模型并不是每次都会输出think标签。有些回合会直接回答没有显式思维段。因此这次新增了一个全新的初始状态LFM2LookingForThinking它的注释写得很清楚当 thinking 启用时这是初始状态LFM2 模型只有在真正进行推理时才会输出显式think标签如果是直接回答则根本不会有这个标签因此 parser 在一开始要先观察输出到底是不是以think开头再决定后续进入 thinking 还是 content 采集状态这实际上是在修复一个非常本质的问题不能因为“启用了 thinking”就假设“模型一定会输出 thinking 标签”十五、LFM2 初始化逻辑变化不再默认进入 thinking 采集在setInitialState中原来当 thinking 启用时会做两件事p.state LFM2CollectingThinkingp.needsThinkingLeadingTrim true而现在改为p.state LFM2LookingForThinking注释说明得也很明确thinking 已启用但模型是否进行 reasoning 是按 turn 决定的要等待一个前导think标签如果没有就把后续作为 direct answer 处理这个改动让 parser 的初始化行为更符合 LFM2 的真实输出模式。十六、LFM2 在最终 chunk 的处理更聪明不再无意义等待不完整 think 标签Add方法里新增了一段重要逻辑当done为 true且当前状态仍然是LFM2LookingForThinking会把 buffer 左侧空白去掉如果去掉空白后并不是以think开头就将其直接视为 content重置 buffer 并切换到LFM2CollectingContent这意味着如果流式输出已经结束但 parser 还在犹豫“会不会出现 think 标签”那么到了最后一个 chunk它必须做出判断。而只要最终并没有形成think前缀就不能继续把内容扣在缓冲区里而要把它当作直接回答释放出来。这对于 direct answer 场景尤其关键避免了 thinking 模式下正常回答被错误吞掉或延迟输出。十七、LFM2 状态机新增分支显式区分 reasoning turn 和 direct answer turn在eat()中新增了LFM2LookingForThinking分支逻辑非常完整先忽略前导空白如果以think开头就切入LFM2CollectingThinking如果当前只有空白或者只是think的部分前缀比如th则继续等待更多数据如果已经足够判断不是think那就认定这是 direct answer重置 buffer把去掉前导空白后的内容作为 content 继续处理这个设计非常适合流式场景因为流式输出里标签经常会被拆开分片比如think以前如果 parser 没有中间态就很容易误判。现在它会在“部分前缀”阶段保持等待在“足够判断不是 think 标签”时立即切到 direct answer。十八、LFM2 测试全面补强大量样例围绕“没有 thinking 标签”的情况展开model/parsers/lfm2_test.go这次增加和调整了大量测试用例几乎可以看作对 parser 行为的重新校验。重点变化包括过去多个“thinking_content”类测试输入中缺失开头think标签现在统一补上新增direct_answer_with_thinking_enabled输入是直接答案即使 thinking 启用也应正确解析为 content新增direct_answer_with_tool_call没有 think 标签直接内容后面跟 tool call应正确提取普通内容和工具调用新增streaming_direct_answer流式直接回答应在 thinking 模式下也正常输出新增streaming_thinking_split_open_tag开始标签拆分在多个 chunk 中也必须正确识别新增streaming_direct_answer_starting_with_angle当直接回答以开头时前期会与think存在歧义必须等到足以排除think后再输出为普通内容初始化测试中期望状态从LFM2CollectingThinking改成LFM2LookingForThinking边界测试中empty_thinking_content被改成empty_thinking_block输入由单独/think改为合法的think/thinkJust content新增direct_answer_with_leading_whitespacedirect answer 前导空白会被处理掉这些测试变化说明本次修复不是打补丁式地修一两个条件判断而是把 LFM2 thinking 机制按“可选思考、可直接回答、支持流式拆标签”的真实行为重新梳理了一遍。十九、LFM2 renderer 修复可从 Thinking 字段重建 think 标签除了 parsermodel/renderers/lfm2.go也有明显增强。这次先新增了两个常量lfm2ThinkingOpenTag thinklfm2ThinkingCloseTag /think最关键的逻辑新增是当满足以下条件时r.IsThinking为 true当前消息角色是assistantmessage.Thinking不为空content中又还没有包含/think则会自动把 content 重建为think Thinking /think content官方注释写得也非常清楚从分离的 Thinking 字段中重建 inline 的think.../think块让 reasoning turn 能以模型自己的原始格式 round-tripthinking 应位于 tool calls 和 content 之前direct answer 因为没有 Thinking 字段所以不会添加标签非 thinking renderer 永远不应发送 think 标签即使是末尾 assistant prefill 也不行这个变化说明renderer 现在能更正确地处理“消息对象里的 Thinking 字段”和“模型原始模板里的 think 标签”之间的转换关系。二十、过去 assistant 消息的 reasoning 清理逻辑同步调整此前 renderer 就有一段逻辑用于在不保留历史 thinking 时去掉旧 assistant 消息中的 reasoning 内容。不过那时是直接查找字面量/think。现在逻辑更统一了使用lfm2ThinkingCloseTag注释说明 reasoning 是一个干净的前缀块去掉 close tag 之前的所有内容后tool calls 和 content 可以完整保留这个改动配合前面的“Thinking 字段重建”就很顺了先按需要把 Thinking 字段重建回think.../think再根据是否保留历史 thinking 决定要不要剥离旧轮次 reasoning这样不仅逻辑更统一也避免了 thinking 信息在多轮历史中的格式不一致问题。二十一、LFM2 renderer 测试新增多种关键场景model/renderers/lfm2_test.go这次增加了大量测试重点围绕“Thinking 字段重建”和“是否保留历史 thinking”两个问题。新增的重要测试包括thinking_field_reconstructed_when_enabled当 renderer 开启 thinking且消息带有 Thinking 字段时输出应重建thinkreason/thinkthinking_field_stripped_for_non_last_when_disabled当不保留过去 thinking 时非最后一个 assistant 的 reasoning 应被剥离thinking_precedes_tool_callsthinking 必须位于 tool call 之前direct_answer_history_has_no_think_tagsdirect answer 的历史消息不应平白出现 think 标签non_thinking_renderer_drops_thinking_metadata_on_prefill非 thinking renderer 即使遇到带 Thinking 字段的 assistant prefill也绝不能输出 think 标签arbitrary_roles_are_rendered_verbatim任意角色应按原样渲染这些测试与 parser 侧的修复共同说明v0.30.9 不是只修“解析”而是把“解析”和“渲染”两个方向都对齐了保证有 thinking 和没 thinking 的两类 LFM2 输出都能闭环工作。二十二、server 调度策略变化context shift 默认行为被重新定义server/sched.go的改动是本次另外一个核心变化。之前存在一个常量contextShiftSmallContextLimit 8192旧的resolveContextShift逻辑是如果用户显式设置了shift就以它为准否则只有在numCtx 0 且 numCtx 8192时默认启用 context shift也就是说小上下文默认 shift大于等于 8k 的上下文默认不 shift而现在这整套逻辑被简化成resolveContextShift(shift *bool) bool { return shift nil || *shift }也就是未设置时默认启用显式 false 时关闭显式 true 时开启不再依赖上下文长度也不再区分是否大于 8k。这就是 changelog 中“context shift for context windows larger than 8k”的关键落地点。它意味着对于更大的 context window默认策略不再自动禁用 shift而是统一按“默认开启、除非明确关闭”的方式处理。二十三、多处 context shift 计算同步改造不再传入 numCtx由于resolveContextShift的签名变了调度流程中多个调用点也全部更新getRunner中不再传opts.NumCtxload中不再传effectiveModelContext(launchOpts.NumCtx, f)已加载 runner 回写req.opts.NumCtx后也不再用effectiveNumCtx再判断 shiftneedsReload中也不再依据optsNew.NumCtx重新推导 context shift简而言之现在 context shift 的决定权只取决于用户是否显式传了shift如果没有显式关闭那么默认就是开。这使得调度逻辑更简单也减少了不同上下文大小下行为不一致的问题。二十四、context shift 测试同步重写从“小上下文启用、大上下文禁用”改为“默认启用”server/sched_test.go的测试也对应重写了。旧测试覆盖的是小上下文默认启用大上下文默认禁用非法上下文默认禁用显式 false 覆盖默认显式 true 覆盖默认新测试改成只验证三种情况未设置时默认启用显式 false 禁用显式 true 启用这意味着“8192 这个阈值”在行为层面已经不再是决策依据。二十五、本次更新如何理解不是加功能那么简单而是在统一边界行为把所有改动串起来看v0.30.9 的价值并不只是新增了某个模型架构或者修了一个 parser bug。它更像是在统一几个关键边界构建兼容层如何按顺序组织和应用没有 UI 资源时构建是否还能通过LFM2 在“有 thinking”和“没 thinking”之间如何稳定切换renderer 如何把 Thinking 字段还原成模型模板需要的标签格式prompt 超长时是悄悄截断还是明确报错context shift 是否还要受 8k 上下文阈值影响这些看似分散但本质上都围绕一件事让 ollama 的行为更确定、更可解释、更接近真实模型输出与运行边界二十六、本次版本所有重点变更清单汇总为了便于快速复盘可以把 v0.30.9 的变更完整总结为以下内容发布时间为 2026年6月17日本次发布为 v0.30.9支持 Cohere2Moe architecture修复 LFM2 在未输出 thinking 时的 parser 和 renderer修复 ollama launch claude 以及其他 coding agent、assistant 场景下只输出一个 token 的问题当单条消息大于当前上下文窗口时ollama 会直接返回错误共 3 次提交共 16 个文件变更共 1 位贡献者共 280 行新增、103 行删除LLAMA_CPP_VERSION从 b9509 更新到 b9626llama-cpp-hooks.patch重命名为001-llama-cpp-hooks.patch新增002-llama-cpp-ui-empty-assets.patchllama-cpp-laguna.patch重命名为003-llama-cpp-laguna.patchcompat README 改为强调数字顺序 patch 集patch 应用脚本新增按文件名顺序应用、日志更清晰、失败信息更精确compat.cmake 中 patch 路径同步更新embed.cpp支持没有 UI assets 时生成空资产表laguna.cpp中hparams.n_layer改为hparams.n_layer()llama server 不再对超长 prompt 自动截断而是直接报 400 错误新错误文案明确提示缩短 prompt 或调整上下文长度设置completion 超限测试从“截断成功”改为“请求被拒绝”LFM2 parser 新增LFM2LookingForThinking初始状态thinking 启用时不再默认认为一定有 think 标签流式解析中支持拆分think开标签对 direct answer、tool call、前导空白、角括号起始内容等场景新增测试LFM2 renderer 新增 Thinking 字段重建think.../think逻辑thinking 内容优先于 tool calls非 thinking renderer 不会输出 think 标签历史 assistant thinking 剥离逻辑更统一context shift 解析逻辑从依赖上下文大小改为默认启用大于 8k 上下文窗口也不再默认关闭 context shift调度器和测试全部同步到新策略二十七、结语代码地址github.com/ollama/ollama如果只看 changelogollama v0.30.9 似乎是一次“支持新架构加若干修复”的常规更新。但从具体 diff 来看这个版本真正有价值的地方在于它对多个底层边界行为做了统一和纠正兼容层补丁管理更规范构建链在无 UI 资源时更稳LFM2 thinking 机制终于真正兼容“可能有思考也可能没有思考”的实际输出模式renderer 与 parser 形成更完整的双向闭环prompt 超限从隐式截断转为显式报错context shift 的默认策略也变得更直接一致