跳到主要內容

NLP Day 25 RAG 架構總覽:檢索、增強與生成

NLP Day 25 RAG 架構總覽:檢索、增強與生成

執行需求:CPU 可跑。本篇以「架構圖+小型端到端 demo」說明檢索增強生成(RAG)的三段流程:檢索(retrieval)、增強(augmentation)、生成(generation)。範例用 Day 24 的維基百科資料與 Qdrant 1.12 做檢索,搭配一個簡單的 prompt 模板與「抽取式回答」當作本地生成器,整個 demo 在 CPU 上 5 分鐘內完成;章節末會展示如何把本地生成器換成 Ollama 上的小模型,整篇啟用一個「不用 API Key 也能完整跑」的 RAG 流程。

引言

Day 24 我們用 sentence-transformers 與 Qdrant 1.12 做了一個能用的語意搜尋系統:給定查詢文字、回傳最相關的幾個段落。這個搜尋本身已經有價值(例如做文件推薦、相似段落比對),但對大多數產品來說還差一步——使用者想看的是「自然語言的答案」,而不是「五個段落讓我自己讀」。這就是檢索增強生成(Retrieval-Augmented Generation,RAG) 出現的原因:把檢索與 LLM 生成結合,讓模型在「有資料可查」的條件下生成答案。

RAG 的核心動機是解兩個 LLM 的老問題。第一是幻覺:LLM 會自信地編造不存在的事實,這在醫療、法律、企業內部問答是不可接受的。第二是知識截止:模型只知道自己訓練截止日的知識,無法回答 2024 年之後的事件,也無法記住企業私有資料。RAG 把「外部事實」先檢索出來、塞進 prompt、再讓模型基於這些事實回答,從而把生成內容鎖在可控範圍內。這是 2020 年 Lewis 等人在 Meta 發表的原始論文之後,整個產業大量採用的工作流。

更精確地說,RAG 系統在「幻覺」問題上只能緩解、無法完全消除。即使 prompt 中放入了正確的段落,LLM 仍可能在生成時偏離資料、加入自己的猜測,或對「資料未提到」的細節自由發揮。這就是為什麼 Day 29 的評估章節要把「忠實度(faithfulness)」當成關鍵指標——它衡量的是「答案真的根據提供的段落回答」這件事的可靠度。實務上 RAG 通常與其他技術疊加使用(例如 citation 標註、self-check、事後驗證),組成多層防線。

今天會把 RAG 拆成三段:檢索(retrieval,昨天的 Qdrant)、增強(augmentation,把檢索結果組裝進 prompt)、生成(generation,LLM 看 prompt 回答)。我們會用一個端到端的小型 demo 把三段串起來,並指出每一段在 RAG 系統中可以換成哪些常見實作。讀完這篇你應該了解 RAG 的工作流,以及為什麼「檢索品質」決定了整個系統的上限。明天我們會把檢索這一塊展開成完整管線:文件切分、嵌入、metadata 設計。

RAG 的三段架構

RAG 的工作流可以拆成三個階段,每個階段各自有常見實作。檢索階段負責「從大量文件中找出與查詢最相關的段落」。最常見的實作是昨天那套:先用嵌入模型把查詢編碼成向量,在向量資料庫裡 ANN 搜尋前 k 筆,再用 metadata filter 縮窄範圍。檢索階段的關鍵指標是召回率(recall):相關段落有沒有被找回來。漏召回是 RAG 系統最致命的問題,因為漏召回的段落再也無法被生成階段挽回。

增強階段負責「把檢索結果組裝成 LLM 能消化的 prompt」。最簡單的作法是把前 k 個段落的原文串接起來,前面加上「請根據以下資料回答問題」之類的指示;進階的作法會做壓縮(把段落摘要成幾個關鍵句)、排序(把最相關的放最前面,因為 LLM 對 prompt 中段的注意力通常最弱)、標記(給每個段落編號,讓 LLM 在回答時引用編號)。增強階段的關鍵指標是資訊密度:在不超過 LLM context window 的前提下,把最多相關資訊塞進去。

