[Python][Gemini CLI] 使用 LangChain 中的 Vertex AI 來處理 LINE Bot 中的圖片內容

前情提要

關於 Vertex AI 上面使用 Gemini 來做圖形偵測的架構圖

絕對可以!您的想法完全正確,這是解決這個問題的標準且唯一的途徑。

既然不能用一個「超級管理員」帳號(服務帳號)來處理所有事情,我們就必須讓每一個使用者授權您的應用程式來存取他們自己的 Google Drive。這就是 OAuth 2.0 的用途。

這個改動會比之前複雜很多,因為它引入了使用者互動的認證流程。我會為您詳細拆解。

宏觀概念:使用者授權流程

  1. 使用者發起連線:使用者在 Telegram 中對您的機器人發送一個指令,例如 /connect_drive。
  2. 產生授權連結:您的機器人會產生一個獨一無二的 Google 授權連結,並將它傳回給使用者。
  3. 使用者授權:使用者點擊連結,會被帶到 Google 的登入和授權頁面。頁面會顯示「TG Helper 想要存取您的 Google Drive」,使用者點擊「允許」。
  4. 重新導向並取得授權碼:Google 會將使用者重新導向到您預先設定好的一個網址(Callback URL),並附上一組一次性的授權碼 (Authorization Code)。
  5. 交換權杖:您的後端服務(Cloud Run)收到這個授權碼後,會用它跟 Google 交換一組存取權杖 (Access Token) 和一個非常重要的更新權杖 (Refresh Token)。
  6. 儲存權杖:您的應用程式需要一個資料庫(例如 Firestore),將使用者的 Telegram ID 和他們的更新權杖安全地儲存起來。
  7. 上傳檔案:當這位使用者之後傳送檔案時,您的機器人會:
    • 從資料庫中讀取這位使用者的更新權杖。
    • 使用更新權杖取得一組新的、有時效性的存取權杖。
    • 使用這組代表該使用者的存取權杖,將檔案上傳到他自己的 Google Drive。

新的架構

這個流程需要一些新的元件:

  • 一個 Web 端點:您的 Cloud Run 應用程式除了接收 Telegram 的 Webhook,還需要一個新的 HTTP 路徑 (例如 /oauth/callback) 來接收 Google 的重新導向。
  • 一個資料庫:用來儲存使用者 ID 和他們的 Refresh Token。最簡單的選擇是 Firestore,因為它與 Cloud Run 整合得很好,而且有免費額度。

實作步驟

