2024年9月16日 星期一

OpenAI API 學習筆記 : 使用 openai 套件串接 GPT 語言模型 (二) 儲值

由於月底茶米老師要來我司授課 (OpenAI API), 我之前用爸及菁菁手機申請 OpenAI 帳號時獲得的 5 美元免費額度都早已超過三個月失效了, 所以今天改用我的備用手機 iPhone 門號與 Gmail 註冊 OpenAI 帳戶與申請 API Key 先來練習一下. 

本系列之前的文章參考 :



1. 註冊 OpenAI 帳戶與申請 API Key :

連線登入網址 :

 
按右下角的 "註冊" :



填寫 Email 按 "繼續" :


設定長度至少 12 字元的密碼按 "繼續" : 



去信箱開啟驗證信函, 按 "驗證電子郵件地址" : 




填寫個資按 "同意" 即完成註冊 :




自動進入 Overview 頁面 :





2. 申請 API Key :

按右上角的姓氏按鈕, 點選 Profile :




點選 User API keys :




按 Start verification 鈕 :




輸入手機號碼 : 




讀取手機收到的 6 位數驗證碼後輸入框框中 : 




結果顯示因為此手機門號已綁定了一個 OpenAI 帳號, 所以不會有免費額度可用 :




蛤? 此門號從未拿來用過啊? 奇怪. 按 Continue 輸入 API key 的名稱, 按 Create secret key :




先按右邊的 Copy 鈕將 API key 複製到記事本檔案中保存 : 




因為之前已用 pip instal openai 安裝過套件, 馬上匯入 OpenAI 類別來測試, 結果出現錯誤訊息  :

>>> from openai import OpenAI     
>>> api_key='輸入 API Key'    
>>> client=OpenAI(api_key=api_key)       
>>> chat_completion=client.chat.completions.create(
    messages=[
        {"role": "user",
         "content": "請問愛情是甚麼?",
        }],
    model="gpt-3.5-turbo",
    )   
... (略) ...
    raise self._make_status_error_from_response(err.response) from None
openai.RateLimitError: Error code: 429 - {'error': {'message': 'You exceeded your current quota, please check your plan and billing details. For more information on this error, read the docs: https://platform.openai.com/docs/guides/error-codes/api-errors.', 'type': 'insufficient_quota', 'param': None, 'code': 'insufficient_quota'}}   

'insufficient_quota' 意思是儲值不足啦! 點選左邊導覽列 Overview 底下的 Billing, 發現 Credit remaining 為 0 :




但我這支 iPhone 手機門號從未用來綁 OpenAI 帳戶啊? 查詢網路才知道, 原來今年三月下旬起 OpenAI 就不再贈送新用戶 5 美元免費體驗額度啦! 參考 :



3. 儲值 OpenAI API 帳戶 : 

若要繼續使用 OpenAI API 必須儲值為付費帳戶, 每次最低 5 美元以上, 用多少 token 扣多少費用 (pay as you go), 直到 credits 扣到 0 再儲值即可. 

按 Profile/Billing 的 Add payment details : 




選擇 Indivisuals :





填寫信用卡卡號等資訊後按 Continue : 




選擇儲值額度, 建議 5 或 10 美元即可, 關閉自動扣款 :




按 Cinfirm payment 完成儲值 :




這時回到 Profile/Billings 就會發現可用額度已變成 10 美元了 : 




再次測試 API 呼叫就能順利取得回應了 : 

>>> from openai import OpenAI     
>>> api_key='輸入 API Key'    
>>> client=OpenAI(api_key=api_key)       
>>> chat_completion=client.chat.completions.create(
    messages=[
        {"role": "user",
         "content": "請問愛情是甚麼?",
        }],
    model="gpt-3.5-turbo",
    )   
>>> chat_completion.choices[0].message.content   
'愛情是一種情感和情緒上的連結,通常是指對另一個人產生深厚的感情和依戀,願意為對方付出和犧牲。愛情包含了關心、尊重、信任、支持和忠誠,是人們之間最重要和特別的情感連結。愛情能夠讓人感到幸福、滿足和安心,同時也需要雙方共同的努力和維護。'

