[Google Cloud] 如何在 GCP Cloud Run 上面透過 LangChain 取得 YouTube 的相關資訊

image-20241006183038597

前言

之前提到過,我開發了一個「透過 IFTTT 與 LangChain 打造的科技時事 LINE Bot」,這個 Bot 可以幫助我獲取所需的資訊。然而,最近我發現許多 YouTube 影片中包含了豐富的技術資訊,這促使我思考如何有效地獲取 YouTube 字幕資訊以便整理和分析。

雖然 LangChain YouTube Transcripts Loader 可以快速獲取字幕資訊,但在部署到 Google CloudRun 時卻遇到了一些問題。本文將分享我遇到的問題及解決過程,希望能對大家有所幫助。

使用 LangChain YouTube Transcripts Loader 獲取影片字幕

根據 LangChain 的教學文件 (YouTube transcripts),我們可以使用這個套件來獲取帶有字幕的 YouTube 影片,並通過分析快速了解影片內容。以下是一些範例程式碼:

%pip install --upgrade --quiet pytube
loader = YoutubeLoader.from_youtube_url(
    "https://www.youtube.com/watch?v=QsYGlZkevEg", add_video_info=True
)
loader.load()

在 GCP CloudRun 上無法獲取資料

當我嘗試將程式碼部署到 Google CloudRun 時,使用以下程式碼:

def summarized_from_youtube(youtube_url: str) -> str:
    """
    Summarize a YouTube video using the YoutubeLoader and Google Generative AI model.
    """
    try:
        print("Youtube URL: ", youtube_url)
        # Load the video content using YoutubeLoader
        loader = YoutubeLoader.from_youtube_url(
            youtube_url, add_video_info=True, language=["zh-Hant", "zh-Hans", "ja", "en"])
        docs = loader.load()

        print("Pages of Docs: ", len(docs))
        # Extract the text content from the loaded documents
        text_content = docs_to_str(docs)
        print("Words: ", len(text_content.split()),
              "First 1000 chars: ", text_content[:1000])

        # Summarize the extracted text
        summary = summarize_text(text_content)

        return summary
    except Exception as e:
        # Log the exception if needed
        print(f"An error occurred: {e}")
        return ""

結果卻完全無法獲取任何資料,沒有錯誤訊息,但結果是空的。

image-20241005230731585

Debug 1: 在 Colab 上測試相同程式碼

可以參考以下的 gist 程式碼

image-20241005230200026

起初我以為是程式碼的問題,但在 Colab 上卻能正常執行。看來需要使用 GoogleApiYoutubeLoader

在 Google CloudRun 上使用 LangChain Youtube Loader

要在 CloudRun 上使用 GoogleApiYoutubeLoader,需要遵循以下步驟:

image-20241005231500039

image-20241006001807126

使用 Secret Manager 獲取資料

  • 首先需要在環境變數中設定 Project ID PROJECT_ID
  • 然後將資料預先存放在 youtube_api_credentials 中。
def get_secret(secret_id):
    logging.debug(f"Fetching secret for: {secret_id}")
    client = secretmanager.SecretManagerServiceClient()
    name = f"projects/{os.environ['PROJECT_ID']}/secrets/{secret_id}/versions/latest"
    response = client.access_secret_version(request={"name": name})
    secret_data = response.payload.data.decode("UTF-8")
    logging.debug(f"Secret fetched successfully for: {secret_id}, {secret_data[:50]}")
    return secret_data

這樣就可以安全地透過 Secret Manager 獲取資料。

在 GCP CloudRun 上部署範例程式碼

程式碼: https://github.com/kkdai/gcp-test-youtuber

