(三)、基于 LangChain 實現大模型應用程序開發 | 模型鏈 Chains

😄 為什么我們需要Chains ?

  • 鏈允許我們將多個組件組合在一起,以創建一個單一的、連貫的應用程序。鏈(Chains)通常將一個LLM(大語言模型)與提示結合在一起,使用這個構建塊,您還可以將一堆這些構建塊組合在一起,對您的文本或其他數據進行一系列操作。例如,我們可以創建一個鏈,該鏈接受用戶輸入,使用提示模板對其進行格式化,然后將格式化的響應傳遞給LLM。我們可以通過將多個鏈組合在一起,或者通過將鏈與其他組件組合在一起來構建更復雜的鏈。
  • 這些鏈的一部分的強大之處在于你可以一次運行它們在許多輸入上。

文章目錄

  • 😄 為什么我們需要Chains ?
  • 0、初始化openai環境
  • 1、LLMChain
  • 2、Sequential Chain
    • 2.1、SimpleSequentialChain
    • 2.2、SequentialChain
  • 3、 Router Chain(路由鏈)
    • 3.1、創建目標鏈
    • 3.2、創建默認目標鏈
    • 3.3、創建LLM用于在不同鏈之間進行路由的模板
    • 3.4、構建路由鏈
  • Reference

0、初始化openai環境

from langchain.chat_models import ChatOpenAI
import os
import openai
# 運行此API配置,需要將目錄中的.env中api_key替換為自己的
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
openai.api_key = os.environ['OPENAI_API_KEY']

1、LLMChain

  • LLMChain是一個簡單但非常強大的鏈,也是后面我們將要介紹的許多鏈的基礎。
from langchain.chat_models import ChatOpenAI    #導入OpenAI模型
from langchain.prompts import ChatPromptTemplate   #導入聊天提示模板
from langchain.chains import LLMChain    #導入LLM鏈。# 這里我們將參數temperature設置為0.0,從而減少生成答案的隨機性。
# 如果你想要每次得到不一樣的有新意的答案,可以嘗試調整該參數。
# 以下的對話均無記憶,即每次調用預測不會記得之前的對話。(想要有記憶功能請看下一節的langchain的Memory模塊)
llm = ChatOpenAI(temperature=0.0,model_name="gpt-3.5-turbo")
# \在字符串里就是取消換行符的意思
template_string =  """\
對與如下三個反引號括住的評論,我需要提取如下信息。
飲料:這個產品是飲料嗎?如果是,返回True,否則返回答False。
產品名:提取出產品的名字,如果沒有,返回-1。
價格與價值:提取出關于該產品的價格或價值的所有信息,將他們存入python list中,并返回。
{format_instructions}
```{query}```"""prompt_template = ChatPromptTemplate.from_template(template_string)chain = LLMChain(llm=llm, prompt=prompt_template)query = '這喜茶新出的桑葚葡萄太好喝里吧,而且才19塊一杯,太值啦,高性價比!'
format_instructions = """\
將輸出組織成帶有如下key的json形式:
飲料
產品名
價格與價值"""
res = chain.run({'query':query,'format_instructions': format_instructions})
print(res)
{"飲料": true,"產品名": "桑葚葡萄","價格與價值": ["19塊一杯", "高性價比"]
}

2、Sequential Chain

2.1、SimpleSequentialChain

  • 順序鏈是按預定義順序執行其鏈接的鏈。具體來說,我們將使用簡單順序鏈(SimpleSequentialChain),這是順序鏈的最簡單類型,其中每個步驟都有一個輸入/輸出,一個步驟的輸出是下一個步驟的輸入
from langchain.chains import SimpleSequentialChain
first_prompt = ChatPromptTemplate.from_template("描述制造{product}的公司的最佳名稱是什么?輸出一個即可。"
)
chain_one = LLMChain(llm=llm, prompt=first_prompt)second_prompt = ChatPromptTemplate.from_template("寫一個20字的描述對于下面這個\公司:{company_name}"
)
chain_two = LLMChain(llm=llm, prompt=second_prompt)overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],verbose=True)
product = "手機"
overall_simple_chain.run(product)
> Entering new  chain...
Techtronics
Techtronics是一家技術公司,專注于創新和開發高科技產品和解決方案。> Finished chain.'Techtronics是一家技術公司,專注于創新和開發高科技產品和解決方案。'

