
🧠 许多初学者,包括曾经的我,可能一开始都会有类似的误解——“Prompting 还需要专门学习吗?不就是像在百度里搜索问题一样吗?” 然而,真正深入接触大语言模型(LLM)后你会发现,Prompting 远不止是问问题那么简单。大模型本身拥有极强的推理能力、逻辑能力与知识覆盖面,但这些能力并不是在默认状态下自动调用的。相反,我们需要通过设计得当的 Prompt 来唤醒、引导并激活模型内部的潜在能力。这就像操作系统中的“指令调用”——你不发出正确的指令,它就不会启动相应的模块。本文将带你系统了解从 Zero-shot 到 Few-shot,再到 CoT、ReAct、Tool Use、Function Calling 等一系列提示设计策略和实践方法。
Zero-shot Learning 是指在没有提供任何示例的前提下,模型仅通过任务描述或问题本身进行推理和生成。(大模型本身无需挖掘的能力,也就是和搜索百度、谷歌一样简单)
Few-shot Learning 指在 Prompt 中提供几个示例(一般 1~5 条),引导语言模型理解任务格式与逻辑结构,再让模型生成新的答案。(挖掘潜在的推理能力)

Q: If John has 3 apples and buys 2 more, how many apples does he have? A: 3 + 2 = 5
Q: Mary has 4 oranges and eats 1. How many are left? A: 4 - 1 = 3
Q: Tom has 5 bananas and gives away 2. How many does he have now? A:
COT 常常用于数学符号运算的推理,将一个问题拆解为一个一个的步骤,一步一步找到答案的思考过程。同时,只需要少量的样本提示即可实现(Few-shot)

作者在文章的实验中提到了:
✅ LLM 内部已经蕴含了推理能力,只是默认不调用 (大型模型),所以这也就是为什么对于小型模型,思维链提示也不会对性能产生积极影响

Large Language Models are Zero-Shot Reasoners这篇文章的作者在后来又提出了zero-shot COT,作者认为大型语言模型是零样本学习推理者,只需在每个答案前加上Let’s think step by step也可实现数学符号运算的计算。
✅ 作者提出Zero-shot需要有两次的prompting,其实就是一次为“Let’s think step by step”,另一次是让模型提取答案信息

✅ Zero-Shot-CoT & Few-Shot-CoT 结果对比,虽然可以避免大量的人工标注,但效果上还是不及 Few-Shot-CoT

⚙️ 为什么是 Let’s think step by stepp
作者在文章中展示了大量的实验对比,发现
Let’s think step by step的效果是最好的
Self-consistency&TOT都是对CoT的改进,本质上都是让模型多思考几轮,最后选择一个最佳的答案,由于计算成本较高,在工业上很少采用,本章只对这两种方法进行简单的介绍。
Self-consistency:作者认为CoT是采用一种贪婪的方式寻找最佳答案,Self Consistency通过调整temperature, 采样多条“思考路径”(reasoning chains),最终以“多数投票”方式选出最可信答案。
ToT:将推理过程从一条链扩展为“一棵树”,类似 BFS 或 Beam Search,多路径并行探索,保留得分最高的分支,当路径得分太低时则不继续展开

为了消除手工设计的prompting推理,作者提出Auto-CoT范式来自动构建带有问题和推理链的演示,作者起初是直接通过Zero-Shot-CoT来生成推理链,但是发现失败了,
Zero-Shot-CoT仍然会在推理链中犯错误。因此,作者将给定数据集的问题划分为几个簇,从每个聚类中选择一个具有代表性的问题,并使用简单的启发式算法Zero-Shot-CoT生成其推理链。
此前也出现了其他检索式的CoT:Retrieval-CoT, Retrieval-Q-CoT(更适合知识问答),核心是根据当前问题 Q 检索最相似的 Q′,使用其 CoT′ 作为提示,而Retrieval-Q-CoT只采用了问答对,没有采用中间的推理过程;这些方法作者发现了以下问题:
🔴 Retrieval-Q-CoT 选择和当前问题最相似的历史问题 + 解题过程作为提示词。实际上,语义上相似 ≠ 推理逻辑相似,模型可能会模仿错误的推理思路;例如两个数学题看起来都提到了“平均值”,但一个是求加权平均,一个是普通平均,提示错误会让模型走错方向。
🔴 Retrieval-CoT 失败时,模型的错误回答往往集中在一类问题上,例如某类题型(如乘法应用题)始终失败。这说明Retrieval-CoT 示例在这些问题上的泛化性不好,出现“模式性错误”,而非偶然失误。
🟢 作者提出与其找最相似的问题,不如 提供结构/思路多样的 CoT 示例,不要只依赖“相似问题”作为提示,而是利用不同类型问题的 CoT 示例来增强泛化能力。Auto-CoT包括两个主要阶段:(i)问题聚类:将给定数据集的问题划分为几个聚类;(ii)示范抽样:从每个聚类中选择一个有代表性的问题,使用简单的启发式Zero-Shot-CoT生成其推理链。


🟢 代码实现:
corpus_embeddings = encoder.encode(corpus)
# Perform kmean clustering
clustering_model = KMeans(n_clusters=num_clusters, random_state=args.random_seed)
clustering_model.fit(corpus_embeddings)
cluster_assignment = clustering_model.labels_
clustered_sentences = [[] for i in range(num_clusters)]
dist = clustering_model.transform(corpus_embeddings)
clustered_dists = [[] for i in range(num_clusters)]
clustered_idx = [[] for i in range(num_clusters)]
for sentence_id, cluster_id in enumerate(cluster_assignment):
clustered_sentences[cluster_id].append(corpus[sentence_id])
clustered_dists[cluster_id].append(dist[sentence_id][cluster_id])
clustered_idx[cluster_id].append(sentence_id)
demos = []
for i in range(len(clustered_dists)):
print("Cluster ", i+1)
tmp = list(map(list, zip(range(len(clustered_dists[i])), clustered_dists[i])))
top_min_dist = sorted(tmp, key=lambda x: x[1], reverse=False)
if not args.sampling == "center":
random.shuffle(top_min_dist)
for element in top_min_dist:
min_idx = element[0]
c_rationale = rationale[clustered_idx[i][min_idx]].strip()
c_pred_ans = pred_ans[clustered_idx[i][min_idx]].strip()
if len(question[clustered_idx[i][min_idx]].strip().split()) <= 60 \
and len(c_rationale.replace("\n\n", "\n").split("\n")) <= max_ra_len and c_rationale[-1] == "." and c_pred_ans != "":
if args.task in ["gsm8k", "multiarith", "singleeq", "addsub", "svamp"]:
if not (c_pred_ans.strip() in c_rationale.split(".")[-2] or c_pred_ans.strip() in c_rationale.split()[-10:]):
continue
c_question = question[clustered_idx[i][min_idx]]
c_rationale = c_rationale.replace("\n\n", "\n").replace("\n", " ").strip()
c_rationale = " ".join(c_rationale.split())
if args.debug:
c_gold_ans = gold_ans[clustered_idx[i][min_idx]]
else:
c_gold_ans = None
demo_element = {
"question": c_question,
"rationale": c_rationale,
"pred_ans": c_pred_ans,
"gold_ans": c_gold_ans,
}
demos.append(demo_element)
print(c_question)
print(c_rationale)
print(c_pred_ans)
print(c_gold_ans)
print("")
break
demos = {"demo": demos}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。