
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方法的实现
解决步骤
- 优先尝试临时手动转义:在 Langfuse 提示模板中,将
{}改写为{{}},将{ }改写为{{ }}。 - 确认是否需要代码修复:检查当前 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 "{")同时确保对应的结束花括号逻辑也做对称修改。
- 提交 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}}' -> [] ← 正确转义

![投机性增长与AI“泡沫”[pdf]](https://www.chat-gpts.plus/wp-content/uploads/2026/07/ai_cover_5-510-768x403.jpg)

![必须积极资助开源AI [pdf]](https://www.chat-gpts.plus/wp-content/uploads/2026/07/ai_cover_3-515-768x403.jpg)