2.2、SequentialChain

  • 當只有一個輸入和一個輸出時,簡單的順序鏈可以順利完成。但是當有多個輸入或多個輸出時該如何實現呢?可用順序鏈。
from langchain.chains import SequentialChain# 下面實現流程:1->2, 1->3, 2,3->4#子鏈1
# prompt模板 1: 翻譯成英語(把下面的review翻譯成英語)
first_prompt = ChatPromptTemplate.from_template("Translate the following review to english:""\n\n{Review}")
# chain 1: 輸入:Review 輸出: 英文的 Review
chain_one = LLMChain(llm=llm, prompt=first_prompt,output_key="English_Review")#子鏈2
# prompt模板 2: 用一句話總結下面的 review
second_prompt = ChatPromptTemplate.from_template("Can you summarize the following review in 1 sentence: \n\n{English_Review}")
# chain 2: 輸入:英文的Review   輸出:總結
chain_two = LLMChain(llm=llm, prompt=second_prompt,output_key="summary")#子鏈3
# prompt模板 3: 下面review使用的什么語言
third_prompt = ChatPromptTemplate.from_template("What language is the following review:\n\n{Review}")
# chain 3: 輸入:Review  輸出:語言
chain_three = LLMChain(llm=llm, prompt=third_prompt,output_key="language")#子鏈4
# prompt模板 4: 使用特定的語言對下面的總結寫一個后續回復
# 根據英文總結,翻譯成language語言
fourth_prompt = ChatPromptTemplate.from_template("Write a follow up response to the following summary in the specified language:\n\nSummary: {summary}\n\nLanguage: {language}")
# chain 4: 輸入: 總結, 語言    輸出: 后續回復
chain_four = LLMChain(llm=llm, prompt=fourth_prompt,output_key="followup_message")
overall_chain = SequentialChain(chains=[chain_one, chain_two, chain_three, chain_four],input_variables=["Review"],output_variables=["English_Review", "summary", 'language', "followup_message"],verbose=False)
review = 'Spark是一個快速、通用的大數據處理引擎,可以進行分布式數據處理和分析。與Hadoop的MapReduce相比,Spark具有更高的性能和更豐富的功能。Spark支持多種編程語言(如Scala、Java和Python(pyspark)),并提供了一組豐富的API,包括用于數據處理、機器學習和圖計算的庫。'
res = overall_chain(review)
type(res), res
(dict,{'Review': 'Spark是一個快速、通用的大數據處理引擎,可以進行分布式數據處理和分析。與Hadoop的MapReduce相比,Spark具有更高的性能和更豐富的功能。Spark支持多種編程語言(如Scala、Java和Python(pyspark)),并提供了一組豐富的API,包括用于數據處理、機器學習和圖計算的庫。','English_Review': "Spark is a fast and versatile big data processing engine that can perform distributed data processing and analysis. Compared to Hadoop's MapReduce, Spark has higher performance and richer functionality. Spark supports multiple programming languages such as Scala, Java, and Python (pyspark), and provides a rich set of APIs including libraries for data processing, machine learning, and graph computation.",'summary': "The review highlights that Spark is a high-performance and versatile big data processing engine that offers distributed data processing and analysis, surpassing Hadoop's MapReduce in terms of performance and functionality, with support for multiple programming languages and a wide range of APIs for various tasks.",'language': 'The following review is in Chinese.','followup_message': '回復:這篇評論強調了Spark是一個高性能且多功能的大數據處理引擎,提供分布式數據處理和分析,性能和功能方面超過了Hadoop的MapReduce。它支持多種編程語言,并提供各種任務的廣泛API。'})

3、 Router Chain(路由鏈)

到目前為止,我們已經學習了LLM鏈和順序鏈。但是,如果您想做一些更復雜的事情怎么辦?

一個相當常見但基本的操作是根據輸入將其路由到一條鏈,具體取決于該輸入到底是什么。如果你有多個子鏈,每個子鏈都專門用于特定類型的輸入,那么可以組成一個路由鏈,它首先決定將它傳遞給哪個子鏈(也輸入寫prompt模板讓llm來選擇),然后將它傳遞給那個鏈(即傳遞給對于的鏈的prompt模板進行預測)。【相當于從輸入到輸出,要經過兩次prompt輸入模型拿到輸出】

路由器由兩個組件組成:

  • 路由器鏈本身(負責選擇要調用的下一個鏈)
  • destination_chains:路由器鏈可以路由到的鏈

