EN

5.4 實現生成器整合

組好提示詞,接上 LLM,並處理沒有金鑰、呼叫失敗這些實際情況。

RAG下一篇 →

檢索器回傳資料後,生成端只需要負責兩件事:組提示詞,以及呼叫 LLM。把兩個步驟分成獨立函式,之後替換模型或修改提示詞時比較不會互相牽連。

提示詞

接續第 4 章的設計:指示放在 system,參考資料和問題放在使用者訊息。

SYSTEM = """你是公司的行政助理。請只根據「參考資料」回答問題。
規則:
1. 資料裡沒有答案時,回答「資料中沒有提到」,不要猜。
2. 用到哪一段資料,就在句子後面標上編號,例如 [1]。
3. 用繁體中文,簡短回答。"""


def build_prompt(question, hits):
    blocks = [f"[{n}]({h['source']} > {h['headings']})\n{h['text']}" for n, h in enumerate(hits, 1)]
    return "# 參考資料\n" + "\n\n".join(blocks) + f"\n\n# 問題\n{question}"

每一段資料都有編號和來源,這樣模型才能標出處(4.6)。

呼叫 LLM

下面用 Anthropic 的 Python SDK 當例子。如果你用別家的模型,換成對應的呼叫方式,整體結構是一樣的:把指示和使用者訊息送過去,取回文字。

import os

LLM_MODEL = "claude-sonnet-5-5"  # 換成你要用的模型


def generate(prompt):
    if os.environ.get("ANTHROPIC_API_KEY"):
        import anthropic

        reply = anthropic.Anthropic().messages.create(
            model=LLM_MODEL,
            max_tokens=500,
            system=SYSTEM,
            messages=[{"role": "user", "content": prompt}],
        )
        return reply.content[0].text
    return "(沒有設定 API 金鑰,這裡不呼叫模型,只顯示送給模型的提示詞)"

幾個重點:

  • 有金鑰才呼叫:沒有設定環境變數時,函式不會報錯,而是回傳一段說明。這讓你在沒有金鑰的時候,也能把整條流程跑通,檢查檢索和提示詞。
  • max_tokens:限制答案的最大長度,要夠長,免得被截斷。
  • 模型名稱用常數:模型名稱經常更換,放在最上面方便修改。
  • SDK 會自動讀金鑰:anthropic.Anthropic() 會自己從 ANTHROPIC_API_KEY 讀取,不需要在程式裡傳金鑰。

注意 這個呼叫我沒有實際執行,因為我手邊沒有設定金鑰。檢索、提示詞組裝這些部分我都跑過,但 generate() 裡呼叫模型的那一段,請你用自己的金鑰測試。模型名稱和 SDK 用法也請以官方文件為準。

實際使用時還要處理的事

範例刻意寫得簡單,正式的系統要多考慮:

問題 做法
呼叫失敗(網路、額度、被限流) 加上錯誤處理和重試,失敗時回傳友善的訊息
回應很慢 設定逾時;考慮串流輸出,邊產生邊顯示
成本 記錄每次呼叫用了多少 token
隨機性 視需要調低溫度,讓答案穩定
換模型 把呼叫包在 generate() 這一個函式裡,其他地方不用動

最後一點很重要:把和特定廠商相關的程式碼,都關在 generate() 裡。這樣以後換模型、換服務,只要改一個函式。

沒有雲端 API 時的選擇

  • 本機模型:用 Ollama 之類的工具在自己的電腦上跑開源模型,資料不外流,但需要足夠的硬體,品質也依模型而異。
  • 只做到提示詞:像範例那樣,先驗證檢索和提示詞,等有金鑰再接上模型。

不管用哪一種,generate(prompt) 這個介面都不用變:進去是提示詞,出來是答案。

← 全部文章