步驟 1:Google Cloud Console 設定

  1. 設定 OAuth 同意畫面
    • 前往 OAuth 同意畫面 (https://console.cloud.google.com/apis/credentials/consent)。
    • 使用者類型:選擇「外部」。
    • 填寫應用程式名稱(例如 TG Helper Bot)、使用者支援電子郵件等資訊。
    • 範圍:點擊「新增或移除範圍」,找到並加入 …/auth/drive.file。這個範圍代表「僅允許上傳由本應用程式建立的檔案」,是權限最小、最安全的選擇。
    • 儲存並繼續。在「測試使用者」步驟中,將您自己的 Gmail 加入,這樣在應用程式發布前您才能進行測試。
  2. 建立 OAuth 2.0 用戶端 ID
    • 前往 憑證頁面 (https://console.cloud.google.com/apis/credentials)。
    • 點擊「建立憑證」 > 「OAuth 用戶端 ID」。
    • 應用程式類型:選擇「網頁應用程式」。
    • 已授權的重新導向 URI:這是最關鍵的一步。點擊「新增 URI」,然後輸入您的 Cloud Run 服務網址,並在後面加上一個回呼路徑,例如: https://tg-helper-xxxx-an.a.run.app/oauth/callback
    • 點擊「建立」。
    • 建立後,您會得到一組用戶端 ID (Client ID) 和用戶端密鑰 (Client Secret)。請將這兩者複製下來,它們非常重要。

步驟 2:啟用 Firestore 並安全地儲存密鑰

  1. 啟用 Firestore API

1 gcloud services enable firestore.googleapis.com

  1. 建立 Firestore 資料庫
    • 前往 Firestore 主控台 (https://console.cloud.google.com/firestore)。
    • 選擇「原生模式」(Native mode)。
    • 選擇一個離您最近的位置。
    • 建立資料庫。
  2. 安全地儲存 Client Secret 我們應該再次使用 Secret Manager 來儲存您在步驟 1-2 取得的 Client Secret。

1 # 將您的 Client Secret 貼在引號中 2 echo -n “YOUR_COPIED_CLIENT_SECRET” | gcloud secrets create tg-bot-client-secret –data-file=-

步驟 3:修改 Go 程式碼 (概念)

這將是一個較大的重構。我先不提供完整程式碼,而是描述邏輯上的變更:

  1. 新增 /connect_drive 指令處理:
    • 當收到此指令,程式會使用 Google 的 Go Auth 函式庫產生一個授權 URL。
    • 這個 URL 會包含您的 Client ID、redirect_uri、scope,以及一個 state 參數。state 參數通常會包含該使用者的 Telegram ID,以便在回呼時能識別是誰。
    • 機器人將此 URL 回傳給使用者。
  2. 新增 /oauth/callback HTTP 處理器:
    • 這個函式會處理來自 Google 的重新導向。
    • 它會從 URL 參數中取得 code 和 state。
    • 驗證 state 以確保請求的合法性,並從中解析出 Telegram User ID。
    • 使用 code 和您的 Client Secret 向 Google 交換權杖。
    • 將 (Telegram User ID, Refresh Token) 這組對應關係存入 Firestore。
    • 向使用者顯示一個「授權成功!」的簡單網頁。
  3. 重構 handleFile 函式:
    • 當收到檔案時,它會先用檔案傳送者的 Telegram User ID 去 Firestore 查詢。
    • 如果找不到對應的 Refresh Token,就回覆訊息請使用者先執行 /connect_drive。
    • 如果找到了,就用 Refresh Token 取得一個新的 Access Token。
    • 用這個 Access Token 建立一個 Drive 服務,然後上傳檔案。

[好書分享] 教練 - 價值兆元的管理課

教練 - 價值兆元的管理課,賈伯斯、佩吉、皮查不公開教練的高績效團隊心法
Trillion Dollar Coach : The Leadership Playbook of Silicon Valley’s Bill Campbell
作者: 艾力克.施密特  強納森.羅森柏格  亞倫.伊格爾  原文作者: Eric Schmidt  Jonathan Rosenberg  Alan Eagle  
譯者: 許恬寧  出版社:天下雜誌出版 

買書推薦網址:

前言:

這是 2025 年第 4 本讀完的書,今年讀完的書,真的有點少。不過這一本書還蠻有趣的,雖然不是 Bill Campbell 本人寫的團隊心法,反而是他過世後,由幾位作者找了許多矽谷的領導人訪談之後的一些心得整理,反而更加的珍貴。 讓人閱讀起來有許多相關的人物與背景,也更容易帶入相關的情境之中。

大綱

從球場到商場,超凡的高績效人士的身後,都有個教練。
即使是身經百戰的戰將,也有連自己都不知道的潛力;
面對沒有標準答案的選項,也需要指引,重新聚焦最重要的事!

從蘋果的庫克、Alphabet的漢尼斯與皮查,到臉書的祖克柏與桑德伯格,當今許多頂尖創業家、CEO、高階主管心中有疑惑時,他們都去問比爾.坎貝爾。

谷歌執行長皮查說︰「他總會適時協助我看清什麼才是最重要的事。」
YouTube執行長沃西基說︰「他能助人發揮潛能,促成團隊同心協力。」
矽谷創投之父杜爾說︰「比爾.坎貝爾是我見過最有智慧的人。」
蘋果執行長庫克說︰「他對蘋果的貢獻難以估算,也無可取代。每個人都可以向我們這個產業最偉大的教練學習。」

優秀的主管,必須先是優秀的教練;
一個人的職位愈高,他的成功就愈取決於能否幫助他人成功!

比爾從大學足球教練出身,四十三歲才進入矽谷。從帶球隊到教企業團隊,比爾都備受敬愛,因為他深諳每個人都希望被尊重、有價值的人性。他的教練之道不曾出現在任何官方文件,他也很少出現在主流媒體上。親密學徒施密特等人歷時超過兩年,採訪近百位業內頂尖人士,總結這位傳奇商業教父的管理智慧和領導哲學,闡釋建立信任、打造團隊、促進成長的32個管理黃金法則。

.不論個人發展或公司命運,都取決於人際關係的品質
.尋求最好的點子,若以達成共識為目標,只會導致團體迷思與較差決策
.每個人想要被喜愛、不想被背叛,激發正面的人性價值就會帶來正面的商業成果
.經理人的權威,來自部屬、同儕與長官的信任,而非權威式管理
.只指導願意受教的人,不必有教無類,不然你會很累

「教練就是跟你說你不想聽的話,要你看你不想看的事,最後讓你成就你想成就的關鍵人物」。每個人都可以從這本書學習如何教練自己和周圍的人變得更好。

這個世界面臨眾多挑戰,唯有靠團隊才能解決,而團隊都需要教練。在亟需領導力的時代,當今最有權力的CEO、創投家、創業者、高階主管們的共同教練,提供你突圍、成功的祕訣。

image-20250728143722873

image-20250728161440971

摘要聚焦於比爾·坎貝爾(Bill Campbell)的教練之道,涵蓋其領導哲學、社交能力、同理心、團隊管理及董事會運作等核心理念,強調信任、心理安全感及有效溝通的重要性。

1. 社交能力與人際連結

比爾強調建立人際關係是領導的基礎,鼓勵管理者主動與同事互動,關心他們的生活,並以真誠的問候建立連結。

  • 重要句子
    • 「試著培養這種人際關係對我來說並不容易,但我努力做到了。幸運的是,愈做就會愈覺得簡單。」
    • 「我曾試著記住大家的名字,在電梯裡碰到人的時候,我會試著開口和旁邊的同事聊聊,問候他們,問問他們最近如何?在忙什麼?」
    • 「善待身邊的人,是人生最有價值的投資。」
  • 比爾以簡單問候(如「家裡的人都好吗?」)拉近距離,先建立關係再處理工作,展現人性化領導風格。

2. 同理心與心理安全感

比爾的領導風格強調同理心,他以傾聽和觀察為基礎,提供適切建議,並創造讓團隊成員敢於表達的心理安全感。

  • 重要句子
    • 「比爾會傾聽與觀察。這是教練的能力,他能夠提供不一樣的觀點,帶你站在制高點看問題。」
    • 「在團隊中培養心理安全感,建立信任是關鍵。康乃爾大學曾在1999年研究中首次對心理安全感下了定義:『團隊成員一致認為可以在團隊中直言不諱,不必害怕會冒犯誰,那是一種團隊氣氛,讓人可以安心做自己。』」
    • 「信任是企業成功的基礎,但今日許多商業書已不再談論它……大家從比爾身上感受到最深刻的就是信任。」
  • 他鼓勵管理者以真誠回饋,承認問題並激勵團隊前進,確保成員感到被尊重和信任。

3. 解決問題與直面挑戰

比爾擅長找出並解決「房間裡的大象」,即那些被忽視的棘手問題,強調領導者應直面挑戰並優先處理。

  • 重要句子
    • 「找出大家避而不談的棘手問題,把它擺到所有人面前,然後優先解決,以免這些問題因辦公室政治繼續在公司裡悶燒,造成更大傷害。」
    • 「比爾會明確提出問題,強迫所有人都關注它,『不留任何空間給人搞辦公室政治』。」
    • 「只要有比爾在,房間裡永遠不會有大象。」
  • 他強調領導者應果斷承諾,專注於對團隊最好的選擇,並避免個人利益凌駕於團隊之上。

4. 有效溝通與積極聆聽

比爾推崇積極聆聽,強調專注傾聽、提問以釐清問題,並激發對方的效能感與歸屬感。

  • 重要句子
    • 「與人溝通時,首先要專注,把所有注意力放在聆聽對方說話;不要一邊聽,一邊想著自己接下來要講什麼。」
    • 「他從比爾那裡學到最重要的一件事,就是『把注意力放在面前的人,仔細聆聽,接著才開始討論,要達到真正有效的溝通,專注、聆聽、對話,是有先後順序的。』」
  • 他以說故事的方式引導他人自行做出最佳決定,而非強行命令。

5. 團隊管理與人才培養

比爾認為優質團隊是成功的關鍵,管理者應提供資源、尊重與信任,幫助人才成長並釋放潛能。

  • 重要句子
    • 「人才是任何公司的成功基礎。管理者的主要工作,就是協助部屬以更有效的方式完成工作,並從過程中有所成長。」
    • 「比爾是團隊教練,他的職責是建立團隊、型塑團隊,把合適的人放在合適的位置(以及讓不合適的人離開不合適他的位置)。」
    • 「做任何事都需要團隊的齊心協力。」
  • 他強調管理者應視部屬如孩子,引導他們走上正確道路,並以慷慨和尊重的態度處理離職事宜。

6. 董事會與高績效人才管理

比爾建議董事會應由具備營運實務經驗的人組成,並強調管理高績效但難相處的人才需平衡其貢獻與團隊和諧。

  • 重要句子
    • 「比爾告訴科斯托洛,你要有其他能仰仗的經營者。比爾也明確指出什麼樣的人是不好的董事:『那種人大搖大擺走進來,想當全場最聰明的人,而且話很多。』」
    • 「如何管理公司裡那些高績效、但難以相處的團隊成員,是管理者最頭痛的問題之一。」
    • 「如果這些恃才傲物的人,不斷把自己的利益看得比團隊更重要,就算再有才華,也不可容忍。」

7. 展現真誠與完整的人格

比爾以真誠和人性化領導聞名,強調管理者應展現完整的自己,並以信任和鼓勵激發他人潛能。

  • 重要句子
    • 「比爾從來不會在工作中刻意去除他的人情味。他也把每個人都當成一個完整的人來看待,有專業的一面、私下的一面、家庭的一面、情緒的一面,是全部面向加起來的一個完整的人。」
    • 「教練就是跟你說你不想聽的話,要你看你不想看的問題,最後讓你成就你想成就的人。」
    • 「比爾總是能把勇氣傳遞給我,而我也總是會因此受到鼓舞。我從比爾身上學到一點:要做一個給予別人能量的人,而不是一直消耗別人能量的人。」

8. 領導者的角色與責任

比爾認為領導者的核心在於做事並帶來影響力,而非僅靠頭銜或個人成就。他強調管理者應以公司利益為先,並以身作則。

  • 重要句子
    • 「你以前做什麼不重要,你現在想什麼也不重要,重點是你每天做了什麼。」
    • 「頭銜使你成為管理者,部屬使你成為領導人。」
    • 「管理者的第一要務,就是確保自己帶領的人既幸福又成功。」

心得

當初會看到這本書,只是沒有想到一個足球教練出身的比爾,竟然能成為百大 CEO 們的團隊導師。

這一本書給我很大的啟發,主要是領導團隊的方面。裡面有許多部分給我很多新的想法:

  • 帶領團隊,從「人」開始:
    • 很多時候,會覺得是制度對了。團隊應該會往正確的方向走下去,但是看起來,團隊中的人還是最大的因素。
  • 找出團隊問題中的「屋裡的大象」:
    • 「屋裡的大象」就是團隊中很明顯的問題,但是往往大家會忽略他。或是以為不需要去處理它,

這些案例,還有我上面相關書籤的文字其實都給我蠻多的想法的。也讓我知道,團隊中的重要問題,可能需要在許多會議前去解決掉。也很推薦許多想要領導團隊的人一起來看這一本書。

[Python][Gemini CLI] 使用 LangChain 中的 Vertex AI 來處理 LINE Bot 中的圖片內容

image-20250305221818691

前情提要

之前 [Python] 在 LangChain 中將 Gemini 換成使用 Vertex AI 曾經有分享給大家該如何使用 LangChain 中的 Vertex AI 的相關功能。它具有以下的優點:

  • 如果你專案放在 GCP CloudRun ,不需要額外放 Gemini API Key。可以更安全處理自己程式碼的安全性。
  • 使用了 VertexAI 還有許多相關進階功能可以使用,之後也可以慢慢分享。

這一篇文章主要寫程式的部分都是使用 Gemini CLI :p ,但是有一些地方也跟大家講一下如何跟 AI 來溝通才能避免錯誤卡住。

範例程式碼:

https://github.com/kkdai/linebot-gemini-python (大家可以參考 )

(透過這個程式碼,可以快速部署到 GCP Cloud Run)

關於 Vertex AI 上面使用 Gemini 來做圖形偵測的架構圖

image-20250728100915757

這一張網路的圖解釋得很清楚,這邊要記得由於 VertexAI 使用到 Gemini 圖片相關處理的時候,必須要使用到 GCS (Google Cloud Storage) ,所以你不能只是放某個網路圖片網址給他,而是必須要將圖片放入 Google Cloud Storage 的 Bucket 之中,才能處理。

這裡程式碼會有一些相關的修改,就會有以下的相關部分來解釋:

如何將圖片上傳到 GCS

  • 記得先到 GCS 建立一個新的 Bucket ,並且把這個名稱保持下來。放在環境變數上。 (這裡使用 GOOGLE_STORAGE_BUCKET )
  • 由於我們偵測完圖片後,就不會再次使用到他,所以可以馬上從 GCS 刪除,避免不小心沒刪除到,然後記得到 Lifecycle 設定一天的生命週期。

image-20250728101738917

要小心 Gemini CLI 使用 LINE Bot 套件造成不段重複錯誤

這邊要小心,即便我的 Gemini CLI 已經有使用了 Contex7 這個 MCP Server ,使得 Gemini CLI 永遠會去讀取最新的套件資訊。但是有時候,還是會卡住,這邊舉一個例子:

Google Chrome 2025-07-28 10.23.28

這是一個 我請 Gemini CLI 直接去開發如何使用 LangChain 中的 Vertex AI 來直接將 LINE Bot 圖片直接放到 GCS (Refer commit)

這邊會發現,其中會發現,他從 line_bot_api.get_message_content(event.message.id) 取得的物件,一直無法成功的取得相關的 stream 資訊。這邊我大改跑了三~四次的 prompt 都無法成功,所以只好人工下來請他修改一下:

其實我本來有先複製正確的寫法,請他幫我順一下之後:

  message_content = await line_bot_api.get_message_content(event.message.id)

  # Asynchronously read all content chunks into a byte string
  image_bytes = b''
  async for chunk in message_content.iter_content():
      image_bytes += chunk

  # Create an in-memory binary stream from the bytes
  image_stream = BytesIO(image_bytes)
  # Reset the stream's pointer to the beginning for the upload function
  image_stream.seek(0)

他還是會把它改回去,我只好又一次的糾正他,這時候才會正確。

image-20250728103206712

這時候才會寫正確 (Refer commit) :

Google Chrome 2025-07-28 10.23.32

相關程式碼,放一下:

        elif (event.message.type == "image"):
            user_id = event.source.user_id
            print(f"Received image from user: {user_id}")

            message_content = await line_bot_api.get_message_content(
                event.message.id
            )

            # Asynchronously read all content chunks into a byte string
            image_bytes = b''
            async for chunk in message_content.iter_content():
                image_bytes += chunk

            # Create an in-memory binary stream from the bytes
            image_stream = BytesIO(image_bytes)
            # Reset the stream's pointer to the beginning for the upload
            image_stream.seek(0)

            file_name = f"{uuid.uuid4()}.jpg"
            gcs_uri = None
            # Default error message
            response = "抱歉,處理您的圖片時發生錯誤。"

            try:
                gcs_uri = upload_to_gcs(
                    image_stream, file_name, google_storage_bucket)
                if gcs_uri:
                    print(f"Image uploaded to {gcs_uri}")
                    response = generate_image_description(gcs_uri)
            finally:
                # Clean up the GCS file if it was uploaded
                if gcs_uri:
                    delete_from_gcs(google_storage_bucket, file_name)

            reply_msg = TextSendMessage(text=response)
            await line_bot_api.reply_message(
                event.reply_token,
                reply_msg
            )
        else:
            continue

由於 GCS 相關使用方式,都是直接使用,大家快速參考即可:

def upload_to_gcs(file_stream, file_name, bucket_name):
    """Uploads a file to the bucket."""
    try:
        storage_client = storage.Client()
        bucket = storage_client.bucket(bucket_name)
        blob = bucket.blob(file_name)

        blob.upload_from_file(file_stream, content_type='image/jpeg')

        # Return the GCS URI
        return f"gs://{bucket_name}/{file_name}"
    except Exception as e:
        print(f"Error uploading to GCS: {e}")
        return None

成果:

image-20250728105409436

[好書分享] 日本製造 ,幻想浪潮 (動漫、電玩、Hello Kitty、2Channel,超越世代的精緻創新與魔幻魅力)

日本製造,幻想浪潮
動漫、電玩、Hello Kitty、2Channel,超越世代的精緻創新與魔幻魅力
Pure Invention: How Japan's Pop Culture Conquered the World
作者: 麥特‧阿爾特  
原文作者: Matt Alt  

買書推薦網址:

前言:

這是 2025 年第 3 本讀完的書,最近讀完的書籍越來越少,可能也跟花比較多的時間在學習 Vibe Coding 有關。這本書我買了蠻久的,但是也是斷斷續續直到近期才將他看完。 雖然裡面的故事都蠻久以前的,但是有許多不為人知的歷史背景與相關的史地資料都相當的珍貴。

大綱

◆ 幻想傳遞道具 ◆
每個人都是明星──【卡拉OK裝置】
◎屬性:魅力+10
◎使用方法:第一代卡拉OK裝置需要先投入100日圓,拿起麥克風盡情發揮即可,效果持續一整首歌。

為自己的世界配樂──【隨身聽】
◎屬性:自我恢復力增加50%
◎使用方法:放入錄音帶、戴上耳機、按下播放鍵,無論走到哪裡,都能親手打造自己的背景音樂。

讓幻想跟著你走──【任天堂Game Boy】
◎屬性:MP回復加速
◎使用方法:走到哪玩到哪,還可以連線對戰。對了,這裡的連線指的是真的用「電線」連接兩台Game Boy。

召集各路英雄的所在──【2Channel討論區】
◎屬性:號召力+20,組隊作戰攻擊力+5
◎使用方法:日本最大的線上匿名布告欄系統,介面簡單,但造成的影響可不簡單,使用者遍佈全日本。

────────────────

● 最後提醒 ●
請記住!這不單單只是這些創造者個人勝利的故事,在創造者所賦予的力量下,包括你我在內的無數玩家與使用者,都意外地親身參與了整個過程,也成為這個幻想世界的眾多推動者之一。

是的,這精采華麗的世界是由我們一起建造的。

心得

這一本書有講到四個很有「歷史感」但是又很有意義的商品: 卡拉OK,隨身聽,任天堂跟討論區。

這四個其實也代表著四個日本從戰後嬰兒潮後的四個重要事物:

  • 卡啦OK拉攏著「朋友」,對應著日本的疏離感。
  • 隨身聽帶來的「音樂」,讓每個忙碌上班族放鬆的方式。
  • 任天堂帶來的「幻想」,讓壓抑日本人放鬆自我的空間。
  • 2Channel 帶來的「連結」,讓每個人可以匿名的發表自己的想法。

雖然是四個因素,但是也告訴我們許多當時日本社會下的現象。同時也感受到那個時代下的日本究竟有多少的創意與現實中的拉扯與衝突。 但是許多的產物都是很美好且難以抹滅的。 日本真的是造就了新的 ACG 世代之外,也有許多創作物讓世世代代的年輕人都難以忘記。

蠻有趣的一本書,很推薦大家來看。

[Gemini CLI] 用 Vibe Coding 打造你的專屬應用:我的 Gemini CLI 健身日誌實戰

Google Chrome 2025-06-25 22.05.23

前言

近期的開發圈,圍繞著「Vibe Coding」的討論不絕於耳,其中 Claude Code 的出現更是將這個概念推向了高峰。這是一種全新的開發典範,開發者透過對話與描述「感覺」來讓 AI 生成程式碼。在這波浪潮中,Google 也推出了自家的殺手級應用:Gemini CLI

本篇文章將分享我如何透過 Gemini CLI,從零開始打造一個個人化的健身日誌 Web App。你會發現,導入這種與 AI 協作的終端機工具後,開發流程不僅僅是加速,更是從根本上改變了我們與程式碼互動的方式。

本次的程式碼與成果

本次實作的專案是一個簡單的訓練日誌,最終成果如上圖所示。

專案 Repo:

快速複習 Vibe Coding

在深入 Gemini CLI 之前,我們先快速摘要一下「Vibe Coding」這個概念。傳統開發模式中,我們需要逐行撰寫精確的指令來建構應用程式。然而,Vibe Coding 讓我們能用更自然、更貼近人類思維的方式與 AI 協作。

開發者不再需要專注於每一行語法的細節,而是可以描述更高層次的目標,例如:

我需要一個深色主題、看起來專業的儀表板

或是

幫我建立一個 API 端點來記錄數據

AI 會理解這些意圖,並將其轉換為具體的程式碼與架構。Gemini CLI 正是實現這種開發模式的強大工具。

導入 Gemini CLI 實戰

Gemini CLI Screenshot

Gemini CLI: https://github.com/google-gemini/gemini-cli

Google 官方文章: https://blog.google/technology/developers/introducing-gemini-cli-open-source-ai-agent/

接下來,我們將拆解如何利用 Gemini CLI 來完成這個健身日誌專案。

第一部分:從 UI 概念到前端程式碼

一個專案的起點,往往是介面設計。在這個階段,我並沒有自己動手畫圖或寫 CSS,而是採用了以下的流程:

  1. 利用 AI Studio 產生 UI Layout:我先到 AI Studio,向它描述我想要的介面風格——簡潔、專注於資訊呈現、易於操作。AI 很快地提供了幾個視覺佈局供我參考。
  2. 生成 Tailwind CSS:在確定了喜歡的風格後,我請 AI Studio 將這個設計轉換成 Tailwind CSS 的格式。這是一個現代化的 CSS 框架,能讓我快速建構出美觀且響應式的介面,而我甚至不需要深入了解其語法細節。

可以看得出來,在專案初期,Gemini 生態系內的工具已經能幫助我們快速將模糊的想法具體化為可用的前端程式碼。

第二部分:了解 Gemini CLI 的運作大腦

有了前端的基礎後,接下來就是 Gemini CLI 大展身手的時刻。它不僅僅是一個程式碼生成器,更像是一個常駐在你終端機裡的資深開發夥伴。

它的強大之處在於:

  • 專案上下文理解:你只需要在專案目錄下啟動它,它就能夠掃描並理解整個專案的檔案結構與既有程式碼。
  • 整合開發工具鏈:它可以直接幫你執行 git 指令來進行版本控制,甚至能透過 gcloud 指令,將你的應用程式一鍵部署到 Cloud Run。
  • 建立自動化工作流:你可以和它建立「默契」。例如,我曾對它下達指令:

以後改完程式碼,都幫我 push 到 GitHub,然後直接跑一次本地端伺服器給我驗證。

從此,這個開發、測試、提交的循環就變得完全自動化且極其順暢。

Gemini CLI 的核心是將 Gemini 1.5 Pro 強大的模型能力與開發者熟悉的 CLI 環境深度整合,讓它能理解你的指令,並調用對應的工具來完成任務。

第三部分:根據實戰結果,來分析一下差異

導入 Gemini CLI 後,與傳統開發流程相比,最顯著的差異有兩點:

  1. 開發流程的無縫整合與自動化 以往,寫碼、測試、版本控制、部署是幾個獨立的步驟,需要手動切換工具與執行指令。但在 Gemini CLI 的輔助下,這些流程可以被串連成一個單一的對話指令。就像前面提到的,一個「改完就推送到 GitHub 並本地運行」的指令,就取代了過去繁瑣的手動操作,大幅提升了開發效率。

  2. 從抽象指令到具體成果的轉譯能力 傳統開發需要我們將需求拆解成非常具體的技術任務。但使用 Gemini CLI,我可以下達更為抽象的指令,例如「幫我把這個列表功能做出來」,它會自己分析現有程式碼,生成對應的邏輯並整合進去。它彌補了從「想法」到「程式碼」之間的巨大鴻溝。

超佛心的免費方案!

看到這裡,你可能會好奇這樣強大的服務是否所費不貲。Google 這次提供了極具誠意的免費方案!

只需使用個人 Google 帳戶登入,即可獲得免費的 Gemini Code Assist 授權。此授權包含:

  • 存取強大的 Gemini 1.5 Pro 模型
  • 高達 100 萬個 token 的龐大上下文視窗
  • 每分鐘 60 次模型請求
  • 每日 1,000 次免費請求

這個額度對於個人專案、學習或 POC 驗證來說,綽綽有餘,堪稱佛心!😍

未來的展望

本篇文章主要介紹了如何利用 Gemini CLI 這一新興工具,將 Vibe Coding 的概念應用於實戰,並成功打造出一個 Web App。可以預見,這類與 AI 深度整合的開發工具將會越來越普及。開發者的角色也將從「程式碼的撰寫者」逐漸轉變為「AI 協作的指揮者」。

接下來,我們或許可以探索更多 Gemini CLI 與 Google Cloud 生態系整合的複雜應用。期待這個工具能為開發者社群帶來更多的可能性,我們下次見。

[DevOps] Netflix 遊戲平台總監將解決技術債視為一種創新 - Tech debt as innovation by Bruce Wang

前提

好像是在 Threads 看到有人貼出的貼文,這明明是一個 25 分鐘的短篇演講。 但是我卻花了兩三個小時仔細的看他,並且不斷勾起我以前的回憶。 這是一篇 LeadDev 研討會的演講,主要內容探討到軟體開發人員最害怕的「技術債」(Technology Debt)。

Netflix的Bruce Wang分享技術負債管理經驗:技術負債是創新的自然產物,需建立共通語言與明確定義,公開討論並主動處理。技術負債管理得當可促進業務創新,推動公司成長。

相關內容分享

以下內容大多是針對某幾張投影片,做一些註解並且寫上自己的想法。

以下哪些不是 Tech Debt?

  • 商業決策(老闆不做的) - 沒有資源
  • 不同 model 間缺乏溝通
  • Bug. (很常~~懶得解就說是技術債)
  • Bad Code (寫的爛~也不會是技術債) - 效能問題 (效能問題絕對不是技術債)
  • 你對這些程式碼不熟…. (好像超多人講這個,好像重寫就沒有技術債一樣 XD)

image-20250610224541232

如何定義與描述「技術債」的準則:

定義上:

  • 最重要需要去研究你所謂的「技術債」究竟是什麼? 不能只是說一句,這是某個舊的框架,所以是個技術債。
  • 要「明確」,「可視化」並且「主動」去將技術債都找出並且明確的定義出來。

image-20250610224523232

對於「技術債」的處理方式:

精確的找到它,給它取個名字。

  • 某個 Tunnel 資訊流通上的限制 -> Tunnel X Project 不可以遇到事情,就說這是「技術債」。
  • 需要清楚的講出來是哪個技術債,不要把技術債當作是不想修復與不想處理上的籠統(suitcase)名詞。

image-20250610224459656

「Maintain/Improve 還是 Migrate?」

軟體開發流程上,許多軟體開發工程師往往接手舊的系統,到了要維護(或是優化)的狀況下,比較沒有經驗的人經常會選擇直接 migrate 到新的系統。 這往往是最有風險的事情,有太多危險可能發生:

  • 主管變動(忽然不想改)
  • 人員變動(又換了一組人)
  • 外在環境變動(生意忽然沒了? Covid 造成生意大好?)
  • 技術變動(AI 忽然跑出來)
  • 最大的風險是: 你根本不知道 Migrate 過去。

你所謂的技術債就會消失。 或許根本不會…. 你只會有一堆商業邏輯忘記搬過來。

image-20250610224439613

破解技術債的迷思

  • Legacy 不是 技術債,只是你沒花時間去搞懂他。
  • 技術債不需要全部清完,而是在必要時候去清除最重要的。
  • 技術債因為牽扯重要商業邏輯與更底層的技術,讓專業(資深)的來。
  • 技術債發生在任何產品中,新創產品其實更多。
  • 導入新的程式語言,新的框架,只會引來更多技術債。
  • 面對技術債,每一間公司都是有辦法來面對的。

image-20250610223511187

處理好技術債,面對更多商業挑戰

如果我們可以更有智慧,有積極的面對這些技術債,而不是天天將技術債作為不想維護的藉口。這樣我們才是認真面對這個商業服務,也才能更有信心的對接下來的商業需求說 “YES” 。

image-20250610224033292

後話

雖然是一個 25 分鐘的演講,但是我卻花了兩三個小時慢慢地欣賞跟品味每一段文字。 許多內容也呼應了身為軟體開發的心路歷程與以前的血淚(?)。 蠻推薦大家要好好思考這些相關的內容。