3.进阶技巧
3.1、思维链(Chain of Thoughts, CoT)
思维链,是大模型涌现出来的一种独特能力。
它是偶然被「发现」(对 OpenAI 的人在训练时没想过会这样)的。有人在提问时以「Let’s think step by step」开头,结果发现 AI 会自动把问题分解成多个步骤,然后逐步解决,使得输出的结果更加准确。
换一个业务场景:客服质检
任务本质是检查客服与用户的对话是否有不合规的地方
- 质检是电信运营商和金融券商大规模使用的一项技术
- 每个涉及到服务合规的检查点称为一个质检项
我们选一个质检项来演示思维链的作用:
产品信息准确性:
当向用户介绍流量套餐产品时,客服人员必须准确提及产品名称、月费价格、月流量总量、适用条件(如有)
上述信息缺失一项或多项,或信息与实时不符,都算信息不准确
import openai
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # 读取本地 .env 文件,里面定义了 OPENAI_API_KEY
openai.api_key = os.getenv('OPENAI_API_KEY')
def get_completion(prompt, model="gpt-3.5-turbo"):
messages = [{"role": "user", "content": prompt}]
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0, # 模型输出的随机性,0 表示随机性最小
)
return response.choices[0].message["content"]
instruction = """
给定一段用户与手机流量套餐客服的对话,
你的任务是判断客服介绍产品信息的准确性:
当向用户介绍流量套餐产品时,客服人员必须准确提及产品名称、月费价格和月流量总量 上述信息缺失一项或多项,或信息与实时不符,都算信息不准确
已知产品包括:
经济套餐:月费50元,月流量10G
畅游套餐:月费180元,月流量100G
无限套餐:月费300元,月流量1000G
校园套餐:月费150元,月流量200G,限在校学生办理
"""
# 输出描述
output_format = """
以JSON格式输出。
如果信息准确,输出:{"accurate":true}
如果信息不准确,输出:{"accurate":false}
"""
context = """
用户:你们有什么流量大的套餐
客服:您好,我们现在正在推广无限套餐,每月300元就可以享受1000G流量,您感兴趣吗
"""
context2 = """
用户:有什么便宜的流量套餐
客服:您好,我们有个经济型套餐,50元每月
"""
context3 = """
用户:流量大的套餐有什么
客服:我们推荐畅游套餐,180元每月,100G流量,大多数人都够用的
用户:学生有什么优惠吗
客服:如果是在校生的话,可以办校园套餐,150元每月,含200G流量,比非学生的畅游套餐便宜流量还多
"""
prompt = f"""
{instruction}
{output_format}
请一步一步分析以下对话
对话记录:
{context3}
"""
response = get_completion(prompt)
print(response)
根据对话记录,客服介绍产品信息的准确性可以分析如下:
- 客服介绍了畅游套餐,包括月费180元和月流量100G,这与实际产品信息相符,属于准确信息。
- 客服介绍了校园套餐,包括月费150元和月流量200G,并且提到了该套餐只限在校学生办理,这与实际产品信息相符,属于准确信息。
综上所述,客服介绍的产品信息是准确的。
因此,输出结果为:{“accurate”:true}
3.2、自洽性(Self-Consistency)
- 采样多个具有多样性的结果
- 通过投票选出最终结果
import openai
import os
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # 读取本地 .env 文件,里面定义了 OPENAI_API_KEY
openai.api_key = os.getenv('OPENAI_API_KEY')
def get_completion(prompt, model="gpt-3.5-turbo"):
messages = [{"role": "user", "content": prompt}]
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=0.8 # 模型输出的随机性,0 表示随机性最小
)
return response.choices[0].message["content"]
instruction = """
给定一段用户与手机流量套餐客服的对话,
你的任务是判断客服介绍产品信息的准确性:
当向用户介绍流量套餐产品时,客服人员必须准确提及产品名称、月费价格和月流量总量 上述信息缺失一项或多项,或信息与实时不符,都算信息不准确
已知产品包括:
经济套餐:月费50元,月流量10G
畅游套餐:月费180元,月流量100G
无限套餐:月费300元,月流量1000G
校园套餐:月费150元,月流量200G,限在校学生办理
"""
# 输出描述
output_format = """
以JSON格式输出。
如果信息准确,输出:{"accurate":true}
如果信息不准确,输出:{"accurate":false}
"""
context = """
用户:流量大的套餐有什么
客服:我们推荐畅游套餐,180元每月,100G流量,大多数人都够用的
用户:学生有什么优惠吗
客服:如果是在校生的话,可以办校园套餐,150元每月,含200G流量
"""
for _ in range(5):
prompt = f"{instruction}\n\n{output_format}\n\n请一步步分析:\n{context}"
response = get_completion(prompt)
print(response)
Output exceeds the size limit. Open the full output data in a text editor 用户:流量大的套餐有什么 客服:我们推荐畅游套餐,180元每月,100G流量,大多数人都够用的 用户:学生有什么优惠吗 客服:如果是在校生的话,可以办校园套餐,150元每月,含200G流量
根据对话内容,客服介绍了两种套餐产品:畅游套餐和校园套餐。经济套餐和无限套餐没有被提及。
对于畅游套餐,客服提到了产品名称、月费价格和月流量总量,信息准确。
对于校园套餐,客服也提到了产品名称、月费价格和月流量总量,信息准确。
因此,客服介绍产品信息的准确性是正确的。
输出:{“accurate”:true} { “accurate”: false } {“accurate”:false} 根据对话内容,客服介绍的产品信息如下:
- 客服介绍的套餐名称是畅游套餐。
- 客服介绍的套餐月费是180元。
- 客服介绍的套餐月流量总量是100G。
与实际产品信息进行对比: …
因此,客服介绍产品信息是准确的。
输出结果为:{“accurate”:true}
3.3、思维树(Tree-of-thought, ToT)
- 在思维链的每一步,采样多个分支
- 拓扑展开成一棵思维树
- 判断每个分支的任务完成度,以便进行启发式搜索
- 设计搜索算法
- 判断叶子节点的任务完成的正确性
业务场景举例:指标解读,项目推荐并说明依据
小明100米跑成绩:10.5秒,1500米跑成绩:3分20秒,铅球成绩:12米。他适合参加哪些搏击运动训练。
import openai
import os, json
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # 读取本地 .env 文件,里面定义了 OPENAI_API_KEY
openai.api_key = os.getenv('OPENAI_API_KEY')
def get_completion(prompt, model="gpt-4",temperature=0):
messages = [{"role": "user", "content": prompt}]
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=temperature # 模型输出的随机性,0 表示随机性最小
)
return response.choices[0].message["content"]
def performance_analyser(text):
prompt = f"{text}\n请根据以上成绩,分析候选人在速度、耐力、力量三方面素质的分档。分档包括:强(3),中(2),弱(1)三档。\
\n以JSON格式输出,其中key为素质名,value为以数值表示的分档。"
response = get_completion(prompt)
return json.loads(response)
def possible_sports(talent, category):
prompt = f"需要{talent}强的{category}运动有哪些。给出10个例子,以array形式输出。确保输出能由json.loads解析。"
response = get_completion(prompt,temperature=0.8)
return json.loads(response)
def evaluate(sports, talent, value):
prompt = f"分析{sports}运动对{talent}方面素质的要求: 强(3),中(2),弱(1)。\
\n直接输出挡位数字。输出只包含数字。"
response = get_completion(prompt)
val = int(response)
print(f"{sports}: {talent} {val} {value>=val}")
return value >= val
def report_generator(name,performance, talents,sports):
level = ['弱','中','强']
_talents = { k: level[v-1] for k, v in talents.items() }
prompt = f"已知{name}{performance}\n身体素质:{_talents}。\n生成一篇{name}适合{sports}训练的分析报告。"
response = get_completion(prompt,model="gpt-3.5-turbo")
return response
name = "小明"
performance = "100米跑成绩:10.5秒,1500米跑成绩:3分20秒,铅球成绩:12米。"
category = "搏击"
talents = performance_analyser(name+performance)
print("===talents===")
print(talents)
cache = set()
#深度优先
#第一层节点
for k, v in talents.items():
if v < 3: #剪枝
continue
leafs = possible_sports(k,category)
print(f"==={k} leafs===")
print(leafs)
#第二层节点
for sports in leafs:
if sports in cache:
continue
cache.add(sports)
suitable = True
for t, p in talents.items():
if t == k:
continue
#第三层节点
if not evaluate(sports,t,p): #剪枝
suitable = False
break
if suitable:
report = report_generator(name,performance,talents,sports)
print("****")
print(report)
print("****")
Output exceeds the size limit. Open the full output data in a text editor ===talents=== {‘速度’: 3, ‘耐力’: 3, ‘力量’: 2} ===速度 leafs=== [‘拳击’, ‘散打’, ‘泰拳’, ‘格斗术’, ‘跆拳道’, ‘柔道’, ‘摔跤’, ‘空手道’, ‘巴西柔术’, ‘击剑’] 拳击: 耐力 3 True 拳击: 力量 3 False 散打: 耐力 3 True 散打: 力量 3 False 泰拳: 耐力 3 True 泰拳: 力量 3 False 格斗术: 耐力 3 True 格斗术: 力量 3 False 跆拳道: 耐力 3 True 跆拳道: 力量 3 False 柔道: 耐力 3 True 柔道: 力量 3 False 摔跤: 耐力 3 True 摔跤: 力量 3 False 空手道: 耐力 2 True 空手道: 力量 3 False 巴西柔术: 耐力 3 True 巴西柔术: 力量 2 True
小明是一位身体素质非常出色的运动员。他在100米跑项目中取得了10.5秒的成绩,显示出了他出色的速度和爆发力。在1500米跑项目中,他以3分20秒的成绩完成比赛,展现了他出色的耐力和持久力。此外,他在铅球项目中达到了12米的成绩,显示出了他中等水平的力量。 … ===耐力 leafs=== [‘拳击’, ‘泰拳’, ‘摔跤’, ‘柔道’, ‘跆拳道’, ‘巴西柔术’, ‘散打’, ‘空手道’, ‘综合格斗’, ‘击剑’] 综合格斗: 速度 3 True 综合格斗: 力量 3 False response using the same format. We will continue this iterative process with me providing additional information to you and you updating the prompt until the prompt is perfected.Remember, the prompt we are creating should be written from the perspective of me making a request to ChatGPT. Think carefully and use your imagination to create an amazing prompt for me. You’re first response should only be a greeting to the user and to ask what the prompt should be about
作业
用提示工程的方法帮你完成一个写作任务,可以是发公众号、回答知乎问题、写周报等等,题材不限。