生成階段負責「用 LLM 根據 prompt 生成答案」。最常見的實作是用商用 API(OpenAI GPT-4o、Anthropic Claude 3.7 Sonnet、Google Gemini)或本地開源模型(Llama 3.3、Qwen 2.5、Mistral)。生成階段的關鍵指標是忠實度(faithfulness):答案有沒有真的根據提供的段落回答、還是模型自己編的。RAG 系統的回應風格可以透過 system prompt 控制:「請只根據提供的資料回答、若資料未涵蓋請回答「我不知道」」是常見的設計。

三段架構彼此解耦:你可以把檢索階段從 Qdrant 換成 BM25,增強階段加上壓縮,生成階段從 GPT-4o 換成 Llama 3.3,整個系統仍能運作。這種模組化是 RAG 受歡迎的原因之一——企業可以根據資料機密、成本、效能需求各自調整。例如醫療機構常見的「資料不能離開內網」需求,可以把生成階段鎖在本地 Llama 3.3 8B;新創公司追求「最低 API 成本」則會選擇 GPT-4o-mini 或 Claude 3.5 Haiku,這些選擇都能與同一個檢索系統共存。

完整實作:用 Day 24 的索引示範 RAG 三段

以下範例在 Colab CPU 上跑約 3 分鐘。我們沿用 Day 24 的 Qdrant 索引,示範「檢索 → 增強 → 生成」三段端到端流程;生成階段先用「抽取式回答」(直接回傳最相關段落的開頭 100 字)當本地替代方案,再展示如何把生成階段換成 Ollama 上的小模型。

# 1. 安裝套件;本篇只用到 qdrant-client 與 sentence-transformers
pip install -q qdrant-client==1.12.0 sentence-transformers==3.4.1

這段安裝兩個套件。qdrant-client 1.12 是當時穩定版,sentence-transformers 3.4 是當時對應 PyTorch 2.6 的版本。本篇沿用 Day 24 的索引與模型,不需要額外下載;若讀者直接從 Day 25 開始,可參考 Day 24 文章的「維基百科 → 段落切分 → 嵌入 → 上傳 Qdrant」流程先建立 wiki_zh collection。

# 2. 建立 retriever:包裝 Qdrant 1.12 的查詢
import numpy as np
from qdrant_client import QdrantClient
from qdrant_client.models import Filter, FieldCondition, MatchValue
from sentence_transformers import SentenceTransformer

class Retriever:
    """RAG 系統的檢索器封裝"""
    def __init__(self, collection_name: str = "wiki_zh"):
        self.client = QdrantClient(":memory:")
        self.model = SentenceTransformer(
            "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
        )
        self.collection_name = collection_name

    def retrieve(self, query: str, top_k: int = 3, topic: str | None = None) -> list[dict]:
        q_vec = self.model.encode([query], convert_to_numpy=True).tolist()[0]
        q_filter = None
        if topic:
            q_filter = Filter(must=[FieldCondition(key="topic", match=MatchValue(value=topic))])
        hits = self.client.search(
            collection_name=self.collection_name,
            query_vector=q_vec,
            query_filter=q_filter,
            limit=top_k,
        )
        return [{"text": h.payload["text"], "title": h.payload["title"],
                 "score": h.score, "url": h.payload["url"]} for h in hits]

# 範例:對「台北 101 有多高」這個查詢跑檢索
retriever = Retriever()
hits = retriever.retrieve("台北 101 有多高", top_k=3)
for h in hits:
    print(f"[{h['score']:.3f}] {h['title']}|{h['text'][:80]}…")
# 輸出(實際分數會略有不同):
# [0.812] 台北|台北 101 是台灣最高的建築,曾是世界第一高樓…
# [0.745] 台北|東京的經典地標是東京鐵塔與晴空塔…(誤召回)
# [0.621] 半導體|…

