上一篇測試是針對字串提示詞模板類別 PromptTemplate, 主要是用於單一句子的簡單提問, 功能類似於 f 字串, 可以快速填充模板參數得到要向 LLM 提交的訊息字串. 本篇旨在測試需要更多上下文語境的對話提示模板類別 ChatPromptTemplate 之用法.
本系列全部文章索引參考 :
本篇同樣會使用 OpenAI 與 Gemini API 來測試對話提示詞模板用法, 首先匯入所需之金鑰與外掛套件並預先建立模型物件 :
(myvenv) D:\python\test>python
Python 3.12.1 (tags/v3.12.1:2305ca5, Dec 7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from langchain_openai import ChatOpenAI
>>> from langchain_google_genai import ChatGoogleGenerativeAI
>>> from dotenv import dotenv_values
>>> config=dotenv_values('.env')
>>> openai_api_key=config.get('OPENAI_API_KEY')
>>> gemini_api_key=config.get('GEMINI_API_KEY')
>>> gpt_model=ChatOpenAI(api_key=openai_api_key, model='gpt-3.5-turbo')
>>> gemini_model=ChatGoogleGenerativeAI(api_key=gemini_api_key, model='gemini-2.5-flash')
然後從 langchain_core 匯入 prompts 子模組下的 ChatPromptTemplate 類別 (因為之前只安裝 langchain_core, 沒有安裝大禮包 langchain) :
>>> from langchain_core.prompts import ChatPromptTemplate
ChatPromptTemplate 類別的核心在於角色扮演, 它不像 PromptTemplate 那樣把所有內容塞成一個大字串, 而是將對話拆解成不同的角色訊息, 在 LangChain 的訊息物件中有三種角色 :
- System (系統) : 設定 AI 的人格, 背景, 規則 (例如 "你是一位 Python 專家")
- Human (使用者) : 你對 AI 的提問
- AI (助手) : AI 之前回覆過的內容 (用於提供對話脈絡)
呼叫 ChatPromptTemplate 類別的建構式 ChatPromptTemplate() 時, 要把對話內容依照角色拆分, 將其 system, human, 與 ai 三種角色的訊息組成元組串列傳入建構式, 傳回值為一個 ChatPromptTemplate 物件, 例如下面的翻譯對話模板 :
>>> chat_template=ChatPromptTemplate.from_messages([
("system", "你是一位專業的 {style} 翻譯員,擅長將繁體中文翻譯成優雅的 {language}。"),
("human", "請翻譯這段話:{text}"),
])
此模板中嵌入了三個模板參數 : style, language, 與 text, 填充此三個參數可以呼叫 ChatPromptTemplate 物件的兩個方法 :
- format_message() : 傳入值為個別模板參數, 傳回值為訊息物件串列
- invoke() : 傳入值為模板參數字典, 傳回值為 ChatPromptValue 物件
不論是哪一種傳回值, 都可以做為參數直接傳給模型物件的 invoke() 方法向 LLM 提交提示詞. 首先來測試使用 format_message() 來填充模板參數, 先準備要翻譯的文本 text :
>>> text='''趁著午後的陽光灑進窗台,我決定暫時放下手中的電路板與程式碼,給自己泡一杯清茶,享受這難得的靜謐時光。生活不應該只有邏輯與迴圈,還要有隨處可見的驚喜。'''
然後傳入 style, language, 與 text 參數來填充模板 :
>>> messages=chat_template.format_messages(style="出版業", language="英文", text=text)
>>> type(messages)
<class 'list'>
>>> messages
[SystemMessage(content='你是一位專業的 出版業 翻譯員,擅長將繁體中文翻譯成優雅的 英文。', additional_kwargs={}, response_metadata={}), HumanMessage(content='請翻譯這段話:趁著午後的陽光灑進窗台,我決定暫時放下手中的電路板與程式碼,給自己泡一杯清茶,享受這難得的靜謐時光。生活不應該只有邏輯與迴圈,還要有隨處可見的驚喜。', additional_kwargs={}, response_metadata={})]
可見 format_messages() 傳回一個訊息物件串列, 裡面有 SystemMessage 與 HumanMessage 等角色的訊息物件 (此對話尚未有 AIMessage 物件), 這樣就可以把填充完的訊息物件串列傳給模型的 invoke() 方法來生成回應了, 例如 GPT :
>>> response=gpt_model.invoke(messages)
>>> print(response.content)
With the afternoon sunlight streaming in through the window, I decided to temporarily set aside the circuit boards and code in my hands, brew myself a cup of clear tea, and savor this rare moment of tranquility. Life shouldn't just be about logic and loops; it should also be filled with unexpected delights at every turn.
下面是串接 Gemini 的回應 :
>>> response=gemini_model.invoke(messages)
>>> print(response.content)
以下是幾種翻譯選項,從較為直接到更為優雅的風格:
**選項一 (較為直接,但仍優雅):**
> As the afternoon sun streamed onto the windowsill, I decided to temporarily set aside my circuit board and code. I would brew myself a cup of soothing tea and savor this rare moment of tranquility. Life shouldn't be solely about logic and loops; it should also be filled with readily found surprises.
**選項二 (更為優雅,帶有文學氣息):**
> Bathed in the afternoon sun gracing the windowsill, I chose to momentarily put down my circuit board and code. A cup of fine tea beckoned, promising a rare interlude of serenity. Life, after all, should not be confined to logic and loops, but should also embrace the unexpected delights found at every turn.
**選項三 (簡潔而富有詩意):**
> With the afternoon sun warming the windowsill, I paused from my circuit board and code. A soothing cup of tea, a rare moment of quietude – these were my new companions. For life, I believe, demands more than just logic and loops; it calls for the unexpected joys that lie around every corner.
---
**選擇建議:**
* 如果希望保持原句的結構和語氣,**選項一** 是個不錯的選擇。
* 如果希望加入更多文學色彩和更豐富的詞彙,讓譯文讀起來更具美感,**選項二** 會是最佳選擇。
* 如果偏好更精煉、更具哲思的表達,**選項三** 則能達到這個效果。
我個人最推薦**選項二**,它最能體現「優雅的出版業翻譯」的要求。
接下來改用 ChatPromptTemplate 物件的 invoke() 方法來填充 :
>>> messages=chat_template.invoke({
'style': '科技業',
'language': '日文',
'text': '這支程式的執行效率非常高。'
})
>>> type(messages)
<class 'langchain_core.prompt_values.ChatPromptValue'>
>>> messages
ChatPromptValue(messages=[SystemMessage(content='你是一位專業的 科技業 翻譯員,擅長將繁體中文翻譯成優雅的 日文。', additional_kwargs={}, response_metadata={}), HumanMessage(content='請翻譯這段話:這支程式的執行效率非常高。', additional_kwargs={}, response_metadata={})])
可見傳回值是一個 ChatPromptValue 物件, 裡面包裹著 SystemMessage 與 HumanMessage 等角色的訊息物件, 可以直接把這個 ChatPromptValue 物件傳給模型的 invoke() 方法來生成回應, 例如 GPT :
>>> response=gpt_model.invoke(messages)
>>> print(response.content)
このプログラムの実行効率は非常に高いです。
也可串接 Gemini :
>>> response=gemini_model.invoke(messages)
>>> print(response.content)
這支程式的執行效率非常高。
**このプログラムは実行効率が非常に高いです。**
或者,稍微更強調性能的話:
**このプログラムの実行効率は非常に優れています。**
*(This program's execution efficiency is excellent.)*
沒有留言 :
張貼留言