langchain從入門到精通(六)——LCEL 表達式與 Runnable 可運行協議

1. 多組件 invoke 嵌套的缺點

prompt = ChatPromptTemplate.from_template("{query}")
llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
parser = StrOutputParser()
# 獲取輸出內容
content = parser.invoke(
llm.invoke(
prompt.invoke(
{"query": req.query.data}
)
)
)

這種寫法雖然能實現對應的功能,但是存在很多缺陷:

  1. 嵌套式寫法讓程序的維護性與可閱讀性大大降低,當需要修改某個組件時,變得異常困難。
  2. 沒法得知每一步的具體結果與執行進度,出錯時難以排查。
  3. 嵌套式寫法沒法集成大量的組件,組件越來越多時,代碼會變成“一次性”代碼

2. 手寫一個"Chain"優化代碼

觀察發現,雖然 Prompt、Model、OutputParser 分別有自己獨立的調用方式,例如:
Prompt 組件 :format、invoke、to_string、to_messages。
Model 組件 :generate、invoke、batch。
OutputParser 組件 :parse、invoke

但是有一個共同的調用方法:invoke,并且每一個組件的輸出都是下一個組件的輸入,是否可以將所有組件組裝得到一個列表,然后循環依次調用 invoke 執行每一個組件,然后將當前組件的輸出作為下一個組件的輸入。

from typing import Any
import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
prompt = ChatPromptTemplate.from_template("{query}")
llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
parser = StrOutputParser()
class Chain: steps: list = []
def __init__(self, steps: list): self.steps = steps
def invoke(self, input: Any) -> Any: output: Any = input
for step in self.steps: output = step.invoke(output)
print(step)
print("執行結果:", output)
print("===============")
return output
chain = Chain([prompt, llm, parser])
print(chain.invoke({"query": "你好,你是?"}))

輸出結果為:

input_variables=['query'] messages=
[HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=['query'],
template='{query}'))]
執行結果: messages=[HumanMessage(content='你好,你是?')] ===============
client=<openai.resources.chat.completions.Completions object at
0x000001C6BF694310> async_client=
<openai.resources.chat.completions.AsyncCompletions object at 0x000001C6BF695BD0> model_name='gpt-3.5-turbo-16k' openai_api_key=SecretStr('**********') openai_api_base='https://api.xty.app/v1' openai_proxy='' 執行結果: content='你好!我是 ChatGPT,一個由OpenAI開發的人工智能語言模型。我可以回答各種各樣
的問題,幫助解決問題,提供信息和創意。有什么我可以幫助你的嗎?' response_metadata=
{'token_usage': {'completion_tokens': 72, 'prompt_tokens': 13, 'total_tokens': 85}, 'model_name': 'gpt-3.5-turbo-16k', 'system_fingerprint': 'fp_b28b39ffa8',
'finish_reason': 'stop', 'logprobs': None} id='run-5bf9e183-4b28-4be9-bf65- ce0ad9590785-0' =============== 執行結果: 你好!我是 ChatGPT,一個由OpenAI開發的人工智能語言模型。我可以回答各種各樣的問題,幫
助解決問題,提供信息和創意。有什么我可以幫助你的嗎?
=============== 你好!我是 ChatGPT,一個由OpenAI開發的人工智

3. Runnable 簡介與 LCEL 表達式

為了盡可能簡化創建自定義鏈,LangChain 官方實現了一個 Runnable 協議,這個協議適用于
LangChain 中的絕大部分組件,并實現了大量的標準接口,涵蓋:

  1. stream :將組件的響應塊流式返回,如果組件不支持流式則會直接輸出。
  2. invoke :調用組件并得到對應的結果。
  3. batch :批量調用組件并得到對應的結果。
  4. astream :stream 的異步版本。
  5. ainvoke :invoke 的異步版本。
  6. abatch :batch 的異步版本。
  7. astream_log :除了流式返回最終響應塊之外,還會流式返回中間步驟。
    除此之外,在 Runnable 中還重寫了 orror 方法,這是 Python 中 | 運算符的計算邏輯,所有的 Runnable 組件,均可以通過 | 或者 pipe() 的方式將多個組件拼接起來形成一條鏈。

在這里插入圖片描述