def load_youtube_data():
    try:
        logging.debug("Loading YouTube data")
        google_api_client = init_google_api_client()

        # Use a Channel
        youtube_loader_channel = GoogleApiYoutubeLoader(
            google_api_client=google_api_client,
            channel_name="Reducible",
            captions_language="en",
        )

        # Use Youtube Ids
        youtube_loader_ids = GoogleApiYoutubeLoader(
            google_api_client=google_api_client,
            video_ids=["TrdevFK_am4"],
            add_video_info=True,
        )

        # Load data
        logging.debug("Loading data from channel")
        channel_data = youtube_loader_channel.load()
        logging.debug("Loading data from video IDs")
        ids_data = youtube_loader_ids.load()

        logging.debug("Data loaded successfully")
        return jsonify({"channel_data": str(channel_data), "ids_data": str(ids_data)})
    except Exception as e:
        logging.error(f"An error occurred: {str(e)}", exc_info=True)
        return jsonify({"error": str(e)}), 500

成果

影片來源:https://www.youtube.com/watch?v=TrdevFK_am4

image-20241006004150943

[好書分享] 我的孩子是霸凌者

Image

作者: しろやぎ秋吾  譯者: 葉門  出版社:台灣角川 
出版日期: 2024/08/23 語言:繁體中文 

買書推薦網址:

前言:

這是 2024 年第 10 本讀完的書。週末的時候,我經常與小孩在誠品書局閱讀,有時候我會看一些雜誌與月刊,這一本書忽然在書架上吸引我的目光,內容不長但是影響很深遠。

內容摘要:

★當知道自己的孩子是「加害者」,父母該如何面對?
★留下的傷口絕無法輕易消逝。被道歉了,難道就一定要選擇原諒嗎?

「我可不記得有把妳教成這種孩子!」

最疼愛的女兒,竟與自己最憎恨的存在劃上等號。
不可原諒的霸凌事件,女兒居然是「加害者」。

關於孩子,原來我一無所知──

▍本書內容
新聞內容播報著「校園霸凌事件」的惡行。

『我的孩子絕不會這樣。』
──赤木加奈子認為那只是與自己無關的社會事件。
然而某天,她竟得知自己的女兒.愛,
在班上對同班同學.馬場小春有霸凌行為。
國中時曾遭受同儕霸凌的加奈子,對此難以忍受。
對自己孩子的厭惡、憤怒,不斷湧上心頭。

另一方面,接受了赤木家道歉後的小春卻開始拒絕上學。
對孩子的不捨、獨自承受外界的壓力,
小春的母親.千春,選擇向第三者傾訴煩惱。

此時網路上的一則匿名貼文成了導火線,
將這件事推向無法預測的方向──

對孩子的不信任感、夫妻間意見的相左、社群媒體上的批判…
被各式問題折磨的雙方家庭。
同時描寫「加害者」與「受害者」雙視角,以不同的視角探討校園霸凌!

心得:

如果你的小孩霸凌別人怎麼辦? 身為爸媽,或許第一句都會是「怎麼可能? 我才不會教導出這樣的小孩」。

小春跟小愛是從小的好朋友,忽然有一天小愛開始欺負小春,甚至在班上鼓勵與霸凌他。

小春後來不敢上課,他的媽媽打給小愛的爸媽報價道歉也沒有改善。小春完全不敢上課,小愛的媽媽雖然是霸凌者的爸媽,但是她小時候也是被霸凌的人。讓小愛的媽媽無地自容。

這本書深入從霸凌事件的兩個家庭去深入描繪。後來霸凌的影片被張貼出來,整件事情更是爆鍋。

小愛在路上被其他人霸凌,他的爸媽上了學校檢討會。 但是小春還是沒有辦法去上學。 或許這個時候、如果是電影,我們會說霸凌者活該。但是這是一個真實是一事件取材。霸凌者被揭開後,他有說要生活的。後來他們也是被逼迫離開學校。小愛同樣也受到不可抹滅的傷害。

[Gemini/Firebase] 個人資訊流 - 透過 IFTTT 與 LangChain 打造科技時事 LINE Bot

PlantUML diagram

近期

