[BwAI workshop][Golang] LINE OA + CloudFunction + GeminiPro + Firebase = 旅行小幫手 LINE 聊天機器人(2): Firebase Database 讓 LINEBot 有個超長記憶

image-20240413210750427

前言:

這是一篇為了 04/18 跟 Google Developer Group 合作的 BUILD WITH AI (BWAI) WORKSHOP 的第二篇系列文章(不知道還需要幾篇)。

本篇文章將專注在以下幾個部分:

  • Firebase Database 設定
  • 如何在 Cloud Function 上透過官方 Golang 存取 Firebase
  • 透過 Firebase Database 來讓你的 Gemini 記住所有講過的事情,優化上一次打造的 LINE Bot

文章列表:

事前準備

  • LINE Developer Account: 你只需要有 LINE 帳號就可以申請開發者帳號。
  • Google Cloud Functions: GGo 程式碼的部署平台,生成供 LINEBot 使用的 webhook address。
  • Firebase:建立Realtime database,LINE Bot 可以記得你之前的對話,甚至可以回答許多有趣的問題。
  • Google AI Studio:可以透過這裡取得 Gemini Key 。

申請 Firebase Database 服務

  • 記得到 Firebase Console,直接選取你現在有的專案。(可能叫做 My First Project?)

  • 建立一個 Firebase Realtime Database 等等會用到

    image-20240413212830827

  • 地區選美國

    image-20240413212903957

  • Start in “lock mode”

  • 為了開發方便,到 “Rules”設定成可以寫跟讀取,千萬注意:

    • 這是為了測試,請勿用在對外環境
    • 這是為了測試,請勿用在對外環境
    • 這是為了測試,請勿用在對外環境

image-20240413213202354

  • 記住哪個 URL (注意!之後要正式上線,需要改回權限),並且加上一個項目: “BwAI

image-20240413213802313

申請 Services Account Credential 讓 Cloud Function 連接 Google 服務

這部分的教學,其實可以參考我另外一篇文章。[學習文件] 如何在 Heroku 上面使用透過 Golang 來存取 Google Cloud 服務,但是這邊還是快速走一次。

  • 進入 Google Cloud Console ,到 IAM & Admin 選擇建立 Services Account

image-20240413221505536

  • Services Account Name 自己決定,要注意好 (上面專案跟 Firebase 專案名稱要一致)

image-20240413222847247

  • Grant this service account access to project 在身份的時候,建議先用 Editor (比較大,需要小心使用)

image-20240413223055288

  • “Grant users access to this service account” 不需要特別設定
  • 按下 “Manage Keys” 來準備下載 Credential

image-20240413223225404

  • 選擇 Add Key -> Create new Key -> 下載 JSON

image-20240413223613244

如何在 Google Cloud Function 導入 Services Account Credential ?

接下來會來分享,要如何正確地能夠在 Cloud Function 內使用呢。 如果你想要直接使用 Cloud Function 去開啟 Credential JSON 檔案,你會一直得到無法正確拿到 credential 的錯誤訊息。

這時候需要先透過環境參數來加入:

  • 將 JSON 檔案中所有內容複製起來。
  • 為了要能夠正確啟動 Firebase 記得新增一個參數, FIREBASE_URL 並且把剛剛的 Firebase link 網址填上去。
  • 設定 GOOGLE_APPLICATION_CREDENTIALS 參數,然後把所有內容貼上環境參數。

image-20240413225710980

相關程式碼要如何修改

到了原始碼那邊,記得要更新兩個檔案: (完整程式碼)

重新 Deploy 之後,就可以來看最新的狀況。

成果與使用 ChatSession 差異:

image-20240413210750427

可以直接看到成果相當的好,並且這樣的記憶長度就會看 Gemini Model Token 的限制,算是相當的好用。

那這個又跟 Gemini Chat Session 有什麼差別呢?

  • Chat Session: 適合使用在 Cloud Run 那種有固定一整台 server 的 LINE Bot 應用。
  • Firebase Database + Chat Session: 就可以放在 Cloud Function 這種 Functional As A Services 上面。

使用 Golang Google Options 套件需要注意:

