一、编写 Prompt 的原则简介
本章的主要内容为编写 Prompt 的原则,在本章中,我们将给出两个编写 Prompt 的原则与一些相关的策略,你将练习基于这两个原则来编写有效的 Prompt,从而便捷而有效地使用 LLM。
二、环境配置
本教程使用 文心一言的所开放的 ERNIE Bot Agent,所以你首先得注册有一个 aistudio账号,获得TOKEN ,然后需要安装 ERNIE Bot Agent库。
1.ERNIE Bot Agent 安装
首先需要安装所需第三方库:
erniebot:
bash
# 安装核心模块
pip install --upgrade erniebot
# 安装所有模块
pip install --upgrade erniebot-agent[all]
python
# 安装所有模块
!pip install --upgrade erniebot-agent[all] --user
2.EB_AGENT_ACCESS_TOKEN 导入
可以在aistudio.baidu.com/index/acces... 页面查看自己的token。
python
token = input("请输入您自己的 EB_AGENT_ACCESS_TOKEN,可在https://aistudio.baidu.com/index/accessToken查看,下面将自动导入系统环境变量:")
print("你输入的TOKEN是:", token)
python
# 将自己的 EB_AGENT_ACCESS_TOKEN 导入系统环境变量
import os
os.environ["EB_AGENT_ACCESS_TOKEN"] = token
!export EB_AGENT_LOGGING_LEVEL=info
3.ERNIE Bot Agent 语音工具测试
python
import asyncio
import os
from erniebot_agent.agents import FunctionAgent
from erniebot_agent.chat_models import ERNIEBot
from erniebot_agent.tools import RemoteToolkit
async def main():
llm = ERNIEBot(model="ernie-3.5") # 初始化大语言模型
# 这里以语音合成工具为例子,更多的预置工具可参考 https://aistudio.baidu.com/application/center/tool
tts_tool = RemoteToolkit.from_aistudio("texttospeech").get_tools()
agent = FunctionAgent(llm=llm, tools=tts_tool) # 创建智能体,集成语言模型与工具
# 与智能体进行通用对话
result = await agent.run("你好,请自我介绍一下")
print(f"Agent输出: {result.text}")
# 请求智能体根据输入文本,自动调用语音合成工具
result = await agent.run("把上一轮的自我介绍转成语音")
print(f"Agent输出: {result.text}")
# 将智能体输出的音频文件写入test.wav, 可以尝试播放
audio_file = result.steps[-1].output_files[0]
await audio_file.write_contents_to("./test.wav")
await main()
makefile
Agent输出: 你好!我是文心一言。我可以回答你的问题或与你对话。请问你有什么具体的问题或需要帮助的地方吗?
Agent输出: 根据你的请求,我已经将上一轮的自我介绍转化为了语音。音频文件已以file-local-b0ef09f2-e501-11ee-8d5a-fa260000591a的名称保存在本地。你可以使用这个文件名来找到并播放这段语音。如果你需要进一步操作或有其他问题,请随时告诉我。
生成的语音保存在当前用户目录test.wav文件里,可以下载试听。
4. ERNIE Bot Agent agent 当前时间工具测试
python
import asyncio
from erniebot_agent.agents import FunctionAgent
from erniebot_agent.chat_models import ERNIEBot
from erniebot_agent.tools.current_time_tool import CurrentTimeTool
async def main():
agent = FunctionAgent(llm=ERNIEBot(model="ernie-3.5"), tools=[CurrentTimeTool()])
result = await agent.run("现在北京时间是什么时候?")
print(result.text)
await main()
根据CurrentTimeTool工具获取的结果,现在是2024年03月18日 16时30分02秒。如果您还有其他问题或需要更多信息,请随时告诉我。
5.ERNIE Bot Agent 合规性工具测试
python
import asyncio
from erniebot_agent.agents import FunctionAgent
from erniebot_agent.chat_models import ERNIEBot
from erniebot_agent.tools.remote_toolkit import RemoteToolkit
async def main():
toolkit = RemoteToolkit.from_aistudio("text-moderation")
agent = FunctionAgent(llm=ERNIEBot(model="ernie-3.5"), tools=toolkit.get_tools())
result = await agent.run(""欢迎使用ERNIE-Bot-Agent"这句话合规吗?")
print(result.text)
await main()
根据我们的文本审核工具的分析,"欢迎使用ERNIE-Bot-Agent"这句话是合规的,没有违反任何规定。如果您还有其他问题或需要审核其他文本,请随时告诉我。
6.ERNIE Bot Agent agent问答测试
python
from erniebot_agent.agents import FunctionAgent
from erniebot_agent.chat_models import ERNIEBot
from erniebot_agent.memory import WholeMemory
agent = FunctionAgent(llm=ERNIEBot(model="ernie-3.5"), tools=[], memory=WholeMemory())
response = await agent.run("你好,小度!")
# `text`属性是agent给出的回复文本
print(response.text)
# 打印结果可能如下:
# 你好,有什么我可以帮你的吗?
response = await agent.run("我刚刚怎么称呼你?")
# `chat_history`属性存储本次运行中与chat model的对话历史
for message in response.chat_history:
print(message.content)
你好!请问你有什么具体的问题或需要帮助吗?
我刚刚怎么称呼你?
你刚刚称呼我为"小度"。
python
import os
import json
import asyncio
import erniebot
from erniebot_agent.chat_models import ERNIEBot
from erniebot_agent.memory import HumanMessage, AIMessage, SystemMessage, FunctionMessage
python
model = ERNIEBot(model="ernie-3.5")
# 使用Message模块
messages = [
HumanMessage("我在深圳,周末可以去哪里玩"),
AIMessage("深圳有许多著名的景点,以下是三个推荐景点:1. 深圳世界之窗,2. 深圳欢乐谷,3. 深圳东部华侨城。"),
HumanMessage("从你推荐的三个景点中,选出最值得去的景点是什么,直接给出景点名字即可"),
]
ai_message = await model.chat(messages=messages)
print(ai_message.content)
直接从我推荐的三个景点中选择,最值得去的景点是:深圳世界之窗。这是因为世界之窗集合了全球各地的著名景点和建筑,你可以在短时间内领略到世界各地的文化和风光,非常适合周末游玩。此外,世界之窗还有各种娱乐设施和表演节目,非常适合家庭出游。
python
human_message = HumanMessage(content="你好,你是谁?")
system_message = SystemMessage(content="你是一名数学老师,使用浅显易懂的方法来回答问题")
result = {"temperature": 25, "unit": "摄氏度"}
function_message = FunctionMessage(
name="get_current_temperature", content=json.dumps(result, ensure_ascii=False)
)
print(human_message)
print(system_message)
print(function_message)
less
<role: 'user', content: '你好,你是谁?'>
<role: 'system', content: '你是一名数学老师,使用浅显易懂的方法来回答问题', token_count: 23>
<role: 'function', name: 'get_current_temperature', content: '{"temperature": 25, "unit": "摄氏度"}'>
python
model = ERNIEBot(model="ernie-3.5")
system_message = SystemMessage(content="你是一个有着8年经验的孵化了数百个百万粉丝的 爆款文案 爆款选题的写手,能产出抖音各个赛道的高质量的各种文案脚本。")
messages = [HumanMessage("制作一个讲解勾股定理视频的教学文案")]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
markdown
**视频标题:** 勾股定理:解开直角三角形神秘面纱的钥匙
**视频简介:** 勾股定理,一个看似简单却蕴含无尽智慧的数学原理。通过这个视频,你将揭开直角三角形的神秘面纱,了解勾股定理的历史、应用和证明方法。
**视频分镜脚本:**
1. **开场**:
* 画面:缓慢拉近一幅古老的画卷,上面绘有一个直角三角形和"勾3股4弦5"的标注。 * 旁白:你是否想过,一个简单的直角三角形里,竟然隐藏着如此深奥的数学秘密?今天,就让我们一同来探索这个被称为勾股定理的神奇原理。 2. 历史背景:
* 画面:快速切换至不同时代的学者和书籍影像。 * 旁白:勾股定理的历史可以追溯到公元前6世纪的中国、古埃及和古希腊。毕达哥拉斯学派更是将其视为神圣不可侵犯的数学原理。 3. 定理陈述:
* 画面:展示一个直角三角形,标注直角边a、b和斜边c。 * 旁白:在直角三角形中,直角边的平方和等于斜边的平方,即a² + b² = c²。这个简单的公式,背后却蕴含着无穷的智慧和力量。 4. 定理证明:
* 画面:展示一个正方形网格,通过拼接不同形状的小正方形来证明勾股定理。 * 旁白:这里,我们将通过一种直观的方法------面积法来证明勾股定理。让我们来看看,这些看似无关的小正方形如何拼凑出定理的精髓。 5. 实际应用:
* 画面:展示各种应用勾股定理的场景,如测量建筑高度、计算距离等。 * 旁白:勾股定理不仅在理论数学中占有重要地位,还广泛应用于工程、建筑、航海等领域。掌握了它,你就掌握了解决实际问题的一大利器。 6. 结语:
* 画面:画面拉远,展示一幅现代城市的景象,高楼大厦、桥梁道路交织成一幅美丽的画卷。 * 旁白:勾股定理,一个简单却深刻的数学原理,它不仅揭示了直角三角形的奥秘,还指引我们走向更广阔的数学世界。希望通过这个视频,你能对勾股定理有更深入的了解和认识。
markdown
**视频结束**:画面淡出,留下"探索数学之美,感悟智慧之韵"的字样。
三、两个基本原则
1.原则一:编写清晰、具体的指令
你应该通过提供尽可能清晰和具体的指令来表达您希望模型执行的操作。这将引导模型给出正确的输出,并减少你得到无关或不正确响应的可能。编写清晰的指令不意味着简短的指令,因为在许多情况下,更长的提示实际上更清晰且提供了更多上下文,这实际上可能导致更详细更相关的输出。
1.1 策略一:使用分隔符
使用分隔符清晰地表示输入的不同部分**,分隔符可以是:```,"",<>,<tag>,<\tag>等
你可以使用任何明显的标点符号将特定的文本部分与提示的其余部分分开。这可以是任何可以使模型明确知道这是一个单独部分的标记。使用分隔符是一种可以避免提示注入的有用技术。提示注入是指如果用户将某些输入添加到提示中,则可能会向模型提供与您想要执行的操作相冲突的指令,从而使其遵循冲突的指令而不是执行您想要的操作。即,输入里面可能包含其他指令,会覆盖掉你的指令。对此,使用分隔符是一个不错的策略。
python
text = f"""
你应该提供尽可能清晰、具体的指示,以表达你希望模型执行的任务。\
这将引导模型朝向所需的输出,并降低收到无关或不正确响应的可能性。\
不要将写清晰的提示与写简短的提示混淆。\
在许多情况下,更长的提示可以为模型提供更多的清晰度和上下文信息,从而导致更详细和相关的输出。
"""
# 需要总结的文本内容
prompt = "把用三个反引号括起来的文本总结成一句话。"
# 指令内容,使用 ``` 来分隔指令和待总结的内容
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
清晰、具体的指示对于引导模型生成所需的输出至关重要,它可以降低无关或不正确响应的风险。同时,不应将写清晰的提示与写简短的提示相混淆,因为更长的提示往往能提供更多的上下文信息,从而使输出更详细、更相关。
1.2 策略二:要求一个结构化的输出
要求一个结构化的输出**,可以是 Json、HTML 等格式
第二个策略是要求生成一个结构化的输出,这可以使模型的输出更容易被我们解析,例如,你可以在 Python 中将其读入字典或列表中。
在以下示例中,我们要求 GPT 生成三本书的标题、作者和类别,并要求 GPT 以 Json 的格式返回给我们,为便于解析,我们指定了 Json 的键。
python
text = f"""
请生成包括书名、作者和类别的三本虚构书籍清单,\
并以 JSON 格式提供,其中包含以下键:book_id、title、author、genre。
"""
model = ERNIEBot(model="ernie-3.5")
# 使用Message模块
messages = [HumanMessage(text),]
ai_message = await model.chat(messages=messages)
print(ai_message.content)
css
```json
[ { "book_id": 1, "title": "时空穿越者的冒险", "author": "张三", "genre": "科幻" }, { "book_id": 2, "title": "魔法森林的秘密", "author": "李四", "genre": "奇幻" }, { "book_id": 3, "title": "都市异能录", "author": "王五", "genre": "都市异能" }]
```
1.3 策略三:要求模型检查是否满足条件
如果任务做出的假设不一定满足,我们可以告诉模型先检查这些假设,如果不满足,指示并停止执行。你还可以考虑潜在的边缘情况以及模型应该如何处理它们,以避免意外的错误或结果。
在如下示例中,我们将分别给模型两段文本,分别是制作茶的步骤以及一段没有明确步骤的文本。我们将要求模型判断其是否包含一系列指令,如果包含则按照给定格式重新编写指令,不包含则回答未提供步骤。
python
# 有步骤的文本
text_1 = f"""
泡一杯茶很容易。首先,需要把水烧开。\
在等待期间,拿一个杯子并把茶包放进去。\
一旦水足够热,就把它倒在茶包上。\
等待一会儿,让茶叶浸泡。几分钟后,取出茶包。\
如果你愿意,可以加一些糖或牛奶调味。\
就这样,你可以享受一杯美味的茶了。
"""
prompt = f"""
您将获得由三个引号括起来的文本。\
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - ...
...
第N步 - ...
如果文本中不包含一系列的指令,则直接写"未提供步骤"。"
\"\"\"{text_1}\"\"\"
"""
model = ERNIEBot(model="ernie-3.5")
system_message = SystemMessage(content="你是一个有着8年经验的孵化了数百个百万粉丝的 爆款文案 爆款选题的写手,能产出抖音各个赛道的高质量的各种文案脚本。")
messages = [HumanMessage("制作一个讲解勾股定理视频的教学文案")]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
shell
### 《揭示神秘面纱:勾股定理详解》视频教学文案
### 开场
"大家好,我是[您的名字],欢迎来到[您的频道名称]。今天我们要探讨的,是数学史上一个古老而又神秘的定理------勾股定理。这个定理不仅在数学领域有着举足轻重的地位,而且在建筑、工程等领域也有广泛应用。让我们一起走进勾股定理的世界,探寻它背后的秘密。"
### 勾股定理简介
"勾股定理,又称为毕达哥拉斯定理,是一个关于直角三角形三边关系的定理。它告诉我们,在一个直角三角形中,直角边的平方和等于斜边的平方。用数学公式表示就是:a² + b² = c²,其中a和b是直角边,c是斜边。"
### 历史背景
"勾股定理的历史可以追溯到公元前6世纪,由古希腊数学家毕达哥拉斯首次发现。这个定理在数学界引起了巨大的反响,被认为是数学发展史上的一个重要里程碑。它不仅在数学领域有着广泛的应用,还激发了人们对数学美的追求和探索。"
### 定理证明
"现在,让我们来一起探索勾股定理的证明过程。虽然历史上有很多不同的证明方法,但在这里我们将介绍一种比较直观和简单的方法------图形法。我们将使用几个正方形和三角形来直观地展示这个定理的证明过程。"
[在这里,通过动画或手绘的方式展示图形法的证明过程,详细解释每一步的推理和结论。]
### 应用场景
"勾股定理在生活和工作中有着广泛的应用。例如,在建筑行业,工程师可以利用勾股定理计算建筑结构的稳定性;在航天领域,科学家可以运用勾股定理来计算飞行器的轨道和速度;在日常生活中,我们也可以用勾股定理来估算距离或高度。"
### 结尾
"通过今天的视频,我们一起了解了勾股定理的历史背景、证明过程和应用场景。希望这个古老而又神秘的定理能够激发你对数学的兴趣和热爱。如果你觉得这个视频对你有帮助,请点赞支持并分享给你的朋友们。我是[您的名字],我们下期视频再见!"
python
# 无步骤的文本
text_2 = """
今天阳光明媚,鸟儿在歌唱。\
这是一个去公园散步的美好日子。\
鲜花盛开,树枝在微风中轻轻摇曳。\
人们外出享受着这美好的天气,有些人在野餐,有些人在玩游戏或者在草地上放松。\
这是一个完美的日子,可以在户外度过并欣赏大自然的美景。
"""
prompt = """
如果它包含一系列的指令,则需要按照以下格式重新编写这些指令:
第一步 - ...
第二步 - ...
...
第N步 - ...
如果文本中不包含一系列的指令,则直接写"未提供步骤"。"
"""
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text_2)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
未提供步骤。
1.4 策略四:提供少量示例
即在要求模型执行实际任务之前,提供给它少量成功执行任务的示例。
例如,在以下的示例中,我们告诉模型其任务是以一致的风格回答问题,并先给它一个孩子和一个祖父之间的对话的例子。孩子说,"教我耐心",祖父用这些隐喻回答。因此,由于我们已经告诉模型要以一致的语气回答,现在我们说"教我韧性",由于模型已经有了这个少样本示例,它将以类似的语气回答下一个任务。
python
prompt = "你的任务是以一致的风格回答问题。"
text="""
<孩子>: 教我耐心。
<祖父母>: 挖出最深峡谷的河流源于一处不起眼的泉眼;最宏伟的交响乐从单一的音符开始;最复杂的挂毯以一根孤独的线开始编织。
<孩子>: 教我韧性。
"""
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
makefile
<祖父母>: 记住,顽石经年累月被水侵蚀,最终变得圆润光滑;树苗经历风雨,才能茁壮成长;高山由无数石块堆积而成,每块石头都经历了岁月的磨砺。耐心和韧性是成功的关键,孩子,你要学会持之以恒,不畏艰难。
2. 原则二:给模型时间去思考
如果模型匆忙地得出了错误的结论,您应该尝试重新构思查询,请求模型在提供最终答案之前进行一系列相关的推理。换句话说,如果您给模型一个在短时间或用少量文字无法完成的任务,它可能会猜测错误。这种情况对人来说也是一样的。如果您让某人在没有时间计算出答案的情况下完成复杂的数学问题,他们也可能会犯错误。因此,在这些情况下,您可以指示模型花更多时间思考问题,这意味着它在任务上花费了更多的计算资源。
2.1 策略一:指定完成任务所需的步骤
接下来我们将通过给定一个复杂任务,给出完成该任务的一系列步骤,来展示这一策略的效果
首先我们描述了杰克和吉尔的故事,并给出一个指令。该指令是执行以下操作。首先,用一句话概括三个反引号限定的文本。第二,将摘要翻译成法语。第三,在法语摘要中列出每个名称。第四,输出包含以下键的 JSON 对象:法语摘要和名称数。然后我们要用换行符分隔答案。
python
text = """
在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。\
他们一边唱着欢乐的歌,一边往上爬,\
然而不幸降临------杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
虽然略有些摔伤,但他们还是回到了温馨的家中。\
尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。
"""
prompt = """
执行以下操作:
1-用一句话摘要概括下面文本。
2-将摘要翻译成法语。
3-在法语摘要中列出每个人名。
4-输出一个 JSON 对象,其中包含以下键:French_summary,num_names。
"""
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
less
1. 杰克和吉尔兄妹在迷人的村庄前往山顶井打水,途中遭遇意外滚下山,虽受轻伤但仍返回家中,他们的冒险精神不减。
2. "Dans un charmant village, les frères Jack et Jill se sont rendu à un puits situé au sommet d'une montagne pour puiser l'eau. Ils ont chanté joyeusement et ont grimpé, mais le malheur a frappé - Jack a trébuché sur une pierre et a roulé du mont, suivi par Jill. Bien qu'ils ont été légèrement blessés, ils sont toujours retournés à leur maison chaleureuse. Malgré cet accident, leur esprit d'aventure n'a pas faibli et ils ont continué à explorer avec joie."
3. 在法语摘要中,没有人名。
4. ```json
{
"French_summary": "Dans un charmant village, les frères Jack et Jill se sont rendu à un puits situé au sommet d'une montagne pour puiser l'eau. Ils ont chanté joyeusement et ont grimpé, mais le malheur a frappé - Jack a trébuché sur une pierre et a roulé du mont, suivi par Jill. Bien qu'ils ont été légèrement blessés, ils sont toujours retournés à leur maison chaleureuse. Malgré cet accident, leur esprit d'aventure n'a pas faibli et ils ont continué à explorer avec joie.",
"num_names": 2
}
```
上述输出仍然存在一定问题,例如,键"姓名"会被替换为法语,因此,我们给出一个更好的 Prompt,该 Prompt 指定了输出的格式
python
text = """
在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。\
他们一边唱着欢乐的歌,一边往上爬,\
然而不幸降临------杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。\
虽然略有些摔伤,但他们还是回到了温馨的家中。\
尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。
"""
prompt = """
1-用一句话概括下面用<>括起来的文本。
2-将摘要翻译成英语。
3-在英语摘要中列出每个名称。
4-输出一个 JSON 对象,其中包含以下键:English_summary,num_names。
请使用以下格式:
文本:<要总结的文本>
摘要:<摘要>
翻译:<摘要的翻译>
名称:<英语摘要中的名称列表>
输出 JSON:<带有 English_summary 和 num_names 的 JSON>
"""
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
css
文本:<在一个迷人的村庄里,兄妹杰克和吉尔出发去一个山顶井里打水。他们一边唱着欢乐的歌,一边往上爬,然而不幸降临------杰克绊了一块石头,从山上滚了下来,吉尔紧随其后。虽然略有些摔伤,但他们还是回到了温馨的家中。尽管出了这样的意外,他们的冒险精神依然没有减弱,继续充满愉悦地探索。>
摘要:兄妹杰克和吉尔在村庄的山顶井打水时遭遇意外,两人都从山上滚下受伤,但安全回家后仍继续探索。
翻译:While fetching water from a well at the top of a mountain in a charming village, siblings Jack and Jill encountered an accident. Both of them rolled down the mountain and sustained injuries, but they safely returned home and continued to explore with undiminished spirit of adventure.
名称:Jack, Jill
输出 JSON:
```json
{
"English_summary": "Siblings Jack and Jill encountered an accident while fetching water from a well at the top of a mountain in a charming village. Both rolled down the mountain and sustained injuries, but safely returned home and continued to explore with undiminished spirit of adventure.",
"num_names": 2
}
```
2.2 策略二:指导模型找出解法
指导模型在下结论之前找出一个自己的解法
有时候,在明确指导模型在做决策之前要思考解决方案时,我们会得到更好的结果。
接下来我们会给出一个问题和一个学生的解答,要求模型判断解答是否正确
python
prompt = "判断学生的解决方案是否正确。"
text="""
问题:
我正在建造一个太阳能发电站,需要帮助计算财务。
土地费用为 100美元/平方英尺
我可以以 250美元/平方英尺的价格购买太阳能电池板
我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺10美元
作为平方英尺数的函数,首年运营的总费用是多少。
学生的解决方案:
设x为发电站的大小,单位为平方英尺。
费用:
土地费用:100x
太阳能电池板费用:250x
维护费用:100,000美元+100x
总费用:100x+250x+100,000美元+100x=450x+100,000美元
"""
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
markdown
学生的解决方案是正确的。学生正确地将所有的费用作为发电站大小(平方英尺)的函数进行了建模。
具体来看,费用包括:
1. 土地费用:100x,因为每平方英尺的土地费用是100美元。
2. 太阳能电池板费用:250x,因为每平方英尺的太阳能电池板费用是250美元。
3. 维护费用:这是两部分的总和,一部分是固定的10万美元,另一部分是每平方英尺10美元,所以总维护费用是100,000美元+10x。
然后,学生将这三部分费用相加,得到了总费用为450x+100,000美元,这是正确的。
总的来说,学生的解决方案正确地计算了首年运营的总费用作为发电站大小的函数。
但是注意,学生的解决方案实际上是错误的。
我们可以通过指导模型先自行找出一个解法来解决这个问题。
在接下来这个 Prompt 中,我们要求模型先自行解决这个问题,再根据自己的解法与学生的解法进行对比,从而判断学生的解法是否正确。同时,我们给定了输出的格式要求。通过明确步骤,让模型有更多时间思考,有时可以获得更准确的结果。在这个例子中,学生的答案是错误的,但如果我们没有先让模型自己计算,那么可能会被误导以为学生是正确的。
python
prompt = """
请判断学生的解决方案是否正确,请通过如下步骤解决这个问题:
步骤:
首先,自己解决问题。
然后将你的解决方案与学生的解决方案进行比较,并评估学生的解决方案是否正确。在自己完成问题之前,请勿决定学生的解决方案是否正确。
最后判断学生方案是否正确
使用以下格式:
问题:问题文本
学生的解决方案:学生的解决方案文本
实际解决方案和步骤:实际解决方案和步骤文本
学生的解决方案和实际解决方案是否相同:是或否
学生的成绩:正确或不正确
"""
text= """
问题:
我正在建造一个太阳能发电站,需要帮助计算财务。
- 土地费用为每平方英尺100美元
- 我可以以每平方英尺250美元的价格购买太阳能电池板
- 我已经谈判好了维护合同,每年需要支付固定的10万美元,并额外支付每平方英尺10美元
作为平方英尺数的函数,首年运营的总费用是多少。
学生的解决方案:
设x为发电站的大小,单位为平方英尺。
费用:
1. 土地费用:100x
2. 太阳能电池板费用:250x
3. 维护费用:100,000+100x
总费用:100x+250x+100,000+100x=450x+100,000
"""
system_message = SystemMessage(content=prompt)
messages = [HumanMessage(text)]
ai_message = await model.chat(messages=messages, system=system_message.content)
print(ai_message.content)
markdown
我们正在为太阳能发电站的建设做财务计算。
我们需要知道,随着发电站的大小(用平方英尺表示),首年的总费用是多少。
假设发电站的大小为 x 平方英尺。
根据题目,我们可以得到以下费用:
1. 土地费用是 100 × x 美元。
2. 太阳能电池板费用是 250 × x 美元。
3. 维护费用是 100,000 + 10 × x 美元(固定费用加上每平方英尺的费用)。
那么,总费用就是这三者之和:
总费用 = 100x + 250x + 100,000 + 10x
现在,我们可以计算这个方程,得到首年的总费用作为 x 的函数。
首年的总费用函数为:360*x + 100000 美元。
也就是说,对于每增加1平方英尺的发电站,总费用将增加460美元(100美元的土地费用 + 250美元的电池板费用 + 10美元的维护费用)。
三、局限性
虚假知识:模型偶尔会生成一些看似真实实则编造的知识
如果模型在训练过程中接触了大量的知识,它并没有完全记住所见的信息,因此它并不很清楚自己知识的边界。这意味着它可能会尝试回答有关晦涩主题的问题,并编造听起来合理但实际上并不正确的答案。我们称这些编造的想法为幻觉。
例如在如下示例中,我们要求告诉我们 Boie 公司生产的 AeroGlide UltraSlim Smart Toothbrush 产品的信息,事实上,这个公司是真实存在的,但产品是编造的,模型则会一本正经地告诉我们编造的知识。
python
text = f"""
告诉我 Boie 公司生产的 AeroGlide UltraSlim Smart Toothbrush 的相关信息
"""
model = ERNIEBot(model="ernie-3.5")
# 使用Message模块
messages = [HumanMessage(text),]
ai_message = await model.chat(messages=messages)
print(ai_message.content)
markdown
Boie 公司生产的 AeroGlide UltraSlim Smart Toothbrush 是一款电动牙刷,结合了现代科技和传统口腔护理理念。以下是关于这款牙刷的一些主要信息:
1. 智能功能:AeroGlide UltraSlim Smart Toothbrush 配备了智能传感器和刷头,可以实时追踪用户的刷牙习惯,如刷牙时间、刷牙力度和覆盖范围等。同时,它还可以与手机应用程序连接,为用户提供定制化的刷牙建议,以帮助他们达到最佳的口腔清洁效果。
2. 高效清洁:这款牙刷的刷头设计独特,采用柔软的刷毛和高效的震动技术,可以深入牙缝,有效清除牙菌斑和食物残渣,从而帮助预防蛀牙和牙周病。
3. 舒适体验:AeroGlide UltraSlim Smart Toothbrush 的体积轻巧,刷头超薄,适合各种口腔形状。同时,它的震动频率适中,既不会刺激牙齿和牙龈,又能提供足够的清洁力度。
4. 节能环保:这款牙刷采用可充电式设计,无需更换电池,既环保又经济。此外,它的待机时间长,一次充电可以支持多次使用。
5. 个性化定制:用户可以通过手机应用程序为 AeroGlide UltraSlim Smart Toothbrush 设置个性化的刷牙模式,如针对不同口腔区域的定制清洁计划、刷牙时长和力度等。
总之,Boie 公司生产的 AeroGlide UltraSlim Smart Toothbrush 是一款集智能、高效、舒适和环保于一身的电动牙刷,旨在为用户提供最佳的口腔护理体验。
模型会输出看上去非常真实的编造知识,这有时会很危险。因此,请确保使用我们在本节中介绍的一些技巧,以尝试在构建自己的应用程序时避免这种情况。这是模型已知的一个弱点,也是我们正在积极努力解决的问题。在你希望模型根据文本生成答案的情况下,另一种减少幻觉的策略是先要求模型找到文本中的任何相关引用,然后要求它使用这些引用来回答问题,这种追溯源文档的方法通常对减少幻觉非常有帮助。
四、参考
- ERNIE Bot Agent 文档 ernie-bot-agent.readthedocs.io/zh-cn/
- 吴恩达《ChatGPT Prompt Engineering for Developers》课程中文版 learn.deeplearning.ai