02|LangChain | 从入门到实战 -六大组件之Models IO

news2024/11/27 0:27:11

by:wenwenC9

上一篇文章
01|LangChain | 从入门到实战-介绍

一、Models IO 组成及其说明

与语言模型的交互,比如在线GPT系列,或各种离线模型
任何语言模型应用程序的核心元素都是XXX模型。LangChain 提供了与任何语言模型交互的构建块。
在这里插入图片描述
从案例理解prompt,下面是一个内容,占位字符串为 foobar,在python中可以根据format,将需要传入的内容代入

template = """
   我最喜欢的运动是{args1},平时最喜欢去{args2}
"""
template = template.format(args1='foo',args2='bar')

我最喜欢的运动是foo,平时最喜欢去bar

langchain,提供了prompt工程,可以通过规定风格,将提示内容代入到各类模型,以便告知模型,你的想法或执行内容;

对于LLM的输出,我们也能进行解析,比如,要求输出为json格式,等等格式要求

其主要交互组件如下图

在这里插入图片描述
注意
内容所出现的代码,我都忽略了key的配置,你们可以自己加

import os
os.environ["OPENAI_API_KEY"] = ''

二、Prompt 提示工程

在这里插入图片描述
语言模型的提示是用户提供的一组指令或输入,用于指导模型的响应,帮助模型理解上下文并生成相关且连贯的基于语言的输出,例如回答问题、完成句子或参与某项活动。对话。
LangChain 提供了几个类和函数来帮助构建和使用提示。

1、提示模板:参数化模型输入
2、示例选择器:动态选择要包含在提示中的示例

1、关于模板的使用

(1)基础模板 PromptTemplate

(1.1)使用预设值实例化
from langchain.prompts.prompt import PromptTemplate

prompt_template = PromptTemplate(input_variables=["content"], template="告诉我一个笑话关于 {content}")
prompt = prompt_template.format(content="兔子")
print(prompt_template)
print(type(prompt_template))
print(prompt)
print(type(prompt))

--------打印结果----------
input_variables=['content'] template='告诉我一个笑话关于 {content}'
<class 'langchain.prompts.prompt.PromptTemplate'>
告诉我一个笑话关于 兔子
<class 'str'>
(1.2)使用from_template实例化
from langchain.prompts.prompt import PromptTemplate

prompt_template = PromptTemplate.from_template(
    template="告诉我一个笑话 {adjective} 关于 {content}."
)
prompt = prompt_template.format(adjective="funny", content="chickens")
print(prompt_template)
print(type(prompt_template))
print(prompt)
print(type(prompt))

--------打印结果----------
input_variables=['adjective', 'content'] template='告诉我一个笑话 {adjective} 关于 {content}.'
<class 'langchain.prompts.prompt.PromptTemplate'>
告诉我一个笑话 funny 关于 chickens.
<class 'str'>
(1.3)在对话中使用模板
from langchain import PromptTemplate
from langchain.llms import OpenAI

invalid_prompt = PromptTemplate(
    input_variables=["adjective"],
    template="Tell me a {adjective} joke about cat. 中文回复我"
)

# llm = ChatOpenAI()
llm = OpenAI()
# 定义一个函数来生成回答
def generate_joke(adjective, content):
    prompt = invalid_prompt.format(adjective=adjective)
    response = llm(prompt)
    print(response)
    # return response.choices[0].text.strip()

# 调用函数生成一个笑话
joke = generate_joke("funny", "cats")
print(joke)
"""
这只猫真有趣:它把自己看作是一只狗!
"""
(1.4)源码

从源码层来说,都是源自这边,并且函数也说明了,是所有模板的基础,建议去看看源码
这里不过多说明
在这里插入图片描述
从源码可以看继承于StringPromptTemplate 字符串模板

而它又继承于 BasePromptTemplate,拥有如下功能函数
在这里插入图片描述
往往有时候,提供的基础模板不够我们使用场景,就需要我们自己创建自定义模板

(2) 自定义模板

举例使用场景:

  1. 用于某些业务实现
  2. 在自定义模板中,我们可以实现很多功能,比如加上日志记录

要创建自定义字符串提示模板,有两个要求:

1、它有一个 input_variables 属性,该属性公开提示模板所需的输入变量。
2、定义了一个 format 方法,该方法接受与预期的 input_variables 相对应的关键字参数并返回格式化的提示。

通过如下案例说明:

第一步,创建一个获取函数源码的函数

import inspect
def get_source_code(function_name):
    return inspect.getsource(function_name)

第二步,构建自定义提示模板

from langchain.prompts import StringPromptTemplate
from pydantic import BaseModel, validator

PROMPT = """
	给定函数名称和源代码,生成该函数的中文解释。.
	函数名称: {function_name}
	源代码:
	{source_code}
	解释:
"""

class CustomPromptTemplate(StringPromptTemplate, BaseModel):
    """ 自定义提示模板,
        将函数名称作为输入,
        并格式化提示模板以提供函数的源代码。
    """

    @validator("input_variables")
    def validate_input_variables(cls, v):
        """验证输入变量是否正确。"""
        if len(v) != 1 or "function_name" not in v:
            raise ValueError("function_name must be the only input_variable.")
        return v

    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

    def _prompt_type(self):
        return "function-explainer"

第四步,使用它

fn_explainer = CustomPromptTemplate(input_variables=["function_name"])

prompt = fn_explainer.format(function_name=get_source_code)
print(prompt)

在这里插入图片描述

(3)基础可选模板

可以实现从一组示例或示例选择器对象构建少量提示模板。
在实现这个前,先补充一下知识

Few-shot和zero-shot是机器学习中常用的术语,用于描述模型在处理新任务或新类别时的能力。

  • Few-shot(少样本学习):Few-shot学习是指在面对只有很少样本的新任务或新类别时,模型能够通过利用有限的样本进行学习和泛化。这意味着模型可以从少量的训练样本中快速学习,并在面对新任务时进行适应。

  • Zero-shot(零样本学习):Zero-shot学习是指在面对完全没有见过的新任务或新类别时,模型能够进行推理和泛化。这意味着模型可以在没有任何训练样本的情况下,通过利用先验知识或外部信息来进行预测和分类。

这些概念在自然语言处理、计算机视觉和强化学习等领域中被广泛应用,旨在提高模型的泛化能力和适应性,使其能够处理新领域、新任务或新类别的数据。

为此langchain也提供了,few-shot模板操作

from langchain.prompts.few_shot import FewShotPromptTemplate
from langchain.prompts.prompt import PromptTemplate
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

examples = [
    {
        "question": "你是谁?",
        "answer":
            """
            我是wenwenc9
            """
    },
    {
        "question": "爸爸叫什么",
        "answer":
            """
            叫爷爷
            """
    },
    {
        "question": "朱自清是谁",
        "answer":
            """
            朱自清是文学家
            """
    }
]
example_prompt = PromptTemplate(input_variables=["question", "answer"], template="Question: {question}\n{answer}")
prompt = FewShotPromptTemplate(
    examples=examples,  # 少量示例
    example_prompt=example_prompt,  # 用户格式化单个示例
    suffix="Question: {input}",  # 前缀,也有后缀prefix
    input_variables=["input"]
)

example_selector = SemanticSimilarityExampleSelector.from_examples(
    # 可供选择的示例模板
    examples,
    # 用于生成用于测量语义相似性的嵌入的嵌入类。
    OpenAIEmbeddings(),
    # 向量数据库
    Chroma,
    # 这是要生成的实例数目
    k=1
)

构建问题,基于用户问题,选择合适的提示模板

# 创建一个问题
question = "朱自清"

# 根据向量引擎从中选择一个符合
selected_examples = example_selector.select_examples({"question": question})
print(selected_examples)

执行输出结果

[{'answer': '\n            朱自清是文学家\n            ', 'question': '朱自清是谁'}]

(4)聊天模板 ChatPromptTemplate

在这里插入图片描述

  1. from_messages
  2. from_template

langchain中,ChatPromptTemplate是一个模版方法,它具有两个功能:from_messagesfrom_template

  1. from_messages:这个功能用于从一系列对话消息中创建聊天模版。您可以提供多个消息作为输入,并将它们转换为聊天模版,以便用于后续的对话生成。

  2. from_template:这个功能用于从现有的聊天模版中创建新的聊天模版。您可以基于现有的模版进行修改或扩展,以便生成更多的对话内容。

from_messages用于从消息创建模版,而from_template用于基于现有模版创建新的模版。

(4.1) 二元数组方式
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate

template = ChatPromptTemplate.from_messages([
    ("system", "你是一个优秀的助手. 你的名字是 {name}."),
    ("human", "你好,你最近过的好嘛?"),
    ("ai", "最近过的不错"),
    ("human", "{user_input}"),
])

messages = template.format_messages(
    name="小爱同学",
    user_input="你的名字是什么?"
)
# 实例化AI对象
llm = ChatOpenAI()

# 响应
res = llm(messages)

print(res)

content='我的名字是小爱同学。有什么我可以帮助你的吗?'
(4.2)BaseMessage 或者 MessagePromptTemplate
from langchain.callbacks import get_openai_callback
from langchain.prompts import ChatPromptTemplate
from langchain.prompts.chat import SystemMessage, HumanMessagePromptTemplate, HumanMessage
from langchain.chat_models import ChatOpenAI

template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(
            content=(
                "你是一个乐于助人的助手,可以将用户的文本重新写入"
                "听起来更乐观"
                "用中文回复我"
            )
        ),
        # HumanMessagePromptTemplate.from_template("{text}"), # 这里对应本小节前面,所示的from_template可以从已有模板进行修改
        HumanMessage(
            content=(
                "{text}"
            )
        ),
    ]
)

llm = ChatOpenAI()
# 使用上下文管理器获取 token 使用情况
with get_openai_callback() as cb:
    res = llm(template.format_messages(text='我很难过'))
    print(res)
# 获取 token 使用总数
total_tokens = cb.total_tokens
print(f"Total tokens used: {total_tokens}")
content='亲爱的用户,你的文本让我感到有些沮丧。但是,无论遇到什么困难,我们都应该保持积极乐观的态度。相信自己,相信明天会更好。让我们一起努力,面对挑战,充满希望地前进吧!加油!'
Total tokens used: 155

(5)聊天Few-shot模板

关于few-shot的含义本文基础可选模板已经提到过

前面的few-shot 并没有带上chat二字

创建多个提示案例

from langchain.prompts import (
    FewShotChatMessagePromptTemplate,
    ChatPromptTemplate,
)

# 生成具体回复
examples = [
    {"input": "2+2", "output": "4"},
    {"input": "2+3", "output": "5"},
]

确认单个实例化的样例

example_prompt = ChatPromptTemplate.from_messages(
    [
        ("human", "{input}"),
        ("ai", "{output}"),
    ]
)

组装promtp

few_shot_prompt = FewShotChatMessagePromptTemplate(
    example_prompt=example_prompt,
    examples=examples,
)


final_prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a wondrous wizard of math."),
        few_shot_prompt,
        ("human", "{input}"),
    ]
)

查看一下final_prompt 内容,可以看到下图,由3个消息提示模板

  1. SystemMessagePromptTemplate
  2. FewShotChatMessagePromptTemplate
  3. HumanMessagePromptTemplate
    在这里插入图片描述

展开FewShotChatMessagePromptTemplate ,可以看到是通过2,实例出2个ChatPromptTemplate
在这里插入图片描述
进行使用

方式一:

from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI
# 创建LLM模型
llm = ChatOpenAI()
# 创建执行链
chain = LLMChain(
    llm=llm,
    prompt=final_prompt
)
res = chain.invoke({"input": "2+2 等于多少"})
res2 = chain.invoke({"input": "2+6 等于多少"})
print(res)
print(res2)

方式二:

from langchain.chat_models import ChatOpenAI

# 创建执行链
chain = final_prompt | ChatOpenAI()

res = chain.invoke({"input": "2+2 等于多少"})
res2 = chain.invoke({"input": "2+2 等于多少"})
print(res)

输出

{'input': '2+2 等于多少', 'text': '2+2等于4。'}
{'input': '2+6 等于多少', 'text': '2 + 6 等于 8。'}

(6)部分总结,一定要看

在开启下一小节时候,最好进行debug一下,理解模板,观察源码

(6.1)怎么创建模版

这2个模板都继承于 BasePromptTemplate

# 基础模版,与聊天模板,对象
from langchain.prompts import PromptTemplate, ChatPromptTemplate


###################### PromptTemplate ######################
# type : <class 'langchain.prompts.prompt.PromptTemplate'>
base_prompt_obj = PromptTemplate.from_template("告诉我一个 {adjective} 的笑话关于 {content}.")

# type :str
demo1 = base_prompt_obj.format(adjective="有趣", content="太阳")
# type : #<class 'langchain.prompts.base.StringPromptValue'>,需要通过转换为str才能使用
demo2 = base_prompt_obj.format_prompt(adjective="有趣", content="太阳")
demo2 = demo2.to_string()
# type :PromptTemplate
demo3 = base_prompt_obj.from_template("帮我解决一个问题,关于 :{input}")
# type:PromptTemplate
prompt_template = PromptTemplate(input_variables=["content"], template="告诉我一个笑话关于 {content}")
prompt = prompt_template.format(content="兔子")

# ###################### ChatPromptTemplate ######################

# type : ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
    ("system", "你是一个优秀的助手. 你的名字是 {name}."),
    ("human", "你好,你最近过的好嘛?"),
    ("ai", "最近过的不错"),
    ("human", "{user_input}"),
])
# type :str
chat_prompt_1 = template.format(name='小哎', user_input='你好')
# type : ChatPromptTemplate
chat_prompt_2 = template.format_messages(name='小哎', user_input='你好')
# type : <class 'langchain.prompts.chat.ChatPromptValue'>
chat_prompt_3 = template.format_prompt(name='小哎', user_input='你好')
# type : ChatPromptTemplate
chat_prompt_4 = ChatPromptTemplate.from_template("帮我解决一个问题,关于 :{input}")
print('debug')
# type: ChatPromptTemplate
chat_prompt_5  = ChatPromptTemplate(input_variables=["content"], template="告诉我一个笑话关于 {content}")
prompt = chat_prompt_5  .format(content="兔子")
(6.2)对于模板的使用方法or如何模型对话
  1. 直接传入模型,进行对话 。模板要求为str
  2. 通过chain调用,对话(后面文章会开chain专栏)。模板要求对象

from langchain.llms import OpenAI,OpenAIChat

from langchain.llms import OpenAI,OpenAIChat
llm = OpenAI()
# llm = OpenAIChat() 自己试这个
res1 = llm(demo1)  # demo1 为str
print(res1)  # 成功响应
res2 = llm(demo3)  # 报错 Argument `prompt` is expected to be a string.
print(res2)  # 报错,说需要字符串

这是因为,demo3,是一个模版对象,需要输入一个参数,直接与模型对话,发送str可以成功,但是传入对象却不行。

可以通过chain使用,解决

from langchain.llms import OpenAI,OpenAIChat
# llm = OpenAIChat()
llm = OpenAI()
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=demo3)
res = chain.run({'input': '1+1等于几'})
print(res)

输出

1+1等于2。

2、模版其它功能

(1)多角色

LangChain提供不同类型的MessagePromptTemplate. 最常用的是
AIMessagePromptTemplate
SystemMessagePromptTemplate
HumanMessagePromptTemplate
分别创建人工智能消息、系统消息和人工消息。关于这个,前面内容也有提到,这里就截图部分
在这里插入图片描述
在这里插入图片描述

但是,如果聊天模型支持以任意角色获取聊天消息,则可以使用ChatMessagePromptTemplate,它允许用户指定角色名称。比如,厨师,老师,运动员

from langchain.prompts import ChatMessagePromptTemplate
prompt = "给我取一个公司名称,公司主要是做{content}"
chat_message_prompt = ChatMessagePromptTemplate.from_template(role="小红", template=prompt)
rest = chat_message_prompt.format(content="海运")

在这里插入图片描述
使用

from langchain.prompts import ChatPromptTemplate
from langchain.llms import OpenAIChat
from langchain.chains import LLMChain
# 使用的时候,需要组装模版,不能直接使用
prompt = ChatPromptTemplate.from_messages([chat_message_prompt])
llm = OpenAIChat()
chain = LLMChain(llm=llm, prompt=prompt)
print(chain.run({"content":'拖拉机'}))
print(chain.run({"content":'拖拉机'}))
小红:好的,给您取一个公司名称:疾速农机有限公司

(2)MessagesPlaceholder

LangChain还提供了MessagesPlaceholder,全控制格式化期间要呈现的消息。当您不确定消息提示模板应使用什么角色或希望在格式化期间插入消息列表时,这会很有用。

from langchain.prompts import MessagesPlaceholder, HumanMessagePromptTemplate, ChatPromptTemplate

# 创建一个模板内容
human_prompt = "总结对话,通过{word_count}个字"
# 使用人类消息模板
human_message_template = HumanMessagePromptTemplate.from_template(human_prompt)
# 构建模版,并且加入一个conversation 参数
chat_prompt = ChatPromptTemplate.from_messages(
    [MessagesPlaceholder(variable_name="conversation"), human_message_template])
print(chat_prompt)

在这里插入图片描述
进行对话使用

from langchain.schema import HumanMessage, AIMessage

human_message = HumanMessage(content="学习编程的最佳方式是什么?")
ai_message = AIMessage(content="""\
1.选择一种编程语言:决定你想学习的编程语言。
2.从基础知识开始:熟悉变量、数据类型和控制结构等基本编程概念。
3.练习,练习,练习:学习编程的最好方法是亲身体验\
""")
print(human_message)
print(type(human_message))  # <class 'langchain.schema.messages.HumanMessage'>

# 此时只是一个消息列表[。。。。]
chat_message = chat_prompt.format_prompt(conversation=[human_message, ai_message], word_count="10").to_messages()
print(chat_message)
# 转换为模板对象使用
final_prompt = ChatPromptTemplate(messages=chat_message)

# 创建chain使用
from langchain.llms import OpenAIChat
llm = OpenAIChat()
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=final_prompt)
print(chain.run({'word_count':11}))

在这里插入图片描述

(3)模版输入参数

from langchain.prompts import PromptTemplate

prompt = PromptTemplate(template="{agrs1}{agrs2}", input_variables=["agrs1", "agrs1"])
partial_prompt = prompt.partial(agrs1="你好!")  # 这个返回模版的输入参数
print(partial_prompt.format(agrs2="今天天气如何!"))  # 也可以格式化操作

prompt = PromptTemplate(template="{agrs1}{agrs2}", 
	input_variables=["agrs1"], 
	partial_variables={"agrs2": "今天天气如何!"} # 可以在这里提前传入部分参数
	)
print(prompt.format(agrs1="你好!"))

(4)混合模板使用 PipelinePromptTemplate

应用场景:自己灵活思考一下吧,比如应对各种业务,flow流的代入

下面这个例子中,创建了3个模板,并且有一个base模板,进行管道管理

from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts.prompt import PromptTemplate

# 创建模版
full_template = """{introduction}

{example}

{start}"""
full_prompt = PromptTemplate.from_template(full_template)
# 可以看到上面有3个参数

# 介绍 1
introduction_template = """你在模拟{person}."""
introduction_prompt = PromptTemplate.from_template(introduction_template)

# 例子 2
example_template = """下面是一个交互的例子:
Q: {example_q}
A: {example_a}"""
example_prompt = PromptTemplate.from_template(example_template)

# 开始 3
start_template = """现在开始!

Q: {input}
A:"""
start_prompt = PromptTemplate.from_template(start_template)

### 组合模板 创建管道
input_prompts = [
    ("introduction", introduction_prompt),
    ("example", example_prompt),
    ("start", start_prompt)
]
pipeline_prompt = PipelinePromptTemplate(final_prompt=full_prompt, pipeline_prompts=input_prompts)
# 打印输入参数
print(pipeline_prompt.input_variables)

主要两个参数

  1. final_prompt 最后输出的模版样式
  2. pipeline_prompts 组合模版

在这里插入图片描述

(5) 序列化模版

导入方法

from langchain.prompts import load_prompt

正常来说,prompt代码不要存储在py文件中。在大型工程中,在相应配置文件中方便维护

langchain是支持存储

  1. json
  2. yaml
  3. txt等文件中
(5.1) 从JSON文件中加载

创建一个json文件 simple_prompt.json

    {
        "_type": "prompt",
        "input_variables": ["adjective", "content"],
        "template": "Tell me a {adjective} joke about {content}."
    }
prompt = load_prompt("simple_prompt.json")
print(prompt.format(adjective="funny", content="chickens"))
(5.2) 从YAML文件中加载

创建一个json文件 simple_prompt.yaml

    _type: prompt
    input_variables:
        ["adjective", "content"]
    template: 
        Tell me a {adjective} joke about {content}.
prompt = load_prompt("simple_prompt.yaml")
print(prompt.format(adjective="funny", content="chickens"))
(5.3) 从TXT文件中加载

创建一个txt文件

方式一
  Tell me a {adjective} joke about {content}.
  
方式二
      {
        "_type": "prompt",
        "input_variables": ["adjective", "content"],
        "template_path": "simple_template.txt"
    }
prompt = load_prompt("xxx.txt")
print(prompt.format(adjective="funny", content="chickens"))
(5.4) 配置多个prompt

上面的内容都是单个prompt,那么多个prompt的也能操作,以下只给出参考样例。

(5.4.1)json

examples.json

 [
        {"input": "happy", "output": "sad"},
        {"input": "tall", "output": "short"}
    ]
(5.4.2)yaml

examples.yaml

    - input: happy
      output: sad
    - input: tall
      output: short
(5.4.2)yaml与json混合使用

创建few_shot_prompt.yml,这里是yaml文件调用json文件

  _type: few_shot
    input_variables:
        ["adjective"]
    prefix: 
        Write antonyms for the following words.
    example_prompt:
        _type: prompt
        input_variables:
            ["input", "output"]
        template:
            "Input: {input}\nOutput: {output}"
    examples:
        examples.json # 这里换成examples.yaml 也是一样的
    suffix:
        "Input: {adjective}\nOutput:"

使用

prompt = load_prompt("few_shot_prompt.yaml")
print(prompt.format(adjective="funny"))

打印

    Write antonyms for the following words.
    
    Input: happy
    Output: sad
    
    Input: tall
    Output: short
    
    Input: funny
    Output:

当然还有很多结合使用,具体使用用的上在纠结要不要学。

(6)快速实现模板生产

对于之前的模板创建方法,过程上都是没有问题,langchain也提供简化版本

(6.1)使用字符串
from langchain.prompts import PromptTemplate
prompt = (
    PromptTemplate.from_template("告诉我一个关于 {topic}的笑话")
    + ", 听起来要有趣"
    + "\n\并且使用 {language}"
)

在这里插入图片描述
在langchain中使用这个模板

from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
llm = ChatOpenAI()
chain = LLMChain(llm=llm, prompt=prompt)
res = chain.run(topic="太阳", language="zh")

输出
在这里插入图片描述

(6.2)对象形式

构建流程:从消息,到消息模板对象,到模版对象,即可使用

from langchain.prompts import ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.schema import HumanMessage, AIMessage, SystemMessage

创建消息对象

prompt = SystemMessage(content="你是一个厨师")

关于prompt的值,跟type

content='你是一个厨师'
<class 'langchain.schema.messages.SystemMessage'>

进行消息模版组合

new_prompt = (
    prompt + HumanMessage(content="hi") + AIMessage(content="what?") + "{input}"
)

关于此时的值,跟type,在此时,创建了一个CahtPromptTemplate的示例,可以像之前那样使用它

input_variables=['input'] messages=[SystemMessage(content='你是一个厨师'), HumanMessage(content='hi'), AIMessage(content='what?'), HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], template='{input}'))]
<class 'langchain.prompts.chat.ChatPromptTemplate'>

使用它

# 模版因为预留了一个输入参数
new_prompt.format_messages(input="i said hi")

通过chain使用它

from langchain.chat_models import ChatOpenAI
from langchain.chains import LLMChain
model = ChatOpenAI()
chain = LLMChain(llm=model, prompt=new_prompt)
chain.run("你好!")

(6.3)模版验证参数

通常而言,模版如果有 {xx} 的,那么在使用的时候,就需要传入,否则报错
可以通过设置参数,不进行调用

template = "我正在学习langchain,因为{reason}."

prompt_template = PromptTemplate(template=template,
                                 input_variables=["reason", "foo"]) # 提示传值错误
prompt_template = PromptTemplate(template=template,
                                 input_variables=["reason", "foo"],
                                 validate_template=False) # 没有任何错误

3、模版进阶

(1)自定义选择样例

有什么用处了?比如,我们设定3个客服,每个客服的性格语气
我们可以服务客户的时候,随机选择一个招待用户,让用户体验体验,。。。

from langchain.prompts.example_selector.base import BaseExampleSelector
from typing import Dict, List
import numpy as np


class CustomExampleSelector(BaseExampleSelector):

    def __init__(self, examples: List[Dict[str, str]]):
        self.examples = examples

    def add_example(self, example: Dict[str, str]) -> None:
        """存储的新示例"""
        self.examples.append(example)

    def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
        """根据输入选择要使用的示例"""
        return np.random.choice(self.examples, size=2, replace=False)


examples = [
    {"foo": "1"},
    {"foo": "2"},
    {"foo": "3"}
]

# 初始化选择器
example_selector = CustomExampleSelector(examples)

# 随机选择2个
example_selector.select_examples({"foo": "foo"})

# 添加一个新的示例
example_selector.add_example({"foo": "4"})

# 随机选择2个
example_selector.select_examples({"foo": "foo"})

(2)长度选择器

对于我理解而言,比如我设计了一个厨师AI,那么对于问题,应该是询问
要点菜,菜不超过10个,我可以这么操作,超过了,我就不给你做了!

from langchain.prompts import PromptTemplate
from langchain.prompts import FewShotPromptTemplate
from langchain.prompts.example_selector import LengthBasedExampleSelector


# 创建一些例子
examples = [
    {"input": "happy", "output": "sad"},
    {"input": "tall", "output": "short"},
    {"input": "energetic", "output": "lethargic"},
    {"input": "sunny", "output": "gloomy"},
    {"input": "windy", "output": "calm"},
]

example_prompt = PromptTemplate(
    input_variables=["input", "output"],
    template="Input: {input}\nOutput: {output}",
)
# 调用长度选择器 类型 LengthBasedExampleSelector
example_selector = LengthBasedExampleSelector(
    # 可供选择的示例。
    examples=examples,
    # 用于格式化示例的PromptTemplate。
    example_prompt=example_prompt,
    # 格式化示例的最大长度。
    # 长度由下面的get_text_Length函数测量。
    max_length=25,
    # 用于获取字符串长度的函数
    # 以确定要包括哪些示例。它被注释掉是因为
    # 如果未指定,则将其作为默认值提供。
    # get_text_length:可调用[[str],int]=lambda x:len(re.split(“\n|”,x))
)


dynamic_prompt = FewShotPromptTemplate(
    # 提供了ExampleSelector而不是示例。
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="给出每个输入的反义词",
    suffix="Input: {adjective}\nOutput:",
    input_variables=["adjective"],
)

进行使用

print(dynamic_prompt.format(adjective="big"))

给出每个输入的反义词
Input: happy
Output: sad

Input: tall
Output: short

Input: energetic
Output: lethargic

Input: sunny
Output: gloomy

Input: windy
Output: calm

Input: big
Output:

输入长文本的时候,因为不超过25,所以看到的output为空

long_string = "big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else"
print(dynamic_prompt.format(adjective=long_string))
给出每个输入的反义词
Input: happy
Output: sad
Input: big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else
Output:

(3)算法选择器

(3.1)最大边界选择器

MaxMarginalRelevanceExampleSelector根据与输入最相似的示例的组合来选择示例,同时还针对多样性进行优化。它通过查找与输入具有最大余弦相似度的嵌入示例来实现这一点,然后迭代地添加它们,同时惩罚它们与已选择示例的接近程度。

from langchain.prompts.example_selector import (
    MaxMarginalRelevanceExampleSelector,
    SemanticSimilarityExampleSelector,
)
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings
from langchain.prompts import FewShotPromptTemplate, PromptTemplate

example_prompt = PromptTemplate(
    input_variables=["input", "output"],
    template="Input: {input}\nOutput: {output}",
)

# #创建反义词的假装任务的示例。
examples = [
    {"input": "happy", "output": "sad"},
    {"input": "tall", "output": "short"},
    {"input": "energetic", "output": "lethargic"},
    {"input": "sunny", "output": "gloomy"},
    {"input": "windy", "output": "calm"},
]

下面有 向量数据库FAISS OpenAIEmbeddings 这个后续文章会讲到
可以理解,向量数据库,将内容编程很多数字,用户问题也数字化,并非传统的sql查询

example_selector = MaxMarginalRelevanceExampleSelector.from_examples(
   	# 可供选择的示例列表。
    examples,
    # 用于生成用于测量的嵌入的嵌入类 (embedding)
    OpenAIEmbeddings(),
    # 用于生成测量嵌入的嵌入类(向量数据库)
    FAISS,
    # 返回结果数目
    k=2,
)
mmr_prompt = FewShotPromptTemplate(
    example_selector=example_selector,
    example_prompt=example_prompt,
    prefix="给出每个输入的反义词",
    suffix="Input: {adjective}\nOutput:",
    input_variables=["adjective"],
)

验证一下好不好用

print(mmr_prompt.format(adjective="happy"))

可以看到happy排第一(自己可以试试别的,这里没什么好说的)
在这里插入图片描述

(3.2)余弦

使用余弦相似度 SemanticSimilarityExampleSelector 自己体验吧,

example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(),
    FAISS,
    k=2,
)
(3.3)相似度

SemanticSimilarityExampleSelector 参考上面案例改下选择器即可

(3.4)Ng

参考上面案例改下选择器即可

NGramOverlapExampleSelector根据 ngram 重叠分数,根据与输入最相似的示例来选择示例并对其进行排序。ngram 重叠分数是 0.0 到 1.0 之间的浮点数(含 0.0 和 1.0)。

选择器允许设置阈值分数。ngram 重叠分数小于或等于阈值的示例被排除。默认情况下,阈值设置为 -1.0,因此不会排除任何示例,只会对它们重新排序。将阈值设置为 0.0 将排除与输入没有 ngram 重叠的示例。

三、语言模型

查看本章前,吃透前面二小节
在这里插入图片描述

.
LangChain提供了两种类型模型的接口和集成:

  • LLM:采用文本字符串作为输入并返回文本字符串的模型
  • 聊天模型:由语言模型支持的模型,但将聊天消息列表作为输入并返回聊天消息

LLM 与聊天
法学硕士和聊天模式有微妙但重要的不同。LangChain中的LLM指的是纯文本补全模型。它们包装的 API 将字符串提示作为输入并输出字符串完成。OpenAI 的 GPT-3 是作为法学硕士实施的。聊天模型通常由法学硕士支持,但专门针对对话进行了调整。而且,至关重要的是,他们的提供商 API 使用与纯文本完成模型不同的接口。他们采用聊天消息列表作为输入,而不是单个字符串。通常这些消息会标有说话者(通常是“系统”、“人工智能”和“人类”之一)。他们返回一条人工智能聊天消息作为输出。GPT-4 和 Anthropic 的 Claude 都是作为聊天模型实现的。

为了能够交换法学硕士和聊天模型,两者都实现了基本语言模型接口。这包括常用方法“predict”(接受字符串并返回字符串)和“predict messages”(接受消息并返回消息)。如果您使用特定模型,建议您使用特定于该模型类的方法(即,LLM 的“预测”和聊天模型的“预测消息”),但如果您正在创建一个应与不同类型一起使用的应用程序对于模型来说,共享界面会很有帮助。

关于模型更多的理解,在后面的章节文章会慢慢理解,这边没必要死磕
了解个大概

大型语言模型(LLM)是LangChain的核心组件。LangChain不为自己的LLM提供服务,而是提供一个标准接口来与许多不同的LLM进行交互。

有很多LLM厂商提供服务(OpenAI,Cohere、hugging face 等) - 该类LLM 所做的功能是封装了标准的接口

如下演示中,将使用OpenAI 的LLM 功能函数,实际上其它厂商的功能函数都是大抵相同的。

在前面内容的时候时常看到,两者有区别,带有Chat更适合聊天

from langchain.llms import OpenAIChat, OpenAI

注意!前面演示案例,其实都用过了,下面内容知识摘要代码

(1.1)OpenAI

基本使用,(当然也可以在chain中使用)

from langchain.llms import OpenAi
llm = OpenAi(openai_api_key='') # 如果不想环境变量设置密匙,可以在功能函数设置密匙
# 单条调用
res = llm("你好")
# 批量调用
res_list = llm.generate(["给我讲一个笑话", "告诉我明天天气"]*15)
l = len((res_list)) # 30 长度
""
    llm_result.generations[0]
    llm_result.generations[-1]
""

输出结果

llm_result.llm_output
 {'token_usage': 
     {'completion_tokens': 3903,     
      'total_tokens': 4023,     
       'prompt_tokens': 120}
 }

(1.2)ChatOpenAI

(1.2.1)在chain中使用

from langchain.chat_models import ChatOpenAI
from langchain import LLMChain
from langchain.prompts.chat import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate
)

# 设置模板
sys_temp_pro = SystemMessagePromptTemplate.from_template(
    """
        你是一个翻译机器人
    """
)
human_temp_pro = HumanMessagePromptTemplate.from_template(
    """
        {text}
    """
)
# 组装模板
chat_prompt = ChatPromptTemplate.from_messages([sys_temp_pro, human_temp_pro])

# 使用
llm = ChatOpenAI()
chain = LLMChain(llm=llm, prompt=chat_prompt)
# 获取响应
resp = chain.run("我喜欢苹果")

print(resp)

(1.2.2)直接使用LLM

from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
    ChatPromptTemplate,
    SystemMessagePromptTemplate,
    HumanMessagePromptTemplate
)

# 系统
sys_template = "你是一个翻译机器人负责将{input_language}翻译成{output_language}"
sys_message_prompt_1 = SystemMessagePromptTemplate.from_template(sys_template)
syst_message_prompt_2 = SystemMessagePromptTemplate(prompt=PromptTemplate(
    template="你是一个翻译机器人负责将{input_language}翻译成{output_language}",
    input_variables=["input_language", "output_language"],
))

# 用户
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)

# 组装聊天
chat_prompt = ChatPromptTemplate.from_messages([sys_message_prompt_1, human_message_prompt])
 # 实例化对象
llm = ChatOpenAI()
 # 进行提问
res = llm(
    chat_prompt.format_prompt(input_language="English", output_language="中文", text="I love programming.").to_messages())
print(res)

四、输出解析器

查看本章前,吃透前面二小节

在这里插入图片描述

在语言模型输出文本的时候,可能想要获得更多结构化的信息,而不仅仅获得默认返回响应.

这个是时候,就可以使用output models.

输出解释器是帮助构建语言模型响应的类.

输出解释器必须实现两个主要的方法:

  1. 获取格式指令:返回一个字符串的方法
  2. 解析: 一种接受字符串(假设是来自语言模型的响应)并将其解析为某种结构的方法

然后是可选的一项

  • “带有提示的解析”:一种方法,它接受一个字符串(假设是来自语言模型的响应)和一个提示(假设是生成这种响应的提示)并将其解析为某种结构。

提示主要是在 OutputParser 希望以某种方式重试或修复输出的情况下提供的,并且需要提示中的信息才能执行此操作。

langchain提供了很多常见的解析器

(1)常用解析器

最常用的也是这个 PydanticOutputParse

from langchain.prompts import (
    PromptTemplate,
)
from langchain.llms import OpenAI
from langchain.output_parsers import PydanticOutputParser  # 输出解释器主要的类型
from pydantic import BaseModel, Field, validator

model_name = "text-davinci-003"
temperature = 0.0
llm = OpenAI(temperature=temperature, model_name=model_name)


# 验证器
class JOKE(BaseModel):
    setup: str = Field(description="讲一个笑话")
    punchline: str = Field(description="处理这个笑话")

    @validator('setup')
    def question_end_with_question_mark(cls, field):
        if field[-1] != '?':
            raise ValueError('字段检查失败')
        return field


# 构建解释器
parser = PydanticOutputParser(pydantic_object=JOKE)

prompt = PromptTemplate(
    template="回复用户的提问\n{format_instructions}\n{query}",
    input_variables=['query'],  # 输入参数
    partial_variables={"format_instructions": parser.get_format_instructions()}
)
joke_query = "告诉我一个笑话"
_input = prompt.format_prompt(query=joke_query)

output = llm(_input.to_string())

print(parser.parse(output))

上面代码执行了什么

  1. 导入所需的模块和类。
  2. 定义了一个名为JOKE的Pydantic模型,用于验证和解析笑话的结构。
  3. 创建了一个OpenAI对象,用于与OpenAI的语言模型进行交互。
  4. 定义了一个PydanticOutputParser对象,用于解析模型输出并将其转换为JOKE对象。
  5. 创建了一个PromptTemplate对象,用于构建输入模板,其中包含了格式化指令和用户提问。
  6. 定义了一个笑话查询字符串。
  7. 使用PromptTemplate对象将查询字符串格式化为输入模板。
  8. 使用OpenAI对象调用模型并获取输出。
  9. 使用PydanticOutputParser对象解析模型输出并将其转换为JOKE对象。
  10. 打印解析后的结果。

(2)列表解释器

列表解释器 CommaSeparatedListOutputParser

当想要输出特定列表时候可以用这个

from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import (
    PromptTemplate,
)
from langchain.llms import OpenAI

output_parser = CommaSeparatedListOutputParser()
# Your response should be a list of comma separated values, eg: `foo, bar, baz`

format_instructions = output_parser.get_format_instructions()
print(format_instructions)
prompt = PromptTemplate(
    template="列举5个{subject}.\n{format_instructions}",
    input_variables=["subject"],
    partial_variables={"format_instructions": format_instructions}
)

model = OpenAI(temperature=0)

_input = prompt.format(subject="颜色")
output = model(_input)  # 原始响应
print(output) # Red, Blue, Green, Yellow, Orange
#  也可以通过输出解释器过滤出来
resp = output_parser.parse(output)
print(resp) # ['Red', 'Blue', 'Green', 'Yellow', 'Orange']

(3)时间日期解析器

时间日期解释器 DatetimeOutputParser

from langchain.prompts import PromptTemplate
from langchain.output_parsers import DatetimeOutputParser
from langchain.llms import OpenAI
from langchain.chains import LLMChain

output_parse = DatetimeOutputParser()
# format='%Y-%m-%dT%H:%M:%S.%fZ'
template = """
    回答用户问题:
        {question}
        {format_instructions}
"""
prompt = PromptTemplate.from_template(
    template,
    partial_variables={"format_instructions": output_parse.get_format_instructions()}
)

chain = LLMChain(prompt=prompt, llm=OpenAI())
output = chain.run(question="比特币是什么时候创立的")
print(output)  # 2020-10-14T00:00:00.000000Z
resp = output_parse.parse(output)
print(resp)  # 2020-10-14 00:00:00

(4)枚举解释器

EnumOutputParser

搜想构建一个枚举解析器

from langchain.output_parsers.enum import EnumOutputParser
from enum import Enum
class Colors(Enum):
    RED = "red"
    GREEN = "green"
    BLUE = "blue"
parser = EnumOutputParser(enum=Colors)  

使用它

parser.parse("red")
parser.parse("green")
parser.parse("blue")
parser.parse("red") # 使用到红色的时候报错,因为只有三个内容可以枚举
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import List

class Actor(BaseModel):
    name: str = Field(description="导演名称")
    film_names: List[str] = Field(description="主演名单")

actor_query = "生成一个随机演员的电影记录"
parser = PydanticOutputParser(pydantic_object=Actor)

misformatted = "{'name': 'Tom Hanks', 'film_names': ['A','B','C']}"

parsed_result = parser.parse(misformatted)

(5)重试解释器

RetryOutputParser

from langchain.prompts import (
    PromptTemplate,
    ChatPromptTemplate,
    HumanMessagePromptTemplate
)
from pydantic import BaseModel, Field
from typing import List
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.output_parsers import (
    PydanticOutputParser,
    OutputFixingParser,
    RetryOutputParser
)

template = """根据用户的问题,提供响应的操作步骤和操作输入
{format_instructions}
Question: {query}
Response:
"""


class Action(BaseModel):
    action: str = Field(description="开始对话")
    action_input: str = Field(description="开始输入")


parser = PydanticOutputParser(pydantic_object=Action)

prompt = PromptTemplate(
    template="回答这个问题.\n{format_instructions}\n{query}\n",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()}
)
# 假如这边提出了一个问题
prompt_values = prompt.format_prompt(query="今天几月几号")

假设模拟了LLM的响应,运行如下代码就会报错

# 得到了是一个这么的回复,而在上面的要求的响应是2个字段的回复
bad_response = '{"action": "search"}'
parser.parse(bad_response) 

运行如上代码会报错,因为输出代码要求是2个字段,一个是action另外一个是action_input

尝试使用OutputFixingParser 修复错误,可以看到回复的内容是丢失了提问的
问的是 谁是冯小刚老婆,通过这个自动修复缺少了 提问的内容

fix_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
res = fix_parser.parse(bad_response)
print(res) # action='search' action_input='example'

可以使用RetryOutputParser 来进行处理

from langchain.output_parsers import RetryWithErrorOutputParser

retry_parser = RetryWithErrorOutputParser.from_llm(
    parser=parser, llm=OpenAI(temperature=0)
)
res = retry_parser.parse_with_prompt(bad_response, prompt_values)

(6)结果化解释器

StructuredOutputParser

from langchain.output_parsers import (
    StructuredOutputParser,
    ResponseSchema,
)
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI

# 定义接受响应的模式
response_schemas = [
    ResponseSchema(name="answer", description='回答用户的问题'),
    ResponseSchema(name="source", description="用于回答用户问题的来源,应该是一个网站。")
]
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)

# 得到一个字符串,其中包含格式化响应的说明,然后插入提示符中
format_instructions = output_parser.get_format_instructions()

prompt = PromptTemplate(
    template="回答用户的问题.\n{format_instructions}\n{question}",
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions}
)


model = OpenAI()
res = model(prompt=prompt.format_prompt(question="百度网站地址").to_string())

print(res)
parsed = output_parser.parse(res)

print(parsed)

查看输出,可以看到是一个标准的json,与我们定义的一样

{
    "answer": "百度的网站地址是https://www.baidu.com/",
    "source": "https://www.baidu.com/"
}

在聊天模型中使用它的示例

chat_model = ChatOpenAI()
prompt2 = ChatPromptTemplate(
    messages=[
        HumanMessagePromptTemplate.from_template(
            "回答用户问题\n{format_instructions}\n{question}")
    ],
    input_variables=["question"],
    partial_variables={"format_instructions": format_instructions}
)

res = chat_model(prompt2.format_prompt(question="百度网站地址是什么?").to_messages())
print(res)
parsed = output_parser.parse(res.content)
print(parsed)

结果

content='```json\n{\n    "answer": "百度网站地址是www.baidu.com。",\n    "source": "https://www.baidu.com"\n}\n```' additional_kwargs={} example=False
{'answer': '百度网站地址是www.baidu.com。', 'source': 'https://www.baidu.com'}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1178885.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[第二章—Spring MVC的高级技术] 2.1Spring MVC配置的替代方案

7.1.1 自定义DispatcherServlet配置 例如&#xff0c;在本章稍后的内容中&#xff08;7.2节&#xff09;&#xff0c;我们将会看到如何在Spring MVC中处理multipart请求和文件上传。 如果计划使用Servlet 3.0对multipart配置的支持&#xff0c;那么需要使用DispatcherServlet的…

​软考-高级-信息系统项目管理师教程 第四版【第16章-项目采购管理-思维导图】​

软考-高级-信息系统项目管理师教程 第四版【第16章-项目采购管理-思维导图】 课本里章节里所有蓝色字体的思维导图

内窥镜项目

★ 手持pad内窥镜项目 项目描述&#xff1a;3D电子内窥镜软件项目是一个基于BS&#xff08;浏览器服务器&#xff09;架构的项目&#xff0c;旨在实现对内窥镜设备的远程控制和高级功能操作。该项目允许操作员使用平板电脑手动触摸屏上的按钮、外部按键或脚踏板 来控制内窥镜设…

[移动通讯]【Carrier Aggregation-11】【5G NR Carrier Aggregation (CA) basics 】

前言&#xff1a; 参考&#xff1a; RF Wireless world 里面的 《5G/NR - Carrier Aggregation》 《5G NR Carrier Aggregation (CA) basics | Carrier Aggregation frequency bands》 This page describes 5G NR Carrier Aggregation (CA) basics. It mentions Carrier Aggre…

Redis 的几种集群对比

文章目录 一、对比分析二、优缺点对比三、总结 如果您对Redis的了解不够深入请关注本栏目&#xff0c;本栏目包括Redis安装&#xff0c;Redis配置文件说明&#xff0c;Redis命令和数据类型说明&#xff0c;Redis持久化配置&#xff0c;Redis主从复制和哨兵机制&#xff0c;Redi…

一些常规的报错和解决方法(持续更新)

一些常规的报错和解决方法&#xff1a; 1、vue创建项目后&#xff0c;项目启动时报错You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included bu…

【JavaEE】实现简单博客系统-前端部分

文件目录&#xff1a; 展示&#xff1a; blog_list.html: <!DOCTYPE html> <html lang"cn"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><t…

05-SpringBoot中yaml文件的语法格式,在程序中读取yaml文件中数据的方式,yaml文件中引用数据的方式

yaml文件格式 语法格式 YAML(YAML Aint Markup Language)是一种数据序列化格式 , 具有容易阅读、容易与脚本语言交互、以数据为核心即重数据轻格式的特点 YAML数据常见的文件扩展名有yml格式(主流)和yaml格式两种 YAML文件的语法格式: 属性层级关系使用多行和缩进描述(同层…

第十一章《搞懂算法:聚类是怎么回事》笔记

聚类是机器学习中一种重要的无监督算法&#xff0c;可以将数据点归结为一系列的特定组合。归为一类的数据点具有相同的特性&#xff0c;而不同类别的数据点则具有各不相同的属性。 11.1 聚类算法介绍 人们将物理或抽象对象的集合分成由类似 的对象组成的多个类的过程被称为聚…

使用IDEA让文本对比不在变的困难

文章目录 前言操作1、IDEA与电脑磁盘任意文件的比较2、项目内部的文件比较3、剪切板比较4、IDEA本地历史比较5、IDEA版本历史对比 前言 在日常实际开发当中我们常常会对一些代码或内容进行比对查看是否有差异&#xff0c;这个时候不需要借用第三方比对插件&#xff0c;在IDEA中…

ubuntu 20.04 server安装

ubuntu 20.04 server安装 ubuntu-20.04.6-live-server-amd64.iso 安装 安装ubuntu20.04 TLS系统后&#xff0c;开机卡在“A start job is running for wait for network to be Configured”等待连接两分多钟。 cd /etc/systemd/system/network-online.target.wants/在[Servi…

【UE4】UE编辑器乱码问题

环境&#xff1a;UE4.27、vs2019 如何解决 问题原因&#xff0c;UE的编码默认是UTF-8&#xff0c;VS的默认编码是GBK 通过"高级保存选项" 直接修改VS的 .h头文件 的 编码 为 UTF-8 步骤1. 步骤2. 修改编码后&#xff0c;从新编译&#xff0c;然后就可以解决编辑器…

Linux基础环境开发工具的使用(二):动静态库的理解,make,makefile

Linux基础环境开发工具的使用[二] 一.动静态库的初步理解1.库的作用2.Linux和Windows中库的后缀名3.如何在Linux中看一个的库名字4.Linux中和Windows平台怎样支持开发的?5.动静态库的概念6.动静态库的优缺点与补充7.代码验证 二.make,makefile1.功能2.基本语法1.快速使用2.依赖…

SV-704LW 无线WIFI网络音柱

SV-704LW 无线WIFI网络音柱(工业级) 一、描述 SV-704LW是深圳锐科达电子有限公司的一款壁挂式WIFI无线网络音柱&#xff0c;通过WIFI无线接入到WIFI覆盖的网络中&#xff0c;可将网络音源通过自带的功放和喇叭输出播放&#xff0c;其采用防水设计&#xff0c;功率可以从30W到6…

品牌如何长期占领小红书市场,小红书投放复盘怎么规划?

想要实现产品种草与品牌营销&#xff0c;达人投放成了很多品牌的选择。然而随着达人协助成本的水涨船高&#xff0c;提高达人投放结果&#xff0c;就变得迫在眉睫。今天我们将为大家分享下&#xff0c;品牌如何长期占领小红书市场&#xff0c;小红书投放复盘怎么规划&#xff1…

找不到x3daudio1_7.dll的解决方法,快速修复x3daudio1_7.dll缺失问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到x3daudio1_7.dll”。这个错误提示通常出现在运行某些程序或游戏时&#xff0c;这个文件是与音频设备相关的动态链接库文件&#xff0c;如果缺失或损坏&#xff0c;可能会导致软件游戏…

RabbitMQ(高级特性):限流

消费端限流 在rabbitmq中&#xff0c;使用消费端限流必须开启手动签收信息 过MQ可以对请求进行“削峰填谷”&#xff0c;即通过消费端限流的方式限制消息的拉取速度&#xff0c;达到保护消费端的目的。 生产者批量发送消息&#xff1a; Test public void testSendBatch() {…

聊聊 Python 的单元测试框架:unittest!

前言 说到 Python 的单元测试框架&#xff0c;想必接触过 Python 的朋友脑袋里第一个想到的就是 unittest。 的确&#xff0c;作为 Python 的标准库&#xff0c;它很优秀&#xff0c;并被广泛用于各个项目。但你知道吗&#xff1f;其实在 Python 众多项目中&#xff0c;主流的…

【SQL篇】一、Flink动态表与流的关系以及DDL语法

文章目录 1、启动SQL客户端2、SQL客户端常用配置3、动态表和持续查询4、将流转为动态表5、用SQL持续查询6、动态表转为流7、时间属性8、DDL-数据库相关9、DDL-表相关 1、启动SQL客户端 启动Flink&#xff08;基于yarn-session模式为例&#xff09;&#xff1a; /opt/module/f…

PubDef:使用公共模型防御迁移攻击

对抗性攻击对机器学习系统的可靠性和安全性构成了严重威胁。通过对输入进行微小的变动&#xff0c;攻击者就可以导致模型生成完全错误的输出。防御这种攻击是一个很活跃的研究领域&#xff0c;但大多数提议的防御措施都存在重大的缺点。 这篇来自加州大学伯克利分校研究人员的…