這段把 Day 24 的查詢邏輯包成 Retriever 類別。retrieve(query, top_k, topic) 回傳一個 list of dict,每個 dict 包含原文、條目名稱、相似度分數、條目網址。回傳 dict 而非 Qdrant 內部的 ScoredPoint,是為了後續增強階段好處理。注意第二名的「東京的經典地標」是誤召回——雖然與「高」「塔」相關,但查詢問的是台北 101;這種情況在 RAG 中需要靠增強階段的重新排序或 LLM 的判斷來處理,Day 28 我們會專門講 rerank。

# 3. 建立 augmenter:把檢索結果組裝成 LLM prompt
SYSTEM_PROMPT = """你是隻會根據「資料」回答事實的助理。若資料未涵蓋使用者的問題,請回答「我不知道」並說「提供的資料未涵蓋此問題」。請使用繁體中文回答。"""

def build_prompt(query: str, hits: list[dict]) -> str:
    """把檢索結果組裝成 user prompt。"""
    if not hits:
        return f"問題:{query}\n資料:(無)\n"
    context_parts = []
    for i, h in enumerate(hits, start=1):
        context_parts.append(f"[資料 {i}] 來源:{h['title']}({h['url']})\n{h['text']}")
    context = "\n\n".join(context_parts)
    return f"問題:{query}\n\n資料:\n{context}\n\n請根據以上資料回答問題。"

# 範例 prompt
sample_prompt = build_prompt("台北 101 有多高?", hits)
print(sample_prompt[:400])
# 輸出(實際內容會略有不同):
# 問題:台北 101 有多高?
#
# 資料:
# [資料 1] 來源:台北(https://…)\n台北 101 是台灣最高的建築…
# [資料 2] 來源:台北(https://…)\n東京的經典地標是東京鐵塔與晴空塔…
# [資料 3] 來源:半導體(https://…)\n…

這段示範增強階段。build_prompt(query, hits) 把檢索結果編號(資料 1、資料 2…)、附上來源 URL、組裝成 user prompt。系統提示 SYSTEM_PROMPT 給模型三條規則:根據資料、不知道就說不知道、用繁體中文。這種 system prompt 是 RAG 系統的「契約」——把模型的角色與限制講清楚,回答品質會明顯提升。注意我們把 system prompt 與 user prompt 分開:system prompt 設定規則,user prompt 放資料與問題,這是 LangChain 0.3.x 與大多 LLM API 的慣例。

# 4. 本地生成器:抽取式回答(CPU 上即時)
def local_generator(prompt: str, hits: list[dict]) -> str:
    """沒有 LLM 時的本地替代方案:直接回傳最相關段落。"""
    if not hits:
        return "我不知道。"
    top = hits[0]
    snippet = top["text"][:120].replace("\n", " ").strip()
    return f"根據「{top['title']}」條目:{snippet}…(來源:{top['url']})"

# 範例:對同一個查詢的完整 RAG 回應
query = "台北 101 有多高?"
hits = retriever.retrieve(query, top_k=3)
prompt = build_prompt(query, hits)
answer = local_generator(prompt, hits)
print(answer)
# 輸出(實際內容會略有不同):
# 根據「台北」條目:台北 101 是台灣最高的建築,曾是世界第一高樓,總高度 508 公尺,含 101 層…(來源:https://…)

這段示範本地生成器。local_generator 是 RAG 三段中的「生成」階段,但用「抽取式回答」代替 LLM:直接回傳檢索結果中分數最高的段落片段,並附上來源。這種作法沒有 LLM 的「理解」能力,但有兩個好處:第一,CPU 即時、不需要昂貴的 GPU;第二,100% 忠實於資料、不會編造。對一些簡單問答(例如客服 FAQ)這種「直白式回答」就夠用。

但對大多數自然語言問答,「抽取式」會顯得僵硬、缺乏語句通順度。這時候就要接 LLM。下一段我們把 local_generator 換成 Ollama 上的本地模型。

# 5. 換成 Ollama 上的小模型:完整本地 RAG
# 安裝:pip install ollama==0.4.0
# 並確認 Ollama 服務已啟動、已 ollama pull gemma3:4b
import os

def ollama_generator(prompt: str, hits: list[dict], model: str = "gemma3:4b") -> str:
    """用本地 Ollama 上的小模型生成。需先啟動 Ollama 服務。"""
    import ollama  # type: ignore
    context = "\n\n".join(f"[{i}] {h['title']}:{h['text']}" for i, h in enumerate(hits, 1))
    response = ollama.chat(
        model=model,
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": f"問題:{prompt}\n資料:\n{context}"},
        ],
    )
    return response["message"]["content"]

# 若 Ollama 服務未啟動,可改回 local_generator
try:
    answer = ollama_generator("台北 101 有多高?", hits)
    print("=== Ollama 生成 ===")
    print(answer)
except Exception as e:
    print(f"Ollama 未啟動或模型未下載:{e}")
    print("改用 local_generator:")
    print(local_generator("", hits))
# 輸出(Ollama 實際生成會略有不同):
# 根據資料,台北 101 是台灣最高的建築,總高度 508 公尺,地上 101 層…
# 6. 把三段封裝成單一 RAGChain:方便日後切換檢索器或生成器
class RAGChain:
    """三段式 RAG 鏈:retriever → augmenter → generator"""
    def __init__(self, retriever, generator):
        self.retriever = retriever
        self.generator = generator

    def __call__(self, query: str, **kwargs) -> dict:
        hits = self.retriever.retrieve(query, **kwargs)
        prompt = build_prompt(query, hits)
        answer = self.generator(prompt, hits)
        return {"query": query, "hits": hits, "prompt": prompt, "answer": answer}

# 範例:用 local_generator 組裝
rag = RAGChain(retriever=Retriever(), generator=local_generator)
result = rag("台北 101 的地址是什麼?", top_k=3)
print("回答:", result["answer"][:80])
# 輸出(實際內容會略有不同):
# 回答:根據「台北」條目:台北 101 座落在台北市信義區…
# 7. 簡單的評估函式:檢查生成答案是否引用了資料編號(粗略忠實度指標)
def citation_check(answer: str, hits: list[dict]) -> float:
    """計算答案中引用的資料編號比例。"""
    import re
    refs = re.findall(r"\[(\d+)\]", answer)
    if not refs:
        return 0.0
    valid = sum(1 for r in refs if 1 <= int(r) <= len(hits))
    return valid / len(refs)

# 範例:local_generator 通常不引用編號(0.0),LLM 應該要引用
score = citation_check(result["answer"], result["hits"])
print(f"引用分數:{score:.2f}")
# 輸出:引用分數:0.00

這段把生成器換成 Ollama。ollama_generator 呼叫 ollama.chat(),傳入 system prompt 與 user prompt(含檢索結果),回傳模型的文字生成。gemma3:4b 是當時(2025 年 3 月)Ollama 上對中文支援不錯的小模型(4B 參數、約 8 GB VRAM 或 4 GB VRAM 量化),CPU 也能跑只是較慢。若 Ollama 服務未啟動或模型未下載,except 區塊會自動 fallback 到 local_generator,整個 RAG 仍能跑——這就是 RAG 的解耦設計價值:生成階段壞了、檢索與增強仍能單獨驗證。

商用 API 的接法類似,只要把 ollama.chat() 換成 openai.ChatCompletion.create() 或 anthropic.Anthropic().messages.create() 即可。實務上多數企業 RAG 系統會用 OpenAI 或 Anthropic 的 API(中文品質穩定、context window 大),但本地小模型在「資料機密不能外流」或「成本敏感」的情境仍是首選。

常見錯誤與踩雷

錯誤一:把整個 prompt 塞太多段,導致超過 LLM context window。GPT-4o 是 128K、Claude 3.7 Sonnet 是 200K、本地 Llama 3.3 8B 通常是 8K context。塞超過 context window 會直接報 context_length_exceeded 或被截斷。對應排查:在 build_prompt 中加長度檢查、若超過上限就降 top_k 或用 Day 28 的 rerank 濃縮。

