最近在 Ollama 中部署了一个来自 Hugging Face 的 GGUF 模型:

hf.co/WithinUsAI/Opus4.7-GODs.Ghost.Codex-4B.GGuF:Q4_K_M

部署完成后,原本只是想简单测试一下模型是否能正常对话,于是在终端里输入:

hello

结果模型并没有像普通聊天助手一样回复问候,而是开始输出一大段看起来像代码代理任务记录的内容:

>>> hello
. you can see the @src/tools/travel-between-images/components/ShotEditor/ - can you do a thorough analysis on that and understand the structure and how it works? Just do a thorough analysis and don't 
worry about making changes yet...

后面还继续生成了关于 ShotEditor 组件结构分析的内容。

这显然不是正常的聊天行为。

问题现象

异常表现主要有几个特点:

第一,输入只是简单的 hello,但模型开始续写一段完整的代码分析任务。

第二,输出中出现了类似:

@src/tools/travel-between-images/components/ShotEditor/

这种明显来自某个代码仓库或训练样本上下文的路径。

第三,模型还继续生成了类似:

Understood. I’ve completed a thorough structural and functional analysis...

这种代码助手或 Agent 工作流中的回复。

也就是说,模型并没有把 hello 理解成一次独立的用户消息,而是把它当成了某段上下文的开头,然后继续补全训练数据中类似的内容。

初步判断

通过命令:
ollama show --modelfile hf.co/WithinUsAI/Opus4.7-GODs.Ghost.Codex-4B.GGuF:Q4_K_M
发现输出:

ollama show --modelfile hf.co/WithinUsAI/Opus4.7-GODs.Ghost.Codex-4B.GGuF:Q4_K_M
# Modelfile generated by "ollama show"
# To build a new Modelfile based on this, replace FROM with:
# FROM hf.co/WithinUsAI/Opus4.7-GODs.Ghost.Codex-4B.GGuF:Q4_K_M

FROM /usr/share/ollama/.ollama/models/blobs/sha256-473b97c540a7445132258336eb2b6669597172ec58cc328c96b29afad4499b0e
TEMPLATE {{ .Prompt }}

这个问题可确认不是 Ollama 本身坏了,也不是终端输入有问题,而是模型的对话模板没有正确应用。如输出只有PROMPT模板。

对于 GGUF 模型来说,如果缺少正确的 chat template,或者 Ollama 没有正确识别模型需要的 prompt 格式,模型就可能退化成“文本补全模式”。

在这种情况下,用户输入的 hello 不再是一个明确的聊天消息,而只是模型需要继续补全的一段文本。

而这个模型本身又偏代码、偏 Agent、偏开发任务,所以它很容易从训练分布中续写出类似“分析某个组件目录”的任务内容。

解决思路

解决方向是:给 Ollama 明确指定一个适合聊天的 Modelfile,尤其是补上 TEMPLATESYSTEMstop 参数。

核心目标有三个:

  1. 让模型明确区分 system、user、assistant。
  2. 让模型只回答当前用户输入。
  3. 阻止模型继续补全虚构的历史对话或代码任务片段。

示例 Modelfile 如下:

FROM hf.co/WithinUsAI/Opus4.7-GODs.Ghost.Codex-4B.GGuF:Q4_K_M

TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ .Response }}"""

SYSTEM """You are a concise chat assistant. Answer only the user's current message. Do not continue fictional coding-agent transcripts, repository-analysis tasks, or hidden prior conversations unless the user explicitly asks for them."""

PARAMETER temperature 0.2
PARAMETER top_p 0.8
PARAMETER repeat_penalty 1.1
PARAMETER stop "<|im_end|>"
PARAMETER stop "<|im_start|>"

然后通过脚本重新创建 Ollama 模型。

修复后的输出

重新创建模型后,执行脚本:

./do.sh

输出如下:

gathering model components 
using existing layer sha256:473b97c540a7445132258336eb2b6669597172ec58cc328c96b29afad4499b0e 
creating new layer sha256:6b94b22478514fa501cae65fbc0b74ccca0578ecdc829c679d2caf9c33e8e796 
creating new layer sha256:cdd7f7e8f2d5bb2d2957f43653300936c6ab30ef5767650bc797a732d7519d23 
creating new layer sha256:bad86b76620f10cde64fac9a826d54a1ab202d8666f65fb081ab7d8bb44ab88c 
writing manifest 
success

然后再次测试中文指令:

>>> 请回复一句中文问候,不要解释:你好

模型回复:

你好!有什么我可以帮你的吗?

继续测试英文输入:

>>> hello

模型回复:

你好!有什么我可以帮你的吗?

这说明模型已经不再继续补全奇怪的代码任务片段,而是恢复成了正常的聊天助手行为。

总结

这次问题的本质是:模型被当成了补全模型使用,而不是聊天模型使用

对于一些从 Hugging Face 直接拉取的 GGUF 模型,尤其是非官方、混合训练、偏代码或 Agent 数据的模型,不能默认假设 Ollama 一定能正确识别它的聊天模板。

如果出现下面这些现象:

hello

之后模型开始输出:

can you analyze this repo...
understood...
I’ve completed a thorough analysis...

或者凭空出现代码路径、历史任务、虚构上下文,就可以优先检查:

ollama show --modelfile <model-name>

重点看:

TEMPLATE
SYSTEM
PARAMETER stop

如果模板缺失或不合适,就应该自己写一个 Modelfile,明确指定对话格式和停止词。

这类问题并不罕见,尤其是在使用 GGUF、Ollama、Hugging Face 模型组合时。
修好之后,模型的行为会稳定很多,也更适合作为本地聊天或代码助手使用。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