這時去查看 Billing 發現已用掉 0.01 美元, 問這一點點就要 3 元台幣, 好像不便宜咧. 

momo購買電扇與藍芽耳機

高雄家電腦桌旁的桌上型電扇上周壞掉了, 昨晚上 momo 買了一個新的, 順便又買了一個藍芽耳機 : 







2024年9月15日 星期日

露天購買 F9無線藍牙耳機

今天傍晚與水某回鄉下時發現放在車上的單聲道藍芽耳機無法連線, 可能是太舊了. 今天上露天買了一組打算放在車上 :





萊爾富取貨免運 198 元. 

這 F9 應該是舊款, 新款 F10 貴 100 塊 : 


不過我剛開始本來是想在 momo 買下面這個電競款超長續航的, 現在打 85 折 :


不過呼吸燈也太搶眼了, 下面這個長續航的也是 85 折 :


2024年9月14日 星期六

如何在 Colab 解壓縮 zip 檔

當要上傳很多檔案到 Colab 時, 一個一個上傳會很花時間, 最好是將這些檔案在本機壓縮成 zip 檔上傳 Colab 後再解壓縮. 

本系列之前的文章參考 :


首先在本機中將要上傳的檔案壓縮成 zip 檔, 例如要辨識的車牌圖檔 : 




按 Colab 檔案管理框上面的上傳按鈕, 點選要上傳的 zip 檔 :





可見 plates.zip 已上傳至 Colab 的預設資料夾 /content 下了. 

在 Colab 中解壓縮 zip 檔有兩個做法 : 


1. 使用 !unzip 指令 :

語法如下 :

!unzip 壓縮檔路徑檔名 -d 解壓目的地資料夾路徑

如果沒有指定資料夾路徑的話, 預設就是根目錄下的 /content 資料夾, 此處我想將解壓縮後的檔案放在 /content/plates 下, 所以先在檔案管理框按滑鼠右鍵點選 "新增資料夾", 然後輸入 plates :





然後在儲存格輸入下列指令 :

!unzip plates.zip -d plates    

也可以明確加上路徑 :

!unzip /content/plates.zip -d /content/plates    




這樣便完成解壓縮了. 點擊 ABC5678.jpg 會在最右邊顯示此車牌圖檔 :




2. 使用 zipfile 模組解壓縮 : 

zipfile 是 Python 的內建模組, 裡面有一個 ZipFile 類別可用來解壓縮 zip 檔, 呼叫其建構式 ZipFile() 並傳入 zip 檔之路徑檔名以 'r' 模式開啟 zip 檔後, 呼叫檔案參考物件之 extractall() 方法即可, 語法如下 :

with ZipFile('zip 檔之路徑檔名', 'r') as z : 
    z.extractall('目的地資料夾路徑') 

先在 Colab 檔案管理框預設資料夾 /content 下新增一個 plates2 資料夾來存放解壓後之圖檔 :




然後在程式碼儲存格輸入下列指令 :

from zipfile import ZipFile
with ZipFile('plates.zip', 'r') as z:
    z.extractall('plates2')

執行後檢查 plates2 資料夾果然圖檔都已解壓在此 :




如前所述, 當 Colab 連線終止時這些上傳到 Linux 虛擬機器上的資料都會被清掉, 所以也不需要特地去刪除. 但如果有節省儲存空間考量需動態刪除不用的資料夾, 可以用 shutil 模組的 rmtree() 函式來刪除 :

import shutil  
shutil.rmtree('plates2')  




可見 plates2 資料夾已被刪除. 注意, 如果是手動操作, Colab 的檔案管理框無法直接刪除一個裡面還有檔案的資料夾, 必須將裡面的檔案一一刪除成為空資料夾後才能刪除它. 

2024年9月13日 星期五

如何管理 Colab 上的檔案 (上傳/下載/更名/刪除)

谷歌 Colab 平台是非常方便好用的 Python 應用執行環境, 只要連線其 Linux 虛擬機器, 即可用與本機 Jupyter Notebook 一樣的操作方式執行 Python 程式碼. 如果執行程式時需要用到外部檔案, 則必須上傳到 Colab 虛擬機器的檔案系統下才行.

本系列之前的文章參考 :

如何在 Colab 開啟終端機 (xterm)

首先開啟 Colab 的 ipynb 筆記本檔案, 如果尚未連線則要按右上角的連線按鈕 : 





連線完成會顯示 "已連線" 或 RAM/磁碟使用情形 : 




然後按左邊導覽列上的檔案系統按鈕 (已連線狀態下按此按鈕才會出現檔案管理框) : 




這時就會出現一個檔案管理框, 內建已經有一個 sample_data 資料夾, 點一下開啟它會看到裡面預設已經放了好幾個資料科學常用的 .csv 與 .json 資料集 :




點擊這些檔案會在頁面最右端顯示檔案內容, txt 或 json 會以純文字編輯器開啟, 可以在上面編輯內容 (具備自動存檔功能) :




如果是 csv 檔則以網頁表格顯示, 無法線上編輯 :




如果是圖檔也是會在網頁中顯示此圖片. 

按一下檔案管理框最上面的上一層 .. 鈕會往上跳一層到系統根目錄, 其下的 /content 就是 Colab 的預設資料夾, 如果沒有特別切會, 上傳的檔案會放在 /content 下. 

但如果是在根目錄下上傳, 檔案會被放在 /var 資料夾下, 例如我在根目錄下上傳一張車牌圖檔 333-AD.jpg, 會先出現一個提醒視窗, 表示上傳到 Colab 的任何檔案都會在連線結束時連同虛擬機器一起被清掉 (連線時間最長是 12 小時) :




上傳到根目錄的檔案會被放在 /var 資料夾下 :




如果是在預設資料夾下上傳, 則檔案會放在 /content 下 : 




點選檔案右邊的三個點按鈕可以對該檔案進行下載/刪除/改名等操作 :





注意, Colab 虛擬機器檔案系統中的檔案都會在連線終止時消失, 因此若使用 Colab 跑 Python 程式, 需注意連線逾時問題即時下載或備份至雲端硬碟, 避免產生的資料因為連線終止而消失. 

而 ipynb 筆記本檔案則是存放於雲端硬碟的 Colab Notebooks 資料夾下面, 不會隨虛擬機器連線終止而消失 : 




2024年9月12日 星期四

高科大還書兩本 : 一行指令學 Python & PyTorch深度學習攻略

今天下班順路去母校還下面兩本書 (有人預約) : 


最近在研究 LLM, 這兩本也沒時間看, 就提前還了. 

Google Gemini API 文字聊天測試 (一)

八月下旬上徐爸的 ESP32-CAM 課程時因要用到 AI 大語言模型申請了 Google Gemini API 金鑰, 並使用 Postman 以 HTTP POST 請求測試聊天功能, 作法參考這篇 :  

前幾天忙完 Groq 上的 llama3 模型測試, 今天開始要來測試與 Groq 同樣是免費的 Google Gemini API, 官方有提供完整的教學文章 : 


網路上也有許多大神提供指引, 參考 :



1. 安裝 google-generativeai 套件 : 

直接用 pip install 指令安裝 : 

D:\python\test>pip install google-generativeai    
Collecting google-generativeai
  Downloading google_generativeai-0.8.0-py3-none-any.whl.metadata (3.9 kB)
Collecting google-ai-generativelanguage==0.6.9 (from google-generativeai)
  Downloading google_ai_generativelanguage-0.6.9-py3-none-any.whl.metadata (5.6 kB)
Collecting google-api-core (from google-generativeai)
  Downloading google_api_core-2.19.2-py3-none-any.whl.metadata (2.7 kB)
Collecting google-api-python-client (from google-generativeai)
  Downloading google_api_python_client-2.145.0-py2.py3-none-any.whl.metadata (6.7 kB)
Requirement already satisfied: google-auth>=2.15.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-generativeai) (2.22.0)
Requirement already satisfied: protobuf in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-generativeai) (4.24.2)
Requirement already satisfied: pydantic in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-generativeai) (2.5.3)
Requirement already satisfied: tqdm in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-generativeai) (4.66.1)
Requirement already satisfied: typing-extensions in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-generativeai) (4.9.0)
Collecting proto-plus<2.0.0dev,>=1.22.3 (from google-ai-generativelanguage==0.6.9->google-generativeai)
  Downloading proto_plus-1.24.0-py3-none-any.whl.metadata (2.2 kB)
Collecting googleapis-common-protos<2.0.dev0,>=1.56.2 (from google-api-core->google-generativeai)
  Downloading googleapis_common_protos-1.65.0-py2.py3-none-any.whl.metadata (1.5 kB)
Requirement already satisfied: requests<3.0.0.dev0,>=2.18.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-api-core->google-generativeai) (2.31.0)
Requirement already satisfied: cachetools<6.0,>=2.0.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-auth>=2.15.0->google-generativeai) (5.3.1)
Requirement already satisfied: pyasn1-modules>=0.2.1 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-auth>=2.15.0->google-generativeai) (0.3.0)
Requirement already satisfied: rsa<5,>=3.1.4 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-auth>=2.15.0->google-generativeai) (4.9)
Requirement already satisfied: six>=1.9.0 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from google-auth>=2.15.0->google-generativeai) (1.16.0)
Requirement already satisfied: urllib3<2.0 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from google-auth>=2.15.0->google-generativeai) (1.26.19)
Requirement already satisfied: httplib2<1.dev0,>=0.19.0 in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from google-api-python-client->google-generativeai) (0.22.0)
Collecting google-auth-httplib2<1.0.0,>=0.2.0 (from google-api-python-client->google-generativeai)
  Downloading google_auth_httplib2-0.2.0-py2.py3-none-any.whl.metadata (2.2 kB)
Collecting uritemplate<5,>=3.0.1 (from google-api-python-client->google-generativeai)
  Downloading uritemplate-4.1.1-py2.py3-none-any.whl.metadata (2.9 kB)
Requirement already satisfied: annotated-types>=0.4.0 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pydantic->google-generativeai) (0.5.0)
Requirement already satisfied: pydantic-core==2.14.6 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pydantic->google-generativeai) (2.14.6)
Requirement already satisfied: colorama in c:\users\tony1\appdata\local\programs\thonny\lib\site-packages (from tqdm->google-generativeai) (0.4.6)
Requirement already satisfied: grpcio<2.0dev,>=1.33.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-ai-generativelanguage==0.6.9->google-generativeai) (1.57.0)
Collecting grpcio-status<2.0.dev0,>=1.33.2 (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-ai-generativelanguage==0.6.9->google-generativeai)
  Downloading grpcio_status-1.66.1-py3-none-any.whl.metadata (1.1 kB)
Requirement already satisfied: pyparsing!=3.0.0,!=3.0.1,!=3.0.2,!=3.0.3,<4,>=2.4.2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from httplib2<1.dev0,>=0.19.0->google-api-python-client->google-generativeai) (3.0.9)
Requirement already satisfied: pyasn1<0.6.0,>=0.4.6 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from pyasn1-modules>=0.2.1->google-auth>=2.15.0->google-generativeai) (0.5.0)
Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests<3.0.0.dev0,>=2.18.0->google-api-core->google-generativeai) (3.2.0)
Requirement already satisfied: idna<4,>=2.5 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests<3.0.0.dev0,>=2.18.0->google-api-core->google-generativeai) (3.4)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\tony1\appdata\roaming\python\python310\site-packages (from requests<3.0.0.dev0,>=2.18.0->google-api-core->google-generativeai) (2023.7.22)
Collecting protobuf (from google-generativeai)
  Downloading protobuf-5.28.1-cp310-abi3-win_amd64.whl.metadata (592 bytes)
Collecting grpcio<2.0dev,>=1.33.2 (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-ai-generativelanguage==0.6.9->google-generativeai)
  Downloading grpcio-1.66.1-cp310-cp310-win_amd64.whl.metadata (4.0 kB)
