事情本身不复杂,线索都在日志里。提示词模板存在 YAML 配置文件里,某条规则写成「注意: 不要编造事实」,用 yaml.safe_load 读出来变成 {'注意': '不要编造事实'},渲染后模型收到的是一条结构化字段,规则整体失效,回答开始编造条款。

第一反应是「模板里含中文全角冒号混用,格式校验被绕过」,验证下来不成立。

排查方向其实有限,先把可能性排一排。未加引号的标量里出现冒号加空格,YAML 会解析成映射。另一种情况是多行规则用了缩进块但首行没写竖线,后续行被当成新键。

还有一种情况,加载后只取了 value 拼字符串,键名被丢掉。

第一件事是看读出来的结构到底是什么类型

python -c "import yaml;d=yaml.safe_load(open('prompts.yaml',encoding='utf-8'));print(type(d['rules'][0]), d['rules'][0])"

再往下把规则改成带引号的字符串再读

python -c "import yaml;print(yaml.safe_load('rules:\n  - \"注意: 不要编造事实\"\n')['rules'])"

长规则改用竖线块保留换行

python -c "import yaml;print(yaml.safe_load('rules:\n  - |\n    注意: 不要编造事实\n    不确定就说不确定\n'))"

末了加载后统一断言类型再拼 prompt

python -c "import yaml;d=yaml.safe_load(open('prompts.yaml',encoding='utf-8'));assert all(isinstance(x,str) for x in d['rules']);print(len(d['rules']))"

改完先别撤,确认这几项。读出来的每条规则都是字符串且与原文逐字一致,渲染后提示词里能看到完整句子,连续三次回答不再出现凭空条款。

提醒一点。YAML 里冒号加空格就是语法,写规则时一律加引号或用块标量,能省掉后面反复对不齐的麻烦。拖得越久,排查成本越高,因为现场状态会被后续操作覆盖。

作者 9823189