大模型agent开发之prompt提示词模板
提示词工程的建模在大模型对话agent的开发中有着重要的地位,好的提示词模板可以辅助大模型做出更加准确的预测,得到更加准确的答案。本文使用langchain进行agnent开发,langchain中封装了很多工具和方法其中就包括不同的prompt模板,接下来本文将详细介绍几种不同风格的prompt模板的使用方式。
PromptTemplate模板
promptTemplate是langchain中最为基础的prompt模板,它是一种单纯的字符模板,具体使用方式如以下带代码。
from langchain.prompts import PromptTemplate def comm_prompt(self,name,country,sex): prompt = PromptTemplate.from_template("你是一个{name},帮我起一个具有{country}特色的{sex}名字") prompt.format(name=name,country=country,sex=sex) return prompt
首先需要在langchain中引入PromptTempalate方法,并将模板字符串传入到PromptTemplate.from_template函数中,该方法支持向模板中注入变量,比如上述代码例子中的name、country和sex,只需要将变量用大括号括起来,然后使用format方法对每个变量赋值。就设置完一个提示词模板。
ChatPromptTemplate模板
ChatPromptTemplate是langchain提供的另一种模板类型,这是一种对话模板结构,该模板使用方式如下代码。
from langchain.prompts import ChatPromptTemplate def chat_prompt(self, name, user_input): # Correct spelling of 'chat_template' and 'robot' template_str = ( "system: 你是一名算命大师,你的名字叫{name}\n" "human: 你好{name},请问你都会什么\n" "robot: 你好先生,我精通五行八卦,周易占卜\n" "human: 你叫什么名字\n" "robot: 你好,我叫{name}\n" "human: {user_input}" ) chat_template = ChatPromptTemplate.from_template(template_str) # Correct 'user_inout' to 'user_input' formatted_chat = chat_template.format(name=name, user_input=user_input) print(formatted_chat) return formatted_chat
该类模板是以对话形式设置的模板类型,通过不同角色的演绎使大模型在推理时得到更多有效信息。上述代码示例中template_str是人类与机器人对话的键值对其中最后一句是人类想要文的问题的变量形式,,其也支持注入变量值。同样使用from_template方法转换成prompt模板对象,使用format方法传入设置的变量值。
自定义模板
自定义模板通过注释进行定义,同样可以注入变量信息,变量使用大括号括起来,代码示例如下:
from langchain.prompts import StringPromptTemplate #自定义模板 PROMPT = """ 你是一个非常有经验和天赋的程序员,现在给你如下函数名称,你会按照如下格式,输出这段代码的名称、源代码、中文解释。 函数名称: {function_name} 源代码: {source_code} 代码解释: """ def get_source_code(function_name): #获取源代码 return inspect.getsource(function_name) class CustmPrompt(StringPromptTemplate): def format(self,**kwargs) -> str: #获取源代码 source_code = get_source_code(kwargs["function_name"]) #生成提示词模板 prompt = PROMPT.format( function_name = kwargs["function_name"].__name__, source_code=source_code ) return prompt
该示例的功能是根据代码的函数名成和源代码给出中文解释,在自定义的模板中,函数名成和源代码都是需要输入的变量,所以在生成最终的模板前需要对模板中的变量赋值。这种模板好处是可以根据需求设置对应的模板,可以灵活的设置模板。
组合示提示词模板
组合词模板的作用是将提示词分成不同层级,每个层级代表不同维度。比如一下代码示例:
from langchain.prompts.pipeline import PipelinePromptTemplate from langchain.prompts.prompt import PromptTemplate def level_prompt(self,full_pompt): #第一层设计(特征) Charater_template = """ 你是{persion},你有着{char}. """ Charater_prompt = PromptTemplate.from_template(Charater_template) #第二层设计(行为) behavior_template = """你要遵循以下行为:{behavior-list}""" behavior_prompt = PromptTemplate.from_template(behavior_template) #第三层设计(禁止) prohibit_template = """你不许有以下行为:{prohibit_list}""" prohibit_prompt = PromptTemplate.from_template(prohibit_template) #将三层结合起来 input_prompts = [ ("Charater",Charater_prompt), ("behavior",behavior_prompt), ("prohibit",prohibit_prompt) ] pipeline_prompt = PipelinePromptTemplate(final_prompt=full_pompt,pipeline_prompts=input_prompts) return pipeline_prompt
在上述代码的提示词设计中,将提示词分成三个层级,第一个层级提示大模型具备什么特征,第二个层级限制大模型的行为,第三层级禁止大模型的动作。最后将各个层级的提示词模板组合起来,使用langchain提供的PipelinePromptTemplate方法进行组合,其中参数full_prompt为一系列变量结构,定义的是模板总体的层级作用,以上述代码为例,改模板的full_prompt的是设计应该如下形式。这种提示词模板的优点是层次分明更加细化的提示功能,对大模型的要求更加规范。
full_template = """{Character} {behavior} {prohibit}""" full_prompt = PromptTemplate.from_template(full_template)
序列化:使用文件管理提示词模板
在真实的生产环境中常常需要针对不同场景不同需求对模板做出修改,这时候如果频繁的更新代码会严重影响开发效率,因此使用文件来维护提示词模板可以有效的缓解以上问题,具体代码示例如下:
from langchain.prompts import load_prompt def load_prompt(self,name,what): #加载yaml提示词文件模板 template = load_prompt("yamls/prompt.yaml") #格式化参数 formatted_prompt = template.format(name=name,what=what) print(formatted_prompt) return formatted_prompt
在以上代码中,本文呢使用langchain提供的load_prompt方法加载yamls/prompt.yaml文件中的模板,并对模板格式化后返回。其中prompt.yaml的设计可以如以下形式:
template: |
system: 你是一名算命大师,你的名字叫{name}
human: 你好{name},请问你都会什么
robot: 你好先生,我精通五行八卦,周易占卜
human: 你叫什么名字
robot: 你好,我叫{name}
human: {what}
使用yaml文件设置提示词模板,这样的好处可以在不修改源代码的前提下直接修改暴露出来的yaml文件就可以。提高在真实生产环境下的程序鲁棒性。
总结
以上本文介绍了大模型agent开发中多种提示词模板的开发设计方式,其中包括promptTemplate模板、ChatPromptTemplate模板、自定义模板、组合词模板以及序列化模板。在实际开发中根据自生需求选择合适的提示词模板方法,也可以相互组合使用建立旁大复杂的提示词工程。