bug: get_langchain_prompt(): empty braces {} are not escaped and break LangChain templates

使用 Langfuse Python SDK(v4.9.0)的 BasePromptClient._get_langchain_prompt_string() 方法处理字符串时触发。常见于自定义提示模板中需要描述 JSON 字段可选为字典(如 can be empty {} )的场景,调用方通常为

bug: get_langchain_prompt(): empty braces {} are not escaped and break LangChain templates

bug: get_langchain_prompt(): empty braces {} are not escaped and break LangChain templates

快速结论:当你在 Langfuse 中使用 get_langchain_prompt() 或在 ChatPromptTemplate 中传入包含空花括号 {} 或带空格的花括号 { } 的提示文本时,LangChain 会将其解析为模板变量(空字符串或空格),导致 Input to ChatPromptTemplate is missing variables {''} 错误。优先排查提示词模板中是否存在未被转义的空花括号。

问题场景

使用 Langfuse Python SDK(v4.9.0)的 BasePromptClient._get_langchain_prompt_string() 方法处理字符串时触发。常见于自定义提示模板中需要描述 JSON 字段可选为字典(如 can be empty {})的场景,调用方通常为 LangChain 的 ChatPromptTemplate

报错原文

ValueError: Input to ChatPromptTemplate is missing variables {''}

# 复现代码输出结果
'can be empty {}'  -> 'can be empty {}'   -> ['']    ← breaks ChatPromptTemplate
'spaced { } too'   -> 'spaced { } too'    -> [' ']   ← breaks ChatPromptTemplate
'{"col": "x"}'     -> '{{"col": "x"}}'    -> []      ← correctly escaped

原因分析

Langfuse 的 BasePromptClient._escape_json_for_langchain 方法在转义花括号时,仅判断 { 后的第一个非空白字符是否为引号(单引号或双引号),用于检测 JSON 结构。但该启发式逻辑未处理 {}{ } 的情况,导致这些花括号未被转义为 {{}} / {{ }}。后续 LangChain 的 Formatter(){} 解析为变量名 ”(空字符串)或 ‘ ‘(空格),从而触发模板变量缺失错误。

环境排查

  • Langfuse Python SDK 版本(已知 v4.9.0 受影响)
  • LangChain 版本(无论版本,只要使用 ChatPromptTemplate 均受影响)
  • 检查本地 langfuse/model.py_escape_json_for_langchain 方法的实现

解决步骤

  1. 优先尝试临时手动转义:在 Langfuse 提示模板中,将 {} 改写为 {{}},将 { } 改写为 {{ }}
  2. 确认是否需要代码修复:检查当前 SDK 版本是否包含修复。如果未修复(如 v4.9.0),请参考以下补丁逻辑(已有社区贡献方案):在 _escape_json_for_langchain 方法中,增加对 { 后紧跟 }(允许中间有空白字符)的检查,将其一并视为需要转义的场景:
    # 修改后的伪代码
    j = i + 1
    while j < n and text[j].isspace():
        j += 1
    is_json = j < n and text[j] in {"'", '"'}
    is_empty_braces = j < n and text[j] == "}"  # 新增检查
    out.append("{{" if (is_json or is_empty_braces) else "{")

    同时确保对应的结束花括号逻辑也做对称修改。

  3. 提交 PR 或等待官方修复:此 Issue 已有用户表示愿意贡献修复,可关注 langfuse/langfuse-python 仓库的 model.py 文件更新。

验证方法

运行以下测试代码,确认所有场景均正确转义且不会产生空变量:

from string import Formatter
from langfuse.model import BasePromptClient

for text in ['can be empty {}', 'spaced { } too', '{"col": "x"}', '{ \n}']:
    out = BasePromptClient._get_langchain_prompt_string(text)
    vars = [f for _, f, _, _ in Formatter().parse(out) if f is not None]
    print(f"{text!r} -> {out!r} -> template vars {vars}")
# 预期输出:
# 'can be empty {}'  -> 'can be empty {{}}'  -> []      ← 正确转义
# 'spaced { } too'   -> 'spaced {{ }} too'   -> []      ← 正确转义
# '{"col": "x"}'     -> '{{"col": "x"}}'     -> []      ← 保持正确
# '{ \n}'           -> '{{ \n}}'            -> []      ← 正确转义

参考来源

langfuse/langfuse #14721

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 13485

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注