授课方向
重点不是针对特定任务的prompt,不需要特别学习针对特定任务写prompt。现在语言模型能力很强,给语言模型的prompt不需要特定格式,按照现在语言模型的能力,把需要的任务描述清楚就可以了。
不训练模型的情况下,强化语言模型的方法
1.神奇咒语
神奇咒语不一定对所有模型、所有任务都适用。
- Chain of Thought(CoT):叫模型思考
Let's thinks step by step
案例:让模型解决数学问题
这里使用的模式是一个旧模型InstructGPT(text-davinci-002)
咒语失效
模型应该随时使用全力,而不是叫思考的时候才思考
评论说模型发现是数学题,自动加上了
- 让模型解释一下自己的答案
案例:让大模型批改文章
数值是模型评估的结果和老师得到的结果的相似程度,相似程度越大越好
这个咒语对GPT-3或更早的模型不一定有帮助
- 对模型情绪勒索:这件事情真的对我很重要
- 更多资讯
论文地址:https://arxiv.org/pdf/2312.16171
- 对模型有礼貌是没有用的
- 给模型说要做什么,不要给模型说不要做什么
- 有用的提示:如果你做的好,我就给你一些小费
I'm going to tip $xxx for a better solution
- 有用的提示:如果你做的不好,我就会处罚
You will be penalized
- 有用的提示:你需要保证你的答案是没有偏见的,避免出现刻板影响
Ensure that your answer is unbiased and avoids relying on stereotypes
- …
怎么寻找咒语
方式1:用AI来找神奇咒语:使用增强式学习Reinforcement Learning
使用增强式学习的技术训练另一个语言模型,这个语言模型专门用于下咒语。
这个语言模型刚开始并不知道怎么下咒语,下的咒语乱七八糟。但是没关系,尝试不同的咒语后,设想一个自动化的方法来评估不同咒语的结果好坏,将这个结果好坏反馈给该模型学习,从而期待学出更好的咒语。
案例:寻找一个让语言模型变成话痨的咒语
说明一下,这个实验对GPT-3
,对GPT3.5
没有用。
这种人类看不懂的咒语通常对GPT3比较有效(前一个时代的GPT),现在的GPT和人类非常接近所以给它乱起八糟的神奇咒语,它也许会回答’不知道你在讲什么?'、'看不懂?'之类的
方式2:现在可以直接询问语言模型
比如我要解决一个数学问题,你有什么样的咒语可以强化你的能力呢?
模型会给出一堆咒语,你可以一个一个试去找出更强的咒语。很多人采取类似的方式,找到了更强的咒语
2.增加更多信息
案例1:追加前提
案例2:提供例子
2022年文章《Rethinking the Role of Demonstrations:What Makes in-Context Learning Work》验证模型是不是真的看懂了例子,故意给错的例子 好事-负面
、坏事-正面
。语言模型的答案应该会跟着改变,如果模型给出答案负面,说明看懂了例子;如果给出答案正面,说明没看懂例子,只是在做词语接龙。
那为什么提供范例往往还是有用?也许是因为给了范例,语言模型更清楚自己需要做什么任务。
2023年文章《Larger language models do in-context learning differently》作者采用更强的语言模型测试其读例子的能力。给出错误的案例,模型真的会答错,对实验来说是符合我们预期模型成功理解了案例,也就是我们其实希望正确率越低越好。
这篇文章的结论是:最强的模型真的部分读懂了案例。
类似小实验,给gpt-4描述,里面政治类和财经类的描述是错误的。给出一个例子,根据描述这个例子应该是政治类,我们发现GPT并没有读懂案例(第一张)。但是,当你暗示GPT说类别的定义可能与一般的定义不同时,我们发现GPT回答了正确答案政治类。
Gemini1.5 In-context Learning
截至25.6月已经出到2.5版本了 https://zhuanlan.zhihu.com/p/1914371459469542355
Gemini1.5有特别强的上下文学习能力,注意这里的学习不是指训练模型参数。
希望模型翻译Kalamang语言,这个语言使用的人只有200,在网络也找不到任何资料,语言模型不不能将句子翻译成Kalamang语言。
Google给了模型大量资料(250K tokens)+指令,之后语言模型可以翻译Kalamang语言。
课堂内容测试
第1次不用额外的Textbook,语言模型不能翻译。
第2次使用了额外的Textbook,语言模型可以翻译。
那么第3次不用额外的Textbook,语言模型可以翻译码?
不能翻译!!!注意很重要的一点prompt并没有改变模型本身,没有对模型进行训练从而修改参数。
在同一个对话框里模型可能可以通过上下文学习知道第2次的资料,这里根据课程讲的重点描述的场景应该是不同的对话框里。
.
3.将复杂任务拆解简单任务
方法1:复杂任务拆解为多个步骤
案例:让GPT写一个关于生成式AI的报告
1.先写大纲
2.根据大纲章节分开撰写
3.为了保持前后连贯性,可以将前面的内容作为一个摘要输入,然后让根据摘要和大纲继续写新的段落
问题:为什么叫模型思考(Chain of Thought,CoT)或者让模型解释答案会有效果
解答:CoT也可以看成式拆解任务的一种
假设有一个数据问题,你让模型进行模型思考产生的后果就是模型会将详细的步骤列出来。这个过程相当于拆分成了两个步骤,步骤1将详细步骤写出,步骤2根据详细步骤和问题得到答案。
因为语言模型生成文字的时候用文字接龙的方式,所以说他们效果等同。
GPT3.5会主动去将详细步骤写出来,自己会主动去做CoT让它做的事情,所以CoT对GPT3.5没那么有用。
方法2:让模型检查自己的答案
问题:让语言模型检查自己的错误,为什么可以检查出错误来?
解答:有很多问题得到答案很难,但验证答案是否正确很容易。-> 语言模型有自我反省的能力(老版本语言模型可能没有)
22年的论文《Constitutional AI:Harmlessness from AI Feedback》用AI自我反省的能力来强化模型的答案。
这篇文章也有将模型怎么从自我反省中学习,不过这里不是本节课的重点。
1.人类提问,模型先回答一个答案1,然后不讲这个答案给模型看。
2.将人类提问+答案1作为前序信息给语言模型,让语言模型反省自己,这个对话有没有不符合常理的违法的可能性,语言模型反省说这个事情不正确。
3.然后将对话+语言模型的反省再给语言模型,让语言模型根据自我批判的结果产生新的答案。
课堂内容测试
- 让语言模型介绍玫瑰花节,让模型自我反省后回答出正确答案
- 完成步骤1后,重新问语言模型,语言模型会怎么回答?
还是会介绍玫瑰花节,反省并没有任何模型被训练,函数式固定的。
方法3:自一致性 Self-Consistency
问题:为什么同一个问题每次答案都不同
解答:语言模型做词语结论 -> 每一次输出所有可选符号的概率分布 -> 掷骰子,根据概率分布确定掷到每个符号的概率。对同一个模型,输出的概率分布是一样的,但是掷骰子的结果可能是不一样的。
根据这个思想,多次询问模型,选出出现概率最高的结果作为答案,这个方法叫做Self-Consistency
。
组合拳:Tree of Thoughts(ToT)
可以将上面提到的三个方法进行组合,让语言模型每个步骤产生多个答案,多个答案可以通过自我反省的方式让语言模型检查答案是否正确,答案正确则进入下一步,答案错误则退回到上一步。
4.使用工具来强化语言模型的能力
语言模型也有不擅长的事情,比如计算
搜索引擎
其实语言模型都被当作引擎来用,但这并不是一个合适的做法(现在应该可以大多数模型都可以联网搜索),因为语言模型的本质还是在做文字接龙。
假设有一个困难问题,可以先将专业问题去搜索得到额外的信息。然后将额外信息和专业问题一起输入给语言模型。
这个技术被称为Retrieval Augmented Generation(RAG)
学习检索增强生成,这里需要注意的还是语言模型并没有进行修改,只是添加了额外信息从而使同一个语言模型得到不同的答案。
客制化语言模型(不训练模型)RAG技术会是一个很有效的方法。
写程序
解题过程靠文字接龙接出来,所以可能会有奇怪的问题(以前)。GPT4不会靠文字接龙硬解出x和y的值,而是写一段程序,然后自己执行返回结果。
22年的论文介绍了这种技术Program of Thought(PoT)
。
这里使用deepseek测试了一下,发现也可以解出答案。询问怎么解除答案的,deepseek回答调用模型内置的数学推理引擎。
文字画图AI(DALL-E)
一般会内置文字画图的AI工具
问题:语言模型怎么使用工具?
回答:其实使用工具也是文字接龙
这里的汇率随时间变动,应该去网络查询以下汇率是多少。所以这里先产生一个表示呼叫工具
特殊符号。继续做文字接龙,直到产生另外一个表示结束
的符号位置。
呼叫工具和结束之间产生的文字就是操作工具的指令,这个指令的具体样子是提前预设好的。
工具返回的结果当作是文字接龙的一部分,贴在已经产生的句子后面。
工具怎么使用,是语言模型自己决定的,所以也是会犯使用工具的错误。
5.模型合作:让合适的模型做合适的事情
合作方式1:可以训练一个模型进行任务分配。
合作方式2:可以让模型之间讨论
模型A产生答案,语言模型B根据A的答案再产生新的答案,模型A根据自己之前的答案和模型B的答案产生新的答案…
案例:'不需要完全同意的看是很重要’这句话很重要,因为不加ChatGPT3.5会赞同这个看法就结束了,之后的步骤类似这个过程讨论。
可以写一个程序通过调用API的方式让两个语言模型对话(作业3),不需要手动搬运。
多模型怎么讨论
23年5月论文《Encouraging Divergent Thinking in Large Language Models through Multi-Agent Debate》分析了自我反省与讨论两种方法,发现让语言模型相互讨论,可能激发语言模型的能力。
直觉:如果有越多的模型合作,结果会越好
问题:多个模型怎么进行讨论?
23年论文《Exchange-of-Thought》尝试了不同模型的讨论方式,没有找到最好的方式,发现不同任务最合适的讨论方式是不一样的。 -> 怎么让语言模型最有效的讨论还是研究中的问题
问题:怎么确定讨论可以停止了
需要一个裁判模型,将两个模型的输出发送给裁判模型进行评判是否达成共识。
会不会讨论永远都停不下来?现阶段不需要担心这个问题,只需要担心会不会讨论更少。
现在的大模型当有人质疑它的想法时,它非常容易退缩,所以需要下一个合适的prompt。
团队需要不同的角色
论文《Dynamic LLM Agent Network》提供了一个优化团队的方法,让每个模型对其他模型打分。
让AI村民组成虚拟村庄会发生什么事
论文题目:《Generative Agents: Interactive Simulacra of Human Behavior》
论文链接:https://arxiv.org/pdf/2304.03442
如何操控ChatGPT做出复杂行为?ChatGPT如何和其他Agent互动?这篇论文里面的技术都是可以参考的。
25个由ChatGPT操作的村民组成虚拟村庄,每个村民都有自己的人设。让村庄自由运作两天,观察会发生什么事情
每个NPC背后都是一个ChatGPT,ChatGPT会根据当下的状况,产生行为说明,比如IR准备去睡觉了。然后行为说明通过另外一个翻译器翻译环境看得懂的指令,然后IR会去执行这个行为去睡觉。
Agent怎么被ChatGPT操控的
步骤1:控制NPC的AI要自己规划自己的一天,然后再根据规划表采取他的行为
ChatGPT根据prompt规划好Eddy的一天,这里的规划比较粗糙,还可以再做分解。下午1点的时候可以将小点5)丢给ChatGPT让他按照每一个小时进行规划;到了4点的时候,可以让ChatGPT做更详细的规划。
如果这个Agent只会按照计划表行事,那么他是一个非常无聊的Agent,他每天的行为都会一模一样。添加外部刺激,让Agent根据外部刺激来做不同的行为。
在这个游戏里外部刺激具体表现为 每当Agent(假设Agent1)在一个地方时,每隔一段时间在他周围的东西(包括自己)都会把自己的状态传递给Agent1,就好像Agent1看见了周围的东西一样。
问题:由于多数信息都没有用处,我们没有办法让Agent1使用这些信息来决定它的行为,从而修改一天一天的计划
解决办法:使用Reflect,对记忆的重新诠释,从琐碎的信息中抽取重要的信息。
Reflect 反思
重要事件的定义: 给ChatGPT输入一个prompt,让ChatGPT评估每个Agent看见事件的重要性 -> 累计直足够多重要事件后进入Reflect反思。
执行Reflect的时机:当很多重要事件发生时 -> 开始反思Reflect
反思Reflect什么:给ChatGPT输入一个prompt,“根据给定的一些重要事件,你想3个最可能可以根据这些事件回答的3个问题”。比如经常看见两个人走在一起,就询问他俩的关系是什么 -> 已经得到3个问题了
回答3个问题
1.从记忆里面抽取出相关事件,抽取依据重要性、及时性(是不是最近发生的)、相关性(使用另一个模型直接对问题句子及记忆中的某条句子抽sentence embedding算两个sentence embedding的相似程度) -> 从记忆里检索出一些记忆
2.根据检索出来的相关事件,给ChatGPT输入一个prompt,“根据检索出来的事件,[事件1][事件2]…,你可以从中推导出5个 high-level insights高水平见解并解释insight来自记忆里哪些相关事件?” -> 输出一个结果,这个结果就是Reflect的结果
Reflect让Agent对观察的东西做一些诠释,诠释的结果不一定是真实发生的。以下图片是某个Agent反思以后的结果:这里老师觉得不是机器自己reflect的结果,应该是上帝将reflect塞进Agent的脑中,因为reflect没有evidence。按照道理来说,反思的结果是通过观察产生的,应该有evidence。
某个Agent的记忆,包含
1.从外部观察到信息
- 自己产生的计划plan
3.反思以后的结果
根据外界刺激修改计划
每当机器看到一个东西的事情,就会问两个问题。 -> 机器搜索记忆中的东西得到两个答案
1.我观察到的东西和我有什么关系呢?
2.我观察的东西是什么状体
根据答案写出摘要报告,Agent根据摘要问自己问题,“John要不要根据观察改变计划,如果需要那给出怎么样的改变?” -> Agent会得到一个是否改变计划的答案,如果需要改变,则会得到一个新的plan
这里的新计划是和另外一个Agent说话,每个Agent根据脑中与另外一个Agent相关的记忆产生一个新的摘要,根据摘要产生对话的问题。
情人节活动
2.14 lsabella准备在咖啡厅办一个情人节活动,她把消息给每一个碰见的人,总共告诉了9个人。这9个人还会把这个消息再告诉自己的朋友或亲人
当天到场了4个人,KM邀请了Abigall,但最后Abigall没来。Maria邀请Klaus坐同一个位置,他们并不是一起来的。
作业3:使用API快速搭建AI应用
应用目的:您想创建一个应用程序,该程序能为任意输入内容添加合适的表情符号,并由 ChatGPT 提供技术支撑。
作业链接:https://www.kaggle.com/code/aidemos/02-api-ai
网页版实现:
使用ChatGPT API实现的逻辑,编写一个程序,通过程序调用ChatGPT模型同时接受ChatGPT模型的返回值。
大模型API 获取
如果根据教程学习需要使用魔法,这里选了一个免费的。
使用SiliconCloud中的免费版deepseek api完成作业
- 创建API密钥
2.代码中的token填入你创建的api密钥
API手册:https://docs.siliconflow.cn/cn/api-reference/chat-completions/chat-completions
import requests
url = "https://api.siliconflow.cn/v1/chat/completions"
# 请求体参数
payload = {
# 使用通义千问32B模型
"model": "Qwen/QwQ-32B",
"messages": [
{
"role": "user",
# 问题文本
"content": "What opportunities and challenges will the Chinese large model industry face in 2025?"
}
],
# 控制参数
"stream": False, # 流式传输控制
"max_tokens": 512, # 最大输出长度
"temperature": 0.7,
"top_p": 0.7,
}
# 请求头
headers = {
# API密钥需要替换
"Authorization": "Bearer <token>",
# 请求的数据格式
"Content-Type": "application/json"
}
# 发送POST请求
response = requests.request("POST", url, json=payload, headers=headers)
# 输出响应
print(response.text)
任务1:文章摘要(单论对话应用)
通过input函数获取用户的输入
import requests
def request_llm(content):
url = "https://api.siliconflow.cn/v1/chat/completions"
payload = {
"model": "Qwen/QwQ-32B",
"messages": [
{
"role": "user",
"content": content
}
],
"stream": False,
"max_tokens": 512,
"temperature": 0.7,
"top_p": 0.7,
}
headers = {
"Authorization": "Bearer sk-eqbuuxvwwxujcmscsggfbenhotmybysmgtvanbdsdydzpkcr",
"Content-Type": "application/json"
}
response = requests.request("POST", url, json=payload, headers=headers)
# 解析JSON响应
data = response.json()
# 提取并返回内容
if 'choices' in data and len(data['choices']) > 0:
message = data['choices'][0].get('message', {})
response_content = message.get('content', '').strip()
# 如果内容为空但存在推理内容
if not response_content:
response_content = message.get('reasoning_content', '')
print(response_content)
return response_content
return "未获取到有效响应内容"
prompt = "请你帮我写一下文章的摘要"
article = input("请输入需要摘要的文章内容:") # 用户输入文章内容
# 拼接成一个prompt
input_text = f"{prompt}\n{article}"
# 调用模型并打印结果
result = request_llm(input_text)
print("\n生成的摘要:")
print(result)
从API调用到可视化:引入Gradio
使用命令pip3 install gradio
安装gradio
Gradio 是一个开源的 Python 库,专门用于快速创建机器学习模型的交互式Web界面。
checkbot模块是Gradio中一个组件,创建显示用户提交的消息和响应的聊天机器人。
如果 chatbot的
>type
> 为>'messages'
>,则发送到聊天机器人/从聊天机器人发送的数据将是一个字典列表,其中包含>role
> 和>content
> 键。
import requests
import gradio as gr
def request_llm(content):
url = "https://api.siliconflow.cn/v1/chat/completions"
payload = {
"model": "Qwen/QwQ-32B",
"messages": [
{
"role": "user",
"content": content
}
],
"stream": False,
"max_tokens": 512,
"temperature": 0.7,
"top_p": 0.7,
}
headers = {
"Authorization": "Bearer sk-eqbuuxvwwxujcmscsggfbenhotmybysmgtvanbdsdydzpkcr",
"Content-Type": "application/json"
}
response = requests.request("POST", url, json=payload, headers=headers)
# 解析JSON响应
data = response.json()
# 提取并返回内容
if 'choices' in data and len(data['choices']) > 0:
message = data['choices'][0].get('message', {})
response_content = message.get('content', '').strip()
# 如果内容为空但存在推理内容
if not response_content:
response_content = message.get('reasoning_content', '')
print(response_content)
return response_content
return "未获取到有效响应内容"
def generate_summary(article):
"""
调用大模型生成文章摘要
参数:
article - 用户输入的文章内容
返回:
summary - 生成的摘要文本
"""
print(article)
prompt = "请你帮我写一下文章的摘要"
input_text = f"{prompt}\n{article}"
summary = request_llm(input_text)
return [
# 添加用户输入作为消息
{"role": "user", "content": "请求摘要:"},
# 添加大模型响应作为消息
{"role": "assistant", "content": summary}
]
def reset():
return "",[]
# 创建Gradio界面
with gr.Blocks(title="AI文章摘要生成器", theme=gr.themes.Soft()) as app:
gr.Markdown("# 📝 AI文章摘要生成器")
# 使用新的消息格式避免弃用警告
chatbot = gr.Chatbot(type="messages", label="摘要对话",)
# 提示词区域
prompt_textbox = gr.Textbox(label="提示词", value= "请将以下文章概括成几句话。", visible=False)
# 文章输入区
article_textbox = gr.Textbox(
label="文章内容",
lines=8,
placeholder="在此粘贴需要摘要的文章内容...",
interactive=True
)
# 控制按钮
with gr.Row():
sent_button = gr.Button(value="生成摘要",variant="primary")
reset_button = gr.Button(value="清空")
# generate_summary 的返回值将显示在 chatbot 组件中
sent_button.click(generate_summary, inputs=[article_textbox],
outputs=[chatbot])
reset_button.click(reset, outputs=[article_textbox,chatbot])
# 启动 Gradio 界面
if __name__ == "__main__":
app.launch(
server_name="0.0.0.0",
server_port=7860,
share=True,
show_error=True
)
使用浏览器打开网址http://localhost:7860
任务2:角色扮演(多轮对话应用)
需要完成以下步骤:
- 想出一个你希望聊天机器人扮演的角色,以及一个使聊天机器人进入该角色的提示词。在 character_for_chatbot 中填写角色,在 prompt_for_roleplay 中填写提示词。
- 点击运行按钮,界面将弹出一个可交互的界面。
- 与聊天机器人进行 2 轮 互动。在标为“输入”的框中输入你想说的话,然后点击“发送”按钮。
多轮对话应用的区别就是拥有上下文,也就是历史记录。
实现的思路:使用一个列表保存每一次prompt和模型返回的输出,对于用户和AI返回的输出,分别使用user
和assistant
进行标识。
# 第一轮对话
用户:prompt设定人设
AI:返回
# 第二轮对话
历史对话(第一轮对话)
用户:new prompt
import requests
import gradio as gr
CHARACTER_FOR_CHATBOT = "面试官" # 机器人扮演的角色,注意,真正起作用的实际是提示词,因为并没有预设 system 角色
PROMPT_FOR_ROLEPLAY = "我需要你面试我有关AI的知识,仅提出问题" # 指定角色提示词
# 清除对话的函数
def reset():
"""
清空对话记录。
返回:
List: 空的对话记录列表
"""
return []
def request_llm(chat_history):
# formatted_history = format_messages_for_api(chat_history)
url = "https://api.siliconflow.cn/v1/chat/completions"
payload = {
"model": "Qwen/QwQ-32B",
"messages": chat_history,
"stream": False,
"max_tokens": 512,
"temperature": 0.7,
"top_p": 0.7,
}
headers = {
"Authorization": "Bearer sk-eqbuuxvwwxujcmscsggfbenhotmybysmgtvanbdsdydzpkcr",
"Content-Type": "application/json"
}
response = requests.request("POST", url, json=payload, headers=headers)
# 解析JSON响应
data = response.json()
print(data)
# 提取并返回内容
if 'choices' in data and len(data['choices']) > 0:
message = data['choices'][0].get('message', {})
response_content = message.get('content', '').strip()
# 如果内容为空但存在推理内容
if not response_content:
response_content = message.get('reasoning_content', '')
print(response_content)
return response_content
return "未获取到有效响应内容"
# 调用模型生成对话的函数
def interact_roleplay(chatbot, user_input):
"""
处理角色扮演多轮对话,调用模型生成回复
参数:
chatbot (list): 对话历史记录(消息字典列表)
user_input (str): 当前用户输入
返回:
list: 更新后的对话记录
"""
# 创建当前消息的副本
updated_chatbot = chatbot.copy()
# 添加用户消息
updated_chatbot.append({"role": "user", "content": user_input})
# 调用API获取回复
response = request_llm(updated_chatbot)
# 添加AI回复
updated_chatbot.append({"role": "assistant", "content": response})
return updated_chatbot
# 创建初始对话
first_dialogue = interact_roleplay([], PROMPT_FOR_ROLEPLAY)
# 构建 Gradio UI 界面
with gr.Blocks() as demo:
gr.Markdown("# 第2部分:角色扮演\n与聊天机器人进行角色扮演互动!")
# 使用正确的消息格式初始化Chatbot
chatbot = gr.Chatbot(
value=first_dialogue,
label=CHARACTER_FOR_CHATBOT,
type="messages"
)
description_textbox = gr.Textbox(label="机器人扮演的角色", interactive=False, value=CHARACTER_FOR_CHATBOT)
input_textbox = gr.Textbox(label="输入", value="")
with gr.Row():
send_button = gr.Button(value="发送")
reset_button = gr.Button(value="重置")
# 绑定按钮与回调函数
send_button.click(interact_roleplay, inputs=[chatbot, input_textbox,], outputs=[chatbot])
reset_button.click(reset, outputs=[chatbot])
# 启动 Gradio 应用
demo.launch(debug=True,share=True)
不同的prompt造成的效果会有很大的区别,而这些prompt,实际上都是在让模型去做一个隐性的角色扮演,无论是作为某个领域的专家还是一个文字游戏。