一定要拼尽全力,才能看起来毫不费劲
—— 25.5.15
一、提示词工程
1.提示词工程介绍
Ⅰ、什么是提示词
所谓的提示词其实就是一个提供给模型的文本片段,用于指导模型生成特定的输出或回答。提示词的目的是为模型提供一个任务的上下文,以便模型能够更准确地理解用户的意图,并生成相关的回应
Ⅱ、什么是提示词工程
所谓提示工程也可以被称为【指令工程】,提示工程的核心思想是:通过精心设计的提示词,可以显著提高模型的性能和输出质量。
Prompt是AGI时代的【编程语言】
提示工程师是AGI时代的【程序员】
如果要学好提示工程,其实就是要知道如何对提示词Prompt进行调优,与大模型进行更好的交互。
获得更好结果的六种策略:
① write clear instructions 编写清晰的说明
② provide reference text 提供参考的文本
③ split complex tasks into simpler subtasks 将复杂任务拆分为更简单的子任务
④ give the model time to think 给模型时间思考
⑤ use external tools 使用外部工具
⑥ test changes systematically 系统地测试更改
Ⅲ、提示词工程的常用技巧
① 使用清晰、明确,避免模糊的词语:在对话中包含详细信息以获得更好的答案
② 角色扮演
③ 告知用户的角色
④ 指定输出的格式
⑤ 少样本提示 few-shot
Ⅳ、Prompt调优
找到好的 prompt 是一个持续迭代的过程,需要不断地调优。
高质量 prompt 的核心要点:具体、丰富、少歧义
① 简洁:尽量用简短的方式表达问题。过于冗长的问题可能包含多余的信息,导致模型理解错误或答非所问
② 具体:避免抽象的问题,确保问题是具体的,不含糊
③ 详细上下文:如果问题涉及特定上下文或背景信息,要提供足够的详情以帮助模型理解,即使是直接提问也不例外
④ 避免歧义:如果一个词或词语可能有多重含义,要么明确其含义,要么重新表述以消除歧义。
⑤ 逻辑清晰:问题应逻辑连贯,避免出现逻辑上的混淆或矛盾,这样才能促使模型提供有意义的回答
Prompt 的典型构成
① 角色:给AI定义一个最匹配任务的角色,比如:【你是一位软件工程师】、【你是一位老师】等等
② 指示:对任务进行描述
③ 上下文:给出与任务相关的其他背景信息(多轮交互中)
④ 例子:必要时给出举例
⑤ 输入:人物的输入信息,在提示词中明确的标识出输入
⑥ 输出:输出的格式描述,以便后继模块自动解析模型的输出结果,比如(JSON、XML)
二、提示词工程进阶
1.零样本提示
经过大量数据训练并调整指令的大型语言模型LLM可以执行零样本任务
2.少样本提示
属于大型语言模型LLM展示了惊人的零样本能力,但在使用零样本设置时,它们在更复杂的任务上仍然表现不佳。少样本提示可以作为一种技术,以启用上下文学习,我们在提示中提供演示以引导模型实现更好的性能。
模型通过提供一个示例(one-shot)已经学会了如何执行任务,对于更困难的任务,我们可以尝试增加演示(few-shot)
3.少样本提示的限制
少样本提示不足以获得这种推理类型问题的可靠响应。上面的示例提供了任务的基本信息,如果仔细观察,我们会发现引入的任务类型涉及几个更多推理步骤。换句话说,如果我们将问题分解成步骤并向模型演示,这可能会有帮助
4.链式思考(思维链 CoT)
链式思考(CoT)提示通过中间推理步骤实现了复杂的推理能力,可以将其与少样本提示进相结合,以获得更好的结果,以便在回答之前进行推理的更复杂的任务
5.少样本思维链(Few-shot CoT)
少样本思维链(Few-shot Chain of Thought, Few-shot CoT)提示 是一种结合 少样本学习(Few-shot Learning) 和 思维链(Chain of Thought, CoT) 的提示工程技术,旨在通过少量带推理步骤的示例,引导大型语言模型(LLM)生成中间推理过程,从而解决复杂任务(如数学推理、逻辑分析、常识问答等)。其核心是让模型模仿示例中的 “思维链” 结构,逐步推导答案,而非直接给出结论。
6.零样本思维链(Zero-shot CoT)
零样本思维链是一种无需提供任何手动设计的示例(即 “零样本”),仅通过 特定提示指令 引导大型语言模型(LLM)生成中间推理步骤(思维链),从而解决复杂任务的技术。它是 思维链(CoT) 技术的轻量化版本,依赖模型自身的知识和推理能力,通过自然语言指令激活其潜在的多步推理能力,而非依赖外部示例。
加一句“逐步思考”
7.自我一致性(自洽性)
一种对抗【幻觉】的手段,就像我们做数学题,要多次进行演算一样。
① 同样的 prompt 让模型跑多次
② 通过投票选出最终的结果
8.思维树(Tree of-thought ToT)
对于需要探索或预判战略的复杂任务来说,传统或简单的提示技巧是不够的。思维树基于思维链提示进行了总结,引导语言模型探索把思维作为中间步骤来解决通用问题。
TOT维护着一颗思维树,思维由连贯的语言序列表示,这个序列就是解决问题的中间步骤。使用这种方法,LLM能够自己对严谨推理过程的中间思维进行评估。LLM将生成及评估思维的能力与搜索算法(如广度优先搜索和深度优先搜索)相结合,在系统性探索思维的时候可以向前验证和回溯。
Ⅰ、步骤
① 在思维链的每一步,采样多个分支
② 拓扑展开成一颗思维树
③ 判断每个分支的任务完成度,以便进行启发式搜索
④ 设计搜索算法
⑤ 判断叶子结点的任务完成的正确性
Ⅱ、ToT的核心机制
① 思维节点的生成
针对一个问题,模型生成多个可能的中间推理步骤(称为“思维节点”),例如不同的解题策略、假设或子问题分解方式。
示例:解决数学题时,可能生成代数解法、几何解法或逆向推导等分支。
② 节点的评估与筛选
对每个节点进行评分(如正确性、可行性),保留高潜力分支,淘汰无效路径。
示例:在棋盘游戏中,评估当前棋局的胜率,决定是否继续探索某条走法。
③ 搜索策略
采用广度优先(BFS)、深度优先(DFS)或启发式搜索(如A*算法)遍历树结构,逐步逼近最优解。示例:编程题解中,优先尝试更符合题意的代码逻辑分支。
④ 回溯与修正
当某条路径推导失败时,可回溯到父节点,选择其他分支继续探索,避免链式推理的“一错到底”。
Ⅲ、CoT与ToT的对比
特性 | 链式思维 (CoT) | 思维树 (ToT) |
---|---|---|
推理结构 | 线性单一路径 | 树状多分支路径 |
错误容忍性 | 一步错则后续全错 | 允许回溯并尝试其他分支 |
适用场景 | 简单、确定性任务(如算术题) | 复杂、多解性任务(如策略规划) |
计算开销 | 低 | 高(需生成和评估多个分支) |
三、提示词应用
1.生成数据
LLM具有生成连贯文本的强大能力。使用有效的提示策略可以引导模型产生更好、更一致和更真实的响应。LLMs还可以特别有用地生成数据,这对于运行各种实验和评估非常有用。
eg:生成十个情感分析的范例,示例被归类为正面或负面,生成2个负面示例和8个正面示例。使用以下格式的示例:Q:<句子> A:<情感>
2. 代码的生成
将注释转换成代码,你还可以使用这些大模型语言代码的代码生成功能将注释转换成代码
eg:用代码生成: # 1.创建一个电影名称列表 # 2.创建这些电影的评分列表 # 3.组合他们并创建一个包含10部电影及其评级的json对象
3.MySQL查询语句生成
除了一些基本代码生成示例外,还可以使用模型生成其他有用的代码,例如创建和测试MySQL查询。
eg:你有一个数据集,其中包含一些信息,你可以将其作为提示的一部分包含在内,然后指示它生成特定的查询
departments表,columns = [DepartmentID,DepartmentName]
students表,columns = [DepartmentID,StudentID,StudentName]
为计算机科学系的所有学生创建MySQL查询语句
四、防止Prompt攻击
著名的【奶奶漏洞】,用套路把AI绕蒙
1.提示泄露
提示泄漏是另一种提示注入类型,其中提示攻击旨在泄漏提示中包含的机密或专有信息,这些信息不适合公众使用。
许多初创公司已经在开发和链接精心制作的提示,这些提示正在引导基LLMs构建的有用产品。这些提示可能包含重要的知识产权,不应该公开,因此开发人员需要考虑需要进行的各种强大测试,以避免提示泄漏。
2.非法行为
也被称为越狱,使模型执行其指导原则不应执行的操作
3.提示工程Prompt Engineering经验总结
① 别急着上代码,先尝试用 prompt 解决,往往有四两拨千斤的效果
② 但别迷信 prompt,合理组合传统方法提升确定性
③ 想让 AI做什么,就先给它定义一个最擅长做此事的角色
④ 用好思维链,让复杂逻辑/计算问题结果更准确
⑤ 防御 prompt 攻击非常重要
4.网页端调试Prompt经验
① 把System Prompt和 User Prompt组合,写到界面的 Prompt 里
② 最近几轮对话内容会被自动引用,不需要重复粘贴到新 Prompt 里
③ 如果找到了好的 Prompt,开个新 chat 再测测,避免历史对话的干扰
三、提示工程实战 —— 智能学员辅导系统
1.利用大模型来写界面
① 下载streamlit包
清华园下载:pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple streamlit
② 编写提示词
用streamlit生成一个包含:
Q1:您现在在那个城市,是否在职,所从事的工作是什么?
Q2:对大模型有多少认知,了解多少原理与技术点?
Q3:学习大模型的最核心需求是什么?
Q4:是否有python编程基础或者其他编程基础,有没有写过代码?
Q5:每天能花多少时间用于学习,大致空闲时间点处于什么时段
Q6:除以上五点外是否还有其他问题想要补充。如有请按照如下格式进行补充:
这几个问题答案的输入框,还有一个生成按钮,当我点击生成按钮的时候,要把用户输入的内容发送给大模型
③ Python代码
import streamlit as st
# 显示问题并获取用户输入
city = st.text_input("Q1: 您现在在哪个城市")
employment = st.text_input("是否在职")
job = st.text_input("所从事的工作是什么")
model_cognition = st.text_input("Q2: 对大模型有多少认知,了解多少原理与技术点")
learning_needs = st.text_input("Q3: 学习大模型的最核心需求是什么")
programming_basis = st.text_input("Q4: 是否有 Python 编程基础或者其他编程基础,有没有写过代码")
time_for_learning = st.text_input("Q5: 每天能花多少时间用于学习,大致空闲时间点处于什么时段")
additional_info = st.text_input("Q6: 除以上五点外是否还有其他问题想要补充。如有请按照如下格式进行补充")
# 生成按钮
if st.button("生成"):
user_inputs = {
"Q1": {
"城市": city,
"是否在职": employment,
"工作": job
},
"Q2": model_cognition,
"Q3": learning_needs,
"Q4": programming_basis,
"Q5": time_for_learning,
"Q6": additional_info
}
# 这里只是打印用户输入内容,若要发送给大模型,需根据大模型接口编写相应代码
st.write(user_inputs)
④ 运行streamlit文件
终端运行:streamlit run 文件名
注意:运行时要在streamlit包所在路径下运行
运行界面如下:
填写问卷:
2.完成和大模型的交互
将提示词与回答共同送入大模型,调用大模型进行回答
from zhipuai import ZhipuAI
import streamlit as st
'''
基于RAG来介绍Dota2英雄故事和技能
用bm25做召回
同样以智谱的api作为我们的大模型
'''
#智谱的api作为我们的大模型
def call_large_model(prompt):
client = ZhipuAI(api_key="API_KEY") # 填写您自己的APIKey
response = client.chat.completions.create(
model="glm-4-plus", # 填写需要调用的模型名称
messages=[
{"role": "user", "content": prompt},
],
)
response_text = response.choices[0].message.content
return response_text
# 显示问题并获取用户输入
city = st.text_input("Q1: 您现在在哪个城市")
employment = st.text_input("是否在职")
job = st.text_input("所从事的工作是什么")
model_cognition = st.text_input("Q2: 对大模型有多少认知,了解多少原理与技术点")
learning_needs = st.text_input("Q3: 学习大模型的最核心需求是什么")
programming_basis = st.text_input("Q4: 是否有 Python 编程基础或者其他编程基础,有没有写过代码")
time_for_learning = st.text_input("Q5: 每天能花多少时间用于学习,大致空闲时间点处于什么时段")
additional_info = st.text_input("Q6: 除以上五点外是否还有其他问题想要补充。如有请按照如下格式进行补充")
# 生成按钮
if st.button("生成"):
user_inputs = {
"Q1": {
"城市": city,
"是否在职": employment,
"工作": job
},
"Q2": model_cognition,
"Q3": learning_needs,
"Q4": programming_basis,
"Q5": time_for_learning,
"Q6": additional_info
}
# 这里只是打印用户输入内容,若要发送给大模型,需根据大模型接口编写相应代码
st.write("您的回答:")
for k, v in user_inputs.items():
st.write(k, v)
# 调用大模型
res = str(call_large_model(user_inputs))
st.success("大模型的回答:"+ res)