LongChain 1:模型的基本调用与提示工程

440 阅读6分钟

LongChain模型的基本调用

LongChain目前支持三种模型:

  1. 大语言模型(LLM) ,也叫Text Model,这些模型将文本字符串作为输入,并返回文本字符串作为输出。Open AI的text-davinci-003、Facebook的LLaMA、ANTHROPIC的Claude,都是典型的LLM。
  2. 聊天模型(Chat Model),主要代表Open AI的ChatGPT系列模型。这些模型通常由语言模型支持,但它们的 API 更加结构化。具体来说,这些模型将聊天消息列表作为输入,并返回聊天消息。
  3. 文本嵌入模型(Embedding Model),这些模型将文本作为输入并返回浮点数列表,也就是Embedding。文本嵌入模型负责把文档存入向量数据库。

模型调用示例

import getpass  
import os  
  
os.environ["OPENAI_API_KEY"] = getpass.getpass()  
  
from langchain_openai import ChatOpenAI  
  
model = ChatOpenAI(model="gpt-4")
from langchain_core.messages import HumanMessage, SystemMessage  
  
messages = [  
SystemMessage(content="Translate the following from English into Italian"),  
HumanMessage(content="hi!"),  
]  
  
model.invoke(messages)
  • model.invoke()用于call模型来给出回复,其返回的类型为AMI message
AIMessage(content='ciao!', 
        response_metadata={'token_usage':
        {'completion_tokens': 3, 'prompt_tokens': 20, 'total_tokens': 23}, 
        'model_name': 'gpt-4', 
        'system_fingerprint': None, 
        'finish_reason': 'stop', 'logprobs': None}, 
        id='run-fc5d7c88-9615-48ab-a3c7-425232b562c5-0')
  • 通常来讲,我们只会用到模型返回的字符串,就需要到LongChain的输出解析器OutputParsers,它还可以进一步格式化模型的输出为json格式,方便以字典形式快速找到我们在消息中所需要的部分内容。
from langchain_core.output_parsers import StrOutputParser  
  
parser = StrOutputParser()
result = model.invoke(messages)
parser.invoke(result)
  • 输出解析器OutputParsers转化为json格式,实际的工作原理就是在prompt后加上一段类似下面的内容:
