思维缓冲库:复用推理模板而非答案—检索、实例化、蒸馏迭代
构建可复用的思考模板库而非记忆单次答案,LLM 通过检索和蒸馏改进推理,比纯 Few-shot 转移效果更好。
构建可复用的思考模板库而非记忆单次答案,LLM 通过检索和蒸馏改进推理,比纯 Few-shot 转移效果更好。
给语言模型一道全新的应用题,普通的 chain-of-thought 每次都会从零开始推导:反复重新得出同一种方法,也反复犯下同样的错误。Few-shot 的表现稍好一些——它会贴上几组看起来相似的「问题→答案」示例——但它迁移的是表面形式,而不是方法。因此,当一道题的表述不同、所需的推理方式却相同时,它很容易错过匹配。Buffer of Thoughts(Yang 等,2024)维护了一个 meta-buffer,其中保存着从已解决问题中提炼出的、可以重复使用的 thought-template。我构建了一个实时演示,实际运行了检索与 buffer 更新流程。它的思路如下。
每个条目都是一个 thought-template:包含用于检索的特征、可复用的推理骨架(也就是方法),以及使用次数。它存储的不是答案,而是「如何解决」。
{ name: "Combined Work Rate", keywords: ["pipe","fill","rate","hours"],
skeleton: [ "each worker's RATE = 1 / time",
"they act at once, so ADD the rates",
"invert for the combined TIME = 1 / total" ], uses: 5 }
拿到一个新问题后,计算每个 template 的相似度分数,然后选取分数最高的那个。生产环境中的 BoT 会对问题和每个特征签名进行 embedding,并使用 cosine similarity;演示版本使用的是 bag-of-words cosine——思路相同,而且不需要 API key。如果相似度低于阈值,就说明没有合适的匹配项。
function retrieve(problem, buffer){
return buffer.map(t => ({ t, sim: similarity(problem, t) }))
.sort((x, y) => y.sim - x.sim)[0]; // best match
}
检索到的 skeleton 是一个脚手架;模型——或者在需要精确算术时使用可信代码——会根据当前问题的具体信息填充其中的槽位并执行。最困难的部分,也就是采用什么方法,已经提前确定,因此与自由形式的 CoT 每次都从头重新推导相比,出错的机会要少得多。
const nums = problem.match(/\d+/g).map(Number); // e.g. times [3, 6]
const rate = nums.reduce((s, t) => s + 1/t, 0); // 1/3 + 1/6
const time = 1 / rate; // = 2 hours
问题解决后,再把结果归纳回 buffer。如果某个 template 与问题高度匹配,就强化它,也就是增加它的使用次数。如果没有任何 template 达到阈值,就从推理 trace 中提炼出一个新 template,并插入 buffer。
正是这种动态更新机制,让 buffer 每解决一道题都会变得更加丰富——这个系统确实会随着使用次数的增加而不断变强。
if (best.sim >= THRESHOLD) best.t.uses += 1; // reinforce the one we used
else buffer.push(await distil(problem, trace)); // learn one: 4 -> 5
整个循环会组装出一个 prompt,其中包含检索到的 template 和当前问题,并明确要求模型实例化这个 template,而不是从零开始推理。正是这种简单的重新表述,让存储的方法能够再次转化为一个全新的答案。
const botPrompt = (tpl, problem) => `
You have a distilled thought-template for problems like this.
Instantiate it on the specifics below — do not reason from scratch.
Template — ${tpl.name}:
${tpl.skeleton.map((s, i) => ` ${i+1}. ${s}`).join("\n")}
Problem: ${problem}`;
由此可以得到三点结论。
第一,推理方法只需推导一次,之后所有具有相同结构的问题都可以分摊这一次推导的成本,而不必每次都重新付出。
第二,template 捕捉的是「如何解决」,因此即使问题的表面形式发生变化,它仍然可以完成迁移;而基于示例的方式往往会在这里失效。
第三,由于 buffer 会在每次解题后更新,因此它能够自我改进。
它只依赖 prompt 和 orchestration,不需要 fine-tune;同时,它还可以叠加在 CoT、chain-of-table 和 tree-of-thoughts 之上,成为这些方法上层的可复用推理层。
我现在记住的核心原则是:不要让模型针对每一个问题都重新推导一遍解法,也不要只是粘贴一些表面相似的答案。应该维护一个可复用的推理方法库,检索出正确的 skeleton,将其实例化,再把新的经验提炼回去。
选择一道题,观察 BoT 如何检索 template、将其实例化,并把提炼结果写回 buffer。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。