首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【大模型学习 | Prompt工程基础学习】

【大模型学习 | Prompt工程基础学习】

原创
作者头像
九年义务漏网鲨鱼
发布2025-07-15 12:05:36
发布2025-07-15 12:05:36
1.1K0
举报

prompting学习

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

基础prompting

Zero-shot & Few-shot

Zero-shot Learning 是指在没有提供任何示例的前提下,模型仅通过任务描述或问题本身进行推理和生成。(大模型本身无需挖掘的能力,也就是和搜索百度、谷歌一样简单)

Few-shot Learning 指在 Prompt 中提供几个示例(一般 1~5 条),引导语言模型理解任务格式与逻辑结构,再让模型生成新的答案。(挖掘潜在的推理能力)

图来源于原文
图来源于原文
  • Few-shot example:

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 (Chain-of-thought)

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

Self-consistency & TOT都是对CoT的改进,本质上都是让模型多思考几轮,最后选择一个最佳的答案,由于计算成本较高,在工业上很少采用,本章只对这两种方法进行简单的介绍。

Self-consistency:作者认为CoT是采用一种贪婪的方式寻找最佳答案,Self Consistency通过调整temperature, 采样多条“思考路径”(reasoning chains),最终以“多数投票”方式选出最可信答案。

ToT:将推理过程从一条链扩展为“一棵树”,类似 BFS 或 Beam Search,多路径并行探索,保留得分最高的分支,当路径得分太低时则不继续展开

图来自别处
图来自别处

Auto CoT

为了消除手工设计的prompting推理,作者提出Auto-CoT范式来自动构建带有问题和推理链的演示,作者起初是直接通过Zero-Shot-CoT来生成推理链,但是发现失败了,Zero-Shot-CoT仍然会在推理链中犯错误。因此,作者将给定数据集的问题划分为几个簇,从每个聚类中选择一个具有代表性的问题,并使用简单的启发式算法Zero-Shot-CoT生成其推理链。

此前也出现了其他检索式的CoT:Retrieval-CoTRetrieval-Q-CoT(更适合知识问答),核心是根据当前问题 Q 检索最相似的 Q′,使用其 CoT′ 作为提示,而Retrieval-Q-CoT只采用了问答对,没有采用中间的推理过程;这些方法作者发现了以下问题:

🔴 Retrieval-Q-CoT 选择和当前问题最相似的历史问题 + 解题过程作为提示词。实际上,语义上相似 ≠ 推理逻辑相似,模型可能会模仿错误的推理思路;例如两个数学题看起来都提到了“平均值”,但一个是求加权平均,一个是普通平均,提示错误会让模型走错方向。

🔴 Retrieval-CoT 失败时,模型的错误回答往往集中在一类问题上,例如某类题型(如乘法应用题)始终失败。这说明Retrieval-CoT 示例在这些问题上的泛化性不好,出现“模式性错误”,而非偶然失误。

🟢 作者提出与其找最相似的问题,不如 提供结构/思路多样的 CoT 示例,不要只依赖“相似问题”作为提示,而是利用不同类型问题的 CoT 示例来增强泛化能力。Auto-CoT包括两个主要阶段:(i)问题聚类:将给定数据集的问题划分为几个聚类;(ii)示范抽样:从每个聚类中选择一个有代表性的问题,使用简单的启发式Zero-Shot-CoT生成其推理链。

图来自原文
图来自原文

🟢 代码实现:

代码语言:python
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • prompting学习
    • 基础prompting
      • Zero-shot & Few-shot
      • COT (Chain-of-thought)
      • Self Consistency & TOT
      • Auto CoT
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档