Downloading google_generativeai-0.8.0-py3-none-any.whl (163 kB)
Downloading google_ai_generativelanguage-0.6.9-py3-none-any.whl (725 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 725.4/725.4 kB 3.7 MB/s eta 0:00:00
Downloading google_api_core-2.19.2-py3-none-any.whl (139 kB)
Downloading google_api_python_client-2.145.0-py2.py3-none-any.whl (12.2 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.2/12.2 MB 6.3 MB/s eta 0:00:00
Downloading google_auth_httplib2-0.2.0-py2.py3-none-any.whl (9.3 kB)
Downloading googleapis_common_protos-1.65.0-py2.py3-none-any.whl (220 kB)
Downloading proto_plus-1.24.0-py3-none-any.whl (50 kB)
Downloading uritemplate-4.1.1-py2.py3-none-any.whl (10 kB)
Downloading grpcio_status-1.66.1-py3-none-any.whl (14 kB)
Downloading protobuf-5.28.1-cp310-abi3-win_amd64.whl (431 kB)
Downloading grpcio-1.66.1-cp310-cp310-win_amd64.whl (4.3 MB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.3/4.3 MB 6.0 MB/s eta 0:00:00
Installing collected packages: uritemplate, protobuf, grpcio, proto-plus, googleapis-common-protos, grpcio-status, google-auth-httplib2, google-api-core, google-api-python-client, google-ai-generativelanguage, google-generativeai
  Attempting uninstall: protobuf
    Found existing installation: protobuf 4.24.2
    Uninstalling protobuf-4.24.2:
      Successfully uninstalled protobuf-4.24.2
  Attempting uninstall: grpcio
    Found existing installation: grpcio 1.57.0
    Uninstalling grpcio-1.57.0:
      Successfully uninstalled grpcio-1.57.0
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
streamlit 1.27.0 requires protobuf<5,>=3.20, but you have protobuf 5.28.1 which is incompatible.
tensorflow-intel 2.13.0 requires protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<5.0.0dev,>=3.20.3, but you have protobuf 5.28.1 which is incompatible.
tensorflow-intel 2.13.0 requires typing-extensions<4.6.0,>=3.6.6, but you have typing-extensions 4.9.0 which is incompatible.
Successfully installed google-ai-generativelanguage-0.6.9 google-api-core-2.19.2 google-api-python-client-2.145.0 google-auth-httplib2-0.2.0 google-generativeai-0.8.0 googleapis-common-protos-1.65.0 grpcio-1.66.1 grpcio-status-1.66.1 proto-plus-1.24.0 protobuf-5.28.1 uritemplate-4.1.1

出現 protobuf 與 tensorflow-intel 這兩個相依套件的版本相容性問題, 但不影響使用 Gemini API.

檢視版本 :

>>> import google.generativeai as genai   
>>> genai.__version__     
'0.8.0'   

檢視套件內容 : 

>>> dir(genai)   
['ChatSession', 'GenerationConfig', 'GenerativeModel', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', 'annotations', 'caching', 'configure', 'create_tuned_model', 'delete_file', 'delete_tuned_model', 'embed_content', 'embed_content_async', 'get_base_model', 'get_file', 'get_model', 'get_operation', 'get_tuned_model', 'list_files', 'list_models', 'list_operations', 'list_tuned_models', 'protos', 'responder', 'string_utils', 'types', 'update_tuned_model', 'upload_file', 'utils']

使用自訂模組 members 檢視套件內容 : 

# members.py
import inspect 
def varname(x): 
    return [k for k,v in inspect.currentframe().f_back.f_locals.items() if v is x][0]
def list_members(parent_obj):
    members=dir(parent_obj)
    parent_obj_name=varname(parent_obj)       
    for mbr in members:
        child_obj=eval(parent_obj_name + '.' + mbr) 
        if not mbr.startswith('_'):
            print(mbr, type(child_obj))

參考 : 


>>> from members import list_members   
>>> list_members(genai)    
ChatSession <class 'type'>
GenerationConfig <class 'type'>
GenerativeModel <class 'type'>
annotations <class '__future__._Feature'>
caching <class 'module'>
configure <class 'function'>
create_tuned_model <class 'function'>
delete_file <class 'function'>
delete_tuned_model <class 'function'>
embed_content <class 'function'>
embed_content_async <class 'function'>
get_base_model <class 'function'>
get_file <class 'function'>
get_model <class 'function'>
get_operation <class 'function'>
get_tuned_model <class 'function'>
list_files <class 'function'>
list_models <class 'function'>
list_operations <class 'function'>
list_tuned_models <class 'function'>
protos <class 'module'>
responder <class 'module'>
string_utils <class 'module'>
types <class 'module'>
update_tuned_model <class 'function'>
upload_file <class 'function'>
utils <class 'module'>

這裡面主要會用到的是 configure() 函式與 GenerativeModel 類別, configure() 用來傳入 API 金鑰進行認證; GenerativeModel 則是用來建立指定模型之 GenerativeModel 物件以便進行聊天. 


2. 使用 API key 認證 : 

在進行聊天之前必須先呼叫 configure() 函式並傳入 api_key 參數進行認證, 為了避免金鑰洩漏, 可以將金鑰存入目前工作目錄下的隱藏檔 .env 內並取一個名稱例如 GEMINI_API_KEY : 




然後使用內建的 os 模組與第三方模組 dotenv 從 .env 檔中讀取指定名稱的金鑰 :

>>> import os   
>>> from dotenv import load_dotenv    
>>> load_dotenv()      
True 
>>> api_key=os.environ.get('GEMINI_API_KEY')      
>>> api_key   
'API KEY 在此'

然後呼叫 configure() 函式並傳入此金鑰 : 

>>> genai.configure(api_key=api_key)   

如果沒出現錯誤訊息表示金鑰認證成功. 


3. 建立 GenerativeModel 物件 : 

接下來就可以呼叫 GenerativeModel 類別的建構式 GenerativeModel() 並傳入模型名稱來建立 GenerativeModel 物件, 目前可用的模型如下 :


 模型名稱 說明
 gemini-1.5-pro 中型多模態模型, 可處理 2 小時影片, 19 小時音訊, 6 萬行程式碼, 2000 頁文本
 gemini-1.5-flash 輕量快速多模態模型, 可處理 1 小時影片, 9.5 小時音訊


例如 :

>>> model=genai.GenerativeModel('gemini-1.5-flash')    
>>> type(model)   
<class 'google.generativeai.generative_models.GenerativeModel'>

用 dir() 檢視這個 GenerativeModel 物件內容 : 

>>> dir(model)     
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_async_client', '_client', '_generation_config', '_get_tools_lib', '_model_name', '_prepare_request', '_safety_settings', '_system_instruction', '_tool_config', '_tools', 'cached_content', 'count_tokens', 'count_tokens_async', 'from_cached_content', 'generate_content', 'generate_content_async', 'model_name', 'start_chat']

用上面的自訂模組 members 檢視 : 

>>> from members import list_members   
>>> list_members(model)      
cached_content <class 'NoneType'>
count_tokens <class 'method'>
count_tokens_async <class 'method'>
from_cached_content <class 'method'>
generate_content <class 'method'>
generate_content_async <class 'method'>
model_name <class 'str'>
start_chat <class 'method'>

此 GenerativeModel 物件主要用來聊天的 API 為 generate_content() 與 generate_content_async() 方法, 兩者差別為同步/非同步呼叫. 呼叫時傳入提示詞會傳回一個 GenerateContentResponse 物件, 例如 :

>>> reply=model.generate_content('請簡單介紹量子力學與古典力學差別.')  
>>> type(reply)   
<class 'google.generativeai.types.generation_types.GenerateContentResponse'>    

回應文本會放在此物件的 text 屬性中 : 

>>> print(reply.text)     
## 量子力學 vs. 古典力學:簡單介紹

**古典力學** 描述的是宏觀世界,也就是我們日常生活中所見的物體的運動。它遵循牛頓定律,認為物體的位置和速度可以被精確測量,並且可以預測它們未來的運動。

**量子力學** 則是描述微觀世界,例如原子、電子和光子等。它與古典力學的區別在於:

* **量子化:** 在量子力學中,能量、動量、角動量等物理量只能取特定的離散值,而不是連續的。例如,電子在原子中只能處於特定的能級,而不是可以任意地取值。
* **波粒二象性:** 量子力學認為光子和電子等粒子同時具有波和粒子的性質。
* **不確定性原理:** 海森堡不確定性原理指出,我們無法同時精確地測量粒子的位置和動量。

**簡單總結:**

* 古典力學:適用於宏觀世界,可精確預測物體的運動。
* 量子力學:適用於微觀世界,描述粒子具有波粒二象性和不確定性。

**舉例:**

* 古典力學可以描述足球的運動軌跡。
* 量子力學可以描述原子中電子的能量狀態。

**補充說明:**

* 古典力學是量子力學的一個特例,當物體尺度很大時,量子效應可以忽略,古典力學就可以很好地描述其運動。
* 量子力學是現代物理學的基礎,它解釋了許多古典力學無法解釋的現象,例如原子光譜、半導體等。

可見 Gemini 的回應還不錯. 

但是如果問它 "愛情是甚麼?" 竟然出現錯誤訊息 :

>>> reply=model.generate_content('請問愛情是甚麼?')   
>>> print(reply.text)      
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\tony1\AppData\Local\Programs\Thonny\lib\site-packages\google\generativeai\types\generation_types.py", line 436, in text
    raise ValueError(
ValueError: Invalid operation: The `response.text` quick accessor requires the response to contain a valid `Part`, but none were returned. Please check the `candidate.safety_ratings` to determine if the response was blocked.

原因是這個提示詞被 Gemini 的預設安全設定阻擋了, 使得回應訊息中沒有 Part 這個屬性所致, 這是因為 Gemini 對於回應訊息的安全與否非常慎重, Gemini 有一個安全性過濾器用來篩選不安全或具有危害的回應, 關於安全性設定參考官網說明 :


我們可以在呼叫 generate_content() 時傳入一個 ssfety_settings 參數字典來關閉它們, 參考 :


>>> safety_settings={
        'HATE': 'BLOCK_NONE',
        'HARASSMENT': 'BLOCK_NONE',
        'SEXUAL' : 'BLOCK_NONE',
        'DANGEROUS' : 'BLOCK_NONE'
    }   
>>> reply=model.generate_content('請問愛情是甚麼?', safety_settings=safety_settings)    

關閉預設的安全性設定後便能取得 Gemini 模型的回應了 : 

>>> print(reply.text)    
愛情是一個非常複雜的情感,很難用簡單的定義概括。它可以包含以下一些元素:

* **親密感:**  對彼此的深切了解和信任,願意分享內心世界和感受。
* **激情:**  強烈的吸引力和慾望,包括生理上的吸引和情感上的渴望。
* **承諾:**  對彼此的長期承诺,願意共同面對人生的挑戰。

但是,愛情不只是一個抽象的概念,它也是一種主觀體驗,每个人对爱意的理解和感受都不同。它可以是:

* **浪漫的愛:**  充滿了激情和浪漫的愛情,常伴隨著心動和悸動。
* **友愛的愛:**  建立在共同興趣、價值觀和互相支持的基础上的愛情,充滿着理解和尊重。
* **家庭的愛:**  親人之間的愛,包含著無私的奉獻和無條件的包容。

總之,愛情是一種多樣且複雜的情感,它可以帶來幸福、快樂、痛苦和成長。它沒有標準答案,每個人生命中的愛情故事都獨一無二。

以下是一些哲學家和作家對愛情的看法:

* **柏拉圖:**  認為愛情是通往真理和美善的道路。
* **莎士比亞:**  以其作品中的爱情故事而闻名,他将爱情描绘成一种强烈的激情和痛苦的折磨。
* **弗洛伊德:**  认为爱情是一种本能的驱动力,是性欲和亲密感的结合。

最終,愛情的定義需要由每個人自己去探索和感受。

2024年9月11日 星期三

註冊流程自動化工具 n8n 帳號

今天維元老師的流程自動化課程來到第四站介紹 n8n, 此線上工具註冊後提供一個月免費試用, 到期後可加入收費計畫, 最低方案月付 20 美元, 但也提供 Community 開源版可下載於本機用 Docker 架設自己的 n8n, 參考官網 :


按 "Get started for free" 申請帳號 : 




填寫 email, 密碼, 與帳號名稱 (作為網址的開頭) 按 "Try for free" 即可 :



接下來會詢問一些問題 :





最後會進入 Dashboard 頁面 :




官網有提供線上教學影片 : 
 



先記到這邊, 有空再回頭看錄影測試一番.