Ollama使用推理模型输出<think></think>导致LangChain OutputParser失败问题"

问题本质

部分 Ollama 模型(尤其带 internlm / qwen / chatglm 等“思维”功能的)默认会在答案前加上 <|im_start|>assistant<think>…</think> 推理块,导致结果 既不符合纯 JSONPydanticOutputParser 解析必然失败。

可行策略

  1. 使用原生 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,无“思考过程”。

  2. 强制停止词
    ChatOllamastop=["</think>", "<think>"],模型一出现 <think> 就被截断。

    self.llm = ChatOllama(..., stop=["<think>", "</think>"])
    
  3. 后处理清洗(兜底)
    当 JSON-mode 不支持时,仍可在 parser 前加一层 OutputFixingParser

    from langchain.output_parsers import OutputFixingParser
    self.parser = OutputFixingParser.from_llm(parser=self.parser, llm=self.llm)
    

    它会自动尝试剥离多余文本并重试解析。

  4. 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%。
CoolCats
CoolCats
理学学士

我的研究兴趣是时空数据分析、知识图谱、自然语言处理与服务端开发