最近弄了一個資訊流,我覺得很有趣:- IFTTT 抓取 HN, HuggingFace 熱門文章

  • 發到 Webhook 裡面有 LangChain 抓爬蟲 + LangChain Summary
  • 發 LINE Bot 給自己看
  • 挑選自己喜歡的,直接貼到 Twitter (目前沒有付費 API 沒辦法發長文

程式碼: https://github.com/kkdai/gh-summarized-scheduler

IFTTT 設定

image-20240911222516788

image-20240911222612321

成果

image-20240911222313402

  • 有詳細的文章連結跟文章摘要。
  • 可以快速決定要不要進去看。
  • 整個格式也改成可以直接複製貼到 Twitter (我有付費發長文)

未來發展:

  • 照理說應該要可以一鍵發文到 twitter ,但是 X API 好貴(一百美)
  • 有想過用 IFTTT 來發文 Twitter 但是有長度限制 (128) ,不能用。
  • 不過 Threads API 似乎可以發長文。

[Gemini/Firebase] 土炮打造- 透過 Firebase 作為 Embedding Vector DB 透過 Gemini 來幫你的 Github Page Blog 做 RAG 服務

RAG

前提

我是一個很喜歡寫作的人,經常學習到東西都會記錄在這一個網站裡面。陸陸續續從 2002 年也寫了 20 多年的部落格。但是經常自己也是會忘記我曾經寫過什麼樣的內容。

之前我也曾經說明過:將我會的東西整理成部落格,主要不是為了幫助其他人,最重要是可以幫助到未來的自己。總有一天你會遇到類似的問題,而你的文章的思緒跟脈絡就跟你想的一樣。只要透過類似的關鍵字,馬上就可以找到你的回憶。

伴隨著 LLM 生成式 AI 的爆發性成長,其實再也不需要透過 Google Search 來搜尋自己寫過的內容。 其實你可以透過 RAG 的方式來直接去詢問一個聊天機器人來達到類似的工作。

相關的內容其實有很多,透過 LangChain 要來做一個 RAG 的功能更是相當的簡潔。 但是本篇文章將反樸歸真,透過 Python 與 Google Gemini 與 Firebase DB 直接告訴你如何打造 Embedding DB ,做成一個可以簡易的查詢功能的 RAG 應用。

完整相關程式碼:

https://github.com/kkdai/jekyll-rag-firebase

透過 Firebase Realtime DB 來當成 Vector DB

程式碼: https://github.com/kkdai/jekyll-rag-firebase/blob/main/embedding.py

image-20240823122740989

之前就一直在思考,究竟有沒有方式可以透過 Firebase 來做 Vector DB。其實是可以的,方式如下:

def generate_embedding(text):
    result = genai.embed_content(
        model="models/text-embedding-004",
        content=text,
        task_type="retrieval_document",
        title="Embedding of single string"
    )
    embedding = result['embedding']
    return embedding

這是一個透過 tex-embedding-004 的 gemini model ,可以幫助你直接將一串文字直接產生 Embedding 的 Vector Value 。

如果要將資料儲存在 Firebase 的資料庫內,其實也沒有那麼複雜。以下程式碼可以很快速了解。

def store_embedding(embedding_data):
    ref = db.reference('embeddings')
    ref.child(embedding_data['id']).set(embedding_data)
    print(f"Embedding data for {embedding_data['id']} stored successfully.")

完整範例大概如下:


# 範例文字
text_1 = "What is the meaning of life?"
text_2 = "How to learn Python programming?"
text_3 = "The quick brown fox jumps over the lazy dog."

# Embedding Vector Value
embedding_vector_1 = generate_embedding(text_1)
embedding_vector_2 = generate_embedding(text_2)
embedding_vector_3 = generate_embedding(text_3)

# 產生 DB data
embedding_data_1 = {
    'id': 'embedding_1',
    'vector': embedding_vector_1
}

embedding_data_2 = {
    'id': 'embedding_2',
    'vector': embedding_vector_2
}

embedding_data_3 = {
    'id': 'embedding_3',
    'vector': embedding_vector_3
}

# 儲存資料
store_embedding(embedding_data_1)
store_embedding(embedding_data_2)
store_embedding(embedding_data_3)

如何解析 Github Page 的 Blog 資料? (以 Jekyll 打造的 Blog 為例子)

範例部落格資料: https://github.com/kkdai/kkdai.github.io

程式碼:

image-20240823124515723

裡面會看到,公開的文章會放在 _posts 資料夾下面。 雖然裡面是 Markdown 的內容,但是這樣的內容往往更適合給 LLM 作為總結與 Embedding 使用。 接下來來看一下程式碼。

取得 Github Token

請參考這篇文章,有完整教學該如何取的 Github Token 作為 Github 操作之用。

讀取 Github 上面的檔案資料

def git_article(github_token, repo_owner, repo_name, directory_path):
    g = Github(github_token)
    repo = g.get_repo(f"{repo_owner}/{repo_name}")
    contents = repo.get_contents(directory_path)
    
    files_data = []
    
    while contents:
        file_content = contents.pop(0)
        if file_content.type == "dir":
            contents.extend(repo.get_contents(file_content.path))
        else:
            files_data.append({
                'file_name': file_content.name,
                'content': file_content.decoded_content.decode('utf-8')
            })
            print(f"Downloaded {file_content.name}")
    
    result = {
        'files': files_data,
        'total_count': len(files_data)
    }
    return result

這段程式碼,可以指定給他 tokenrepo_owner, repo_namedirectory_path 之後。他會將裡面的檔案一個個存取出來。

整個打包 - 讀取 Github Page 然後製作 Embedding Vector 在 Firebase 上

程式碼: https://github.com/kkdai/jekyll-rag-firebase/blob/main/blog_embedding.py

直接單獨執行這個程式碼即可。但是整個資料夾時間會比較久,也會花費相當程度的費用。

這部分程式碼中,請記得要將以下資料改成你的資料夾資料。

  • REPO_OWNER = ‘kkdai’
  • REPO_NAME = ‘kkdai.github.io’
  • DIRECTORY_PATH = ‘_posts’
def git_article(github_token, repo_owner, repo_name, directory_path):
    g = Github(github_token)
    repo = g.get_repo(f"{repo_owner}/{repo_name}")
    contents = repo.get_contents(directory_path)
    
    files_data = []

    while contents:
        file_content = contents.pop(0)
        if file_content.type == "dir":
            contents.extend(repo.get_contents(file_content.path))
        else:
            file_id = file_content.name.split('.')[0]
            if check_if_exists(file_id):
                print(f"File {file_id} already exists in the database. Skipping.")
                continue
            
            file_content_decoded = file_content.decoded_content.decode('utf-8')
            cleaned_content = remove_html_tags(file_content_decoded)
            embedding = generate_embedding(cleaned_content)
            
            embedding_data = {
                'id': file_id,
                'vector': embedding.tolist(),  # 将 numpy 数组转换为列表
                'content': cleaned_content
            }
            store_embedding(embedding_data)
            
            files_data.append({
                'file_name': file_id,
                'content': cleaned_content
            })
            print(f"Downloaded and processed {file_id}")
    
    result = {
        'files': files_data,
        'total_count': len(files_data)
    }
    return result

這邊稍微解釋一下,整個邏輯:

  • 讀取 jekyll 目錄底下 _posts
  • 取出檔案名稱,比如 2024-08-10-reading-elon-musk 作為 firebase 的 I
  • 先檢查是否已經在 Firebase Realtime DB 中有存在的物件
    • 如果有,就 skip 到下一個檔案
  • 取出裡面 utf-8 編碼的內容 file_content.decoded_content.decode('utf-8')
  • 並且去除掉所有 HTML tags remove_html_tags
  • 透過 generate_embedding 來產生整篇文章的 embedding vector value
  • 存入資料庫

透過 Firebase Realtime DB詢問資料

程式碼: https://github.com/kkdai/jekyll-rag-firebase/blob/main/blog_query.py

直接單獨執行這個程式碼即可。

# 示例调用
if __name__ == "__main__":    
    # 示例查询和生成响应
    question = "我哪一天架設 oracle8i 的?"
    response = query_and_generate_response(question, top_k=1)
    for res in response:
        print(f"File ID: {res['file_id']}, Similarity: {res['similarity']}")
        # print(f"Content: {res['content']}")
        content_str = res['content']
        # print(f'content_str: {content_str}')
        prompt = f"""
        use the following CONTEXT to answer the QUESTION at the end.
        If you don't know the answer, just say that you don't know, don't try to make up an answer.

        CONTEXT: {content_str}
        QUESTION: {question}

        reply in zh_tw
        """

        # print(f'prompt: {prompt}')
        completion = generate_gemini_text_complete(prompt)
        print(completion.text)
  • 先產生問句 question 的 Embedding

  • query_and_generate_response(question, top_k=1) 其中 k=1 只要最接近的一個答案。

    • def query_embedding(question, top_k=1):
          # 生成问句的嵌入
          question_embedding = generate_embedding(question)
              
          # 从数据库中获取所有存储的嵌入
          ref = db.reference('blog_embeddings')
          all_embeddings = ref.get()
              
          if not all_embeddings:
              return "No embeddings found in the database."
              
          # 计算问句嵌入与存储嵌入之间的相似度
          similarities = []
          for file_id, embedding_data in all_embeddings.items():
              stored_embedding = np.array(embedding_data['vector'])
              similarity = 1 - cosine(question_embedding, stored_embedding)
              similarities.append((file_id, similarity))
              
          # 按相似度排序并返回最相关的结果
          similarities.sort(key=lambda x: x[1], reverse=True)
          top_results = similarities[:top_k]
              
          results = []
          for file_id, similarity in top_results:
              file_content = ref.child(file_id).get()
              results.append({
                  'file_id': file_id,
                  'similarity': similarity,
                  'content': file_content
              })
              
          return results
      
    • 講問題與每一個資料的比對結果存入 similarities

    • 透過排序之後,挑選最相似的答案

      • similarities.sort(key=lambda x: x[1], reverse=True)
        top_results = similarities[:top_k]
        
  • 取出資料之後,將問句跟參考資料放入 prompt 之中來詢問。

    • prompt = f"""
      use the following CONTEXT to answer the QUESTION at the end.
      If you don't know the answer, just say that you don't know, don't try to make up an answer.
          
      CONTEXT: {content_str}
      QUESTION: {question}
          
      reply in zh_tw
      """
      
  • 回覆答案。

未來發展

本篇文章透過一些簡單的程式碼,來了解如何透過 Gemini 與 Firebase Realtime DB 來打造一個 RAG 的應用。程式碼儘可能使用原生的一些套件,儘量不使用比較複雜的 LangChain 或是 LlamaIndex 。

雖然使用 LangChain 或是 LlamaIndex 打造出來的 RAG 會更加的效果好甚至程式碼更少。但是我們還是需要知道 RAG 的原理是什麼,這樣才能針對相關的細節來優化與改善。

接下來我們可以持續改善的方向如下:

  • Embedding 的方式與演算法
  • 如果文章修改了,可以自動來更新 Embedding DB
  • 透過 LINE 官方帳號的應對與回覆,可以有更漂亮的畫面與相關應用。

[研討會筆記] Made by Google 一些雜記

在 20240814 凌晨有 Made by Google 的線上發表會,這裡快速記錄一些資訊。

手機相關功能

連接 YouTube 的 RAG

image-20240814130417331

直接問說影片裡面主角吃了什麼食物?後來就全部列下來。

預設電話筆記

Google Chrome 2024-08-14 12.52.23

  • 全程語音 STT 記錄下來
  • 資料放手機端
  • 不過應該還是會有隱私的問題。

Make you look

image-20240814131558885

拍小朋友照片,總是難以抓到小孩注意力。

這個小功能很聰明誒~我很喜歡。

一些心得

Google 也在自己手機加上了 on-device LLM ,首先看到幾個不錯的應用。

  • 電話筆記本真的很實用,不過會不會有隱私問題,我也很好奇就是。
  • 連接 YT 的 RAG 詢問,感覺會是需要付費的功能。(Gemini Advance)

期待著九月 iPhone 發表會會有什麼應對?

相關資料:

Google 舉辦了年度 Made By Google 發表會,推出了 Pixel 9 系列手機、Pixel Watch 3 手錶和 Pixel Buds Pro 2 耳機,並整合了 Gemini AI 技術。

重點:

  • Gemini Live 語音對話功能上線: 允許用戶與 Gemini AI 進行自然語音對話,並選擇回應的聲音。目前僅支援英語,提供給 Gemini Advanced 訂閱用戶。
  • Pixel 9 系列手機: 搭載 Tensor G4 晶片,支援多項 AI 功能,包括 Pixel Weather、Call Notes、Pixel Screenshots、Pixel Studio 等。攝錄功能也升級,新增 Add Me、Made You Look 和 Magic Editor 等 AI 功能。
  • Pixel 9 Pro Fold: 首次推出摺疊螢幕手機,搭載 16GB 記憶體,具備 Pixel Pro Camera。
  • Pixel Watch 3: 延續經典圓弧造型,新增 Lost of Pulse Detection 功能,可偵測用戶脈搏並緊急通報。
  • Pixel Buds Pro 2: 搭載 Tensor A1 晶片,體積更小、重量更輕,ANC 降噪功能更強,並支援 Gemini 語音助理。

總體而言,Google 在這次發表會上展示了其在 AI 和硬體方面的最新進展,並強調了 Gemini AI 在各項產品中的

[好書分享] 馬斯克傳:唯一不設限、全公開傳記

馬斯克傳:唯一不設限、全公開傳記
Elon Musk
 共 138 人評分
作者: 華特.艾薩克森  原文作者: Walter Isaacson  譯者: 吳凱琳  出版社:天下雜誌出版 

買書推薦網址:

前言:

這是 2024 年第 9 本讀完的書。這本在當初要出刊的時候就相當的轟動,但是實際看到實體書之後,應該也會不少人會被勸退。 但是其實書籍本身還是蠻有趣的,蠻推薦大家可以看一下。

內容摘要:

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

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

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

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

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

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

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

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

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

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

投影片

https://gamma.app/docs/-4rx3tbi4xovhgkk

image-20240813185124640

心得:

當初看這本書,原本就是一個很欣賞 Musk 在許多層面的成就。但是對他的過往與相關成就又沒有那麼的熟悉,於是買了這本書來看。本來想說這一本書可能會看很久(因為真的很厚一本,就算用電子書來看,也是覺得看了很久)。但是其實整本書及說明了許多階段的馬斯克的過往,讓人很容易沈浸其中。

我覺得他的個性跟他得成長環境有相當大的關係,當然也跟他天生下來個性也有關。

image-20240815213408533

雖然大家都說馬斯克是暴君,是一個喜怒無常的人。(類似的形容詞好像也有出現在 Jobs 身上)但是比起 Jobs 是一個超級的產品經理加上銷售人員。 Musk 就像是超級工程師加上極度會節省成本的老闆。

image-20240815213314272

當然講到作為一個老闆,大家都對於馬斯克頗受爭議的一些作為跟思維有關,以下也整理一些。

image-20240815213525179

這本當然有提到 Tesla, SpaceX 甚至到了近期的 Twitter 購併跟 Neuralink 。這邊稍微提一下 Neuralink 的目標。

image-20240816125104596

為什麼馬斯克那麼的獨特? 而且為什麼他願意做這樣的事情,我們不知道,但是能夠像他這樣每次都把自己手上所有身家都壓下去,並且全心下去做的企業家,至今真的很少。 在 TED 的主持人就有問他這樣的問題,為什麼你願意把自己身家都放在一個全新的領域。是否有一些比較好的訣竅?

image-20240816124926360

馬斯克則拿出他的思考邏輯,試著去思考基礎的真理。不要去想著人家告訴你們怎麼做,或是原有的規範與流程。透過相關的思考,可以將許多重大事情的成本加以大幅度地降低,或是將許多困難的事情重新的去思考與測試。

image-20240816125452931

這件事情相當的重要,我想也是這本書籍一個很推薦大家去了解的點。

許多事情的作法上,永遠存在兩種以上的方向。一個是最輕鬆的,另外一個需要不斷地思考與測試才能看到的正確道路。
當你選擇最輕鬆的那一條路,往往那是得不到成功(或許是拒絕或是放棄)。
試著再思考一次,從物理邏輯上去重新思考。

真的很推薦大家去看這本書。

相關資料: