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

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'}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QQ邮箱批量发送

场景 已有用户邮箱,需要批量对他们发送一些广告信息。 完整代码 # coding=gbk import smtplib import csv from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipartdef send_email(msg_from, passwd, msg_to_list, text_content)

Harbor企业级Registry基础镜像仓库的详细安装使用教程(保姆级)

Harbor Docker 官方提供的私有仓库 registry&#xff0c;用起来虽然简单 &#xff0c;但在管理的功能上存在不足。 Harbor是vmware一个用于存储和分发Docker镜像的企业级Registry服务器&#xff0c;harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。 ha…

有趣的数学 sign是什么函数

在数学中&#xff0c;函数sign指的是符号函数&#xff0c;它的定义如下&#xff1a;对于任意实数x&#xff0c;若x>0&#xff0c;则sign(x)1&#xff1b;若x0&#xff0c;则sign(x)0&#xff1b;若x<0&#xff0c;则sign(x)-1&#xff1b;简单来说&#xff0c;sign函数就…

【ChatOCR】OCR+LLM定制化关键信息抽取(附开源大语言模型汇总整理)

目录 背景技术方案存在的问题及解决思路关键信息提取结果其他解决方案替换文心一言LangChain大型多模态模型&#xff08;Large Multimodal Model, LMM&#xff09; 开源大模型汇总LLaMA —— Meta 大语言模型Stanford Alpaca —— 指令调优的 LLaMA 模型Lit-LLaMA —— 基于 na…

GEE错误——XXX is not a function,如何解决这个问题?

错误&#xff1a; 这里的时错误原始的代码链接&#xff1a; https://code.earthengine.google.com/4bf0975a41e14d0c40e01925c6f3cf2a 这里主要的问题时这个单一影像不存在&#xff1a; ImageCollection (Error) ImageCollection.load: ImageCollection asset LANDSAT/LC0…

【HTML】播放器如何自动播放【已解决】

自动播放器策略 先了解浏览器的自动播放器策略 始终允许静音自动播放在以下情况&#xff0c;带声音的自动播放才会被允许 2.1 用户已经与当前域进行交互 2.2 在桌面上&#xff0c;用户的媒体参与指数阈值(MEI)已被越过&#xff0c;这意味着用户以前播放带有声音的视频。 2.3 …

weblogic弱口令漏洞复现

文章目录 一、漏洞特征1.可以直接获取passwd文件2.可以直接获取密文文件3.可以直接获取密钥文件4.解密密码5.登录后台 二、命令执行复现1.部署webshell2.Shell命令执行3.jsp一句话木马 一、漏洞特征 1.可以直接获取passwd文件 http://192.168.232.131:7001/hello/file.jsp?p…

Android 应用流量监控实践

背景 得物Apm系统本身包含网络接口性能监控的能力&#xff0c;但接口监控主要关注的是接口的耗时、异常率等信息&#xff0c;没有流量消耗相关维度的统计信息&#xff0c;并且一部分流量消耗可能来自于音视频等其他特殊场景&#xff0c;在接口监控的盲区外。 为了了解用户目前…

QML 仪表盘小示例

本次项目已发布在CSDN->GitCode,下载方便,安全,可在我主页进行下载即可,后面的项目和素材都会发布这个平台。 个人主页:https://gitcode.com/user/m0_45463480怎么下载:在项目中点击克隆,windows:zip linux:tar.gz tar # .pro TEMPLATE = appTARGET = dialcontrol​#…

最新 vie-vite框架下 jtopo安装使用

官方地址 官方源码 安装下载 1.官方好像都没有给git地址&#xff0c;尝试npm安装报错 2.找到1.0.5之前的版本npm i jtopo2&#xff0c;安装成功后使用报错&#xff0c;应该是版本冲突了 1.本地引入&#xff0c; 点击官方源码下载&#xff0c;需要jtopo_npm文件 2.引入到本…

计算机毕设 基于大数据的服务器数据分析与可视化系统 -python 可视化 大数据

文章目录 0 前言1 课题背景2 实现效果3 数据收集分析过程**总体框架图****kafka 创建日志主题****flume 收集日志写到 kafka****python 读取 kafka 实时处理****数据分析可视化** 4 Flask框架5 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&a…

基于SSM的鲜花商城系统

基于SSM的鲜花商城系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 鲜花列表 热销商品 商品详情 登录界面 购物车 管理员界面 摘要 基于SSM的鲜花商…

oracle 数据库 LISTAGG详解

目录 简介: 效果展示&#xff1a; 举例&#xff1a; 测试表及数据&#xff1a; 简介: Oracle数据库的LISTAGG函数用于将多行数据合并为单个字符串&#xff0c;常见于分组操作&#xff0c;实现数据的垂直到水平的转换。 解决问题如&#xff1a;一个人有多个手机号&#xff0c…

AI 绘画 | Stable Diffusion 提示词

Prompts提示词简介 在Stable Diffusion中&#xff0c;Prompts是控制模型生成图像的关键输入参数。它们是一种文本提示&#xff0c;告诉模型应该生成什么样的图像。 Prompts可以是任何文本输入&#xff0c;包括描述图像的文本&#xff0c;如“一只橘色的短毛猫&#xff0c;坐在…

pandas - 数据分组统计

1.分组统计groupby()函数 对数据进行分组统计&#xff0c;主要适用DataFrame对象的groupby()函数。其功能如下。 &#xff08;1&#xff09;根据特定条件&#xff0c;将数据拆分成组 &#xff08;2&#xff09;每个组都可以独立应用函数&#xff08;如求和函数sum()&#xff0…

C++多态基础

文章目录 1.多态概念2.多态使用3.多态析构4.多态隐藏5.多态原理5.1.单类继承5.1.1.问题一&#xff1a;非指针或引用无法调用多态5.1.2.问题二&#xff1a;同类对象共用虚表5.1.3.问题三&#xff1a;子类对象拷贝父类对象虚表5.1.4.问题四&#xff1a;打印虚表地址和虚表内容 5.…

【C++类和对象中:解锁面向对象编程的奇妙世界】

【本节目标】 1. 类的6个默认成员函数 2. 构造函数 3. 析构函数 4. 拷贝构造函数 5. 赋值运算符重载 6. const成员函数 7. 取地址及const取地址操作符重载 1.类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xf…

Nginx默认会自动忽略请求头Headers里带下划线_的参数

起因&#xff1a;该接口设置了必须要传送app_code和app_secret才能正常访问。实际我在本地环境测试中&#xff0c;发现该接口是正常访问的&#xff0c;但是部署到正式系统之后发现&#xff0c;该接口一直提示app_code和app_secret不能为空。 后续排查&#xff1a;发现正式系统…

GitLab CI/CD 持续集成/部署 SpringBoot 项目

一、GitLab CI/CD 介绍 GitLab CI/CD&#xff08;Continuous Integration/Continuous Deployment&#xff09;是 GitLab 提供的一种持续集成和持续部署的解决方案。它可以自动化软件的构建、测试和部署过程&#xff0c;以便开发者更快地、更频繁地发布可靠的产品。 整体过程如…

Unity meta的一些常见属性

Unity会项目文件夹中的每个文件分配一个同名后缀为.meta的文件。 我们可以将meta文件理解不同文件之间的桥梁&#xff0c;通过它引擎可以管理不同文件之间的依赖关系。 使用TXT文本文件打开之后&#xff0c;大致属性如下&#xff1a; 其中常用的属性有guid、 assetBundleName以…