錯誤二:生成的答案引用了「資料中沒有」的內容。這是 RAG 系統最常見的失敗模式——LLM 看完 prompt 後,仍用自己的世界知識補充。對應排查:system prompt 中明確寫「只能引用資料中的編號」,並用 regex 檢查生成結果是否包含 [資料 N] 格式的編號;若沒有,表示模型在自由發揮。

錯誤三:檢索結果都是同一個條目的不同段落。如果 top_k=3 都來自同一個條目,模型會得到冗餘資訊、甚至找不到其他相關觀點。對應排查:在 build_prompt 中用 set 去重,確保每個條目最多貢獻 2 段;或在檢索階段就對來源做 diversify。

錯誤四:system prompt 與 user prompt 內容重疊。例如 system prompt 寫「請根據以下資料回答」、user prompt 又寫「請根據以下資料回答」,模型會困惑。對應排查:system prompt 只放「角色與限制」、user prompt 只放「資料與問題」。

錯誤五:local_generator 在沒有檢索結果時直接當機。hits 是空 list 時,hits[0] 會 IndexError。對應排查:在函式開頭加 if not hits: return "我不知道。",讓無資料的查詢回傳固定字串而不是崩潰。

效能與實務提醒

本篇 demo 的時間分配:檢索階段(Qdrant ANN)每次小於 30 毫秒;增強階段(拼 prompt)小於 1 毫秒;生成階段(Ollama gemma3:4b)每次 1–3 秒;OpenAI API 端到端(含網路)約 1–2 秒。整體延遲瓶頸在 LLM 生成,因此 RAG 系統的延遲最佳化主要落在生成階段(用更快的模型、量化、串流輸出)。

成本面上,商用 API 約每千次查詢 0.5–3 美元(依模型與輸入長度),本地 Ollama 約每千次查詢 0 美元但需要 GPU。對中小企業來說,每天 1,000 筆查詢用 GPT-4o-mini 約 0.5 美元、用本地 Llama 3.3 8B 約 0 美元——這是 RAG 系統選型時最常被討論的權衡點之一。

更重要的提醒:檢索品質決定 RAG 上限。如果檢索找不到相關段落,再貴的 LLM 也救不回來;反過來,檢索能找到好段落、LLM 寫得「普通」,整體回答品質仍可接受。這也是 Day 26–28 都在講檢索優化(切分、查詢改寫、rerank)的原因。明天我們會把「文件切分」這個檢索優化的關鍵環節展開,從 fixed、recursive 到 semantic 三種策略的差別。

小結

今天把 RAG 拆成三段:檢索(Day 24 的 Qdrant)、增強(把檢索結果組裝成 prompt)、生成(LLM 看 prompt 回答)。我們用 Retriever、build_prompt、local_generator 三個函式把三段串起來,整個 demo 在 CPU 上 5 分鐘內完成,並展示了把 local_generator 換成 Ollama 上的小模型或商用 API 的方法。重點回顧:檢索品質決定 RAG 上限、system prompt 要明確「只能引用資料」、每段都要有 fallback、top_k 不能太大以免超過 context window。我們用「台北 101 有多高」這個查詢走了完整 RAG 流程,並展示了誤召回案例(東京的塔被召回)需要靠 rerank 處理。明天會把檢索的第一步「文件切分」展開成完整管線,從 fixed、recursive 到 semantic 三種策略。

結語

今天的重點是「把 RAG 拆成三段並各自展示最小可行實作」。我們從「為什麼需要 RAG」出發(解幻覺、補知識截止),介紹了三段架構的分工與各自的關鍵指標,並用 Day 24 的維基百科索引 + Qdrant 1.12 做檢索,用簡單的 build_prompt 做增強,用「抽取式回答」做本地生成,最後把生成器換成 Ollama 上的 gemma3:4b。讀完這篇你應該能回答:RAG 為什麼能解幻覺?三段架構各自的關鍵指標是什麼?為什麼檢索品質決定 RAG 上限?system prompt 與 user prompt 的分工是什麼?