The output should be a markdown code snippet formatted in the following schema, including the leading and trailing "```json" and "```":
```json {         
"description": string  // 鲜花的描述文案        
"reason": string  // 问什么要这样写这个文案 
}
  • LongChain还支持使用管道|连接model以及输出解释器
chain = model | parser
chain.invoke()

LongChain中的提示工程

LongChain中prompt的构建过程总体来讲可以分为四步

  1. 构建template模板
  2. 给出Few-shot的示例
  3. 实例化template

一个良好的prompt结构:

image.png

  • 指令(Instuction)告诉模型这个任务大概要做什么、怎么做,比如如何使用提供的外部信息、如何处理查询以及如何构造输出。这通常是一个提示模板中比较固定的部分。一个常见用例是告诉模型“你是一个有用的XX助手”,这会让他更认真地对待自己的角色。
  • 上下文(Context)则充当模型的额外知识来源。这些信息可以手动插入到提示中,通过矢量数据库检索得来,或通过其他方式(如调用API、计算器等工具)拉入。一个常见的用例时是把从向量数据库查询到的知识作为上下文传递给模型。(这一部分对应于RAG)
  • 提示输入(Prompt Input)通常就是具体的问题或者需要大模型做的具体事情,这个部分和“指令”部分其实也可以合二为一。但是拆分出来成为一个独立的组件,就更加结构化,便于复用模板。这通常是作为变量,在调用模型之前传递给提示模板,以形成具体的提示。
  • 输出指示器(Output Indicator)标记​​要生成的文本的开始。这就像我们小时候的数学考卷,先写一个“解”,就代表你要开始答题了。如果生成 Python 代码,可以使用 “import” 向模型表明它必须开始编写 Python 代码(因为大多数 Python 脚本以import开头)。这部分在我们和ChatGPT对话时往往是可有可无的,当然LangChain中的代理在构建提示模板时,经常性的会用一个“Thought:”(思考)作为引导词,指示模型开始输出自己的推理(Reasoning)。例如 Answer:

Step 1:创建template

使用langchain.prompts.prompt中的PromptTemplate创建prompt的template,其中{}用于指定模板中可变化的变量

from langchain.prompts.prompt import PromptTemplate
template="鲜花类型: {flower_type}\n场合: {occasion}\n文案: {ad_copy}"
prompt = PromptTemplate.from_template(template)

Step 2: 构建Few-shot示例并实例化template 使用langchain.prompts.few_shot中的FewShotPromptTemplate构建FewShot示例

  1. 给出示例变元对应的字典列表
samples = [   
{     "flower_type": "玫瑰",    
     "occasion": "爱情",     
     "ad_copy": "玫瑰,浪漫的象征,是你向心爱的人表达爱意的最佳选择。"   
},   
{     "flower_type": "康乃馨",     
      "occasion": "母亲节",     
      "ad_copy": "康乃馨代表着母爱的纯洁与伟大,是母亲节赠送给母亲的完美礼物。"   
},   
{     "flower_type": "百合",     
      "occasion": "庆祝",     
      "ad_copy": "百合象征着纯洁与高雅,是你庆祝特殊时刻的理想选择。"   
},  
{     "flower_type": "向日葵",   
      "occasion": "鼓励",     
      "ad_copy": "向日葵象征着坚韧和乐观,是你鼓励亲朋好友的最好方式。"   
} ]
  1. 实例化Few-shot模板
prompt_sample = PromptTemplate(input_variables=["flower_type", "occasion", "ad_copy"], template=template)
prompt = FewShotPromptTemplate(     
            examples=samples,     
            example_prompt=prompt_sample,  
            suffix="鲜花类型: {flower_type}\n场合: {occasion}",     
            input_variables=["flower_type", "occasion"] )
  • examplesexample_prompt对应于prompt中的Few-shot部分
  • suffixinput_variables则是本次对话用户prompt中真正的query部分

Step3:将prompt给到大模型得到回复

import os os.environ["OPENAI_API_KEY"] = '你的Open AI Key' 
from langchain.llms import OpenAI 
model = OpenAI(model_name='gpt-3.5-turbo-instruct') 
result = model(prompt.format(flower_type="野玫瑰", occasion="爱情")) 
print(result)
  • LongChain中也给出了示例选择器用于从samples中利用向量挑选与query相似度最高的k个作为Few-shot提示的示例
# 5. 使用示例选择器
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

# 初始化示例选择器
example_selector = SemanticSimilarityExampleSelector.from_examples(
    samples,
    OpenAIEmbeddings(),
    Chroma,
    k=1
)

# 创建一个使用示例选择器的FewShotPromptTemplate对象
prompt = FewShotPromptTemplate(
    example_selector=example_selector, 
    example_prompt=prompt_sample, 
    suffix="鲜花类型: {flower_type}\n场合: {occasion}", 
    input_variables=["flower_type", "occasion"]
)
print(prompt.format(flower_type="红玫瑰", occasion="爱情"))

为什么要使用Few-shot

  • 增强模型的上下文理解:Few-shot示例可以给模型提供任务的语境和期望的输出格式,帮助模型更好地理解具体任务的要求。这种方式相当于给模型做“预热”,让模型明白输入和输出之间的关系。

  • 提高生成结果的准确性和一致性:通过Few-shot示例,模型能够学习到任务的具体风格和内容,使输出更符合用户预期。尤其是对于复杂的任务,Few-shot可以显著提高模型的表现,使生成的内容更加准确、连贯。

  • 减少对特殊任务的微调需求:Few-shot提示让模型能够在没有大量专门数据微调的情况下,也能完成特定任务。例如,给出几个翻译示例后,模型可以较好地翻译未见过的内容,从而降低微调成本。

  • 提升多样性和灵活性:Few-shot示例可以让模型适应不同的任务和风格,增强其灵活性。例如,可以通过提供不同领域或风格的Few-shot示例,使模型能够在不同的领域中给出相应的解答或生成内容。