Back to blog
    在您的 SaaS 中發布 AI 搜索,無需按查詢 API 費用
    saassearchfine-tuningtutorialdeploymentcost-reduction

    在您的 SaaS 中發布 AI 搜索,無需按查詢 API 費用

    使用微調的 3B-7B 模型構建自然語言搜索的逐步教程。包括訓練資料來源、模型選擇、通過 Ollama 的 GGUF 部署和延遲基準測試。

    EErtas Team·

    自然語言搜索是 SaaS 產品中最受歡迎的 AI 功能。用戶希望輸入「顯示上季度關閉的超過 $50K 的交易」,而不是點擊篩選器下拉菜單。問題是:通過外部 API 的每個搜索查詢都需要花費金錢,而搜索是高頻的。一個有 10,000 個用戶、每個用戶每天 20 次搜索的 SaaS 是每天 200,000 次 API 調用。按 GPT-4o 定價,那是每年 $48,000——用於搜索框。

    本教程介紹如何使用在本地運行、零按查詢費用的微調模型來構建自然語言搜索。

    模型實際上做什麼

    AI 搜索模型執行一個特定任務:將自然語言查詢翻譯為您現有搜索基礎設施可以執行的結構化搜索過濾器。

    輸入: "deals over 50K that closed in Q4"

    輸出:

    {
      "filters": [
        { "field": "amount", "operator": "gt", "value": 50000 },
        { "field": "status", "operator": "eq", "value": "closed_won" },
        { "field": "close_date", "operator": "between", "value": ["2025-10-01", "2025-12-31"] }
      ],
      "sort": { "field": "close_date", "direction": "desc" }
    }

    這不是 RAG 問題。您不是在文件中搜索。您是在將意圖翻譯為結構。這個區別很重要,因為它意味著:

    1. 您需要一個小模型(3B-7B 參數已綽綽有餘)
    2. 您的訓練資料緊湊(200-500 個範例)
    3. 延遲很快(輸出很短——通常 50-200 個 token)

    第一步:獲取訓練資料

    您需要 200-500 對自然語言查詢映射到結構化過濾器的配對。以下是獲取它們的方法。

    來源 A:搜索日誌(最佳品質)

    如果您的產品已經有基於過濾器的搜索,您就有隱式訓練資料。每次用戶手動應用過濾器,那就是一個結構化查詢。您需要等效的自然語言。

    方法: 匯出您最常見的過濾器組合。對於每個組合,寫 3-5 個自然語言變體。

    結構化過濾器自然語言變體
    status=active, created > 30d ago"active items from the last month"、"show me active ones created recently"、"new active items"
    assignee=current_user, priority=high"my high priority items"、"high priority assigned to me"、"what's urgent on my plate"
    amount > 10000, stage=negotiation"big deals in negotiation"、"negotiations over 10K"、"large deals we're negotiating"

    目標:100-150 個唯一過濾器組合,每個有 3 個自然語言變體 = 300-450 個訓練範例。

    來源 B:支援票據

    搜索您的支援票據和聊天日誌,尋找包含搜索意圖的消息。用戶經常告訴支援「我試圖找到 X」或「我如何按 Y 篩選」。這些是免費的訓練資料。

    要搜索的模式:

    • "How do I find..."
    • "I'm looking for..."
    • "Can I filter by..."
    • "Where are my..."
    • "Show me..."

    典型產出:每 1,000 張支援票據 50-100 個可用範例。

    來源 C:合成生成(僅作補充)

    使用 GPT-4o 生成現有範例的額外變體。這對擴展自然語言變體很有效,但不應該是您的主要來源。

    提示模式:

    Given this structured search filter:
    { "field": "status", "operator": "eq", "value": "active" }
    
    Generate 5 natural language queries a user might type to
    express this search intent. Vary formality, length, and phrasing.
    The user is searching within a [your product type] application.
    

    使用合成資料填補您的覆蓋差距,而不是作為基礎。

    資料格式

    將您的訓練資料構建為對話對:

    {
      "messages": [
        {
          "role": "system",
          "content": "Convert the user's search query into a structured filter. Respond only with valid JSON."
        },
        {
          "role": "user",
          "content": "big deals closing this quarter"
        },
        {
          "role": "assistant",
          "content": "{\"filters\":[{\"field\":\"amount\",\"operator\":\"gt\",\"value\":50000},{\"field\":\"close_date\",\"operator\":\"between\",\"value\":[\"2026-01-01\",\"2026-03-31\"]}],\"sort\":{\"field\":\"amount\",\"direction\":\"desc\"}}"
        }
      ]
    }

    第二步:選擇正確的基礎模型

    對於搜索意圖解析,您不需要大型模型。任務是受限的:固定的輸入詞彙(您產品的領域)、固定的輸出模式(您的過濾器格式)和短輸出。

    搜索意圖的模型比較

    模型參數GGUF 大小 (Q4)搜索準確率*延遲(本地)
    Qwen 2.5 3B3B1.8 GB89%45ms
    Llama 3.2 3B3B1.9 GB87%48ms
    Phi-3.5 Mini3.8B2.2 GB91%52ms
    Qwen 2.5 7B7B4.1 GB94%85ms
    Llama 3.1 8B8B4.7 GB93%92ms
    Mistral 7B v0.37B4.0 GB92%88ms

    *準確率衡量為在用 300 個訓練範例微調後,在 100 個查詢的保留測試集上產生有效、正確結構化過濾器的查詢百分比。

    建議: 從 Qwen 2.5 3B 開始。它足夠小可以在最小硬體上運行,足夠快可以進行實時搜索,微調後足夠準確可以用於生產。只有在需要處理帶嵌套邏輯的複雜多過濾器查詢時,才移至 7B 變體。

    為什麼不用更大的模型?

    70B 模型不會在這個任務上顯著優於微調的 3B 模型。搜索意圖解析是一個狹窄的、定義明確的轉換。微調資料教導模型您特定的模式、欄位名稱和過濾器語法。帶有 300 個高品質範例的 3B 模型完全學習了這個模式。

    我們直接測試了這個:

    模型微調前準確率微調後準確率差值
    Qwen 2.5 3B31%89%+58%
    Qwen 2.5 7B47%94%+47%
    Llama 3.1 70B72%96%+24%

    3B 模型從微調中獲益最多,因為基礎模型有能力學習模式,但在預訓練中沒有看到足夠多的類似範例。70B 模型在零樣本上已經不錯,但微調後只比 7B 多 2 個百分點。這 2 個點不值得 17 倍的計算。

    第三步:微調

    格式化訓練資料並選擇基礎模型後,微調就很直接了。

    訓練配置

    對於搜索意圖解析,使用這些參數:

    參數原因
    Epochs3-5小數據集,需要多次遍歷
    Learning rate2e-4LoRA 微調的標準
    LoRA rank16對於狹窄任務已足夠
    LoRA alpha322 倍排名是標準
    Batch size4-8小數據集,小批次
    Max sequence length512搜索查詢和過濾器很短

    在單個 GPU 上的訓練時間:

    • 300 個範例,3B 模型:A100 上約 8 分鐘,RTX 4090 上約 25 分鐘
    • 300 個範例,7B 模型:A100 上約 15 分鐘,RTX 4090 上約 45 分鐘

    使用 Ertas,上傳您的 JSONL 訓練文件,選擇基礎模型,平台處理其餘的。無需 GPU 配置,無需訓練腳本,無需超參數調整。

    驗證

    保留 20% 的資料(60-100 個範例)用於驗證。測量:

    1. 模式有效性: 輸出是否解析為有效 JSON?目標:超過 98%
    2. 過濾器正確性: 欄位名稱、運算符和值是否正確?目標:超過 85%
    3. 意圖覆蓋: 過濾器是否捕獲了完整的用戶意圖?目標:超過 80%

    如果模式有效性低於 95%,您需要更多訓練範例或更大的模型。如果過濾器正確性低於 80%,您的訓練資料可能有不一致——稽核它是否有衝突的標籤。

    第四步:通過 GGUF + Ollama 部署

    模型微調後,將其匯出為 GGUF 文件,並使用 Ollama 進行生產推理部署。

    量化選擇

    量化文件大小(3B)文件大小(7B)品質損失速度
    Q8_03.2 GB7.4 GB可忽略不計基線
    Q5_K_M2.2 GB5.1 GB不到 1% 的準確率下降快 15%
    Q4_K_M1.8 GB4.1 GB1-2% 的準確率下降快 25%
    Q4_01.7 GB3.8 GB2-3% 的準確率下降快 30%

    建議: 生產使用 Q4_K_M。1-2% 的準確率權衡值得 25% 的速度提升和更小的記憶體佔用。

    Ollama 部署

    創建 Modelfile:

    FROM ./search-intent-qwen3b-q4km.gguf
    
    PARAMETER temperature 0.1
    PARAMETER top_p 0.9
    PARAMETER num_predict 256
    PARAMETER stop "</s>"
    
    SYSTEM "Convert the user's search query into a structured filter. Respond only with valid JSON matching the schema: {filters: [{field, operator, value}], sort: {field, direction}}"
    
    # 創建模型
    ollama create search-intent -f Modelfile
    
    # 測試它
    ollama run search-intent "big deals closing this quarter"

    API 端點

    Ollama 在端口 11434 上公開 OpenAI 兼容的 API:

    curl http://localhost:11434/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "search-intent",
        "messages": [
          {"role": "user", "content": "active customers in Sydney"}
        ],
        "temperature": 0.1
      }'

    您的應用程式程式碼保持不變——只需將基礎 URL 從 api.openai.com 更改為 localhost:11434。如果您使用 OpenAI SDK,設置 base_url="http://localhost:11434/v1"

    第五步:延遲基準測試

    搜索延遲比幾乎任何其他 AI 功能更重要。用戶期望在 300ms 以內獲得搜索結果。以下是本地推理與 API 往返的比較。

    端到端延遲比較

    場景模型網路推理JSON 解析總計
    OpenAI API (GPT-4o-mini)雲端80-150ms200-400ms1ms281-551ms
    OpenAI API (GPT-4o)雲端80-150ms400-800ms1ms481-951ms
    本地 Ollama (3B Q4)0ms35-55ms1ms36-56ms
    本地 Ollama (7B Q4)0ms70-100ms1ms71-101ms
    遠程 Ollama(同區域)VPC2-5ms35-55ms1ms38-61ms

    本地模型在這個任務上比 API 快 5-15 倍。差異主要是網路延遲——API 需要往返到 OpenAI 的服務器,而本地模型的網路開銷為零。

    P99 延遲

    P99 對搜索很重要。用戶注意到每 100 次搜索中有 1 次慢。

    部署P50P95P99
    OpenAI API (GPT-4o-mini)320ms580ms1,200ms
    本地 Ollama (3B Q4)42ms58ms75ms
    本地 Ollama (7B Q4)82ms105ms130ms

    API P99 延遲因速率限制、冷啟動和網路變化而飆升到 1.2 秒。本地推理 P99 為 75ms——在用戶對「即時」感知的範圍內。

    第六步:生產架構

    生產部署如下所示:

    用戶輸入查詢
        ↓
    前端去抖(200ms)
        ↓
    POST /api/search { query: "big deals closing this quarter" }
        ↓
    後端調用 Ollama(本地或 VPC)
        ↓
    模型返回結構化過濾器 JSON(40-80ms)
        ↓
    後端驗證 JSON 模式
        ↓
    後端對數據庫/Elasticsearch 執行過濾器
        ↓
    結果返回到前端
    

    錯誤處理

    模型偶爾會產生無效 JSON(Q4 量化有 2-5% 的查詢)。處理這個:

    import json
    
    def parse_search(query: str) -> dict:
        response = ollama_client.chat(model="search-intent", messages=[
            {"role": "user", "content": query}
        ])
    
        try:
            filters = json.loads(response["message"]["content"])
            validate_schema(filters)  # 您的模式驗證
            return filters
        except (json.JSONDecodeError, ValidationError):
            # 備用:基本關鍵字搜索
            return {"fallback": True, "keyword": query}

    始終有關鍵字搜索備用。用戶寧願獲得近似結果也不想看到錯誤。

    硬體要求

    並發用戶模型推薦硬體每月費用
    1-503B Q44 CPU 核心,4 GB RAM$20-30
    50-5003B Q48 CPU 核心,8 GB RAM$45-60
    500-5,0007B Q416 CPU 核心,16 GB RAM$80-120
    5,000 以上7B Q4GPU 實例(T4/L4)$150-300

    與同等規模的 API 費用比較:

    並發用戶估計每月查詢GPT-4o-mini API 費用本地模型費用節省
    5030,000$45$2544%
    500300,000$450$5588%
    5,0003,000,000$4,500$11098%
    50,00030,000,000$45,000$25099%

    在 500 個並發用戶時,您節省 88%。在 5,000 時,您節省 98%。費用曲線趨於平緩,而 API 曲線保持線性。

    Ship AI that runs on your users' devices.

    Ertas early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    整合起來

    完整的實施時間表:

    任務輸出
    1從日誌和票據獲取訓練資料200-300 個標記範例
    1-2生成合成變體,清理資料300-500 個訓練範例
    2微調模型,驗證準確率微調的 GGUF 模型
    2-3部署 Ollama,構建 API 端點可工作的搜索 API
    3與前端整合,添加備用生產就緒功能
    3-4監控,收集新範例,重新訓練持續改善

    總耗時:一名工程師 3-4 週。不需要 ML 團隊。沒有持續的 API 費用。更快、更便宜、完全在您控制下的搜索。

    延伸閱讀

    Ship AI that runs on your users' devices.

    Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.

    Keep reading