上一篇文章我們了解了是如何透過 LangChain 來使用語言模型,分享了三個語言模型分別是 Gemini、GPT-4o、台智雲的 FFM-Llama3。然後我發文後發現 Hugging Face 也整合進 LangChain 框架了,今天 (2024/08/17) 看版本才 0.0.3,應該算是比較新整合進 LangChain,所以我應該會另外找時間加在 【Day 12】LLMs 最佳拍檔 - LangChain 🦜️🔗 中~
LangChain 最大亮點就是可以將我們所想要的東西,根據流程一個個的透過所謂的 Chain 🔗 連接起來。這個 Chain 的動作就是 LangChain 最核心的框架,被叫做 LCEL (LangChain Expression Language)。那接下來就來看看如何將我們的東西一個個的 Chain 起來吧!
LangChain 框架實作中,因為只會有不同企業推出的模型名稱不同的問題,但其實後續的 Chain 的部分都是一樣的。所以模型我會以 台智雲的 LLama3-FFM 70B
來實作,然後另外兩個 GPT 和 Gemini 會使用註解的方式補充。
我自己最主要會用到的只有三種(我看網路上別人分享也差不多),分別是 PromptTemplate
和 ChatPromptTemplate
還有 FewShotPromptTemplate
,那下面將分別進行實戰!
from langchain_core.prompts import PromptTemplate
from langchain_ffm import ChatFormosaFoundationModel
llm = ChatFormosaFoundationModel(model="ffm-llama3-70b-chat", temperature=0.01)
# from langchain_openai import ChatOpenAI
# llm = ChatOpenAI(model="gpt-4o", temperature=0)
# from langchain_google_genai import ChatGoogleGenerativeAI
# llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0)
# 一個 input
template = "介紹{input}是誰?內容要包含他們成員、出道日期和最著名的一首歌。"
# 兩種寫法都可以
prompt = PromptTemplate.from_template(template)
prompt = PromptTemplate(input_variables=["input"], template=template)
# 使用 "|" 將 Prompt 和 Model Chain 起來
chain = prompt | llm
response = chain.invoke("Aespa")
print(response.content)
# 兩個 input
template = "{league}在{year}賽季的總冠軍是誰?"
# 兩種寫法都可以
prompt = PromptTemplate.from_template(template)
prompt = PromptTemplate(input_variables=["league", "year"], template=template)
# 使用 "|" 將 Prompt 和 Model Chain 起來
chain = prompt | llm
response = chain.invoke({"league" : "NBA", "year":"2020"})
print(f"\n兩個 input 的結果:{response.content}")
程式碼結果探討 🧐:
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate
from langchain_core.messages import HumanMessage, AIMessage
prompt1 = ChatPromptTemplate.from_messages(
[
("system", "你是一位NBA的資深球迷,名字叫{name}"),
("human", "你知道NBA在2020賽季的總冠軍是誰嗎?"),
("ai", "洛杉磯湖人"),
("human", "{user_input}"),
]
)
prompt2 = ChatPromptTemplate.from_messages(
[
SystemMessagePromptTemplate.from_template("你是一位NBA的資深球迷,名字叫{name}"),
HumanMessage(content="你知道NBA在2020賽季的總冠軍是誰嗎?"),
AIMessage(content="洛杉磯湖人"),
HumanMessagePromptTemplate.from_template("{user_input}"),
]
)
messages1 = prompt1.format_messages(name="Sean", user_input="那2021賽季的呢?對了我還不知道你的名字,可以告訴我嗎?")
messages2 = prompt2.format_messages(name="Sean", user_input="那2021賽季的呢?對了我還不知道你的名字,可以告訴我嗎?")
print(messages1, '\n', messages2)
程式碼結果探討 🧐:
from langchain_core.prompts import ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate
from langchain_core.messages import HumanMessage, AIMessage
from langchain_ffm import ChatFormosaFoundationModel
llm = ChatFormosaFoundationModel(model="ffm-llama3-70b-chat", temperature=0.01)
# from langchain_openai import ChatOpenAI
# llm = ChatOpenAI(model="gpt-4o", temperature=0)
# from langchain_google_genai import ChatGoogleGenerativeAI
# llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0)
# 使用 ChatPromptTemplate 模塊
prompt = ChatPromptTemplate.from_messages(
[
SystemMessagePromptTemplate.from_template("你是一位NBA的資深球迷,名字叫{name}"),
HumanMessage(content="你知道NBA在2020賽季的總冠軍是誰嗎?"),
AIMessage(content="洛杉磯湖人"),
HumanMessagePromptTemplate.from_template("{user_input}"),
]
)
# 使用 "|" 將 Prompt 和 Model Chain 起來
chain = prompt | llm
response = chain.invoke({"name" : "Sean", "user_input" : "那2021賽季的呢?對了我還不知道你的名字,可以告訴我嗎?"})
print(response.content)
程式碼結果探討 🧐:
先解釋一下什麼是 Few Shot,他是類似於 Zero Shot 的東西。在 【Day 08】Hugging Face 文本生成實戰 我有提過 Zero Shot,AI 會根據交辦的任務自行產出我們要的結果,但是 Zero Shot 往往在過於複雜的任務中表現不佳,譬如說要求他進行一個數學的數列推理、或是中文錯字修正。那 Few Shot 其實意思差不多,但是我們給予 AI 少量的樣本提示,在提示中提供示範以引導模型實現更好的效能。所以簡單來說 Zero Shot 就是不給 AI 提示,給一個提示叫做 One Shot,給兩個叫 Two Shot,以此類推~
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_ffm import ChatFormosaFoundationModel
llm = ChatFormosaFoundationModel(model="ffm-llama3-70b-chat", temperature=0.01)
# from langchain_openai import ChatOpenAI
# llm = ChatOpenAI(model="gpt-4o", temperature=0)
# from langchain_google_genai import ChatGoogleGenerativeAI
# llm = ChatGoogleGenerativeAI(model="gemini-pro", temperature=0)
# 設定欲修正的詞 -> 現金餘額
text = "現金允額"
# zero-shot 的 prompt
template = """糾正以下文字的錯字 : {input}
修正結果 : """
prompt = PromptTemplate(input_variables=["input"], template=template)
# 使用 "|" 將 Prompt 和 Model Chain 起來
chain = prompt | llm
response = chain.invoke({"input":text})
print(f"Zero Shot 的結果\n欲修正內容 : {text}\n修正結果 : {response.content}")
# few-shot 的 prompt
template = """修正以下文字的錯字 : {input}
修正結果 : {answer}"""
example_prompt = PromptTemplate(input_variables=["input", "answer"], template=template)
# 根據上面 Prompt 的參數設定給 AI 的 few-shot
examples = [
{
"input": "通貨紅脹",
"answer": "通貨膨脹"
},
{
"input": "政府有一個獎注的補助費用",
"answer": "政府有一個獎助的補助費用"
},
{
"input": "庫藏骨",
"answer": "庫藏股"
},
]
# 使用 FewShotPromptTemplate 模塊
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="修正以下文字的錯字 : {input}",
input_variables=["input"],
)
# 使用 "|" 將 Prompt 和 Model Chain 起來
chain = prompt | llm
response = chain.invoke({"input":text})
print(f'\nFew Shot 的結果\n欲修正內容 : {text}\n修正結果 : {response.content}')
程式碼結果探討 🧐:
提示內容(examples)
和 範例模塊(example_prompt)
,那麼 suffix 是為模型提供最終的輸入提示,模型接著會根據這個新輸入來生成回應。以我這個例子來說就是最後會給 AI:修正以下文字的錯字 : 現金允額
,AI 會參考前面提示然後根據這個最後提示最修正。我們使用最常被使用到的幾個 Template,在 LangChain 架構下可以更方便的去跟 AI 互動。那大家應該有發現,將 Prompt 和 Model 鏈接起來都是透過 "|" 這個符號,在 LangChain 中他就是將各種元件 Chain 起來的。那如果你跟我一樣常常忘記 Chain 的順序應該怎麼放,譬如說為什麼先放 Prompt 再放 Model,那你可以思考看看我們一般使用模型時是會先下 Prompt,才會經過模型。所以先開始的動作,那就會在前面。如果 Chain 的東西越來越多,才不會因此而忘記順序!
今天回來屏東阿嬤家幫阿公阿嬤調整家裡的擺設,結果因為家具老舊的關係都很不好搬。結果沒想到鄰居都超熱心,有的主動來幫忙,有的直接送我們需要汰換的東西,還有幫我們處理冷氣、熱水管線的。果然熱心助人的人情味是台灣最美的風景😍
(明天要去東港吃爆生魚片!!)