IBM发布LLMON:用结构化标记解决大模型提示注入难题
为什么大模型需要自己的标记语言
大语言模型(LLM)的核心工作机制是基于上下文生成下一个令牌。随着对话轮次增加或任务复杂化,模型的上下文窗口里塞满了各种内容:系统提示词、历史对话、检索到的文档片段、工具返回的结果,以及用户输入的数据。这些内容混杂在一起,大部分结构对模型来说是隐式的,或者被迫使用JSON等格式进行编码。
问题在于,JSON这类格式最初是为程序解析器设计的,而不是给因果语言模型“消化”的。对于模型而言,JSON中的引号、括号只是普通令牌,它们并不真正理解嵌套层级或转义规则。这种结构上的模糊性不仅让小型模型容易出错,还留下了安全漏洞——攻击者可以将恶意指令隐藏在用户数据中,诱导模型执行非预期操作,这就是所谓的“提示注入”。
为了解决这个问题,IBM Granite团队开发了LLMON(LLM Object Notation,读作“lemon”)。这是一种原生于大语言模型的标记语言,旨在向模型明确传达结构和语义。LLMON使用有意义的标签包裹语义连贯的组件,并通过保留的特殊令牌分隔符来界定边界。这种方式让数据模式(包括嵌套关系)对因果LLM来说变得毫无歧义。更重要的是,LLMON引入了唯一ID机制,允许指令指向上下文中的任意特定数据负载,就像编程语言中函数调用传递参数一样精确。
目前,IBM基于Granite 4.1基础模型发布了两个实验性预览版本:granite-4.1-3b-LLMON-preview和granite-4.1-8b-LLMON-preview。同时,官方也在GitHub上开源了相关工具库,包含处理LLMON的工具包、工作流示例及模板。
JSON为何不适合大模型
很多开发者习惯用JSON与大模型交互,但这其实是一种妥协。JSON的结构依赖于字符如 {、"、:,这些字符在正常文本中也会出现。 tokenizer(分词器)并没有被约束去尊重JSON语法。对模型来说,文档内部的引号和闭合字段的引号是同一个令牌。那些对解析器清晰的转义规则,对模型而言只是统计规律。此外,Transformer架构在处理长跨度内的括号计数和嵌套深度时表现较弱,容易导致结构解析错误。
LLMON则不同。它类似XML,但其结构分隔符是tokenizer词汇表中的保留特殊令牌,而非普通字符。这意味着结构和内容使用了词汇表的不同部分。每个片段的开头都明确声明了标签,片段之间的边界清晰可见。嵌套结构在局部声明,模型无需在长上下文中追踪层级关系。
考虑到大多数团队已有基于JSON的流程,IBM提供了转换工具,可以无损地将JSON转换为LLMON,反之亦然。这降低了迁移门槛,让开发者可以在不重构整个数据管道的前提下尝试新方案。
LLMON与聊天模板的关系
LLMON并不是要取代聊天模板,而是对其增强。传统的聊天模板告诉模型哪部分属于哪个角色(如system、user、assistant),而LLMON进一步告诉模型每个组件的含义,以及组件之间在角色内部和跨角色的关系。
LLMON预览模型自带专用的聊天模板。开发者构建消息列表的方式与常规聊天模型无异,调用 apply_chat_template 即可。区别在于,现在可以为对话轮次的各个部分命名,并标记 exec: True 或 False。
标记为 True 的部分会被绑定到渲染输出底部的 exec 块中,明确指定要运行哪条指令、作用于哪些数据;标记为 False 的部分虽然仍渲染到上下文中,但不会被任何指令引用。例如,一个用户请求可能包含指令、数据和需求三个部分,LLMON会将它们渲染为五个独立的可寻址块,并通过第六个块(exec块)将它们关联起来:执行该指令,使用该数据,遵循这些要求,并将答案填入指定的助手块。
相比之下,传统模板会将所有组件扁平化为一个字符串,迫使模型自行推断哪部分是任务、哪部分是主体、哪部分是约束。LLMON通过显式绑定消除了这种猜测。
如何抵御提示注入攻击
间接提示注入是一种常见攻击手段,恶意指令被隐藏在检索文档、工具响应或用户提供的数据载荷中。LLMON的核心设计——指令与数据的显式分离——正是为了应对这一问题。
在OPI基准测试中,研究人员将注入指令隐藏在经典NLP任务的数据部分。测试结果显示,非LLMON模型极易受攻击,高概率执行注入的恶意指令。而LLMON模型在该基准测试中几乎完全消除了这一问题。与测试中表现最好的前沿模型相比,LLMON避免了多出47%的攻击;与最好的开源模型相比,这一数字高达95%。在ASB和StruQ等其他基准测试中也观察到了类似的趋势。
这种安全性提升源于LLMON的“特权规则”:只有通过执行块到达的指令才具有权威性,而作为输入到达的内容(数据、文档、工具结果)仅被视为阅读材料,而非待执行的命令。未在執行块中被调用的指令和数据片段会被模型忽略。这是一种通过学习获得的行为,而非硬编码的护栏。
通用能力并未受损
通常,加强安全性往往以牺牲通用能力为代价,但LLMON模型打破了这一惯例。在标准基准测试类别中,LLMON模型的表现与Granite 4.1 Instruct模型持平。
这意味着,如果你正在使用Granite 4.1 3B或8B模型,可以直接替换为LLMON预览版。无需修改转换管道,只需在构建消息时命名轮次的各个部分(如instruction、data、requirement),内置的聊天模板会自动将其转换为LLMON块。你将获得相当的通用性能,同时具备更强的抗提示注入能力。
如果某部分内容本身具有结构(如JSON文档),使用LLMON转换器可以将其保留为类型化、可单独寻址的块,而不是一个不透明的字符串。这有助于模型更精细地理解复杂数据结构。
模型训练细节
LLMON模型是从Granite 4.1基础检查点开始训练的,而不是在已发布的Instruct模型上叠加。这意味着LLMON的行为是在后训练阶段习得的。
LLMON定义了六个分隔符,用于标记标签的开始和结束,支持嵌套和锚定,它们作为保留的单令牌安装在tokenizer中。研究团队将传统的指令微调语料库重新序列化为LLMON格式:每个提示组件成为其 own 可寻址块,每个轮次携带一个执行块,指明要运行的指令、操作对象及输出位置。
任务混合包含了常规Instruct模型所见的内容(聊天、多轮对话、RAG、工具调用),因此基准测试性能保持接近。此外,数据中增加了诱饵指令和数据块,这些块存在于上下文中但故意未被绑定,而目标输出保持不变。这迫使模型学习遵循执行块规定的依赖关系,并忽略其余部分。
随后进行了强化学习,包括五个顺序的GRPO阶段,涵盖多领域推理、RLHF、知识校准和数学,最后是一个基于DPO的阶段,使用从模型自身对注入尝试的响应中构建的一千个在线偏好对。
自定义词汇表:以ScienceWorld为例
LLMON不绑定于固定模式。你可以选择适合你领域的标签名称和结构,并微调适配器来读写它们。
在ScienceWorld基准测试中,代理需要通过发出命令来完成基础科学任务(如烧水)。研究团队定义了一套捕获规划轨迹结构的词汇表,包括 instr.task.goal、req.planning_policy.rule、data.state.room 等标签。他们将ScienceWorld参考解决方案的每一步都用这些标签渲染,并在LLMON模型之上微调了一个LoRA。
训练后的模型在持有游戏中表现出色,并能用新词汇表写出下一步动作。这证明了LLMON的灵活性:开发者可以为特定应用场景定义专属的结构化语言,并通过轻量级微调让模型掌握它。GitHub仓库中提供了完整的笔记本示例,展示了从转换参考轨迹到玩游戏及评分的全过程。
如何开始尝试
目前发布的LLMON模型属于实验性预览版,适合探索和评估,暂不建议直接用于生产环境。
你可以通过Hugging Face获取granite-4.1-3b-LLMON-preview和granite-4.1-8b-LLMON-preview模型。如果想直观理解LLMON如何在注意力层工作,可以尝试LLMON Attention Visualization演示。此外,Mellea项目已原生支持LLMON,能自动将LLM调用“LLMON化”,是一个不错的上手工具。
IBM团队鼓励开发者在GitHub Discussions中反馈使用体验:哪些地方奏效,哪些地方出错,以及希望看到哪些用例。这种早期反馈对于完善LLMON生态至关重要。随着更多开发者参与,LLMON有望成为构建安全、可靠大模型应用的标准基础设施之一。