02-LangChain 核心模块学习 模型输入 Prompts

143 阅读6分钟

模型输入 Prompts

一个语言模型的提示是用户提供的一组指令或输入,用于引导模型的响应,帮助它理解上下文并生成相关和连贯的基于语言的输出,例如回答问题、完成句子或进行对话。

  • 提示模板(Prompt Templates):参数化的模型输入
  • 示例选择器(Example Selectors):动态选择要包含在提示中的示例 fewshots 提示样例选择

提示模板 Prompt Templates

Prompt Templates 提供了一种预定义、动态注入、模型无关和参数化的提示词生成方式,以便在不同的语言模型之间重用模板。

一个模板可能包括指令、少量示例以及适用于特定任务的具体背景和问题。

通常,提示要么是一个字符串(LLMs),要么是一组聊天消息(Chat Model)。

类继承关系:

BasePromptTemplate --> PipelinePromptTemplate
                       StringPromptTemplate --> PromptTemplate
                                                FewShotPromptTemplate
                                                FewShotPromptWithTemplates
                       BaseChatPromptTemplate --> AutoGPTPrompt
                                                  ChatPromptTemplate --> AgentScratchPadChatPromptTemplate



BaseMessagePromptTemplate --> MessagesPlaceholder
                              BaseStringMessagePromptTemplate --> ChatMessagePromptTemplate
                                                                  HumanMessagePromptTemplate
                                                                  AIMessagePromptTemplate
                                                                  SystemMessagePromptTemplate

PromptValue --> StringPromptValue
                ChatPromptValue

代码实现:github.com/langchain-a…

使用 PromptTemplate 类生成提升词

通常,PromptTemplate 类的实例,使用Python的str.format语法生成模板化提示;也可以使用其他模板语法(例如jinja2)。

使用 from_template 方法实例化 PromptTemplate

from langchain import PromptTemplate

prompt_template = PromptTemplate.from_template(
    "Tell me a {adjective} joke about {content}."
)

# 使用 format 生成提示
prompt = prompt_template.format(adjective="funny", content="chickens")
print(prompt)
# 输出样例
Tell me a funny joke about chickens.

使用构造函数(Initializer)实例化 PromptTemplate

使用构造函数实例化 prompt_template 时必须传入参数:input_variables 和 template

在生成提示过程中,会检查输入变量与模板字符串中的变量是否匹配,如果不匹配,则会引发异常;

示例1


from langchain import PromptTemplate
from langchain_openai import OpenAI
import os
api_key = 'sk-xxx'
os.environ["OPENAI_API_KEY"] = api_key

serp_api = 'xxx'
os.environ["SERPAPI_API_KEY"] = serp_api

valid_prompt = PromptTemplate(
    input_variables=["adjective", "content"],
    template="Tell me a {adjective} joke about {content}"
)

prompt = valid_prompt.format(adjective="funny", content="chickens")

llm = OpenAI(model_name="gpt-3.5-turbo-instruct", max_tokens=1000)
result = llm(prompt)

print(f"result: {result}")

示例2

prompt_template = PromptTemplate.from_template(
    "讲{num}个给程序员听得笑话"
)

from langchain_openai import OpenAI

llm = OpenAI(model_name="gpt-3.5-turbo-instruct", max_tokens=1000)

prompt = prompt_template.format(num=2)
print(f"prompt: {prompt}")

result = llm(prompt)
print(f"result: {result}")

使用 jinja2 生成模板化提示


from langchain import PromptTemplate
from langchain_openai import OpenAI
import os

api_key = 'sk-xx'
os.environ["OPENAI_API_KEY"] = api_key

serp_api = 'xxx'
os.environ["SERPAPI_API_KEY"] = serp_api

jinja2_template = "讲{{num}}个 给程序员听得笑话"
template_prompt = PromptTemplate.from_template(jinja2_template, template_format="jinja2")

prompt = template_prompt.format(num="2")

print(prompt)

llm = OpenAI(model_name="gpt-3.5-turbo-instruct", max_tokens=1000)

result = llm(prompt)
print(f"result: {result}")

使用 ChatPromptTemplate 类生成适用于聊天模型的聊天记录

