LangChain实战:Prompt提示词调优

前置体验

PromptTemplate【字符串模板替换】

from langchain_core.prompts import PromptTemplate

prompt_template = PromptTemplate.from_template("我今天心情{feel},我想{content}")
message = prompt_template.format(feel = "非常开心",content = "去吃一顿火锅好好庆祝一下")
print(message)
我今天心情非常开心,我想去吃一顿火锅好好庆祝一下
给变量feel和content赋值,达到动态输出内容

ChatPromptTemplate【具有角色的模板替换】

注意:需要在.env文件中设置
OPENAI_API_KEY=sk-XXXXXXXXXXXXXXXX
OPENAI_API_BASE=https://xxx
from dotenv import load_dotenv, find_dotenv
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

load_dotenv(find_dotenv())
chat_prompt_template = ChatPromptTemplate.from_messages(
    [
        ("system","你是一个厨师"),
        ("human","{user_input}")
    ]
)
model = ChatOpenAI()
chain = chat_prompt_template | model
response = chain.invoke({
   "user_input":"你会做什么饭?"})
print(response.content)
我可以做各种不同类型的菜肴,包括中式、西式、日式、意式等等。无论是炒菜、烤肉、炖汤、烘培,我都可以应对。我也可以根据你的口味和饮食习惯来调整菜谱,让你的用餐体验更加愉快。

什么是提示工程(Prompt Engineering)

我们发给大模型的指令就叫提示词,比如:
【我今天心情不好,讲一个笑话给我听】
【我女朋友生气了,怎么哄好她】
【我的代码出现问题了,报这个错误,怎么解决】
这些都叫做提示词。

案例体验

 哄哄模拟器 ,不知道怎么哄好女朋友的可以提前练习一下。
 地址:https://hong.greatdk.com/ 

Prompt调优

找到好的 prompt 是个持续迭代的过程,需要不断调优。
如果知道训练数据是怎样的,参考训练数据来构造 prompt 是最好的。
「当人看」类比:
你知道 ta 喜欢三国演义,就和 ta 聊三国演义
你知道 ta 是个吃货,就和 ta 说美食
你知道 ta 喜欢健身,就夸 ta 身材好

Prompt 的典型构成

角色:指定具体的角色
指示:对任务进行描述
上下文:给出与任务相关的其它背景信息(尤其在多轮交互中)
例子:必要时给出举例
输入:任务的输入信息;在提示词中明确的标识出输入
输出:输出的格式描述,以便后继模块自动解析模型的输出结果,比如(JSON、XML)

如果换做成生活中,我们如何和别人沟通,同样都是确定好彼此的角色
如果我参观动物园的大熊猫,但是不知道具体位置,就要和工作人员沟通
描述好我的诉求,并且告诉 ta 我希望得到什么样的结果

【推荐流量包的智能客服】调优案例

某运营商的流量包产品:

名称 流量(G/月) 价格(元/月) 适用人群
经济套餐 10 50 无限制
畅游套餐 100 180 无限制
无限套餐 1000 300 无限制
校园套餐 200 150 在校生

需求:智能客服根据用户的咨询,推荐最适合的流量包。

导入依赖

from dotenv import find_dotenv, load_dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

加载.env环境变量设置

load_dotenv(find_dotenv())
任务描述、用户输入、输出格式、模板定义
# 任务描述
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称,月费价格,月流量。
根据用户输入,识别用户在上述三种属性上的需求是什么。
"""
#输出格式
output_format = """
以 JSON 格式输出
"""
# 用户输入
input_text = """
办个100G的套餐。
"""
template = """
{instruction}
{output_format}
用户输入:
{input_text}
"""
设置chain并测试结果
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI()
out = StrOutputParser()

chain =prompt | llm | out
message = chain.invoke(
    {
   
        "instruction": instruction,
        "output_format": output_format,
        "input_text": input_text
    }
)
print(message)
输出结果
{
   
    "需求": {
   
        "名称": null,
        "月费价格": null,
        "月流量": "100G"
    }
}
大模型是懂 JSON 的,但需要对 JSON 结构做严格定义。
把输出格式定义的更精细再试试呢

【改进】增加输出格式

from dotenv import find_dotenv, load_dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai import ChatOpenAI

load_dotenv(find_dotenv())

# 任务描述
instruction = """
你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
根据用户输入,识别用户在上述三种属性上的需求是什么,符合哪个套餐。
已知产品包括:

经济套餐:月费50元,月流量10G
畅游套餐:月费180元,月流量100G
无限套餐:月费300元,月流量1000G
校园套餐:月费150元,月流量200G,限在校学生办理
"""
#输出格式
output_format = """
以JSON格式输出。
1. name字段的取值为string类型,取值必须为以下之一:经济套餐、畅游套餐、无限套餐、校园套餐 或 null;

2. price字段的取值为套餐的价格

3. data字段的取值为取值为一个结构体 或 null,包含两个字段:
(1) operator, string类型,取值范围:'<='(小于等于), '>=' (大于等于), '=='(等于)
(2) value, int类型或string类型,string类型只能是'无上限'

4. 用户的意图可以包含按price或data排序,以sort字段标识,取值为一个结构体:
(1) 结构体中以"ordering"="descend"表示按降序排序,以"value"字段存储待排序的字段
(2) 结构体中以"ordering"="ascend"表示按升序排序,以"value"字段存储待排序的字段

只输出中只包含用户提及的字段,不要猜测任何用户未直接提及的字段。
"""
# 用户输入
input_text = """
办个200G的套餐。
"""

template = """
{instruction}
{output_format}
用户输入:
{input_text}
"""
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI()
out = StrOutputParser()
chain = prompt | llm | out
print("任务描述:" + instruction)
for c in range(5):
    print(f"=====
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值