Ollama使用推理模型输出<think></think>导致LangChain OutputParser失败问题"
问题本质
部分 Ollama 模型(尤其带 internlm / qwen / chatglm 等“思维”功能的)默认会在答案前加上 <|im_start|>assistant
或 <think>…</think>
推理块,导致结果 既不符合纯 JSON,PydanticOutputParser
解析必然失败。
可行策略
使用原生 JSON-Mode / function-call(首选)
Ollama ≥0.1.27 支持请求参数self.llm = ChatOllama( model=OLLAMA_MODEL, base_url=OLLAMA_BASE_URL, format="json" # <-- 关键 )
或在 prompt 中加
"tool": { "name": "output", "parameters": {...}}
等函数调用格式,让模型直接返回结构化 JSON,无“思考过程”。强制停止词
给ChatOllama
传stop=["</think>", "<think>"]
,模型一出现<think>
就被截断。self.llm = ChatOllama(..., stop=["<think>", "</think>"])
后处理清洗(兜底)
当 JSON-mode 不支持时,仍可在 parser 前加一层OutputFixingParser
:from langchain.output_parsers import OutputFixingParser self.parser = OutputFixingParser.from_llm(parser=self.parser, llm=self.llm)
它会自动尝试剥离多余文本并重试解析。
Prompt 级硬要求
在系统/前置提示里反复强调:“只能输出 JSON 数组,绝不输出任何解释或 <think> 块。 若含解释性文字将被视为错误。”
推荐改动示例
self.llm = ChatOllama(
model=OLLAMA_MODEL,
base_url=OLLAMA_BASE_URL,
temperature=0,
format="json", # ✅ 直接要求 JSON 输出
stop=["<think>", "</think>"] # 双保险
)
若 format="json"
仍不支持该模型:
from langchain.output_parsers import OutputFixingParser, PydanticOutputParser
base_parser = PydanticOutputParser(pydantic_object=EventList)
self.parser = OutputFixingParser.from_llm(base_parser, self.llm)
这样就算模型输出:
<think>先判断类别…</think>[{...}]
OutputFixingParser
也能保留 [ {...} ]
部分给 Pydantic 解析。
小结
- 首选用 Ollama 的 JSON / function-call 模式直接杜绝思考文本;
- 同时设
stop
截断<think>
; - 最后再加
OutputFixingParser
兜底清洗,可让解析成功率接近 100%。