前言
官方文档:提示工程(Prompts)
编程模型的新方式是通过提示进行的。
我们在使用AI时,AI回复的效果通常取决于我们的提问方式,例如:
- 你期望AI回答物理问题时,会先和AI约定说”你现在是一个物理学教授“;
- 你不希望AI自由发挥无中生有,你会在问题最后补上一句”如果你不知道,就说不知道,不要创造答案“(If you don’t know the answer, just say that you don’t know, don’t try to make up an answer)
而这些成规律的对话内容就形成了所谓对话的”模板“。
除了可以自己创造模板并调试外,LangChain也内置了很多种的模板。个人理解来说,LangChain很多封装的功能也是基于自己调整的对话模板来实现的。
一点尝试
比如,随便抽个包文件来看看:
Python 3.11.5\Lib\site-packages\langchain\chains\retrieval_qa\prompt.py
# flake8: noqa
from langchain.prompts import PromptTemplate
prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
{context}
Question: {question}
Helpful Answer:"""
PROMPT = PromptTemplate(
template=prompt_template, input_variables=["context", "question"]
)
即便不使用封装好的类或者模板,我们复制这里的对话模板直接和AI对话也是可以的。
import include
from langchain.chat_models import ChatOpenAI
# 使用的模型
chat = ChatOpenAI(
model="gpt-35-turbo",
model_kwargs={"deployment_id": "gpt-35-turbo"},
temperature=0.5
)
# 直接复制模板内容,和问题一起组装
prompt_template_msg = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
充值金额 charge_money
退款金额 refund_money
广告费 ad_money
充值人数 charge_people
登陆人数 login_people
Question: 和金额有关的指标有哪些?
Helpful Answer:"""
# 直接使用模型对话
rs = chat.predict(prompt_template_msg)
print(rs)
充值金额、退款金额和广告费是和金额有关的指标。
Process finished with exit code 0
做一个自己的Prompt
例如我们希望,能够将用户的自然语言输入转换成代码可以阅读的数据格式,例如Json,并且按指定的结构返回,可以通过说明和一些案例来实现。
import include
from langchain.chat_models import ChatOpenAI
llm = ChatOpenAI(
model="gpt-35-turbo",
model_kwargs={"deployment_id": "gpt-35-turbo"},
temperature=0,
)
template = """Recognize all the meta names, dimension names, and filters in the given sentence, return them in json format.
example:
Sentence:星穹铁道2022年8月充值金额、退款金额、广告费,按天、渠道
Result:
{
"metas": ["充值金额", "退款金额", "广告费"],
"dims": ["天", "渠道"],
"filters": {"游戏":"凡人修仙传", "时间":"2022年8月"}
}
Question: 凡人修仙传2023年上半年的广告费、渠道费、税费,按自然月、平台、服务器
Result:"""
result = llm.predict(template)
print(result)
{
"metas": ["广告费", "渠道费", "税费"],
"dims": ["自然月", "平台", "服务器"],
"filters": {"游戏":"凡人修仙传", "时间":"2023年上半年"}
}
这样,我们就从自然语言中(虽然必须按示例的方式说话才行)得到了一个期望的数据格式。
另一种模板构建方式
除了一次性写好所有消息格式内容外,也还有面向对象的消息组装方式。
import include
from langchain import LLMChain
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate, HumanMessagePromptTemplate, \
AIMessagePromptTemplate
llm = ChatOpenAI(
model="gpt-35-turbo",
model_kwargs={"deployment_id": "gpt-35-turbo"},
temperature=0,
)
# 系统消息
template = "Recognize all the meta names, dimension names, and filters in the given sentence, return them in json format."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
# 用户消息
human_message_example = HumanMessagePromptTemplate.from_template("星穹铁道2022年8月充值金额、退款金额、广告费,按天、渠道")
# AI回复 此处用到Json,为了与{}界定变量的语法区分开来,此处json格式需要用{{和}}来取代{和}符号
ai_message = """
{{
"metas": ["充值金额", "退款金额", "广告费"],
"dims": ["天", "渠道"],
"filters": {{"游戏":"星穹铁道", "时间":"2022年8月"}}
}}
"""
ai_message_example = AIMessagePromptTemplate.from_template(ai_message)
# 用户消息-提问,使用text变量占位问题
human_message_question = HumanMessagePromptTemplate.from_template("{text}")
# 将上面的系统消息、用户消息、AI消息组合起来成为模板
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_example, ai_message_example, human_message_question])
# 通过chain使用模板
split_chain = LLMChain(llm=llm, prompt=chat_prompt, verbose=True)
result = split_chain.run("凡人修仙传2023年上半年的广告费、渠道费、税费,按自然月、平台、服务器")
print(result)
> Entering new LLMChain chain...
Prompt after formatting:
System: Recognize all the meta names, dimension names, and filters in the given sentence, return them in json format.
Human: 星穹铁道2022年8月充值金额、退款金额、广告费,按天、渠道
AI:
{
"metas": ["充值金额", "退款金额", "广告费"],
"dims": ["天", "渠道"],
"filters": {"游戏":"星穹铁道", "时间":"2022年8月"}
}
Human: 凡人修仙传2023年上半年的广告费、渠道费、税费,按自然月、平台、服务器
> Finished chain.
{
"metas": ["广告费", "渠道费", "税费"],
"dims": ["自然月", "平台", "服务器"],
"filters": {"游戏":"凡人修仙传", "时间":"2023年上半年"}
}
Process finished with exit code 0
PS.
当然提示工程还有很多很多中形式,此处示例只是最便于理解的部分,如何基于LangChain做出更高效的Prompts、如何做出更适合自己的Prompts还需要自行探索,建议可以参考一下langchain包内自己做的一些Prompts。