schemagate 会从数百张表中挑出文本转 SQL 模型应该查看的少数几张。它先用简单的数学方法排序(BM25、嵌入、名称匹配,再用 RRF 融合)。然后,如果你提供 API 密钥,模型可以重新排列排名前 20 的表。这第二步就是重排序。
有人问我为什么用 RRF 而不用 LLM 重排序。我说它有这个功能,--rerank,就去演示它的运行效果。结果它没能正常工作。
我在 claude-haiku-5-5 上,用和不用 --rerank,对同样的三个问题各跑了一遍。三次得到的表顺序都完全相同。
如果数学排序已经排对了,就可能出现这种情况。所以我给服务提供方套了一层封装,记录每次调用及其返回内容。模型确实被调用了,只是始终没有给出答案。
reply = provider.complete(SYSTEM, prompt, max_tokens=120)
120 个 token 足够给出类似 3, 1, 7, 2, 5 这样的回复。我写下这句话时,它确实足够。
Claude 5 模型会在回答前思考,而思考也会占用 max_tokens。它们把 120 个 token 全用来思考,在写出任何数字之前就停下了。服务提供方报错了。重排序器按设计捕获了这个错误:
except Exception:
return list(docs) # never worse than the maths alone
然后返回数学排序的顺序。没有崩溃,没有警告,结果就和不用 --rerank 时一样。
tests/test_rerank.py 的测试做得不错。模型报错时,顺序保持不变。模型回复一堆垃圾时,顺序保持不变。模型不能把调用方无权查看的表排到前面。这些都没错,也都通过了测试。
这些测试全都验证了失败时系统能安全回退。没有一个验证模型确实有机会回答。当回退机制被设计得不露痕迹时,彻底失效看起来就和成功一模一样。
max_tokens 现在设为 1024。测试套件新增了一个假模型:低于 512 个 token 时它会拒绝回答,因此如果有人再次调低上限,测试就会失败。基准测试现在也会记录模型是否回答了每个问题,而不只记录最终分数。
我检查的是已发布的包,而不是我的工作副本:PyPI 上的 1.4.4 得到了 3 个模型回答中的 1 个,且 3 个问题的排序一个也没变;1.5.0 得到了 3 个回答,并改变了其中 2 个问题的排序。
它真正运行起来后,我首次在公开基准上测量了它的表现。把 Spider dev(876 张表)和 BIRD dev 的所有数据库放在一个候选池中,不提供问题所属数据库的提示。如果正确 SQL 用到的每张表都出现在前 5 名中,就算命中。
set questions maths order reranked only rerank right only maths right
spider 1034 80.3% 96.5% 169 1
bird 1534 88.6% 96.7% 125 1
配对 McNemar 检验:Spider 上 p 值约为 1e-49,BIRD 上约为 1e-36。这是基准测试文件中单项提升幅度最大的一项。
这项测量反映的是正确的表是否进入提示词,而不是最终 SQL 是否正确。只用了一个模型。Spider 和 BIRD 都是公开数据集,因此模型可能在训练时见过它们。它只会重新排列数学方法已筛选出的表,并且看到的是表名和简短摘要,而不是答案 SQL。
如果你构建了“安全回退”机制,也要记录它何时触发。否则,这项功能即使完全失效,你的仪表板看起来仍可能一切正常。
试试看:pip install "schemagate[ai]",然后 schemagate demo "which customers owe us money" --rerank --provider anthropic --model claude-haiku-5-5。在 MCP 服务器中,设置 SCHEMAGATE_MCP_RERANK=1。代码和完整基准测试:https://github.com/ashishsinha1602/schemagate