雖然已經將 Firebase Realtime Database 設定成每個人都可以讀寫,但是如果是透過 Golang 去存取的時候,你會出現 Unauthorized request 的錯誤訊息。 這時候就是因為你的 JSON 檔案的 Project 跟你的 Firebase Project 是不同的。 只要重新建立一個 Services Account 並且更新 JSON 內容即可。

image-20240413220630196

關於修改程式碼的細節

  • 接下來會跟大家講,如何修改相關程式碼?
	// Init firebase related variables
	ctx := context.Background()
	opt := option.WithCredentialsJSON([]byte(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")))
	config := &firebase.Config{DatabaseURL: os.Getenv("FIREBASE_URL")}
	app, err := firebase.NewApp(ctx, config, opt)
	if err != nil {
		log.Fatalf("error initializing app: %v", err)
	}
	client, err := app.Database(ctx)
	if err != nil {
		log.Fatalf("error initializing database: %v", err)
	}
  • 首先option.WithCredentialsJSON([]byte(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"))) 可以讓你從環境參數讀取到 credential 。
  • 接下來 &firebase.Config{DatabaseURL: os.Getenv("FIREBASE_URL")} 則是將 FIREBASE_URL 內容設定好。
  • 這樣就可以正確執行了,接下來要來看相關處理 Gemini 聊天記憶的部分了。

Gemini Pro Chat History 要如何正確處理?

首先也要讓大家了解一下,跟 OpenAI 不同的是: Gemini Chat History 的格式不太一樣(也不是很好了解)。根據網頁資料如下:

[parts {
   text: "In one sentence, explain how a computer works to a young child."
 }
 role: "user",
 parts {
   text: "A computer is like a very smart machine that can understand and follow our instructions, help us with our work, and even play games with us!"
 }
 role: "model"]

不是很確定為何 “parts” 會用集合, anyway 在 Python 中還不算難處理,但是在 Golang 裡面的處理方式如下:(參考自 Google Golang GAI Github https://github.com/google/generative-ai-go)

func ExampleChatSession_history() {
	ctx := context.Background()
	client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()
	model := client.GenerativeModel("gemini-1.0-pro")
	cs := model.StartChat()

	cs.History = []*genai.Content{
		&genai.Content{
			Parts: []genai.Part{
				genai.Text("Hello, I have 2 dogs in my house."),
			},
			Role: "user",
		},
		&genai.Content{
			Parts: []genai.Part{
				genai.Text("Great to meet you. What would you like to know?"),
			},
			Role: "model",
		},
	}

	res, err := cs.SendMessage(ctx, genai.Text("How many paws are in my house?"))
	if err != nil {
		log.Fatal(err)
	}
	printResponse(res)
}

問題來了, cs.History 竟然是對應到 []*genai.Content。這並不是一個對於 JSON unmarshall 就能夠直接使用的資料格式。還需要有相關的轉換。

透過 Firebase Database 處理 Chat History 的流程:

這邊稍微讓大家知道一下,由於 Firebase Database 其實就是一大包的 JSON Database 。你可以直接存取一整包的 JSON Structure 進這個資料庫。 這樣來說讓整個資料庫處理上,還有寫小型 POC 應用來說相當的方便。(但是效率是可以討論的)

// Define your custom struct for Gemini ChatMemory
type GeminiChat struct {
	Parts []string `json:"parts"`
	Role  string   `json:"role"`
}

.....

	// Get chat history from Firebase
	var InMemory []GeminiChat
	err = fireDB.NewRef("BwAI").Get(ctx, &InMemory)
	if err != nil {
		fmt.Println("load memory failed, ", err)
	}

	fmt.Println("InMemory: %v", InMemory)

	// convert InMemory to Memory
	for _, c := range InMemory {
		parts := make([]genai.Part, len(c.Parts))
		for i, part := range c.Parts {
			parts[i] = genai.Text(part)
		}
		dst := &genai.Content{
			Parts: parts,
			Role:  c.Role,
		}

		Memory = append(Memory, dst)
	}

上面是從 Firebase Database 取出後需要轉換的程式碼,但是使用方式則是直接將 Memory 直接交給 chat.History 即可。需要記得的是,在處理完之後,要把這一次的對話也放進 Memory之中。部分程式碼如下:

				// Pass the text content to the gemini-pro model for text generation
				model := client.GenerativeModel("gemini-pro")
				cs := model.StartChat()
				cs.History = Memory

				res, err := cs.SendMessage(ctx, genai.Text(req))
				if err != nil {
					log.Fatal(err)
				}
				var ret string
				for _, cand := range res.Candidates {
					for _, part := range cand.Content.Parts {
						ret = ret + fmt.Sprintf("%v", part)
						log.Println(part)
					}
				}

				// Save the conversation to the memory
				Memory = append(Memory, &genai.Content{
					Parts: []genai.Part{
						genai.Text(req),
					},
					Role: "user",
				})

				// Save the response to the memory
				Memory = append(Memory, &genai.Content{
					Parts: []genai.Part{
						genai.Text(ret),
					},
					Role: "model",
				})

				// Save the conversation to the firebase
				err = fireDB.NewRef("BwAI").Set(ctx, Memory)
				if err != nil {
					fmt.Println(err)
					return
				}

重點就在:

  • 要把之前講過的話,放入 History
  • 把現在講過的,直接丟給 cs.SendMessage()
  • 最後要記得把後來使用者輸入的文字,跟 Gemini 回覆的文字都加入 Memory

錯誤處理

Q: 如果從第一篇的文章做過來,改了 FIREBASE_URLGOOGLE_APPLICATION_CREDENTIALS 之後,反而傳訊息都不會回覆了?

A: 請幫我做以下檢查:

  • 傳遞一個圖片訊息,看看有沒有回覆。
  • 如果圖片有回覆,那麼就是你的 Services Account 設定權限跟 Firebase 不同。

Q: 怎麼本來可以對話? 但是忽然沒有回覆了? 查看 Log 卻出現 unknown field “usageMetadata”

image-20240503211859408

這是因為由於 Google Gemini 伺服器今天早上修改相關變動,但是 Golang 官方套件還無法來得及改動。 (https://github.com/google/generative-ai-go/issues/97)

目前這部分程式碼有透過直接換成 新版本的程式碼

接下來:

感謝各位的支持,接下來就是要透過 Gemini Vision 去識別並且翻譯收據。還要讓 Gemini 可以快速幫我們找出哪時候買的? 什麼地方買的? 當初花了多少錢的「收據小幫手」。

完整原始碼

你可以在這裡找到相關的開源程式碼: https://github.com/kkdai/linebot-cf-firebase

[BwAI workshop][Golang] LINE OA + CloudFunction + GeminiPro + Firebase = 旅行小幫手 LINE 聊天機器人(一): 景色辨識小幫手

image-20240412221312444

前言:

這是一篇為了 04/18 跟 Google Developer Group 合作的 BUILD WITH AI (BWAI) WORKSHOP 的第一篇系列文章(不知道還需要幾篇),裡面包含了完整的 LINE 開發者相關帳號設定與 GCP 相關設定,只需要有付費認證帳號,其實是不會花費到任何錢的。

文章列表:

事前準備:

  • LINE Developer Account: 你只需要有 LINE 帳號就可以申請開發者帳號。
  • Google Cloud Functions: GGo 程式碼的部署平台,生成供 LINEBot 使用的 webhook address。
  • Firebase:建立Realtime database,LINE Bot 可以記得你之前的對話,甚至可以回答許多有趣的問題。
  • Google AI Studio:可以透過這裡取得 Gemini Key 。

關於 Gemini API Price

根據官方網站: https://ai.google.dev/pricing?hl=zh-tw

image-20240410164827279

申請 Gemini API Key

  • 到 Google AI Studio https://aistudio.google.com/
  • Click “Get API Key”
  • 選擇你已經有綁定信用卡的付費帳號,來取得 API Keyimage-20240412195805278

申請一個 LINE 聊天機器人 (Messaging API)

image-20240410165008871

  • LINE Developer Console )並且登入 image-20240410165104899
  • 在挑選 Channel 的時候,如果要申請 LINE Chatbot (官方帳號),就要申請 Messaging API image-20240410170120876
  • 相關資料填寫上:
    • Cmpany or owner’s country or region:
    • Channel Name: 也就是你的 LINE Bot 名稱。
    • Channel description: 相關敘述來描述你 LINE Bot 做什麼。
    • 其他都可以隨便填寫即可。
  • 接下來要到 Messaging API Tab 執行以下設定:
    • Auto-reply messages: 關閉它 image-20240410170924360
  • 接下來要取得兩個重要的參數:
    • Basic Setting Tab 下方的 Channel secret image-20240410171544805
    • Messaging API Tab 下方的 Channel access token (long-lived) image-20240410171731815
  • 目前先到這邊,稍後還會回來設定相關 Webhook 。

建立一個新的 Google Cloud Function

雖然 Google Cloud Function 跟 Firebase Realtime database 都是有免費額度的,但是可能你還是需要有一個付費帳號。也就是說你的 Google Cloud Account 需要填寫上你的信用卡資訊(有效的帳單帳戶)

關於 Cloud Function (cloud function 第 1 代) 的費用部分

根據網站定價,基本上在以下的狀況是不需要費用的。白話文來說

免費方案
Cloud Functions 針對運算時間資源提供永久免費方案,當中包括 GB/秒和 GHz/秒的分配方式。除了 200 萬次叫用以外,這個免費方案也提供 400,000 GB/秒和 200,000 GHz/秒的運算時間,以及每月 5 GB 的網際網路資料傳輸量。免費方案的使用額度,是以上述級別 1 價格的同等美元金額計算。無論執行函式的區域採用的是級別 1 和/或級別 2 價格,系統都會分配同等美元金額給您。不過在扣除免費方案的額度時,系統將以函式執行區域的級別 (級別 1 或級別 2) 為準。

請注意,即便您採用的是免費方案,也必須擁有有效的帳單帳戶。

Cloud Function 這邊,開始建立一個 Cloud Functions ,相關設定參考以下:

  • 環境: 第 1 代
  • 函式名稱: 隨便填
  • 地區: asia-east1 (台灣)
  • HTTP
    • 驗證: 允許未經驗證的叫用

image-20240410174823233

  • 執行階段、建構作業、連線和安全性設定
    • 不需要修改,先使用 256MB 記憶體是足夠的。
  • 執行階段環境變數
    • 開始設定以下變數:
      • GOOGLE_GEMINI_API_KEY: 剛剛取得的 Gemini API Key
      • ChannelAccessToken: 在 LINE Developer Console 取得的 Channel Access Token
      • ChannelSecret: 在 LINE Developer Console 取得的 Channel Secret

image-20240412200122236

開始修改 Cloud Function 的程式碼

image-20240412214423901

LINE Bot 完成最後設定

  • 到 “Messaging API” Tab
  • 填入 “Webhook URL” 數值,將剛剛得「觸發網址填上去」
  • 更新(update)後,使用 “Verify” 看看有沒有設定錯誤。
  • 如果沒有問題,可以打開「Use webhook」

image-20240412214745544

來測試吧

image-20240412221246422

完整原始碼

你可以在這裡找到相關的開源程式碼: https://github.com/kkdai/linebot-cloudfunc-gemini-go

[Golang][GCP] 在 Cloud Function 上面透過 Golang 操控 Firebase Database 需要注意與可能踩雷的地方

前提:

本篇文章將快速走過一次,如何申請 GCP Services Account Credential ,還有如何在 Cloud Function 使用這樣的資料,最後如何透 Golang 來在 Cloud Function 操控 Firebase Database ,還有可能發生的雷點。

申請 Services Account Credential 讓 Cloud Function 連接 Google 服務

這部分的教學,其實可以參考我另外一篇文章。[學習文件] 如何在 Heroku 上面使用透過 Golang 來存取 Google Cloud 服務,但是這邊還是快速走一次。

  • 進入 Google Cloud Console ,到 IAM & Admin 選擇建立 Services Account

image-20240413221505536

  • Services Account Name 自己決定,要注意好 (上面專案跟 Firebase 專案名稱要一致)

image-20240413222847247

  • Grant this service account access to project 在身份的時候,建議先用 Editor (比較大,需要小心使用)

image-20240413223055288

  • “Grant users access to this service account” 不需要特別設定
  • 按下 “Manage Keys” 來準備下載 Credential

image-20240413223225404

  • 選擇 Add Key -> Create new Key -> 下載 JSON

image-20240413223613244

使用 Golang Google Options 套件需要注意:

雖然已經將 Firebase Realtime Database 設定成每個人都可以讀寫,但是如果是透過 Golang 去存取的時候,你會出現 Unauthorized request 的錯誤訊息。 這時候就是因為你的 JSON 檔案的 Project 跟你的 Firebase Project 是不同的。 只要重新建立一個 Services Account 並且更新 JSON 內容即可。

image-20240413220630196

如何在 Google Cloud Function 導入 Services Account Credential ?

接下來會來分享,要如何正確地能夠在 Cloud Function 內使用呢。 如果你想要直接使用 Cloud Function 去開啟 Credential JSON 檔案,你會一直得到無法正確拿到 credential 的錯誤訊息。

這時候需要先透過環境參數來加入:

  • 將 JSON 檔案中所有內容複製起來
  • 設定 GOOGLE_APPLICATION_CREDENTIALS 參數,然後把所有內容貼上環境參數。

image-20240413225710980

  • 接下來會跟大家講,如何修改相關程式碼?
	// Init firebase related variables
	ctx := context.Background()
	opt := option.WithCredentialsJSON([]byte(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")))
	config := &firebase.Config{DatabaseURL: os.Getenv("FIREBASE_URL")}
	app, err := firebase.NewApp(ctx, config, opt)
	if err != nil {
		log.Fatalf("error initializing app: %v", err)
	}
	client, err := app.Database(ctx)
	if err != nil {
		log.Fatalf("error initializing database: %v", err)
	}
  • 首先option.WithCredentialsJSON([]byte(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"))) 可以讓你從環境參數讀取到 credential 。
  • 接下來 &firebase.Config{DatabaseURL: os.Getenv("FIREBASE_URL")} 則是將 FIREBASE_URL 內容設定好。
  • 這樣就可以正確執行了,接下來要來看相關處理 Gemini 聊天記憶的部分了。

參考文章:

[科技工作講-心得] 在 LINE 的世界裡: Evan Lin 的科技之旅

前言

最近,我有幸受邀參加了一場精彩的Podcast專訪,由科技工作講主辦。在這個以科技職涯和人才發展為主題的節目中,我分享了自己在LINE台灣開發者關係與技術推廣部門的工作經驗,以及對於科技行業的見解。以下是這次專訪的精華,希望能給大家帶來一些啟發。

專訪概覽

  • 專訪時間:4月3日,晚上10點
  • 專訪形式線上直播
  • 單集標題:LINE的主管聊聊他們在做什麼 feat. LINE 台灣開發者關係與技術推廣部門資深經理 Evan Lin
  • 上線時間:4月6日

職涯分享

我的職業旅程從研究所畢業後開始,那時我加入了一家跨國的軟體公司,他們的業務遍及美國和加拿大。隨後,我也在台灣的硬體公司和新創企業中擔任過要職。特別是在新創公司的時光,我非常積極地參與技術分享和開源軟體開發,這讓我有機會接觸到許多新的領域和機會。

這段經歷對我來說是一個轉捩點,因為我在開源軟體開發和技術推廣方面的熱情,恰好與 LINE 當時的職缺非常契合。所以,在2018年底,我決定加入LINE台灣,開始了我在這裡的新篇章。

LINE的工作文化

在 LINE,溝通是我們極為重視的一環。我們不僅透過自家開發的通訊平台進行直接討論,還非常注重開放性和自主性。我們鼓勵員工與上司討論,表達自己對於新專案或新挑戰的意願。這種文化鼓勵我們主動探索和擴展自己的能力範圍。實習生也能夠體驗到這樣的開放文化,這證明了LINE的開放和自主。

部門工作內容

我們的部門負責推廣LINE的開發者生態系統和技術品牌。我們舉辦外部活動和工作坊教學,並且推廣LINE工程團隊的技術分享活動。我們的總公司在日本,提供全球市場的服務,並且在台灣也持續發展在地服務,如LINE TODAY。

img

(關於 LINE 台灣的企業參訪: 詳情請看文章關於 LINE 台灣開發者關係與技術推廣部門的校園相關資源)

工作上的挑戰

img

(在 LINE 研發工程團隊中,我們有相關的文化來塑造團隊合作氛圍,請參考 LINE Engineering Culture)

在LINE,我們鼓勵直接與相關部門的同仁溝通,這種開放的溝通方式大大提高了效率。在這裡,老闆不僅期待你執行既定的任務,他們更希望你能提出新的想法,並且主動去推動讓這些想法成為現實。

資深軟體開發人力市場

資深軟體開發人員的需求一直都很高。在LINE,我們透過舉辦技術研討會和社群聚會來吸引資深人才,並且非常注重人才的培養。我們有「LINE TECH FRESH」的技術新星實習計畫,旨在培養有潛力的軟體開發工程師。

img

(LINE 台灣的開發者技術年會 - LINE TAIWAN TECHPUSE )

加入LINE的建議

對於想要加入LINE的朋友,學歷背景並不是唯一標準。更重要的是你對軟體開發的熱情,你的學習能力和願意深入了解系統架構背後的效能限制。我們鼓勵參與開源專案,這對於開發工作來說是非常重要的。在LINE的實習生中,我們也有來自不同學科的優秀學生,他們的跨領域學習精神和對軟體開發的熱愛,讓他們在實習結束後也獲得了轉為正職的機會。

img

LINE TECH FRESH:培育下一代科技領袖

在我們的專訪中,我提到了「LINE TECH FRESH」計畫,這是LINE台灣為了培養新一代科技人才而特別推出的培育計畫。在這個快速變遷的數位時代,我們深刻理解到,培養年輕學子的重要性。因此,我們致力於幫助參與者建立堅實的技術基礎,同時兼顧軟實力的提升,為未來職涯發展奠定全面的基石。

計畫特色

專業訓練課程

我們提供一系列精心設計的訓練課程,涵蓋最新的技術趨勢與工具。這些課程旨在讓實習生能夠快速適應職場環境,並掌握必要的技術知識。

實務實習機會

實習生將有機會參與實際的專案,並在專業人士的指導下,將所學知識應用於實務工作中。這不僅是一個學習的機會,也是一個證明自己能力的舞台。

跨部門交流

透過與LINE各部門專業人才的交流,實習生將能夠獲得多元化的視角與經驗。這種跨部門的互動對於擴展視野和建立人脈網絡都是非常有價值的。

職涯發展支援

從個人職涯規劃到專業技能提升,我們提供全方位的支援。我們的目標是協助實習生找到最適合自己的職涯道路,並在科技領域中脫穎而出。

轉正機會

表現優異的實習生將有機會在計畫結束後,成為LINE台灣的正式員工。這是一個讓實習生能夠持續在LINE這個大家庭中成長的機會。

更多細節請參考: LINE TECH FRESH 2024 Summer Class 招募相關說明 (時程, 職缺)

活動小結

「LINE TECH FRESH」計畫是我們對於人才培養的承諾,也是LINE文化的一部分。我們相信,透過這個計畫,我們不僅能夠吸引優秀的開發人才,更能為台灣的資深軟體開發人力市場做出貢獻。

立即加入「LINE 開發者官方社群」官方帳號,就能收到第一手 Meetup 活動,或與開發者計畫有關的最新消息的推播通知。▼

「LINE 開發者官方社群」官方帳號 ID:@line_tw_dev

img

關於「LINE 開發社群計畫」

LINE 於 2019 年開始在台灣啟動「LINE 開發社群計畫」,將長期投入人力與資源在台灣舉辦對內對外、線上線下的開發者社群聚會、徵才日、開發者大會等,已經舉辦 30 場以上的活動。歡迎讀者們能夠持續回來查看最新的狀況。詳情請看:

[好書分享] 馬斯克傳

馬斯克傳:唯一不設限、全公開傳記
作者: 華特.艾薩克森  
原文作者: Walter Isaacson  
譯者: 吳凱琳  
出版社:天下雜誌出版 
出版日期:2023/09/27

買書推薦網址:

前言:

這是 2024 年第 2 本讀完的書,這是一本相當厚的書籍,但是我覺得裡面包括了近幾年許多的科技大小事情,讀起來一點也不會疲累反而覺得相當的有趣。

內容摘要:

馬斯克唯一不設限、全公開傳記
權威傳記作家艾薩克森重磅力作

兩年深度跟訪,解密全世界最令人好奇,也最具爭議性的創新者——
是狂人還是造勢天才?是破壞者還是創新者?是混蛋還是英雄?
想要了解最真實的馬斯克,只能透過這本書!

★第一視角觀察馬斯克獨有的英雄模式與惡魔模式
★深入解讀馬斯克旗下六大事業的商業與創新策略
★揭露AI、自動駕駛、太空探險三大尖端科技趨勢

「不管你喜歡與否,我們都生活在馬斯克創造的世界裡。」—《時代》

馬斯克引領世界進入電動車時代、開發私人太空探險、嚴肅想像人工智慧,他改變了三大關鍵產業,也改變了我們的未來。喔,他還買下了推特。

他是打破常規的夢想家,沒有開不出的路徑,沒有打不破的框架,沒有丟不掉的包袱。對風險,不但冷靜計算,更熱情擁抱,冒險不設限。當其他企業家在發展世界觀時,馬斯克已在構建他的宇宙觀。

比任何科幻小說都更精采的傳奇人生,他旗下的每一個事業:特斯拉、SpaceX 與星鏈、X(原為推特)、鑽孔公司、Neuralink、xAI,都在改寫歷史。未來,他會如何進一步改變科技世界﹖

《賈伯斯傳》作者、最能捕捉天才腦中靈光的艾薩克森,跟隨馬斯克長達兩年,跟他一起開會、走訪工廠,採訪馬斯克本人、他的家人、朋友、同事和對手,寫出這部考證詳實、藏著驚人內幕的人生故事。寫作過程中,馬斯克從不掌控內容走向,也不要求在出版前先看過,甚至鼓勵他的對手、前員工跟作者談一談。

艾薩克森精闢描述馬斯克的成功與風暴,也探討了一個問題:驅動馬斯克的惡魔,是否也是創新和進步的推手?

馬斯克的成功無法複製,沒人能像他那樣。但他在成長、創新、創業歷程中的有效方法,值得你一讀。

‧設計工廠有什麼祕密﹖
‧特斯拉下一個要顛覆的是什麼﹖
‧遠大計畫的務實商業目標該怎麼訂﹖
‧講求硬派精神的馬斯克都怎麼用人﹖
‧從電玩可以學習到什麼人生道理或商業思維﹖
‧如何提升學習力、快速形成見解、精通新領域﹖
‧閱讀如何讓一個人的影響力從地球到太空……

心得:

整本書包括了幾個 Musk 許多重要的相關里程碑:

  • 小時候父親偏激造就他的獨特個性
  • Paypal 與 x.com
  • SpaceX 的火箭夢
  • Tesla 電動車的未來夢
  • 自動駕駛與機器人的特斯拉
  • Twitter 的愛恨情仇

這些的重要成就都圍繞著他的獨特思維:

「第一性原理」的思考方式是用物理學的角度看待世界的方法,也就是說一層層剝開事物的表象,看到裏面的本質,然後再從本質一層層往上走。

透過第一性原理的方式,馬斯克經常做出許多不可思議的要求,讓他的員工相當的痛苦與難受。並且透過馬斯克經常性的開啟的加速模式,來讓許多本來不可能的專案也逐漸地完成。 舉凡像是:

  • 火箭如何將成本不斷地降低
  • 如何能夠回收火箭
  • 電動車的成本分析,如何節省電池的費用。
  • 到最近一次的如何節省 Twitter 開發人員的費用。

也都發現了馬斯克極盡苛刻的成本樽節與細節追求,讓追隨他的員工都無法忍受。但是也是因為這些原因才有可能有這些相關成就的發生。 同樣身為科技從業人員,都同意極致的追求細節與拼命的成本鑽研才會是造就令人驚豔的科技。

至於相關的員工能不能接受一樣的想法,造就出相關的完美的追求與拼命的個性。有看過一些 YTer 曾經分享過,特斯拉就像是新創公司一樣,每天幾乎不可思議的超長工時與經常性的大規模的專案追求團隊。都會讓裡面的員工戰戰兢兢,相當痛苦。但是完成後的成就感也會是無比巨大的。 但是又有多少人能夠在這樣的公司待得夠久呢? 或許追求出自己完美的一個里程碑之後,都會回歸到自己想要持續的平衡吧?

[LINE Bot][Python] Cloud Function + Gemini Pro + Firebase Database = 記憶體聊天機器人

image-20240318204441270

起因

這邊文章,主要是透過【LineBot實作】如何製作有記憶的對話機器人 的相關修改。 把需要付費的服務 OpenAI 改成目前還有免費額度的 Google Gemini ,並且針對相關訊息的程式碼做一些調整。 主要的 LINe Bot 設定與 Firebase 設定請參考原先文章。

快速講解一下設定的方法:

這裡僅快速條列式,講解一下該如何設定這個應用。

  • 建立 LINE Bot 帳號
    • 首先先去 LINE Developer Console 建立一個 Messaging API Channel
    • 在 Basic Setting Tab 取得 Channel secret
    • 在 Messaging API Tab 產生 (issue) Channel access token
  • 到 Google Cloud 的 Firebase
    • 建立一個專案
    • 設定一個 Realtime Database
    • 更改安全規則,讓資料庫可以被任何人存取與修改。(請注意: 這是因為做測試專案,請勿再正式專案如此設定)
    • 取得該資料庫網址: https://XXX.firebaseio.com/
  • 到 Google Cloud 的 Cloud Functions
    • 建立一個 Cloud Functions - Gen1 或是 Gen2 都可以
    • 採取 HTTPS
    • 驗證部分: 使用「允許未經驗證的叫用」
    • 新增四個環境變數
      1. GEMINI_API_KEY:(在 Google AI Studio 獲得的secret key)
      2. LINE_BOT_TOKEN:(在Line Developers獲得的Channel access token)
      3. LINE_BOT_SECRET:(在Line Developers獲得的Channel secret)
      4. FIREBASE_URL:(在Firebase獲得的URL)
    • 程式碼部分,請使用以下修改的程式碼。

主要修改程式碼部分

首先是 requirements.txt 需要將相關設備改成 Gemini pro - google.generativeai

接下來建立另外一個檔案: main.py

設定 “進入點” 到 linebot,並且記錄觸發網址 https://xxxxxxxx.cloudfunctions.net/function-test1

關於 OpenAI ChatComplete 與 Google Gemini Pro - Multi-turn conversations 格式轉換

這邊講解一下,關於 OpenAI 的 Chat Completion API 的格式:

[
  {
    "role": "system",
    "content": "You are a helpful assistant."
  },
  {
    "role": "user",
    "content": "Hello!"
  }
]

但是 Google Gemini Pro 的 Multi-turn Conversations 格式不太一樣。

[
    {'role':'user',
     'parts': ["Briefly explain how a computer works to a young child."]},
    {'role':'model',
     'parts': ["想像一下你的電腦就像一個超級聰明的機器人,它可以按照你的指令去做很多事情....."]}   
]

主要差別除了 “content” 與 “parts” 命名不同外, parts 可以接受多種資料格式。可以參考 API Reference 關於 Gemini Content

回頭設定 LINE Bot

  • 設定 LINE Developer Console 到了 Messaging API Tab 並且將 Webhook URL 放入剛剛輸入的 https://xxxxxxxx.cloudfunctions.net/function-test1
  • 測試是否成功,即可開始對聊天機器人溝通。

參考文章: