【LangChain】如何优雅的构造prompt

背景

我们要想自定义一个prompt,习惯行写一个txt文档,里面放prompt_template

!<INPUT 0>!name

===split===
!<INPUT 0>!的兴趣爱好是什么?

构建prompt时,先定义变量input0="bob",导入template之后,替换掉对应变量


def create_prompt(input: [], template: str)
	prompt = template
	for i, v in enumnate(input):
		prompt = prompt.replace(f"!<INPUT {v}>!", v)
	return prompt

with open("prompt_template.txt", 'w') as f:
	template = f.read()
	
input = []
input0="马斯克"
input.append(input0)

prompt = create_prompt(input, template)

这样一类prompt就对应着一个template(txt文件),以及一个构造函数,文件一多就很烦

使用LangChain构造prompt

先看代码,背景中的代码可以用LangChain的两行代码就能实现

from langchain.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template("{name}的兴趣爱好是什么?")
print(prompt_template.format(name="马斯克"))
> 马斯克的兴趣爱好是什么?

Chat模板

我们用PromptTemplate定义一个Chat模板,Chat模板是一个<role - contet>List

from langchain_core.prompts import PromptTemplate

chat_template = PromptTemplate.from_template(
    [
        ("system", "You are a helpful AI bot. Your name is {name}."),
        ("human", "Hello, how are you doing?"),
        ("ai", "I'm doing well, thanks!"),
        ("human", "{user_input}"),
    ]
)

messages = chat_template.format(name="Bob", user_input="What is your name?")

我们发现写<role - contet>对的时候比较繁琐,role是提前定义好了的,我们只要赋值content就行

LangChain在PromptTemplate之上提供了专门的ChatPromptTemplate来构造Chat模板

from langchain.prompts import ChatMessagePromptTemplate
from langchain.prompts import HumanMessagePromptTemplate
from langchain_core.messages import SystemMessage

chat_template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(
            content=(
                "You are a helpful assistant that re-writes the user's text to "
                "sound more upbeat."
            )
        ),
        HumanMessagePromptTemplate.from_template("{text}"),
    ]
)
messages = chat_template.format_messages(text="I don't like eating tasty things")
print(messages)
[SystemMessage(content="You are a helpful assistant that re-writes the user's text to sound more upbeat."), HumanMessage(content="I don't like eating tasty things")]

PromptTemplate不同,ChatPromptTemplate调用from_messages方法来构造模板,其参数是一个Message List,用format_messages方法来创建prompt。

想要Few Shot怎么办

在需要prompt中加入Few Shot时, 我们一般直接在prompt模板中加入,比如

!<INPUT 0>!name

===split===
Question: 李明的兴趣爱好是什么?
李明是一位热情的户外探险者和环保主义者。他热爱徒步旅行和山地自行车运动,经常在周末组织或参加远足活动,探索自然的美丽。他还对摄影有着浓厚的兴趣,喜欢用镜头记录下旅途中的壮丽风景和野生动物。此外,李明还是一名志愿者,积极参与当地的环保项目,致力于提高公众对可持续发展和生态保护的意识。

Question: 王晓华的兴趣爱好是什么?
王晓华是一位热爱艺术和文化的自由职业者。她对绘画和陶艺特别感兴趣,经常在工作室里创作自己的艺术作品。王晓华也喜欢参加各种艺术展览和文化节,从中汲取灵感和学习新的艺术技巧。她还是一个书籍爱好者,尤其喜欢阅读历史和文学方面的书籍,她的书架上摆满了各种经典和现代作品。

Question: 张伟的兴趣爱好是什么?
张伟是一名科技爱好者和编程极客。他对最新的科技发展和创新保持高度关注,业余时间经常参与开源项目,贡献自己的编程技能。张伟对电子制作和机器人学也有浓厚的兴趣,他的家中摆满了各种电子元件和自制的机器人模型。此外,他还是一个电子竞技爱好者,经常与朋友们一起在线玩游戏,参加本地的电竞比赛。

Question: !<INPUT 0>!的兴趣爱好是什么?

LangChain中的FewShotChatMessagePromptTemplate能实现从库中加载Few-shot示例

from langchain.prompts import (
    ChatPromptTemplate,
    FewShotChatMessagePromptTemplate,
)
examples = [
    {"input": "王晓华的兴趣爱好是什么?", "output": "..."},
    {"input": "张伟的兴趣爱好是什么?", "output": "..."},
    {"input": "李明的兴趣爱好是什么?", "output": "..."},
]

# 为库中每个example格式化的模板
example_prompt = ChatPromptTemplate.from_messages(
    [
        ("human", "{input}"),
        ("ai", "{output}"),
    ]
)

few_shot_prompt = FewShotChatMessagePromptTemplate(
    example_prompt=example_prompt,
    examples=examples,
)
print(few_shot_prompt.format())
Human:王晓华的兴趣爱好是什么?
AI: ...省略

Human:张伟的兴趣爱好是什么?
AI: ...省略

Human:李明的兴趣爱好是什么?
AI: ...省略

但这样的示例是写死的,不能换的
假设examples有:

Question: 赵雨的兴趣爱好是什么?
赵雨是一位文学爱好者和语言学习者。她对世界各地的文化和历史充满好奇,喜欢通过阅读各国的经典文学作品来了解不同的生活方式和思想。赵雨精通英语和法语,目前正在学习西班牙语,希望能够流利地使用多种语言进行交流。在业余时间,她还喜欢参加书法和茶艺课程,以此来陶冶情操和放松心情。