個人感覺,就是可以用來根據輸入切換不同的設定角色,從而定位到更好的prompt輸入給模型預測

舉一個具體的例子,讓我們看一下我們在不同類型的鏈之間路由的地方,我們在這里有不同的prompt:

#第一個提示適合回答物理問題
physics_template = """你是一個非常聰明的物理學家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。
問題:{input}"""#第二個提示適合回答數學問題
math_template = """你是一個非常聰明的數學家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。
問題:{input}"""#第三個適合回答歷史問題
history_template = """你是一個非常聰明的歷史家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。
問題:{input}"""#第四個適合回答計算機問題
computerscience_template = """你是一個非常聰明的計算機學家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。
問題:{input}"""

? 在我們擁有了這些提示模板后,可以為每個模板命名,然后提供描述。例如,第一個物理學的描述適合回答關于物理學的問題,這些信息將傳遞給路由鏈,然后由路由鏈決定何時使用此子鏈。

prompt_infos = [{"name": "物理","description": "擅長回答物理問題","prompt_template": physics_template},{"name": "數學","description": "擅長回答數學問題","prompt_template": math_template},{"name": "歷史","description": "擅長回答歷史問題","prompt_template": history_template},{"name": "計算機科學","description": "擅長回答計算機科學問題","prompt_template": computerscience_template}
]

? LLMRouterChain(此鏈使用 LLM 來確定如何路由事物)
在這里,我們需要一個多提示鏈。這是一種特定類型的鏈,用于在多個不同的提示模板之間進行路由。 但是,這只是你可以路由的一種類型。你也可以在任何類型的鏈之間進行路由。

這里我們要實現的幾個類是LLM路由器鏈。這個類本身使用語言模型來在不同的子鏈之間進行路由。 這就是上面提供的描述和名稱將被使用的地方。

3.1、創建目標鏈

目標鏈是由路由鏈調用的鏈,每個目標鏈都是一個語言模型鏈:

? 將上面定義的4個鏈用LLMChain構建好,存在destination_chains里:

from langchain.chains.router import MultiPromptChain  #導入多提示鏈
from langchain.chains.router.llm_router import LLMRouterChain,RouterOutputParser
from langchain.prompts import PromptTemplatedestination_chains = {}
for p_info in prompt_infos:name = p_info["name"]prompt_template = p_info["prompt_template"]prompt = ChatPromptTemplate.from_template(template=prompt_template)chain = LLMChain(llm=llm, prompt=prompt)destination_chains[name] = chaindestinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
destinations_str = "\n".join(destinations)
destination_chains
{'物理': LLMChain(memory=None, callbacks=None, callback_manager=None, verbose=False, tags=None, prompt=ChatPromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, template='你是一個非常聰明的物理學家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。\n問題:{input}', template_format='f-string', validate_template=True), additional_kwargs={})]), llm=ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key='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', openai_api_base='', openai_organization='', openai_proxy='', request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None, tiktoken_model_name=None), output_key='text', output_parser=NoOpOutputParser(), return_final_only=True, llm_kwargs={}),'數學': LLMChain(memory=None, callbacks=None, callback_manager=None, verbose=False, tags=None, prompt=ChatPromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, template='你是一個非常聰明的數學家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。\n問題:{input}', template_format='f-string', validate_template=True), additional_kwargs={})]), llm=ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key='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', openai_api_base='', openai_organization='', openai_proxy='', request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None, tiktoken_model_name=None), output_key='text', output_parser=NoOpOutputParser(), return_final_only=True, llm_kwargs={}),'歷史': LLMChain(memory=None, callbacks=None, callback_manager=None, verbose=False, tags=None, prompt=ChatPromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, template='你是一個非常聰明的歷史家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。\n問題:{input}', template_format='f-string', validate_template=True), additional_kwargs={})]), llm=ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key='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', openai_api_base='', openai_organization='', openai_proxy='', request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None, tiktoken_model_name=None), output_key='text', output_parser=NoOpOutputParser(), return_final_only=True, llm_kwargs={}),'計算機科學': LLMChain(memory=None, callbacks=None, callback_manager=None, verbose=False, tags=None, prompt=ChatPromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, messages=[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['input'], output_parser=None, partial_variables={}, template='你是一個非常聰明的計算機學家,你擅長解答物理相關的問題。當你不知道如何解答時你應該承認你不知道。\n問題:{input}', template_format='f-string', validate_template=True), additional_kwargs={})]), llm=ChatOpenAI(cache=None, verbose=False, callbacks=None, callback_manager=None, tags=None, client=<class 'openai.api_resources.chat_completion.ChatCompletion'>, model_name='gpt-3.5-turbo', temperature=0.0, model_kwargs={}, openai_api_key='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', openai_api_base='', openai_organization='', openai_proxy='', request_timeout=None, max_retries=6, streaming=False, n=1, max_tokens=None, tiktoken_model_name=None), output_key='text', output_parser=NoOpOutputParser(), return_final_only=True, llm_kwargs={})}
destinations, destinations_str
(['物理: 擅長回答物理問題', '數學: 擅長回答數學問題', '歷史: 擅長回答歷史問題', '計算機科學: 擅長回答計算機科學問題'],'物理: 擅長回答物理問題\n數學: 擅長回答數學問題\n歷史: 擅長回答歷史問題\n計算機科學: 擅長回答計算機科學問題')