RAG 的檢索階段比我們今天展示的複雜得多:文件怎麼切分、切多大、metadata 怎麼設計、query 怎麼改寫、結果怎麼 rerank——每一個都是 RAG 系統能否上線的關鍵。明天,我們會把「文件切分」展開成完整管線:fixed、recursive、semantic 三種策略的差別,以及它們對檢索品質的影響。

延伸資源

  • RAG 原始論文(Meta,2020):Lewis et al., Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks,arXiv 2005.11401,RAG 概念的標準來源。
  • LangChain 0.3 官方文件(2025):https://python.langchain.com/docs/introduction/,RetrievalQA、ConversationalRetrievalChain 等高階介面;本篇用的是手寫的三段,LangChain 0.3 則把它們封裝成 Chain。
  • OpenAI Chat Completions API 官方文件(2025):https://platform.openai.com/docs/guides/chat,把 local_generator 換成 GPT-4o 的範例。
  • Ollama 官方文件(2025):https://github.com/ollama/ollama,ollama.chat() 的 Python SDK、模型清單與 pull 指令。
  • Qdrant 1.12 官方文件(2025):https://qdrant.tech/documentation/,Filter 與 payload 索引設計。

留言

這個網誌中的熱門文章

Day 2 變數與資料型別

Day 2 變數與資料型別 引言 寫程式的過程中,變數與資料型別是處理資料的基礎。變數是存放資料的容器,資料型別則決定這筆資料有哪些特性、可以進行哪些操作。學會定義變數、認識各種資料型別,是學好 Python 的關鍵一步。 這篇文章會帶你了解 Python 中變數的觀念、如何定義變數,以及常見的資料型別,包括整數、浮點數、字串、布林值,還有串列、元組、字典與集合等容器型別。我們也會介紹變數的命名規則與撰寫風格建議,以及如何用 type() 檢查資料型別。 什麼是變數?如何在 Python 中定義變數 變數是在程式執行時用來存放資料的名稱。透過定義變數,我們可以給一筆資料一個名字,並在程式的其他地方用這個名字取用該筆資料。在 Python 中,變數不需要事先宣告型別,因為 Python 是動態型別語言,變數的型別由指定給它的值決定。 定義變數的基本語法 在 Python 中定義變數非常簡單,只要用賦值符號 = 把值指定給變數即可。例如: x = 5 # 定義變數 x,並把整數 5 賦值給它 name = "Alice" # 定義變數 name,並把字串 "Alice" 賦值給它 在這裡,x 是一個變數,被賦予整數 5;name 是另一個變數,被賦予字串 "Alice"。 變數的更新與覆寫 變數的值可以修改,也就是說,我們可以在程式的不同地方給同一個變數新的值。例如: x = 10 # x 最初被賦予 10 x = 15 # x 的值現在被更新為 15 這樣就能依照需求,在程式執行過程中靈活調整變數的值。 Python 的動態型別系統 Python 和某些靜態型別語言不同,定義變數時不需要宣告型別。賦值時,Python 會根據值自動判斷變數的型別。例如: x = 5 # x 是整數 x = 3.14 # x 變成浮點數 x = "Hi" # x 變成字串 同一個變數在程式執行過程中可以存放不同型別的值,這是 Python 的彈性之一。 常見資料型別 在 Python 中,資料型別決定我們可以對變數進行哪些操作...

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門 隨著人工智慧(AI)與深度學習(Deep Learning)快速發展,越來越多人對這些技術產生興趣。不論你是想踏入 AI 領域的初學者,還是已經有程式基礎的開發者,學好 Python 與深度學習框架(例如 PyTorch),都能為你打開更多可能。 為什麼選擇 Python? Python 已經是資料科學與人工智慧領域的首選語言。它的語法簡潔、容易上手,而且擁有龐大的生態系與大量開源函式庫。無論是資料處理、資料視覺化,還是建立機器學習與深度學習模型,Python 都能勝任。對想進入 AI 或資料科學領域的人來說,它幾乎是必備工具。 PyTorch 是什麼? PyTorch 是由 Meta(原 Facebook)AI 研究團隊開發的開源深度學習框架,以易用、靈活和動態計算圖著稱,是許多 AI 研究人員與開發者的首選。相較於其他框架,PyTorch 的寫法更貼近原生 Python,對初學者相對友善。無論是簡單的實驗,還是複雜的深度學習模型,PyTorch 都能提供強大的支援。 這個系列能帶給你什麼? 這個系列會從 Python 的基礎開始,帶你一步一步學習,最後能自己用 PyTorch 建立深度學習模型。即使你完全沒有寫過程式,也能跟著文章的節奏累積技能,理解 AI 與深度學習的核心觀念。 本系列涵蓋的主題 Python 基礎:從變數、條件判斷到函式與模組。 資料處理工具:用 NumPy 與 Pandas 有效率地操作資料。 資料視覺化:用 Matplotlib 與 Seaborn 把資料畫成圖表。 深度學習的數學基礎:線性代數、微積分與機率。 PyTorch 入門:理解張量、模型建構與 GPU 加速。 基礎深度學習模型:CNN 與 RNN 的實作應用。 深度學習專案實戰:從資料前處理到模型部署的端到端流程。 誰適合這個系列? 程式初學者 :如果你對 AI 充滿好奇,卻還沒寫過程式,系列的第一部分會帶你快速上手 Python,並幫助你理解深度學習的基本觀念。 資料科學愛好者 :如果你已經熟悉一些資料處理方法,進階部分會教你如何用 PyTorch 建構深度學習模型。 開發者與研究人員 :想更深入了...