組件輸入類型輸出類型
Prompt 提示Dict 字典PromptValue 提示值
ChatModel 聊天模型字符串、聊天消息列表、PromptValue提示值ChatMessage 聊天消息
LLM 大語言模型字符串、聊天消息列表、PromptValue提示值String 字符串
OutputParser 輸出解析器LLM 或聊天模型的輸出取決于解析器
Retriever 檢索器單個字符串List of Document 文檔列表
Tool 工具字符串、字典或取決于工具取決于工具

例如上面自定義"Chain"的寫法等同于如下的代碼:

from typing import Any
import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
prompt = ChatPromptTemplate.from_template("{query}")
llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
parser = StrOutputParser()
chain = prompt | llm | parser # 等價于以下寫法
composed_chain_with_pipe = (
RunnableParallel({"query": RunnablePassthrough()})
.pipe(prompt)
.pipe(llm)
.pipe(parser)
)
print(chain.invoke({"query": "你好,你是?"}))

Runnable 底層的運行邏輯本質上也是將每一個組件添加到列表中,然后按照順序執行并返回最終結果,這里參考核心源碼:

def invoke(self, input: Input, config: Optional[RunnableConfig] = None) -> Output:
from langchain_core.beta.runnables.context import config_with_context
# setup callbacks and context config = config_with_context(ensure_config(config), self.steps) callback_manager = get_callback_manager_for_config(config)
# start the root run
run_manager = callback_manager.on_chain_start(
dumpd(self),
input, name=config.get("run_name") or self.get_name(), run_id=config.pop("run_id", None),
)
# 調用所有步驟并逐個執行得到對應的輸出,然后作為下一個的輸入
try:
for i, step in enumerate(self.steps):
input = step.invoke(
input, # mark each step as a child run patch_config( config, callbacks=run_manager.get_child(f"seq:step:{i+1}")
),
)
# finish the root run
except BaseException as e:
run_manager.on_chain_error(e)
raise
else:
run_manager.on_chain_end(input)
return cast(Output, input)

4. 兩個Runnable核心類的講解與使用

1. RunnableParallel 并行運行

RunnableParallel 是 LangChain 中封裝的支持運行多個 Runnable 的類,一般用于操作 Runnable 的輸出,以匹配序列中下一個 Runnable 的輸入,起到并行運行 Runnable 并格式化輸出結構的作用。例如 RunnableParallel 可以讓我們同時執行多條 Chain,然后以字典的形式返回各個 Chain 的結果,對比每一條鏈單獨執行,效率會高很多。

import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
# 1.編排2個提示模板
joke_prompt = ChatPromptTemplate.from_template("請講一個關于{subject}的冷笑話,盡可能
短")
poem_prompt = ChatPromptTemplate.from_template("請寫一篇關于{subject}的詩,盡可能短")
# 2.創建大語言模型
llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
# 3.創建輸出解析器
parser = StrOutputParser()
# 4.構建兩條鏈
joke_chain = joke_prompt | llm | parser poem_chain = poem_prompt | llm | parser
# 5.使用RunnableParallel創建并行可運行
map_chain = RunnableParallel(joke=joke_chain, poem=poem_chain)
# 6.運行并行可運行組件得到響應結果
resp = map_chain.invoke({"subject": "程序員"})
print(resp)

輸出內容:

{'joke': '為什么程序員總是用尺子測電腦屏幕?因為他們聽說了“像素”是屏幕上的一種“尺寸”。',
'poem': '在代碼的海洋里徜徉,\n程序員心懷夢想與創意。\n鍵盤敲擊是旋律,\nbug 是詩歌的瑕疵。
\n\n算法如詩的韻律,\n邏輯是句子的構思。\n編程者如詩人般,\n創造出數字的奇跡。'}

除了并行執行,RunnableParallel 還可以用于操作 Runnable 的輸出,用于產生符合下一個 Runnable 組件的數據。
例如:用戶傳遞數據,并行執行檢索策略得到上下文隨后傳遞給 Prompt 組件,如下。

import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
def retrieval(query: str) -> str: """模擬一個檢索器,傳入查詢query,輸出文本""" print("執行檢索:", query)
return "我叫老鐵,是一名AI應用開發工程師。"
# 1.編排Prompt
prompt = ChatPromptTemplate.from_template("""請根據用戶的提問回答問題,可以參考對應的上下
文進行回復。
<context>
{context} <context> 用戶的問題是: {query}""")
# 2.構建大語言模型
llm = ChatOpenAI(model="gpt-3.5-turbo")
# 3.創建輸出解析器
parser = StrOutputParser()
# 4.編排鏈
chain = RunnableParallel( context=retrieval, query=RunnablePassthrough(),
) | prompt | llm | parser
# 5.調用鏈生成結果
content = chain.invoke("你好,我叫什么?")
print(content)

輸出內容:

執行檢索: 你好,我叫什么?
你好,你叫老鐵。

在創建 RunnableParallel 的時候,支持傳遞字典、函數、映射、鍵值對數據等多種方式,
RunnableParallel 底層會執行檢測并將數據統一轉換為 Runnable,核心源碼如下:

# langchain-core/runnables/base.py
def __init__( self, steps__: Optional[
Mapping[
str, Union[
Runnable[Input, Any], Callable[[Input], Any], Mapping[str, Union[Runnable[Input, Any], Callable[[Input], Any]]],
],
]
] = None, **kwargs: Union[
Runnable[Input, Any], Callable[[Input], Any], Mapping[str, Union[Runnable[Input, Any], Callable[[Input], Any]]],
],
) -> None: # 1.檢測是否傳遞字典,如果傳遞,則提取字段內的所有鍵值對
merged = {**steps__} if steps__ is not None else {}
# 2.傳遞了鍵值對,則將鍵值對更新到merged進行合并
merged.update(kwargs) super().__init__( # type: ignore[call-arg]
# 3.循環遍歷merged的所有鍵值對,并將每一個元素轉換成Runnable
steps__={key: coerce_to_runnable(r) for key, r in merged.items()}
)

除此之外,在 Chains 中使用時,可以簡寫成字典的方式, orror 會自動將字典轉換成
RunnableParallel,核心源碼:

# langchain_core/runnables/base.py
def coerce_to_runnable(thing: RunnableLike) -> Runnable[Input, Output]: """Coerce a runnable-like object into a Runnable.
Args:
thing: A runnable-like object.
Returns: A Runnable. """
if isinstance(thing, Runnable): return thing
elif is_async_generator(thing) or inspect.isgeneratorfunction(thing):
return RunnableGenerator(thing) elif callable(thing): return RunnableLambda(cast(Callable[[Input], Output], thing)) elif isinstance(thing, dict): # 如果類型為字典,使用字典創建RunnableParallel并轉換成Runnable格式
return cast(Runnable[Input, Output], RunnableParallel(thing)) else:
raise TypeError(
f"Expected a Runnable, callable or dict."
f"Instead got an unsupported type: {type(thing)}"
)

2. RunnablePassthrough 傳遞數據

除了 RunnablePassthrough,在 LangChain 中,另外一個高頻使用的 Runnable 類是RunnablePassthrough,這個類透傳上游參數輸入,簡單來說,就是可以獲取上游的數據,并保持不變或者新增額外的鍵。通常與 RunnableParallel 一起使用,將數據分配給映射中的新鍵。
例如:使用 RunnablePassthrough 來簡化 invoke 的調用流程。

import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
# 1.編排prompt
prompt = ChatPromptTemplate.from_template("{query}")
# 2.構建大語言模型
llm = ChatOpenAI(model="gpt-3.5-turbo-16k")
# 3.創建鏈
chain = {"query": RunnablePassthrough()} | prompt | llm | StrOutputParser()
# 4.調用鏈并獲取結果
content = chain.invoke("你好,你是")
print(content)

輸出內容:

你好!是的,我是ChatGPT,你需要什么幫助嗎?

RunnablePassthrough() 獲取的是整個輸入的內容(字符串或者字典),如果想獲取字典內的某個部
分,可以使用 itemgetter 函數,并傳入對應的字段名即可,如下:

from operator import itemgetter
chain = {"query": itemgetter("query")} | prompt | llm | StrOutputParser()
content = chain.invoke({"query": "你好,你是?"})

除此之外,如果想在傳遞的數據中添加數據,還可以使用 RunnablePassthrough.assign() 方法來實現快速添加。例如:為

import dotenv
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
def retrieval(query: str) -> str: """模擬一個檢索器,傳入查詢query,輸出文本""" print("執行檢索:", query)
return "我叫老鐵,是一名AI應用開發工程師。"
# 1.編排Prompt
prompt = ChatPromptTemplate.from_template("""請根據用戶的提問回答問題,可以參考對應的上下
文進行回復。
<context>
{context} <context> 用戶的問題是: {query}""")
# 2.構建大語言模型
llm = ChatOpenAI(model="gpt-3.5-turbo")
# 3.創建輸出解析器
parser = StrOutputParser()
# 4.編排鏈,RunnablePassthrough.assign寫法
chain = (
RunnablePassthrough.assign(context=lambda query: retrieval(query)) |
prompt |
llm |
parser
)
# 5.調用鏈生成結果
content = chain.invoke({"query": "你好,我叫什么?"})
print(content)

5. LangChain 中 Runnable 的進階組合用法


1. 整體流程說明

一個典型的 AI 應用鏈可以分為以下幾個模塊,每個模塊都是一個 Runnable

用戶輸入 → Prompt 模板 → LLM 模型 → 輸出解析器 → 最終輸出

2. 所需組件導入

from langchain_core.runnables import RunnableLambda, RunnableMap
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI

3. 定義 Prompt 模板(PromptTemplate)

prompt = PromptTemplate.from_template("請用中文寫一首關于{topic}的詩。")

這是一個可填充的提示模板,接收參數 topic


4. 初始化 LLM 模型(ChatOpenAI)

llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0.7)

你也可以替換為 Claude、Gemini、Qwen 等其他模型。


5. 定義輸出解析器(StrOutputParser)

parser = StrOutputParser()

用于將 LLM 的結構化輸出(如 JSON、Message)轉換為純字符串。


6. 構建完整的鏈(組合多個 Runnable)

# 將輸入 topic 映射為 prompt 所需格式
input_mapper = RunnableLambda(lambda x: {"topic": x})# 構建完整鏈條:輸入 → Prompt → LLM → 解析器
chain = input_mapper | prompt | llm | parser

7. 調用鏈條(invoke、batch、stream)

7.1 單次調用
result = chain.invoke("長城")
print(result)
7.2 批量調用
topics = ["長江", "黃山", "故宮"]
results = chain.batch(topics)
print(results)
7.3 流式輸出(逐 token 打印)
for chunk in chain.stream("泰山"):print(chunk, end="")

8. 使用 RunnableMap 處理多輸入字段

如果你的提示模板需要多個輸入字段(如 productaudience),可以使用 RunnableMap

prompt = PromptTemplate.from_template("請寫一個關于{product},面向{audience}的廣告文案。")# 輸入映射器:將用戶輸入拆分為多個字段
input_map = RunnableMap({"product": lambda x: x["product"],"audience": lambda x: x["audience"]
})# 構建鏈
chain = input_map | prompt | llm | parser# 調用
result = chain.invoke({"product": "智能手表","audience": "年輕上班族"
})
print(result)

9. 使用 OutputParser 解析 JSON 輸出(可選)

如果你的 LLM 輸出是結構化 JSON,可以使用 JsonOutputParser

from langchain.output_parsers import JsonOutputParserparser = JsonOutputParser()

然后在提示中引導模型輸出 JSON 格式:

prompt = PromptTemplate.from_template("""
請以 JSON 格式回答以下問題:
問題:{question}
輸出格式:
{{"answer": "...","confidence": "高/中/低"
}}
""")

10. 總結:鏈式組合的優勢

特性描述
可組合各模塊可自由組合、替換
可調試每個模塊可單獨測試
可擴展支持加入工具、檢索器、函數調用等
可追蹤可與 LangSmith 集成,進行鏈路追蹤

完整組合鏈一覽

from langchain_core.runnables import RunnableLambda
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI# 模塊定義
prompt = PromptTemplate.from_template("請寫一首關于{topic}的七言絕句。")
llm = ChatOpenAI(model="gpt-3.5-turbo")
parser = StrOutputParser()# 輸入映射
input_mapper = RunnableLambda(lambda x: {"topic": x})# 鏈式組合
chain = input_mapper | prompt | llm | parser# 調用鏈
print(chain.invoke("西湖"))

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

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

相關文章

ArcGIS中批量獲取輸入面圖層A中各要素的四至點的實現方法

一、背景及意義 在日常工作中&#xff0c;我們經常會需要獲取面圖層的四至點&#xff0c;我們能否在ArcGIS中直接獲取面圖層的四至點呢&#xff1f;答案是肯定的&#xff0c;請繼續往下看。 二、大體思路 使用字段計算器計算輸入面圖層A中各面要素的XY的最大值和最小值&…

大IPD之——華為的戰略本質與實踐(二)

華為戰略執行的能力如此強&#xff0c;有兩個核心原因&#xff1a;一是管理體系起了非常重大的作用&#xff1b;二是企業文化導致華為的執行力特別強。華為在戰略方面&#xff0c;為什么每次都能轉型成功&#xff1f;背后是有很多實質性的內容支撐的。而華為如何做戰略&#xf…

『大模型筆記』第3篇:多長的 Prompt 會阻塞其他請求?優化策略解析

『大模型筆記』多長的 Prompt 會阻塞其他請求?優化策略解析 文章目錄 一、更簡單的問題:長 Prompt 阻塞請求隊列1. 請求并行預填方案(Request-Parallel Prefills)二、根本的問題(Fundamental Flaw):Token 生成被并行預填拖慢1. 解耦預填(Disaggregated Prefill):以延遲優…

21 - GAM模塊

論文《Global Attention Mechanism: Retain Information to Enhance Channel-Spatial Interactions》 1、作用 這篇論文提出了全局注意力機制&#xff08;Global Attention Mechanism, GAM&#xff09;&#xff0c;旨在通過保留通道和空間方面的信息來增強跨維度交互&#xf…

Java01--使用IDEA編寫運行第一個Java程序HelloWorld

一.先新建一個文件夾存放項目(后續可以推送到Gitee) 二.創建項目 1.打開IDEA&#xff0c;點擊首頁的新建項目 2.新建空項目并命名&#xff0c;存放路徑為步驟一創建的文件夾&#xff1a; 3.在新項目中新建一個src文件夾&#xff08;用于集中管理文件&#xff09; 4.在src文件夾…

目標檢測相關【清晰易懂】

目標檢測相關 &#xff08;b&#xff09;是語義分割&#xff0c;&#xff08;c&#xff09;是實例分割 目標檢測 每個目標一個框標簽 實例分割 語義分割 識別每一個目標個體 目標檢測基礎上進一步提升模型能力有兩個方向&#xff1a;實例分割、旋轉目標檢測。 實例分割 …

強化學習 A2C算法

3.actor-critic方法 3.1 Reinforce 算法&#xff0c;也稱為蒙特卡洛策略梯度。蒙特卡洛方差 第一節介紹了DQN 在上一節基于策略的方法中&#xff0c;我們的目標是直接優化策略&#xff0c;而無需使用價值函數。更準確地說&#xff0c;Reinforce 是 基于策略的方法 的一個子類…

關于MCU、MPU、SoC、DSP四大類型芯片

目錄 MCU、MPU、SoC、DSP四大類型芯片分析 一、MCU 1、概念 2、特點 3、常見芯片 4、應用場景 二、MPU 1、概念 2、特點 3、常見芯片 4、應用場景 三、SoC 1、概念 2、特點 3、常見芯片 4、應用場景 四、DSP 1、概念 2、特點 3、常見芯片 4、應用場景 MCU、…

【數據結構】圖論最短路圣器:Floyd算法如何用雙矩陣征服負權圖?

最短路徑 穿越負權迷霧&#xff1a;Floyd算法如何解鎖全圖最短路徑&#xff1f;??一、Floyd算法1.1 算法思想1.2 算法邏輯1.3 算法評價1.4 算法限制 二、三種算法對比&#x1f31f;結語 穿越負權迷霧&#xff1a;Floyd算法如何解鎖全圖最短路徑&#xff1f;?? 大家好&…

寶塔面板集成阿里云 OSS 備份失敗的解決方案

寶塔面板集成阿里云OSS備份失敗的解決方案 一、問題背景 在使用寶塔面板配置阿里云OSS云存儲備份功能時,用戶遇到如下錯誤: Traceback (most recent call last):File "class/CloudStoraUpload.py", line 144, in __init__from alioss_main import OSSClient as ocFile "…

如何安全高效地維護CMS智能插件?

作為網站開發者或運維人員&#xff0c;你是否經歷過這樣的場景&#xff1a;滿懷期待地點擊了插件“更新”按鈕&#xff0c;刷新頁面后卻看到一片刺眼的500錯誤&#xff1f;或發現網站加載速度從2秒驟降到10秒&#xff1f;智能插件為CMS系統&#xff08;如WordPress、Drupal、億…

FastAPI如何用角色權限讓Web應用安全又靈活?

title: FastAPI如何用角色權限讓Web應用安全又靈活? date: 2025/06/13 05:46:55 updated: 2025/06/13 05:46:55 author: cmdragon excerpt: 基于角色的路由訪問控制是Web應用中常見的安全控制模式,通過為用戶分配特定角色來管理權限。FastAPI利用依賴注入系統實現權限控制…

利用 SpreadJS 優化表格渲染性能

引言 在當今的數據驅動時代&#xff0c;表格作為一種重要的數據展示和交互方式&#xff0c;廣泛應用于各類 Web 應用中。然而&#xff0c;當表格數據量增大或操作復雜度提高時&#xff0c;渲染性能往往會成為一個關鍵問題。SpreadJS 作為一款功能強大的純前端電子表格控件&…

狀態檢查常用SQL

使用MySQL自身命令獲取數據庫服務狀態。 連接數 -- 最大使用連接數 show status like Max_used_connections; -- 系統配置的最大連接數 show global variables like %max_connections; -- 當前打開的連接數 show status like Threads_connected; 緩存 -- 未從緩沖池讀取的次…

【Mac 上離線安裝 ADB 工具】

? 一、步驟總覽&#xff08;離線安裝 ADB&#xff09; 下載 ADB 離線包&#xff08;zip 文件&#xff09;解壓到一個固定位置&#xff08;比如 ~/adb&#xff09;配置環境變量驗證安裝是否成功 ? 二、步驟詳情&#xff08;假設你已經下載好了 zip 文件&#xff09; &#x1…

什么是數據倉庫的ETL

ETL詳解&#xff1a;數據整合的核心技術 1. 什么是ETL&#xff1f; ETL&#xff08;Extract, Transform, Load&#xff09;是數據倉庫和數據分析領域的核心數據處理流程&#xff0c;指從不同數據源**抽取&#xff08;Extract&#xff09;數據&#xff0c;經過清洗轉換&#x…

數字ic后端設計從入門到精通8(含fusion compiler, tcl教學)ULVTLL、LVT、ULVT詳解及應用

LVT vs ULVT vs ULVTLL:從PPA、成本的角度出發 比較維度LVTULVTULVTLL閾值電壓(Vth)中等低極低但經過優化減少泄漏開關速度中等快略慢于ULVT但優于LVT驅動能力較低高較高,略低于ULVT漏電流較低高顯著低于ULVT動態功耗中等低低靜態功耗低高低面積小小略大(因需額外技術減少泄…

Jupyter notebook中的感嘆號!魔法命令介紹

背景&#xff1a; 之前用過anaconda conda創建過虛擬環境&#xff0c;也用過venv虛擬環境&#xff0c;也搭建過Jupyter notebook環境&#xff0c;但是今天看到下列的代碼&#xff0c;不清楚感嘆號代表什么。 如&#xff1a; !python -m venv signlang_env 解答&#xff1a; &a…

mysql 數值函數 介紹

MySQL 提供了多種數值函數&#xff0c;用于處理和操作數值數據。以下是一些常見的 MySQL 數值函數的介紹和使用示例&#xff1a; 1. ABS() 功能&#xff1a;返回一個數值的絕對值。語法&#xff1a;ABS(number)示例&#xff1a; SELECT ABS(-5); -- 輸出&#xff1a; 5 2. …

HBase 安裝與簡單操作指南

一、安裝前準備 1. 系統要求 Java 1.8+Hadoop 2.x/3.x (已配置并運行,偽分布式或全分布式)SSH 免密登錄配置完成確保系統主機名解析正確2. 下載 HBase 最新穩定版下載地址: wget https://downloads.apache.org/hbase/2.4.11/hbase-2.4.11-bin.tar.gz 二、安裝步驟 1. 解…