3.2、創建默認目標鏈

除了目標鏈之外,我們還需要一個默認目標鏈。這是一個當路由器無法決定使用哪個子鏈時調用的鏈。在上面的示例中,當輸入問題與物理、數學、歷史或計算機科學無關時,可能會調用它。

default_prompt = ChatPromptTemplate.from_template("{input}")
default_chain = LLMChain(llm=llm, prompt=default_prompt)

3.3、創建LLM用于在不同鏈之間進行路由的模板

這包括要完成的任務的說明以及輸出應該采用的特定格式。

#  以下輸出是LLMRouterChain的輸出keys是內置的:['destination', 'next_inputs'],所以prompt里定義好它所需的輸出MULTI_PROMPT_ROUTER_TEMPLATE = """給定一段原始輸入文本,由語言模型來選擇對于該段輸入\
文本最合適的prompt。我將給定候選prompts和對各prompt適合哪個領域的描述。\
如果您認為修改原始輸入最終會導致語言模型得到更好的響應,您也可以修改原始輸入。<<格式>>
輸出返回如下格式的json對象:
```json
{{{{"destination": string \ name of the prompt to use or "DEFAULT""next_inputs": string \ a potentially modified version of the original input
}}}}
```記住: "destination"一定要是以下候選prompts中的名字之一或者\
如果輸入不適合所有候選prompts,destination命名為 “DEFAULT”。
記住: "next_inputs"可以只是原始輸入,如果您認為不需要任何修改。<< 候選prompts>>
{destinations}<< 輸入 >>
{{input}}<< 輸出 (記住包括```json)>>
"""

3.4、構建路由鏈

首先,我們通過格式化上面定義的目標創建完整的路由器模板。這個模板可以適用許多不同類型的目標。 因此,在這里,您可以添加一個不同的學科,如英語或拉丁語,而不僅僅是物理、數學、歷史和計算機科學。

接下來,我們從這個模板創建提示模板

最后,通過傳入llm和整個路由提示來創建路由鏈。需要注意的是這里有路由輸出解析,這很重要,因為它將幫助這個鏈路決定在哪些子鏈路之間進行路由。

print(destinations_str)
router_template = MULTI_PROMPT_ROUTER_TEMPLATE.format(destinations=destinations_str
)
router_prompt = PromptTemplate(template=router_template,input_variables=["input"],output_parser=RouterOutputParser(),
)
#  LLMRouterChain的輸出keys是內置的:['destination', 'next_inputs'].
router_chain = LLMRouterChain.from_llm(llm, router_prompt)
print(router_chain.output_keys)
物理: 擅長回答物理問題
數學: 擅長回答數學問題
歷史: 擅長回答歷史問題
計算機科學: 擅長回答計算機科學問題
['destination', 'next_inputs']
router_chain('1+1=?')
{'input': '1+1=?', 'destination': '數學', 'next_inputs': {'input': '1+1=?'}}

最后,將所有內容整合在一起,創建整體鏈路:

#多提示鏈
# 設置verbose=True,我們可以看到它被路由到哪條目標prompt鏈路
chain = MultiPromptChain(router_chain=router_chain,    #路由鏈路destination_chains=destination_chains,   #目標鏈路default_chain=default_chain,      #默認鏈路verbose=True)chain.run("什么是黑體輻射?")
# 物理: {'input': '什么是黑體輻射?'}
# '黑體輻射是指一個理想化的物體,它能夠完全吸收所有入射到它上面的輻射能量,并以熱輻射的形式重新發射出來。黑體輻射的特點是其輻射能量的分布與溫度有關,即黑體輻射譜隨著溫度的升高而增強,并且在不同波長處的輻射強度也不同。根據普朗克輻射定律和斯蒂芬-玻爾茲曼定律,我們可以描述黑體輻射的性質和行為。'

Reference

  • [1] 吳恩達老師的教程
  • [2] DataWhale組織

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/162304.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/162304.shtml
英文地址,請注明出處:http://en.pswp.cn/news/162304.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

永久免費!N個excel表一鍵合并成一個表(excel表格合并技巧)

您是否還在用手工復制粘貼來將多個EXCEL或表的數據合并到一個表里&#xff1f;那就太麻煩&#xff0c;效率太低了&#xff0c;用金鳴表格文字識別的“表格合并”功能&#xff0c;可免費將N個excel文件或N個excel表一鍵合并到一個表里面&#xff0c;而且這個功能永久免費&#x…

【C++】特殊類設計 {不能被拷貝的類;只能在堆上創建的類;只能在棧上創建的類;不能被繼承的類;單例模式:懶漢模式,餓漢模式}

一、不能被拷貝的類 設計思路&#xff1a; 拷貝只會發生在兩個場景中&#xff1a;拷貝構造和賦值重載&#xff0c;因此想要讓一個類禁止拷貝&#xff0c;只需讓該類不能調用拷貝構造以及賦值重載即可。 C98方案&#xff1a; 將拷貝構造與賦值重載只聲明不定義&#xff0c;并…

FDG6306P PowerTrench? MOSFET P溝道 特點及其應用詳解

關于PowerTrench MOSFET&#xff1f; 它是一種MOS場效應晶體管&#xff0c;可以提高系統效率和功率密度。該技術采用了屏蔽柵極技術&#xff0c;可以減少開關損耗和導通損耗&#xff0c;從而提高了系統效率。此外&#xff0c;PowerTrench MOSFET還具有低導通電阻和高開關速度的…

三角洲雜志三角洲雜志社三角洲編輯部2023年第19期目錄

作家在線 李明聰 把寫作當成一種享受 李明聰; 2 頭條作品 冬天的童話 王排; 5-7 迎來春色換人間 王排; 8《三角洲》投稿&#xff1a;cnqikantg126.com 小說精選 鋼哥 曹茂炯; 9-25 重逢 莫艷陽; 26 散文現場 孩子&#xff0c;你相信光嗎&#xff1f; 趙…

前端js語音朗讀文本

<!DOCTYPE html> <html lang"zh"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>語音朗讀</title></head><body>&l…

如何滿足BMW EDI項目的PKT需求?

近期寶馬BMW&#xff08;以下簡稱BMW&#xff09;在其部分供應商之間試點推進PKT項目&#xff0c;BMW為什么要啟動 PKT 計劃呢&#xff1f; 業務系統全面升級統一全球所有寶馬工廠的流程 寶馬內部的物流供貨流程 近期BMW PKT需求主要針對其內部物流供貨流程展開&#xff1a; …

嵌入式開發--賽普拉斯cypress的鐵電存儲器FM25CL64B

嵌入式開發–賽普拉斯cypress的鐵電存儲器FM25CL64B 簡介 FM25CL64B是賽普拉斯cypress出品的一款鐵電存儲器&#xff0c;這種存儲器最大的優勢是可以像RAM一樣隨機存儲&#xff0c;和按字節寫入&#xff0c;也可以像ROM一樣掉電仍然可以保存數據&#xff0c;是一種相當優秀的…

Redis 持久化機制

client Redis[內存] --> 內存數據、磁盤數據----> 磁盤&#xff0c;Redis官方提供了兩種不同的持久化方案將內存中的數據存儲在硬盤中&#xff1a; 快照&#xff08;Snapshot&#xff09; AOF只追加日志文件。 1、快照&#xff08;Snapshot&#xff09; 1、快照的特點…

如何用CHAT解釋文章含義?

問CHAT&#xff1a;解釋“ 本身樂善好施&#xff0c;令名遠近共欽&#xff0c;待等二十左右&#xff0c;定有高親可攀&#xff1b;而且四德俱備&#xff0c;幫夫之緣亦有。主持家事不紊&#xff0c;上下亦無閑言。但四十交進&#xff0c;家內謹防口舌&#xff0c;須安家堂&…

分布式篇---第一篇

系列文章目錄 文章目錄 系列文章目錄前言一、分布式冪等性如何設計?二、簡單一次完整的 HTTP 請求所經歷的步驟?三、說說你對分布式事務的了解前言 前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到網站,這篇文章男女通用,…

非遺之光:十八數藏柏松數字保護的璀璨之路

隨著數字技術的崛起&#xff0c;非物質文化遺產的保護進入了一個新的紀元。在這個時代的先鋒中&#xff0c;十八數藏以其對傳統工藝的數字保護而獨領風騷。這是一條璀璨之路&#xff0c;通過數字技術的應用&#xff0c;為傳統工藝注入了新的活力。 十八數藏柏松將數字創新融入傳…

軟件包管理器yum和git

目錄 一、Linux軟件包管理器yum 1、Linux下的軟件安裝方法 2、了解yum 1、實際例子引入 2、yum 3、查找軟件包 4、安裝軟件包 5、卸載軟件 二、git 一、Linux軟件包管理器yum 1、Linux下的軟件安裝方法 1、在Linux下安裝軟件&#xff0c;一個通常的辦法是下載到程序的源…

c 一維數組轉為二維數組

通過數組指針來轉換 用這種方法可以把屏幕mmap 中的數據轉為二維的長乘高的數據 #include <stdio.h>int main() {int mm[5] { 0,1,2,3,4 };int (*pm)[3] (int (*)[3])mm; //pm 排 &#xff0c;[3]表示列printf("%d\n", pm[0][2]); // {0,1,2}…

經典百搭女童加絨衛衣,看的見的時尚

經典版型套頭衛衣 寬松百搭不挑人穿 單穿內搭都可以 胸口處有精美的小熊印花 面料是復合柔軟奧利絨 暖和又不顯臃腫哦&#xff01;&#xff01;

Jenkins+Maven+Gitlab+Tomcat 自動化構建打包、部署

JenkinsMavenGitlabTomcat 自動化構建打包、部署 1、環境需求 本帖針對的是Linux環境&#xff0c;Windows或其他系統也可借鑒。具體只講述Jenkins配置以及整個流程的實現。 1.JDK&#xff08;或JRE&#xff09;及Java環境變量配置&#xff0c;我用的是JDK1.8.0_144&#xff0…

排序算法--快速排序

實現邏輯 ① 從數列中挑出一個元素&#xff0c;稱為 “基準”&#xff08;pivot&#xff09;&#xff0c; ② 重新排序數列&#xff0c;所有元素比基準值小的擺放在基準前面&#xff0c;所有元素比基準值大的擺在基準的后面&#xff08;相同的數可以到任一邊&#xff09;。在這…

LoRa技術-什么是LoRa

1 概述 LoRa是創建長距離通信連接的物理層無線調制技術&#xff0c;屬于CCS&#xff08;線性調制擴頻技術&#xff09;的一種&#xff0c;工作頻段范圍在Sub-1GHz以下。相較于傳統的FSK等技術&#xff0c;LoRa在保持低功耗的同時極大地增加了通訊距離&#xff0c;且具備抗干擾…

2023年度openGauss標桿應用實踐案例征集

標桿應用實踐案例征集 2023 openGauss 數據庫作為企業IT系統的核心組成部分&#xff0c;是數字基礎設施建設的關鍵&#xff0c;是實現數據安全穩定的保障。openGauss順應開源發展趨勢&#xff0c;強化核心技術突破&#xff0c;著力打造自主根社區&#xff0c;攜手產業伙伴共同…

【開源】基于JAVA的高校實驗室管理系統

項目編號&#xff1a; S 015 &#xff0c;文末獲取源碼。 \color{red}{項目編號&#xff1a;S015&#xff0c;文末獲取源碼。} 項目編號&#xff1a;S015&#xff0c;文末獲取源碼。 目錄 一、摘要1.1 項目介紹1.2 項目錄屏 二、研究內容2.1 實驗室類型模塊2.2 實驗室模塊2.3 實…

這個問題你必須關注!網上申請的流量卡未激活是否可以更換套餐?

資費低&#xff0c;流量多&#xff0c;所以近年來在網上申請流量卡已經成了一種趨勢&#xff0c;雖然在網上申請流量卡比較方便&#xff0c;但是很多問題大家都比較迷惑&#xff0c;就比如&#xff0c;下面有私信小編的一個問題。 ?  網友咨詢&#xff0c;網上申請的流量卡…