Day 1 Python 簡介與環境設定

Day 1 Python 簡介與環境設定 引言 在現在的科技環境裡,程式設計已經是一項重要技能。無論你是對資料科學有興趣、想成為開發者,或是想踏入人工智慧(AI)領域,學會寫程式都能明顯提升你的競爭力。在眾多程式語言中,Python 因為語法簡單、功能強大、應用範圍廣泛,成為許多人進入程式世界的第一選擇。這篇文章會帶你認識 Python 的背景與優勢,並一步步教你在不同系統上安裝與設定 Python 開發環境,最後寫出第一支 Python 程式。 為什麼選擇 Python? Python 是一種高階程式語言,由 Guido van Rossum 在 1991 年發布。Python 的設計哲學強調程式碼的可讀性,並用縮排來定義程式區塊,這點和許多使用大括號的語言不同。簡潔的語法讓它成為初學者的理想選擇;就算是經驗豐富的開發者,也能用它完成複雜的專案。 Python 的優勢如下: 簡單易學 :Python 的語法清楚、結構簡潔,初學者很快就能上手。和其他語言相比,學習曲線相對平緩,不需要先弄懂一堆複雜觀念,就能開始寫程式。 應用範圍廣泛 :從資料科學、網頁開發、人工智慧、機器學習、自動化測試到網路爬蟲,Python 都有大量開源函式庫與工具支援,而且在這些領域都扮演關鍵角色。 豐富的函式庫與框架 :Python 的函式庫生態系非常龐大。做資料分析有 NumPy、Pandas;開發網站有 Django、Flask;做深度學習有 TensorFlow、PyTorch。各種需求幾乎都能找到對應的套件,讓開發更有效率。 跨平台支援 :Python 支援 Windows、macOS、Linux 等作業系統,程式通常不需要太多修改就能跨平台執行,讓開發與部署更有彈性。 活躍的社群 :Python 擁有龐大的開發者社群。學習或開發上遇到問題,幾乎都能在社群與論壇(例如 Stack Overflow)找到答案,對初學者來說是很強的後盾,也能減少卡關時的挫折感。 Python 的應用領域 Python 的流行與強大功能,讓許多領域都開始大量使用它。以下是幾個常見的應用方向: 資料科學 :隨著大數據與人工智慧興起,資料科學大量使用 Python。NumPy、Pandas 與 Matplotlib 等工具能處理和分析龐...