自然语言没有"无效句子"的概念。
没有人检查进入上下文的东西
看看在当前LLM管道中,信息是如何进入上下文的。
RAG返回块。 Agent接收API响应。 之前的对话在历史中积累。 用户上传文档。
这些进入上下文窗口。 没有检查。
为什么没有检查? 因为自然语言没有"无效"的概念。
自然语言接受一切字符串
在编程中,存在语法错误这回事。
def calculate(x, y
return x + y
括号没有关闭。在执行之前就被拒绝了。 代码可以在运行之前、甚至在被阅读之前,就被明确宣告"这不是有效代码"。
自然语言没有这种东西。
“He went to the bank.” 语法完美。 你无法知道谁去了、哪个bank、为什么去, 但没有任何东西违反自然语言的语法规则。
“2024年13月45日的销售报告。” 没有13月,也没有45日。 但没有任何东西违反自然语言的语法规则。 这是一个语法上有效的句子。
“来源:不明。可信度:不明。日期:不明。三星电子市值为1200万亿韩元。” 来源不明,可信度不明,参考日期不明。 但没有任何东西违反自然语言的语法规则。
自然语言接受一切。 无效的自然语言句子在结构上不存在。 因此,不存在机械地"拒绝"以自然语言表达的信息的标准。
机械校验需要什么
看看Go编译器。
如果有未使用的import,Go拒绝编译。 即使代码运行完全正常。 即使逻辑没有任何问题。 仅仅因为一行import未被使用,就拒绝编译。
这就是机械校验。
机械校验有三个特征。
它是确定性的。 结果是"是"或"否"。不是概率。没有"大概没问题"。有效或无效。
它是廉价的。 不需要LLM调用。字符串比较、字段存在性检查、值范围检查。纳秒级别的CPU操作。
它不阅读含义。 它不判断内容是真还是假。它只检查格式是否符合规范。它不知道"三星电子市值为1200万亿韩元"是否为真。但它知道来源字段是否为空。
这三件事要成为可能,有一个前提条件。 信息必须有规范。
如果有规范,违规就被定义了。 如果违规被定义了,拒绝就成为可能。 如果拒绝成为可能,校验就存在。
自然语言没有规范,所以没有违规。 没有违规意味着没有拒绝。 没有拒绝意味着没有校验。
为什么需要上下文前校验
上下文窗口是有限的。
无论是128K token还是1M token,都是有限的。 进入有限空间的信息质量决定了输出的质量。
然而在当前的管道中, 质量判断只在信息进入上下文之后才发生。 你期望LLM自己去阅读、判断,然后得出"这条信息不太可信"的结论。
这在三个方面是错误的。
它很昂贵。 你在用LLM推理成本做格式检查。你运行一个数十亿参数的模型来过滤掉没有来源的块。你在用概率推理完成一个只需检查单个字段的任务。
它不可靠。 不能保证LLM总是忽略没有来源的信息。事实上,一旦东西进入上下文,LLM更倾向于使用它。期望模型忽略你放进上下文的东西,这本身就是矛盾。
它太晚了。 窗口空间已经被消耗。如果5个没有来源的块各占200个token,1000个token就浪费了。即使它们后来被过滤掉,那些空间已经花掉了。
机械校验在所有这些之前。 在进入上下文之前。 在LLM阅读之前。 在窗口被消耗之前。
校验什么
机械校验检查的不是内容的真假,而是对格式规范的符合性。
具体来说,检查这些东西:
结构完整性。 必填字段是否存在?边是否有主语和宾语?是否缺少什么?
标识符有效性。 被引用的节点是否存在?写着"三星电子"的东西是否实际指向一个已定义的实体?引用是否悬空?
类型符合性。 日期字段里是否有日期?数字字段里是否有数字?“2024年13月45日"在这里被捕获。
元数据存在性。 是否有来源字段?是否有时间字段?是否指定了可信度?如果没有,拒绝、标记为缺失、或赋予默认值。
引用完整性。 边指向的节点是否真实存在?是否在引用一个已删除的节点?
这些检查有一个共同点。 所有这些都可以在不阅读内容的情况下完成。 你不知道"三星电子市值为1200万亿韩元"是否为真。 但你知道这条陈述是否指定了来源。 你知道这条陈述是否记录了时间。 你知道这条陈述的格式是否符合规范。
廉价的先行
在上下文工程管道中,检查有顺序。
机械校验:规范符合性。成本接近零。确定性。 语义过滤:相关性、可信度、有用性判断。成本高。概率性。 一致性检查:被选中的信息之间的矛盾。成本更高。需要推理。
如果按从最廉价到最昂贵的顺序排列, 昂贵的检查需要处理的内容就更少。
如果机械校验过滤掉了30%缺少来源的陈述, 语义过滤只需要处理70%。 如果语义过滤去除了不相关的, 一致性检查处理的集合就更小。
这和数据库查询优化是同一个原理。 先在WHERE子句中应用可索引过滤的条件。 全扫描条件放后面。 如果廉价的先行,昂贵部分的负担就减轻了。
反过来, 如果先运行昂贵的检查再运行廉价的检查, 你在已经花费成本之后才发现格式错误。 你分析一条引用了不存在节点的陈述的含义, 然后才发现引用是无效的。
这个顺序在自然语言管道中是不可能的
自然语言没有规范,所以机械校验不可能。 既然机械校验不可能,最廉价的检查就不存在。
于是,每次检查都是语义检查。 每次检查都需要LLM。 每次检查都很昂贵。
“这个块有来源吗?"——LLM必须阅读。 “这个块的时间引用是否合适?"——LLM必须阅读。 “这个块的格式是否正确?"——自然语言没有格式,所以这个问题本身就不成立。
这就是当前上下文工程的现实。 即使是最简单的检查,也要用最昂贵的工具来完成。 一个字符串比较就能结束的任务,交给推理引擎来处理。
校验的前提条件
机械校验的存在需要三件事。
规范。 信息必须遵循的格式必须被定义。哪些字段是必填的,哪些值是允许的,哪些引用是有效的。没有规范,就无法定义违规。
形式化。 信息必须以规范要求的格式表达。不是以自然语言句子,而是以规范要求的结构编码。未形式化的信息无法被检查。
拒绝权。 对不符合要求的信息必须能够实际拒绝。如果检查了但总是通过,那不是校验。无效信息必须被阻止进入上下文。
这三件事在编程语言中被视为理所当然。 有一个叫语法的规范,一个叫代码的格式,一个叫编译器的拒绝权。
在自然语言中,三者全部缺失。 语法不是格式规范而是惯例。 句子不是结构化格式而是自由文本。 “无效的自然语言"这个概念不存在,所以没有什么可以拒绝。
要在上下文工程中引入机械校验, 信息的表示方式本身必须改变。
总结
在当前的上下文管道中,信息未经检查就进入上下文。 因为自然语言没有"无效句子"的概念。
机械校验检查的不是内容的真假,而是对格式规范的符合性。 结构完整性、标识符有效性、类型符合性、元数据存在性、引用完整性。 确定性的、廉价的,而且不阅读含义。
在管道中,廉价的检查必须先行。 如果机械校验过滤掉了格式错误, 昂贵的语义判断需要处理的内容就更少。
自然语言没有规范,所以这种检查不可能。 每次检查都变成语义检查,每次检查都很昂贵。
机械校验要成为可能, 必须有规范、形式化和拒绝权。 信息的表示方式本身必须改变。