Question: 陈磊的兴趣爱好是什么?
陈磊是一位健身爱好者和营养师。他坚信健康的生活方式对于生活质量至关重要,因此他每天都会进行至少一小时的体育锻炼,包括力量训练、有氧运动和瑜伽。陈磊对营养学有着深入的研究,喜欢制定个性化的饮食计划,帮助他人达到健康和健身的目标。此外,他还是一位烹饪爱好者,擅长制作健康美味的低脂菜肴
 
Question: 林静的兴趣爱好是什么?
林静是一位音乐和旅行的狂热爱好者。她从小就学习钢琴和小提琴,现在是一名业余的音乐家,经常参加社区的音乐演出和慈善活动。林静热爱旅行,她的梦想是游遍世界上的每一个角落,体验不同国家的文化和风景。她喜欢在旅行中尝试当地的美食,与当地人交流,并通过摄影记录下旅途中的点点滴滴。

Question: 李明的兴趣爱好是什么?
李明是一位热情的户外探险者和环保主义者。他热爱徒步旅行和山地自行车运动,经常在周末组织或参加远足活动,探索自然的美丽。他还对摄影有着浓厚的兴趣,喜欢用镜头记录下旅途中的壮丽风景和野生动物。此外,李明还是一名志愿者,积极参与当地的环保项目,致力于提高公众对可持续发展和生态保护的意识。

Question: 王晓华的兴趣爱好是什么?
王晓华是一位热爱艺术和文化的自由职业者。她对绘画和陶艺特别感兴趣,经常在工作室里创作自己的艺术作品。王晓华也喜欢参加各种艺术展览和文化节,从中汲取灵感和学习新的艺术技巧。她还是一个书籍爱好者,尤其喜欢阅读历史和文学方面的书籍,她的书架上摆满了各种经典和现代作品。

Question: 张伟的兴趣爱好是什么?
张伟是一名科技爱好者和编程极客。他对最新的科技发展和创新保持高度关注,业余时间经常参与开源项目,贡献自己的编程技能。张伟对电子制作和机器人学也有浓厚的兴趣,他的家中摆满了各种电子元件和自制的机器人模型。此外,他还是一个电子竞技爱好者,经常与朋友们一起在线玩游戏,参加本地的电竞比赛。

我们准备为人设为文科学生的梁静设定兴趣爱好,最好的示例选择应该是

Question: 赵雨的兴趣爱好是什么?
赵雨是一位文学爱好者和语言学习者。她对世界各地的文化和历史充满好奇,喜欢通过阅读各国的经典文学作品来了解不同的生活方式和思想。赵雨精通英语和法语,目前正在学习西班牙语,希望能够流利地使用多种语言进行交流。在业余时间,她还喜欢参加书法和茶艺课程,以此来陶冶情操和放松心情。

Question: 王晓华的兴趣爱好是什么?
王晓华是一位热爱艺术和文化的自由职业者。她对绘画和陶艺特别感兴趣,经常在工作室里创作自己的艺术作品。王晓华也喜欢参加各种艺术展览和文化节,从中汲取灵感和学习新的艺术技巧。她还是一个书籍爱好者,尤其喜欢阅读历史和文学方面的书籍,她的书架上摆满了各种经典和现代作品。

Question: 林静的兴趣爱好是什么?
林静是一位音乐和旅行的狂热爱好者。她从小就学习钢琴和小提琴,现在是一名业余的音乐家,经常参加社区的音乐演出和慈善活动。林静热爱旅行,她的梦想是游遍世界上的每一个角落,体验不同国家的文化和风景。她喜欢在旅行中尝试当地的美食,与当地人交流,并通过摄影记录下旅途中的点点滴滴。

Question: 梁静的兴趣爱好是什么?

LangChain提供ExampleSelector来根据某种策略从库中选择example

  • 基于长度
  • 基于语义相似度
  • 基于ngram重叠度
  • 基于maximal marginal relevance (MMR)

以基于长度的策略示例,使用LengthBasedExampleSelector设置一个基于长度来动态选择example的选择器

from langchain.prompts.example_selector import LengthBasedExampleSelector

example_selector = LengthBasedExampleSelector(
    # The examples it has available to choose from.
    examples=examples,
    # The PromptTemplate being used to format the examples.
    example_prompt=example_prompt,
    # The maximum length that the formatted examples should be.
    # Length is measured by the get_text_length function below.
    max_length=100,
    # The function used to get the length of a string, which is used
    # to determine which examples to include. It is commented out because
    # it is provided as a default value if none is specified.
    # get_text_length: Callable[[str], int] = lambda x: len(re.split("\n| ", x))
)

dynamic_prompt = FewShotPromptTemplate(
    # We provide an ExampleSelector instead of examples.
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="Give the answer of every question",
    suffix="Human: {name}的兴趣爱好是什么?\nAI:",
    input_variables=["name"],
)

这样就会动态选择example,使得prompt的长度不超过100

print(dynamic_prompt.format(name="梁静"))

Human:王晓华的兴趣爱好是什么?
AI: ...省略

Human:张伟的兴趣爱好是什么?
AI: ...省略

Human:梁静的兴趣爱好是什么?
AI: 
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值