ChatPromptTemplate 类的实例,使用format_messages方法生成适用于聊天模型的提示。

使用 from_messages 方法实例化 ChatPromptTemplate

import os
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI

api_key = 'sk-xx'
os.environ["OPENAI_API_KEY"] = api_key

serp_api = 'xxx'
os.environ["SERPAPI_API_KEY"] = serp_api

template = ChatPromptTemplate.from_messages([
    ("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 = template.format_messages(
    name="Bob",
    user_input="What is your name?"
)

print(messages)

chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", max_tokens=1000)

result = chat_model(messages)
print(result)

摘要总结

import os
from langchain.prompts import ChatPromptTemplate
from langchain.chat_models import ChatOpenAI

api_key = 'sk-xxx'
os.environ["OPENAI_API_KEY"] = api_key

serp_api = 'xxxx'
os.environ["SERPAPI_API_KEY"] = serp_api

summary_template = ChatPromptTemplate.from_messages([
    ("system", "你将获得关于同一主题的{num}篇文章(用-----------标签分隔)。首先总结每篇文章的论点。然后指出哪篇文章提出了更好的论点,并解释原因。"),
    ("human", "{user_input}"),
])

# 生成提示
messages = summary_template.format_messages(
    num=3,
    user_input='''1. [PHP是世界上最好的语言]
PHP是世界上最好的情感派编程语言,无需逻辑和算法,只要情绪。它能被蛰伏在冰箱里的PHP大神轻易驾驭,会话结束后的感叹号也能传达对代码的热情。写PHP就像是在做披萨,不需要想那么多,只需把配料全部扔进一个碗,然后放到服务器上,热乎乎出炉的网页就好了。
-----------
2. [Python是世界上最好的语言]
Python是世界上最好的拜金主义者语言。它坚信:美丽就是力量,简洁就是灵魂。Python就像是那个永远在你皱眉的那一刻扔给你言情小说的好友。只有Python,你才能够在两行代码之间感受到飘逸的花香和清新的微风。记住,这世上只有一种语言可以使用空格来领导全世界的进步,那就是Python。
-----------
3. [Java是世界上最好的语言]
Java是世界上最好的德育课编程语言,它始终坚守了严谨、安全的编程信条。Java就像一个严格的老师,他不会对你怀柔,不会让你偷懒,也不会让你走捷径,但他教会你规范和自律。Java就像是那个喝咖啡也算加班费的上司,拥有对邪恶的深度厌恶和对善良的深度拥护。
'''
)

print(messages)

chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", max_tokens=1000)

result = chat_model(messages)
print(result)

使用 FewShotPromptTemplate 类生成 Few-shot Prompt

构造 few-shot prompt 的方法通常有两种:

  • 方法1 从示例集(set of examples)中手动选择;
  • 方法2 通过示例选择器(Example Selector)自动选择.

示例选择器 Example Selectors

如果你有大量的参考示例,就得选择哪些要包含在提示中。最好还是根据某种条件或者规则来自动选择,Example Selector 是负责这个任务的类。

BaseExampleSelector 定义如下:

class BaseExampleSelector(ABC):
    """用于选择包含在提示中的示例的接口。"""

    @abstractmethod
    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        """根据输入选择要使用的示例。"""

ABC 是 Python 中的 abc 模块中的一个缩写,它表示 "Abstract Base Class"(抽象基类)。在 Python 中,抽象基类用于定义其他类必须遵循的基本接口或蓝图,但不能直接实例化。其主要目的是为了提供一种形式化的方式来定义和检查子类的接口。

使用抽象基类的几点关键信息:

  1. 抽象方法:在抽象基类中,你可以定义抽象方法,它没有实现(也就是说,它没有方法体)。任何继承该抽象基类的子类都必须提供这些抽象方法的实现。
  2. 不能直接实例化:你不能直接创建抽象基类的实例。试图这样做会引发错误。它们的主要目的是为了被继承,并在子类中实现其方法。
  3. 强制子类实现:如果子类没有实现所有的抽象方法,那么试图实例化该子类也会引发错误。这确保了继承抽象基类的所有子类都遵循了预定的接口。