写在前面
2025.6月这个节点,谈论提示词工程有点过时了,但每个时期技术的产物都有一定的道理,写出一个合理的提示词对RAG或者Agent还是挺重要的。
如果只是用户使用一些API调用大模型,或者期望得到一些更精确的结果,只需要看下面的大白话总结就可以了:↓
-
如果任务挺复杂的,比如说实体识别之类的,可以做Few Shot,可以去GraphRAG看看里面用的提示词,当然提示词越长,token就越多,钱越多
-
如果是对格式有要求, 比如说想让llm作为workflow的一环的话, 可以One Shot
-
Zero Shot平时在对话场景下用的最多,现在模型贼强,就硬问,回答的不合期望就再改
-
如果任务挺复杂的话, 可以加一个let's think step by step, 让模型进行思考,"深度不够,长度来凑"。如果是类似Deep Research的工程,提示词可以是添加一些,提示多步推理的步骤。
In-Context-Learning
in-context-learning,就是类似于在提示词中给出例子让llm进行输出,那这个例子怎么给,也是有技巧的
[示例1:输入 -> 输出][示例2:输入 -> 输出]...[新查询:输入 -> ?]
ICL有什么特点呢?
-
无参数更新:不需要进行模型训练,就在提示词上下功夫
-
注意力&模式识别:当进行推理时, 模型会回顾整个提示词, 这时提供示例的关系就被注意力机制注意到了, 比如说是翻译任务,还是情感推测等等
-
元数据假说:也不知道是真是假,LLM在预训练过程中已经"学会如何学习", 内化了从上下文快速推理和模仿任务的能力
怎么能用好呢?
-
如果目的是情感分类,就提供情感分类的例子:"我喜欢这个电影"->"正面"
-
-
-
Few Shot: 在prompt中提供几个任务示例。
-
-
Zero Shot:不提供。类似于:将以下文本从英文翻译成中文
关于以上3种怎么选择的问题,有很多书籍和教程都教过,但随着模型能力的增强, 这个标准越来越模糊,到现在提示词工程也不再时髦,但提示词仍然很重要。这里只说一些个人心得:
-
如果任务挺复杂的,比如说实体识别之类的,可以做Few Shot,可以去GraphRAG看看里面用的提示词,当然提示词越长,token就越多,钱越多
-
如果是对格式有要求, 比如说想让llm作为workflow的一环的话, 可以One Shot
-
有。但都是曾经,有一些叫Example Retrieval 或者 Demonstration Retrieval的做法,流程跟RAG非常像
有一个非常大的候选池 -> 匹配 问题的embedding -> 选top k -> 组成提示词
几乎是RAG的做法。有没有人真的这样写提示词呢?按我自己的理解应该是没有吧,至少我本人是没听过。
那还有没有对怎么写提示词总结过一些模板呢?有!虽然现在人不一定遵守这些模板,但了解下也是有益处的,虽然这都是上古时代的产物了。
Cross-Task Generalization via Natural Language Crowdsourcing Instructions
Title:high level 的任务描述,以及相关技能Prompt:提示词Definition: 指令的补充内容Things to avoid:规则Emphasis and caution:警告正例反例reason:为什么是正例或反例
同时需要数据集,并进行微调,没什么水花。但这样的思路对写好一个提示词也是有益处的。
COT
COT的原理(大白话版)
Chain-of-Thought (Cot) 是一种改进的 Prompt 技术,目的在于提升大模型 LLMs 在复杂推理任务上的表现,对于复杂问题尤其是复杂的数学题大模型很难直接给出正确答案。如算术推理 (arithmetic reasoning)、常识推理 (commonsense reasoning)、符号推理 (symbolic reasoning) 。CoT 通过要求模型在输出最终答案之前,显式输出中间逐步的推理步骤这一方法来增强大模型的算数、常识和推理能力,简单但有效。通过让大模型逐步参与将一个复杂问题分解为一步一步的子问题并依次进行求解的过程可以显著提升大模型的性能。区别于传统的 Prompt 从输入直接到输出的映射 < input—>output > 的方式,CoT 完成了从输入到思维链再到输出的映射,即 < input—>reasoning chain—>output>
因为LLM本质上还是一个文字接龙的东西,思维链可以认为是一个深度不够 长度来凑的活,一步一步推理得到正确的答案
常见的就是在提示词里:let's think step by step。来引导大模型进行逻辑推理。这有用吗?确实有用,而且这句话效果最好!
发展到现在一些推理模型自己就推理,比如DeepSeek r1, 内心的小剧场非常长, 长到过分。也感慨下模型竞争的激烈,春节期间爆火的deepseek,现在体感上也远不如Gemini 2.5和GPT 4.5了
COT的改进
等等,从R1的思考过程中有时也能看出, 在不停的思考, 多角度验证,怎么做到的?我也不知道, 可能真的是玄学
其他的研究
Language Model as Optimizer
Language Model as Optimizer" (LMO) 这类研究的核心思想。这个领域的代表性工作之一是谷歌的 "Large Language Models as Optimizers",其提出的方法叫做 OPRO (Optimization by PROmpting)
就是把prompt里面塞多个: 提示词例子-分数,比如
让llm看看这些提示词, 思考一个新的提示词,再经过一个评估器(可以是LLM或者其他的东西,人类标注都可以), 给这个新的提示词分数,慢慢尝试出最优的提示词
当然如果把这个当成更严肃的学术问题,可以继续往下看,我建议使用者了解上面的概念就可以了
原理(大白话版)
写好一个prompt可以认为是一个优化任务。首先,我们回到“优化”这个概念的本源。无论形式如何,一个优化问题都可以被定义为:
寻找一个输入 x,使得一个目标函数 f(x) 的值最大化或最小化。
-
梯度下降 (Gradient Descent):这是最著名的一类。原理是“沿着梯度最陡峭的方向走一小步”。它需要目标函数 f(x) 是可微分的,这样才能计算梯度。x 通常是一组数值向量(例如,神经网络的权重)。
传统优化的核心:输入 x 是数值,优化器是数学算法,优化的过程是在数值空间中进行搜索。
"Language Model as Optimizer" 的核心思想,就是彻底颠覆上述传统。它提出:
优化的过程,不是一个数学计算过程,而是一个基于语言的、迭代式的“生成与反思”过程。
范式革命的核心:将**在数值空间中的搜索**,转变为**在语义空间中的生成**。LLM 不“计算”下一步该怎么走,而是“构思”和“写出”一个更好的新方案。这到底是个什么意思呢?看看下面的流程就知道了
工作流程(简单流程)
OPRO (Optimization by PROmpting) 的工作流程完美地体现了这种思想。我们可以把它拆解为以下步骤:
目标:找到一个最优的**指令 (Instruction)**,让另一个模型(我们称之为“任务模型”)在某个任务上表现最好。这里的 x 就是指令文本,f(x) 就是任到一个最优的**指令 (Instruction)**,让另一个模型(我们称之为“任务模型”)在某个任务上表现最好。这里的 x 就是指令文本,f(x) 就是任务模型使用该指令后得到的分数(例如,准确率)。
-
-
-
操作:我们先提供一些初始的、由人类编写的指令作为“第0代”解。或者,直接让 LLM 自己生成几个初始版本的指令。
-
-
第一性原理:这是整个方法的核心。为了让 LLM 能够“优化”,我们必须为它提供足够的上下文,让它理解“好”是什么样的,以及如何变得“更好”。这完全依赖于 LLM 的上下文学习 (In-Context Learning, ICL)能力。
-
操作:这个精心设计的 Prompt 包含以下内容:
-
步骤 A:构建提示 (Construct the Prompt)
-
-
历史轨迹 (Trajectory):这是关键中的关键。我们会把**上一代或过去几代的所有“解(指令文本)”以及它们对应的“分数(f(x) 史轨迹 (Trajectory):这是关键中的关键。我们会把**上一代或过去几代的所有“解(指令文本)”以及它们对应的“分数(f(x) 的值)” 全部放入上下文中。例如:
指令1: "请简洁地回答问题。" -> 分数: 75%指令2: "一步一步思考,然后给出答案。" -> 分数: 82%...
-
生成指令:在 Prompt 的最后,明确指示 LLM:“请分析以上示例,生成一个新的、可能获得更高分数的指令。”
* 步骤 B:LLM 生成新的候选解 (Generate New Candidates)
* 原理:这是 LLM 取代传统优化算法的地方。LLM 不会 * 原理:这是 LLM 取代传统优化算法的地方。LLM 不会计算梯度,而是利用其在海量文本中学到的归纳和推理能力。它看到“一步一步思考”比“简洁回答”分数更高,就会推断出“引导模型进行思考过程”是一个好的方向。
* 操作:LLM 输出一个新的或一批新的指令文本。这些新指令可能不是对旧指令的微小修改,而可能是语义上完全不同但方向正确的全新构思。例如,它可能生成:“首先,将问题分解为几个子问题。然后,依次解决每个子问题。最后,综合所有答案形成最终结论。”
* 步骤 C:评估新解 (Evaluate New Candidates)
* 操作:将 LLM 生成的新指令,输入给“任务模型”,在验证集上运行,得到一个新的分数 f(x_new)。
* 操作:将新生成的指令和它的分数,添加到我们的历史轨迹中。
循环结束:重复这个循环,直到达到预设的迭代次数,或者分数不再显著提升。最终,历史轨迹中分数最高的那个指令,就是我们找到的最优解。
为什么这能行?(更深层的原理)
-
ICL 是引擎:整个 OPRO 的有效性,完全建立在 LLM 强大的上下文学习能力之上。历史轨迹 (解, 分数) 对的作用,就如同 Few-shot Learning 中的 **Demonstrations**。LLM 从这些示例中学习到了一个“元技能 (meta-skill)”:如何提出更是引擎:整个 OPRO 的有效性,完全建立在 LLM 强大的上下文学习能力之上。历史轨迹 (解, 分数) 对的作用,就如同 Few-shot Learning 中的 **Demonstrations**。LLM 从这些示例中学习到了一个“元技能 (meta-skill)”:如何提出更好的解决方案。
-
搜索空间的转变:传统优化器在连续或离散的数值空间中搜索。而 LLM 在一个由语言构建的、更加丰富和复杂的语义空间 (Semantic Space)中进行搜索。这使得它可以进行“概念跳跃”,而不是“数值微调”,从而可能更快地找到优质的、结构全新的解。
-
利用预训练的先验知识:LLM 在预训练中已经学习了海量关于“如何改进文本”、“什么是好的指令”的隐式知识。OPRO 做的,就是通过一个精巧的 Prompt 结构,将这种隐式的的先验知识:LLM 在预训练中已经学习了海量关于“如何改进文本”、“什么是好的指令”的隐式知识。OPRO 做的,就是通过一个精巧的 Prompt 结构,将这种隐式的、通用的知识,引导并应用到解决一个非常具体的优化问题上。
总结
"Language Model as Optimizer" 的主体思路是,利用大型语言模型强大的上下文学习能力,将传统的、基于数学计算的优化过程,重新定义为一个迭代式的、基于自然语言的“生成-评估-反思”循环。它通过在 Prompt 中提供历史解及其得分,来引导 LLM 生成语义上更优的新解,从而在文本、指令、配置等离散且复杂的空间中,实现高效的黑箱优化