標籤: RAG

  • 實戰 Agentic RAG 與 Hybrid Search

    實戰 Agentic RAG 與 Hybrid Search

    📌 本文重點

    • 單一檢索策略讓 RAG 在真實場景很容易翻車
    • Hybrid Search 能互補向量與關鍵字的盲點
    • 讓 Agent 負責檢索策略與多輪重試能顯著提升穩定度
    • 不換模型也能透過 eval、Hybrid 與權限控管大幅升級 RAG

    在實際專案裡,多數 RAG 翻車不是因為模型不夠聰明,而是檢索策略太單一:只用向量會被專有名詞和代碼玩死,只用關鍵字又抓不到語義相近的長文件內容。Agentic RAG + Hybrid Search 的組合,重點就是讓「檢索」變成可調度、可重試、可觀測的一級公民,而不是一個寫死的 search(query) 函式。


    重點說明

    1. 為什麼單一檢索在真實專案會翻車?

    常見四種翻車場景:

    1. 長文件 / 手冊
    2. 只用向量:整份手冊被切成很多 chunk,語義太接近,top-k 都很像,但真正要的那一段不一定排前面。
    3. 只用 BM25:查詢句子太口語,關鍵字重疊度不高,直接 miss。

    4. 專有名詞 / 法規條文 / 內部代號

    5. 向量模型常常把 DS-104DS-140 當成類似,專案實際上兩者完全不同。
    6. 法規編號、API 名稱、Ticket ID 等,關鍵字檢索反而更穩

    7. 程式碼、表格、錯誤訊息

    8. 向量對縮排、符號、stack trace 的敏感度很差。
    9. Log ID 或錯誤碼這類「硬字串」,BM25/關鍵字幾乎是必要條件

    10. 跨語言 / 口語查詢

    11. 使用者用自然語言描述問題,文件是正式用語或英文,公司內還混雜縮寫。
    12. 需要先用 LLM 做 query 改寫,再讓向量與 BM25 各自發揮。

    Hybrid Search(向量 + BM25) 的實際好處:

    • 可以 補各自的盲點:專有名詞用 BM25 鎖定,模糊描述用向量補齊。
    • 可以針對不同類型文件設定 權重策略(例如法規 > 內部 wiki > Slack 摘要)。
    • 可以後面用 rerank 模型 做第二次排序,穩定提升回答可靠度。

    💡 關鍵: 單一檢索在長文件與專有名詞場景很容易漏抓關鍵內容,Hybrid Search 能同時顧到語義相似與精確字串匹配,明顯降低 RAG 翻車率。


    2. 讓 Agent 負責檢索策略,而不是把檢索寫死

    典型 Agentic RAG 設計:

    • 一個 Orchestrator Agent(對話主控)
    • 多個 retriever 工具keyword_retrievervector_retrieverhybrid_retrieverlegal_retriever

    Agent 的工作不是「自己產生答案」,而是先判斷:

    1. 要用哪種檢索策略?
    2. 查錯誤碼或 ticket:優先 關鍵字 → 再向量精抽
    3. 問概念解釋:優先 向量 → 再用 BM25 找原始定義
    4. 法規/權威階層:改用 分層 retriever(例如每一層級至少取 1–2 筆)

    5. 要不要改寫 Query?

    6. 第一輪命中文件相關度低時,讓 Agent 自動:

      • 摘出關鍵詞
      • 加上同義詞 / 全名(例如:DSData Steward
      • 限縮 domain(例如:限定 product=core-banking
    7. 多輪重試與合併結果

    8. 第一輪檢索後如果信心不足(例如 top-3 相似度都 < 0.7),
    9. Agent 改寫 query 或更換 retriever,再抓一次,最後合併去重後送入 LLM。

    這樣做的實際好處:

    • 檢索策略可迭代:只要調整工具 / prompt,不必重寫服務架構。
    • 容易在線上 A/B:只換掉 Orchestrator 的 prompt 或 routing 邏輯即可。
    • 可以針對不同客戶 / 部門掛不同的工具組合。

    一個可落地的組合:

    • LLM:OpenAIgpt-4.1)、Anthropicclaude-3.7)皆可
    • 檢索:
    • Elasticsearch:BM25 + dense vector + hybrid score
    • Weaviate / Qdrant:向量 + keyword filter

    簡化架構:

    User → Orchestrator Agent → (tool calls) →
      - keyword_retriever (Elasticsearch BM25)
      - vector_retriever  (Weaviate / ES dense vector)
      - hybrid_retriever  (ES rank_feature / script_score)
    → merge + dedup + rerank → LLM answer
    

    實作範例

    1. Orchestrator Agent Prompt(決定使用哪個 retriever)

    假設用 OpenAI Assistants API 或自行封裝 tools:

    系統指示(Orchestrator):
    你是一個檢索協調代理,負責從多種檢索器取得最相關的企業知識。
    
    - 若使用者詢問:
      - 錯誤碼、ticket ID、法規條號、API 名稱 → 優先使用 **keyword_retriever**。
      - 抽象概念、最佳實踐、流程說明 → 優先使用 **vector_retriever**。
      - 法律 / 合規問題,且需多層級來源 → 使用 **legal_hybrid_retriever**。
    
    流程:
    1. 先決定要呼叫哪些工具(可以多個)。
    2. 若第一輪檢索結果的「來源數量 < 3」或「相關度評估偏低」,
       - 自行改寫查詢(更精簡、加入關鍵字),再重試一次。
    3. 最終將所有檢索結果去重、排序,回傳給後續回答模型。
    禁止自行編造公司內部資料,所有答案必須可追溯到文件片段。
    

    索引 mapping:

    PUT knowledge_base
    {
      "mappings": {
        "properties": {
          "content": { "type": "text" },
          "content_vec": { "type": "dense_vector", "dims": 1536, "index": true },
          "source_type": { "type": "keyword" },   
          "tenant_id": { "type": "keyword" }
        }
      }
    }
    

    簡化版 hybrid 查詢(BM25 + 向量):

    POST knowledge_base/_search
    {
      "size": 20,
      "query": {
        "script_score": {
          "query": {
            "bool": {
              "must": [
                {"match": {"content": "GDPR data retention"}},
                {"term": {"tenant_id": "acme_corp"}}
              ]
            }
          },
          "script": {
            "source": "0.6 * _score + 0.4 * cosineSimilarity(params.q_vec, 'content_vec')",
            "params": {"q_vec": [/* query embedding */]}
          }
        }
      }
    }
    

    關鍵點:

    • BM25 與向量權重(例子中 0.6 / 0.4)要透過線上 A/B 或離線 eval 調整。
    • tenant_id filter 做多租戶權限隔離,非常重要。

    💡 關鍵: 在同一個查詢裡用 script score 同時結合 BM25 分數與 cosine similarity,能控制兩者權重,調整出最適合自己資料分佈的 Hybrid 策略。


    3. Chunking 與 max context 的工程細節

    基本原則:

    • 語義切分(semantic splitting)+ 適度 overlap 為主,而不是死切 512 tokens
    • 避免 chunk 過長導致:
    • 向量語義太混濁,top-k 噪音變高。
    • LLM context 塞滿 retrieval 噪音,回答變模糊。

    實作骨架(pseudo-code):

    from semantic_splitter import split_semantic
    
    def chunk_doc(text: str):
        sections = split_semantic(text, max_chars=1200)
        chunks = []
        overlap = 150  # 字元級 overlap
        for sec in sections:
            if len(sec) <= 1200:
                chunks.append(sec)
            else:
                # 針對長 section 再做 sliding window
                for i in range(0, len(sec), 1200 - overlap):
                    chunks.append(sec[i:i+1200])
        return chunks
    

    max context tokens 的關係:

    • 假設 LLM context 32k,系統 prompt + 對話占 4k,其實留給 RAG 的只有約 28k
    • 若每個 chunk 約 400 tokens,你實際能塞 約 50–60 個 chunk 就爆,但通常 8–16 個 chunk 就夠,更多只會拉高成本與噪音。

    rerank 與去重

    • 先取寬一點的 top_k(例如 30–50),再用輕量 rerank(如 bge-reranker)縮到 8–12 個。
    • 去重邏輯可以用:same doc_id + 高度相似 直接只留一個,減少重複內容浪費 context。

    💡 關鍵: 雖然 context 可能有 32k tokens,但實務上只保留約 8–16 個高質量 chunk,通常就能兼顧成本與效果,塞太多反而害答題品質下滑。


    建議與注意事項

    1. 不要只做 embedding,不做 eval

    常見錯誤流程:

    1. 把全部文件 embed → 塞進向量庫 → 上線。
    2. 發現回答怪怪的 → 開始懷疑模型。

    比較健康的流程:

    1. 先準備一組 標記好的 QA/Eval 集10–50 題也好)。
    2. 對同一組問題,分別跑:
    3. 純 BM25
    4. 純向量
    5. Hybrid + 不同權重
    6. 用簡單指標(hit@k、人工評分)挑一個 baseline,再上線 A/B。

    2. 向量庫維護:重建 / 追加 / 版本化

    • Embedding 模型版本變更 時:
    • 盡量用新 index 重建(kb_v2),舊版保留一段時間做對照。
    • 不要在同一個 index 裡混不同 embedding 模型的向量。
    • 大量文件更新策略:
    • 批次追加新文檔時,要記錄 批次 ID / 資料版本,方便 rollback。
    • 下線文件要標記 is_active=false 或直接 soft delete,避免回答引用過期政策。

    3. 多租戶與權限過濾

    • 在 Elasticsearch / Weaviate 中務必存:tenant_idvisibilityrole 等欄位。
    • 檢索 query 層一定要加:
    "filter": [
      {"term": {"tenant_id": "${current_tenant}"}},
      {"terms": {"visibility": ["public", "internal"]}}
    ]
    
    • 不要指望 LLM 自己遵守權限,權限控制一定要在檢索階段完成。

    4. 線上評測與 A/B 驗證

    簡易做法:

    1. 選一組真實高頻 query(客服 ticket、搜尋 log)。
    2. 設計兩條路線:
    3. A:純向量 RAG
    4. B:Agentic RAG + Hybrid Search
    5. 隨機分流流量,收集:
    6. 使用者是否重問 / 追問率
    7. 是否需要人工接手
    8. CSR / domain expert 的 1–5 分主觀評分

    通常在企業知識庫場景,只要加上 Hybrid Search + Agent 重試,就能看到 10–30% 的 query 成功率提升,而且失誤類型會明顯變少(比較少「答錯法規條」、「引用過期政策」)。


    總結:如果你現在的 RAG 還是「單一向量庫 + top-k 塞給 LLM」,要提升穩定性,不一定要換更大的模型,先把 Hybrid Search 與 Agentic 檢索策略補上,通常是成本最低、效果最直接的升級路線。


    🚀 你現在可以做的事

    • 從現有專案中抽出 10–50 則真實 query,分別用純 BM25、純向量與 Hybrid 跑一次,記錄 hit@k 與人工評分
    • 在現有 RAG 服務前面加一個簡單 Orchestrator,把關鍵字與向量檢索拆成兩個 tool,用 prompt 控制選用策略
    • 在搜尋層加入 tenant_idvisibility 欄位與 filter,先確保權限過濾正確,再進一步調整 Hybrid 權重與 rerank 策略
  • 讓 LLM 真的會做研究:拆解 ResearchEVO

    📌 本文重點

    • ResearchEVO 讓 LLM 直接在程式碼空間做演化搜尋
    • 論文寫作以 sentence-level RAG 確保可檢索與可驗證
    • 可拆解為可落地的 Auto-Research / Auto-ABTest / Auto-Feature-Engineering 流程

    多數所謂「AI 做研究」還停留在幫你寫 code、寫報告;ResearchEVO 解決的痛點是:讓 LLM 直接在程式碼空間裡做演化搜尋、自己排實驗、自己寫論文。從工程角度看,它提供了一個可實作的 blueprint,讓你能在公司內做 Auto-Research / Auto-ABTest / Auto-Feature-Engineering,而不是只多一個聊天機器人。


    重點說明

    1. 演化階段:LLM 驅動的「程式碼空間搜索」

    ResearchEVO 的核心是 LLM + 演化算法 操作「程式碼本身」:

    1. 程式碼空間表示
    2. 個體 = 一份可執行程式碼(例如一個 train.py 或一個 model 定義 + config)。
    3. 用 LLM 實作 變異 / 交配
      • 變異:改損失函數、網路結構、優化器、訓練 schedule。
      • 交配:將兩個高適應度方案的關鍵設計融合。
    4. 不做 AST 級別操作也可以,實務上多數情況直接用 自然語言 prompt + code diff 就夠用。

    5. fitness 評估與搜索控制

    6. fitness 只看 metrics:例如 val_accuracyAUClatency
    7. Search loop:
      1. LLM 生成/修改程式碼。
      2. 提交到 GPU/雲端排程系統跑實驗。
      3. 收集結果 → 更新種群 → 再交給 LLM 反思與生成。
    8. 約束控制 避免亂飛:
      • 硬約束:只允許改特定檔案 / 函數;強制保持 I/O 介面不變。
      • 軟約束:LLM prompt 中加入「只動這幾個維度」「保留下列設計」。

    💡 關鍵: 把 fitness 完全交給客觀 metrics(如 val_accuracylatency),可以讓 LLM 的創意探索與實際效能緊密對齊。

    1. 對接現有 GPU / 雲端排程
    2. ResearchEVO 本身不是新的 scheduler,而是:
      • 上游:LLM 生成/修改 code & config。
      • 下游:把 job 提交給你已有的 Kubernetes / Slurm / Airflow / SageMaker / Vertex AI
    3. 你只需要做一層 adapter,把 ExperimentSpec → Job 映射好。

    2. 寫作階段:sentence-level RAG + 驗證

    演化出最佳演算法後,ResearchEVO 的寫作階段是在做 「可檢索、可驗證」的自動論文生成

    1. 論文結構模板
    2. 先固定一個論文 schema(Title / Abstract / Intro / Method / Exp / Discussion / Related Work)。
    3. 每個 section 再細分成 段落 level 的子任務,讓 LLM 聚焦生成。

    4. 句子級 RAG(sentence-level RAG)

    5. 檢索單位不是 chunk,而是句子
      • 實驗 log、表格、程式碼註解、對照文獻都 embed 成 sentence vector。
      • 每當 LLM 要生成一個句子,就檢索最相關的 3~5 個 evidence。
    6. 這樣可以:
      • 降低 context 噪音。
      • 讓每句話都有「引用依據」。

    💡 關鍵: 以「句子」為檢索單位,讓每一句論文敘述能精確對應到 3–5 條證據,大幅降低幻覺與錯引。

    1. 事實核查與防幻覺
    2. 對每一句包含數字、claim 的句子,送到 Verifier agent
      • 檢查是否能在實驗結果 / log / paper corpus 中找到支持證據。
      • 找不到就要求 LLM 重寫或改成不那麼強的 claim。
    3. 論文內引用的實驗表格、圖表,ID 必須能對回到真實跑出的 artifacts(例如 MLflow run id / S3 path)。

    3. 如何落地 Auto-Research / Auto-ABTest / Auto-Feature-Engineering

    你不一定要重現完整 ResearchEVO。實務上可以拆成:

    • 一個 orchestrator(Airflow / Prefect / Dagster / LangGraph)
    • 幾個 LLM agent(code 生成 / 反思 / 寫作)
    • 一個實驗調度器(K8s / Slurm / 自家平台)
    • 一個結果分析工具(MLflow / Weights & Biases / 自製 dashboard)

    核心流程:

    1. 目標定義
    2. LLM 生成候選方案
    3. 實驗排程跑
    4. 收集結果 & 自動分析
    5. LLM 反思改進
    6. 收斂後自動產出報告/論文

    💡 關鍵: 把「做研究」拆成可編排的 6 步驟流程後,Auto-Research 就變成一組可插拔模組,而不是神秘黑盒。


    實作範例

    以下用 Python + Airflow/LangGraph 說明一個簡化版 pipeline。

    1. 演化 loop 的 code 表示與變異

    假設我們把「演算法個體」抽象成一個簡單的 spec:

    from pydantic import BaseModel
    from typing import Dict, Any
    
    class AlgoSpec(BaseModel):
        name: str
        base_script: str              # 參考模板路徑
        hyperparams: Dict[str, Any]   # 学习率, layer 数等
        patches: str                  # LLM 產生的程式碼 patch (diff-like)
    

    讓 LLM 做「變異」:

    SYSTEM_PROMPT = """你是資深 ML 研究員,幫我在保持 I/O 介面不變的前提下,
    只修改 loss function、網路架構與訓練策略。輸出 unified diff 格式的 patch。"""
    
    user_msg = f"""
    目前的程式碼:
    {current_code}
    
    本輪實驗結果:
    val_accuracy = {metrics['val_acc']}
    train_loss_curve = {metrics['loss_curve'][:10]}
    
    請根據結果給出改進 patch。"""
    
    resp = llm.chat([
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": user_msg},
    ])
    
    patch = extract_patch(resp)  # 解析成純文本 diff
    new_spec = AlgoSpec(
        name=f"algo_v{gen_id}",
        base_script="templates/train_base.py",
        hyperparams={"lr": 3e-4, "hidden_dim": 512},
        patches=patch,
    )
    

    接著用簡單的 patch engine 把 diff 套進檔案,產生下一版 train.py


    2. 串接實驗排程(以 K8s Job 為例)

    假設有一個內部的 submit_experiment(spec: AlgoSpec) -> str 會幫你:

    1. 打包 code + config 到 image/volume。
    2. 生成 K8s Job yaml。
    3. 提交到 cluster,回傳 job_id

    簡化 pseudo-code:

    import kubernetes as k8s
    
    def submit_experiment(spec: AlgoSpec) -> str:
        job = build_k8s_job(spec)  # 填入 image, args, resource 限制
        api = k8s.client.BatchV1Api()
        resp = api.create_namespaced_job(namespace="research", body=job)
        return resp.metadata.name
    
    # fitness 評估:等 job 完成,讀取 metrics.json
    
    def fetch_fitness(job_id: str) -> float:
        # 假設每個 job 在 /results/metrics.json 寫入 val_acc
        metrics = load_from_object_store(f"results/{job_id}/metrics.json")
        return metrics["val_acc"]
    

    你只要確保:

    • 所有實驗都寫出 統一格式的 metrics.json / config.json
    • job name、run id 能對應回實驗記錄系統(MLflow、W&B)。

    3. Orchestrator:以 LangGraph 為例構建演化 DAG

    LangGraph 可以把 LLM、工具、迭代邏輯包成圖:

    from langgraph.graph import StateGraph, END
    
    class EvoState(BaseModel):
        population: list[AlgoSpec]
        history: list[dict]
        generation: int
    
    
    def propose_candidates(state: EvoState) -> EvoState:
        # 用 LLM 對每個 top-k spec 做變異
        ...
    
    
    def run_experiments(state: EvoState) -> EvoState:
        # 提交所有 candidates,等待完成,回寫 fitness
        ...
    
    
    def select_and_check_stop(state: EvoState) -> str:
        if state.generation >= MAX_GEN:
            return END
        return "propose"
    
    
    graph = StateGraph(EvoState)
    
    graph.add_node("propose", propose_candidates)
    graph.add_node("run", run_experiments)
    
    graph.add_edge("propose", "run")
    
    graph.add_conditional_edges("run", select_and_check_stop, {"propose": "propose", END: END})
    
    evo_app = graph.compile()
    

    後面你可以在另一個 graph 裡接上 writing phase:以最優 AlgoSpec + 實驗結果為輸入,調用 sentence-level RAG agent 生成報告或論文。


    4. sentence-level RAG 實作簡例

    from sentence_transformers import SentenceTransformer
    from qdrant_client import QdrantClient
    
    encoder = SentenceTransformer("all-mpnet-base-v2")
    qdrant = QdrantClient(host="localhost", port=6333)
    
    # 建 index:把實驗 log、表格、文獻拆成句子
    
    def index_sentences(sentences: list[str], meta: list[dict]):
        vecs = encoder.encode(sentences)
        qdrant.upsert(
            collection_name="research_corpus",
            points=[{"id": i, "vector": v, "payload": meta[i]} for i, v in enumerate(vecs)],
        )
    
    
    def retrieve_evidence(query_sentence: str, k: int = 5):
        qvec = encoder.encode([query_sentence])[0]
        hits = qdrant.search("research_corpus", query_vector=qvec, limit=k)
        return hits
    
    # LLM 每寫一句話前,先取 evidence
    
    claim = "在 QEC 任務上,我們的演算法平均錯誤率降低了 12.3%。"
    evidences = retrieve_evidence(claim)
    llm_context = format_evidence(evidences)
    
    resp = llm.chat([
        {"role": "system", "content": "根據下面的實驗證據,生成一個對應的結論句。"},
        {"role": "user", "content": llm_context},
    ])
    

    再加一個 Verifier:重新檢索一次,看 claim 是否可被證據支持,不行就標記為需重寫。


    建議與注意事項

    1. 實驗結果格式不一致

    • :每個實驗 script 隨意 print,LLM/agent 很難 parse,fitness 評估混亂。
    • 建議
    • 強制所有實驗輸出 統一 schema 的 JSON,例如:
      • metrics.json{"val_acc": 0.92, "train_time": 360}
      • config.json(完整 hyperparams)。
    • schema 驗證(Pydantic)檢查 artifact;不合法就標記這個個體為低適應度。

    2. LLM 收斂到壞思路 / mode collapse

    • :LLM 易過度放大小樣本成功設計,反覆微調同一個局部解,失去探索。
    • 建議
    • 搜索策略上引入 探索度控制:族群裡保留一部分「純隨機變異」個體。
    • 每 N 代重啟一次高多樣性的種群(借鑑 evolutionary algo 的 restart 策略)。
    • LLM prompt 中顯式要求「給出三類不同思路」,避免只改超參數。

    3. 成本與資源控制

    • :LLM + GPU 雙重成本,很容易跑成燒錢機器。
    • 建議
    • 在 orchestrator 層面設 hard budget:最大世代數、最大 job 數、最大雲端花費。
    • 用低成本模型做日常迭代,大模型只用在 跨世代總結 / 報告撰寫
    • 優先讓 LLM 做 靜態檢查(例如檢查明顯錯誤設計)再送去跑 GPU。

    4. LLM 對數據科學工具的錯用

    • :LLM 可能亂用 API(例如 pandas groupby 用錯、Sklearn split 漏掉 stratify),結果漂亮但不可信。
    • 建議
    • 對關鍵 API(train/test split、metrics 計算、cross-validation)儘量做成 封裝好的 utility 函數,禁止 LLM 自己寫這些低級邏輯。
    • 在 pipeline 裡加入 sanity check step
      • label 分布是否合理?
      • baseline 是否被超過?
      • 結果是否疑似 data leakage?

    5. 開始時先做「窄版」

    • 不要一開始就做「全自動研究員」。較務實的起點:
    • Auto-ABTest:讓 LLM 只改部分業務策略 / feature 配置,實驗系統沿用現有 AB 平台。
    • Auto-Feature-Engineering:LLM 只負責產生特徵轉換 pipeline(例如 SQL / PySpark),模型訓練沿用既有框架。
    • 寫作階段先只產出 自動實驗報告(非論文),幫團隊省時間。

    從工程的角度看,ResearchEVO 真正帶來的啟發是:

    把「做研究」拆成可編排的演化搜尋 + sentence-level RAG 寫作兩個 pipeline,然後用現成的 LLM、orchestrator、GPU 排程系統拼起來。

    只要你公司已經有基本的實驗平台,做一個自己的「輕量版 ResearchEVO」其實沒有想像中難,但能快速幫你把實驗速度和研究產出拉一個量級。

    🚀 你現在可以做的事

    • 先為現有實驗腳本統一輸出 metrics.json / config.json schema,打好 Auto-Research 地基
    • 選一個任務,用一個 LLM agent + 既有 K8s/Slurm 搭出最小可用的演化搜尋 loop
    • 把歷史實驗 log 拆成句子建一個向量索引,試做 sentence-level RAG 自動實驗報告生成
  • LatentAudit:用殘差幾何盯住 RAG 幻覺

    📌 本文重點

    • 光看檢索分數與事後自評難以即時監控幻覺
    • LatentAudit 直接讀殘差流幾何結構估真實度分數
    • 可在 RAG pipeline 中低延遲加入實時 guardrail

    在實務 RAG 專案裡,光靠「檢索品質 + 事後自評/投票」抓幻覺是不夠的
    – 檢索成功 ≠ 回答一定忠於證據(模型還是會自由發揮)
    – 自評 / judge 模型會 吃額外 Token 和延遲,流量大時成本爆炸
    – 多輪對話、串接工具後,哪一步開始幻覺常常完全沒監控

    💡 關鍵: 只靠檢索分數和事後評審,既無法即時阻斷幻覺,又會讓延遲與成本大幅增加。

    LatentAudit 提供另一條路:直接讀取生成模型的 殘差流(residual stream)幾何結構,在推理中測量「模型內部狀態」與檢索證據之間的 馬氏距離,做到:

    • 不需要額外 judge 模型
    • sub-millisecond 延遲、可 16-bit 固定點實作
    • 少量標註就能校準成實用的 真實度分數,在 API 層或 UI 層直接觸發 fallback

    重點說明

    1. 為什麼傳統 RAG 監控做不到「實時 + 便宜」

    實務上的典型做法:

    1. 只看檢索分數:例如 cosine 相似度、BM25 分數
    2. 問題:檢索到對的文獻,但模型回答的細節錯了(over-generalize, mis-attribute)完全抓不到。

    3. 事後自評 / 多模型投票

    4. judge LLM 問「這個回答是否根據檢索到的內容?」
    5. 或讓多個模型生成,再投票 / 聚合。
    6. 問題:

      • 推理路徑變成:檢索 → 回答 → 評審,延遲翻倍以上
      • 成本和吞吐量吃不消,很難在大規模 production 開啟
      • judge 模型本身也會幻覺,還得再校準
    7. log 後離線分析

    8. 用人審 / labeling 分析錯誤 pattern
    9. 問題:無法 實時阻斷 危險輸出(醫療/法律/金融)

    LatentAudit 直接把監控塞進 生成時的 forward pass

    • 白盒讀取中後段 殘差流 activation
    • 與「證據 representation」做幾何對齊度測量
    • 即時計算 距離 → 真實度分數 → 決策(放行 / fallback)

    💡 關鍵: 把監控邏輯塞進 forward pass,能在幾乎零額外延遲下拿到可用的真實度分數。

    2. LatentAudit 的核心做法(殘差幾何 + 馬氏距離)

    架構概念:

    1. 選定幾層殘差流:例如 Llama-3-8B 的 layer 20–30 殘差向量 ( h_l )

    2. 建一個 evidence representation ( e ):

    3. 通常來自:

      • 把所有檢索到的 passages 拼在一起,取 encoder / 第一層 decoder 的 CLS / BOS 向量
      • 或平均檢索 chunks 的 embedding
    4. 在訓練(校準)階段

    5. 收集 (question, evidence, answer) 三元組,並有「忠於證據 / 不忠」標註
    6. 對每個樣本取出中後段殘差流,做 pooling(例如平均或拼接):

      [
      z = P(h_{l_1}, …, h_{l_k})
      ]

    7. 在 latent 空間中估計「忠實」分佈的均值 ( \mu ) 和協方差 ( \Sigma )

    8. 定義馬氏距離規則

    9. 把 residual 表示 ( z ) 投影到 evidence 表示空間,或做簡單線性對齊,最後計算

      [
      d_M(z, e) = (z – W e – b)^T \Sigma^{-1} (z – W e – b)
      ]

    10. 這就是 LatentAudit 的核心:一條二次判別規則(不需要深 judge 模型)

    11. 校準成真實度分數

    12. 用 held-out 集合做 threshold / logistic calibration,得到:

      [
      s_{faith} = \sigma(\alpha \cdot d_M(z,e) + \beta)
      ]

    13. ( s_{faith} ) 越接近 1 表示越「有可能忠於證據」。

    因為只做矩陣乘、向量內積和少量逆協方差運算,
    可以用 16-bit fixed point 實作,延遲在 0.x ms 級別,可進一步配合 Groth16 做可驗證計算(不展開細節)。

    💡 關鍵: 使用 16-bit 固定點與馬氏距離,使得真實度評估可以在 sub-millisecond 延遲下完成。


    如何嵌入既有 RAG pipeline

    你需要:
    可白盒存取的模型(LlamaQwenMistral 等開源或自託管)
    – 在 forward 裡 hook activation,並在生成過程中同步喂入 evidence 表示

    常見 stack:

    • OpenAI compatible API(自託管 vLLM / Ollama 上掛開源模型)
    • 各種向量庫(PGVectorMilvusWeaviateQdrantElastic,…)

    典型 pipeline:

    1. user query → 檢索(向量庫) → 構造 prompt + evidence
    2. 呼叫 自託管模型(非黑盒雲 API)生成
    3. 在生成中,LatentAudit 模塊監控殘差流 → 算馬氏距離 → 輸出真實度分數
    4. API 返回:{ answer, faithfulness_score }
    5. 前端 / Orchestrator 根據 score 做 fallback 策略。

    實作範例

    以下以 vLLM + Llama3 自託管為例,展示核心落地點(偽碼 + Python 範例)。

    1. 在 HF 模型上 hook 殘差層

    from transformers import AutoModelForCausalLM, AutoTokenizer
    import torch
    
    MODEL_NAME = "meta-llama/Meta-Llama-3-8B-Instruct"
    model = AutoModelForCausalLM.from_pretrained(
        MODEL_NAME, torch_dtype=torch.bfloat16, device_map="auto"
    )
    tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
    
    TARGET_LAYERS = [20, 24, 28]
    residual_acts = []
    
    
    def make_hook(layer_idx):
        def hook(module, input, output):
            # input[0] 通常是 residual stream
            # 只取最後一個 token 的向量,減少開銷
            h = input[0][:, -1, :].detach().to(torch.float32)
            residual_acts.append((layer_idx, h))
        return hook
    
    
    for idx, blk in enumerate(model.model.layers):
        if idx in TARGET_LAYERS:
            blk.register_forward_hook(make_hook(idx))
    

    2. 建立 evidence representation

    假設你已經從向量庫拿到 top-k passages:

    def build_evidence_rep(passages: list[str]):
        text = "\n".join(passages)[:4096]  # 避免太長
        inputs = tokenizer(text, return_tensors="pt").to(model.device)
        with torch.no_grad():
            out = model.model(**inputs, output_hidden_states=True)
        # 用最後一層 hidden state 的 BOS / 第一 token 表示
        e = out.hidden_states[-1][:, 0, :].detach().to(torch.float32)
        return e  # shape: [1, d]
    

    3. 馬氏距離計算 + 校準

    事前你要離線擬合:
    WbΣ^{-1}αβ(可用 sklearn 或手寫)

    線上部分簡化為:

    # 假設以下參數已離線訓練好並載入
    W = torch.load("wa_projection.pt")         # [d_residual, d_e]
    b = torch.load("wa_bias.pt")              # [d_residual]
    Sigma_inv = torch.load("wa_sigma_inv.pt")  # [d_residual, d_residual]
    alpha, beta = torch.load("wa_logistic.pt")
    
    
    def latent_audit_score(evidence_vec, residual_acts):
        # pooling residual: 取指定層平均
        hs = [h for idx, h in residual_acts if idx in TARGET_LAYERS]
        H = torch.stack(hs, dim=1).mean(dim=1)  # [1, d_residual]
    
        # 對 evidence 做線性對齊
        e_proj = (evidence_vec @ W.T) + b  # [1, d_residual]
    
        diff = (H - e_proj)  # [1, d_residual]
        # 馬氏距離
        d_M = (diff @ Sigma_inv @ diff.transpose(0,1))[0,0]
    
        # logistic 校準成 [0,1]
        score = torch.sigmoid(alpha * d_M + beta).item()
        return score
    

    生成時流程:

    def rag_answer_with_faith(query, passages):
        residual_acts.clear()
    
        evidence_vec = build_evidence_rep(passages)  # [1,d]
    
        prompt = build_rag_prompt(query, passages)  # 你的 RAG prompt 模板
        inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
    
        with torch.no_grad():
            out = model.generate(
                **inputs,
                max_new_tokens=256,
                do_sample=False,
            )
    
        answer = tokenizer.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True)
        score = latent_audit_score(evidence_vec, residual_acts)
    
        return {
            "answer": answer,
            "faithfulness_score": score,
        }
    

    這邊只在 一次 forward + generate 裡多做幾個矩陣運算,延遲增量極小;你可以把結果包成 OpenAI 兼容 API 回傳:

    {
      "id": "chatcmpl-...",
      "object": "chat.completion",
      "choices": [
        {
          "message": {
            "role": "assistant",
            "content": "...",
            "faithfulness_score": 0.82
          }
        }
      ]
    }
    

    前端或 Orchestrator 可以直接讀 faithfulness_score 做決策。

    💡 關鍵: 直接在 API 回傳中加入 faithfulness_score,可讓前端與協調層即時採用不同的 fallback 策略。

    4. Fallback 策略示例(醫療 / 法律 / 客服)

    簡單策略:

    THRESHOLD_WARN = 0.7
    THRESHOLD_BLOCK = 0.4
    
    
    def route_by_faithfulness(result):
        s = result["faithfulness_score"]
    
        if s < THRESHOLD_BLOCK:
            # 高風險:重新檢索 + 明確要求引用 evidence,或升級人工
            return {
                "mode": "escalate",
                "message": "本次回答可信度較低,已轉交人工處理。",
            }
        elif s < THRESHOLD_WARN:
            # 中風險:要求模型引用更多 evidence / 提示使用者核對
            return {
                "mode": "warn",
                "message": "以下回答可能不完全可靠,請以實際條文/文獻為準。",
            }
        else:
            # 正常放行
            return {
                "mode": "ok",
                "message": "",
            }
    

    實際場景:

    • 醫療問答mode == "escalate" 時強制顯示「非醫療建議」,並把 case 丟進人工客服隊列
    • 法律諮詢mode == "warn" 模式時要求模型 列出具體條文/條號 並顯示原文片段
    • 客服查詢:低分時先做 重新檢索(不同索引 or 更寬鬆 query) 再生成一次,若仍低分再轉人工

    多模型 / 多輪對話:
    – 對每輪回答都算一個 faithfulness_score,記錄在對話 state
    – 對 工具返回 / 多模型投票輸出 也可以跑 LatentAudit,看哪個候選與 evidence 更對齊,再做投票加權


    建議與注意事項

    1. 必須白盒存取模型

    • 無法在 OpenAI / Anthropic 純雲端黑盒模型上做(拿不到殘差流)
    • 適合:
    • 自託管 Llama / Qwen / Mistral
    • Ollama / vLLM,但要在本地 wrap core HF 模型 做 hook,而不是只用遠端 HTTP

    2. 殘差層選擇與標準化影響很大

    • 中後段層(例如 60–80% depth)通常信號最好
    • 建議在校準時網格搜尋:
    • 選幾組 layer subset + pooling 策略(最後 token / mean / concat)
    • 對每組分別訓練 WΣ^{-1},選 AUROC / AUPRC 最佳
    • 標準化:
    • 建議對 residual 做 per-dimension z-score 或 whitening,有助於 Σ^{-1} 穩定

    3. 校準集的 domain mismatch 是大坑

    • 如果你用 PubMedQA 上的校準結果直接套到法律問答,誤報 / 漏報會很嚴重
    • 建議:
    • 至少針對你的業務 domain 收集 數百到數千個標註樣本
    • type 要包含:
      • 正確且完全有證據支撐
      • 幻覺 / 瞎掰
      • 部分支持(evidence 裡只有一半說法)

    4. 隱私與合規下收集校準資料

    • 若資料有 PHI / PII:
    • 在內網做標註與訓練,不要把 prompt / evidence / answer 傳出公司
    • 可以只存 殘差向量 + 二元標籤,丟棄原文內容,以降低隱私風險
    • 若需要對外可驗證(尤其在金融 / 公共服務):
    • 考慮用論文中的 16-bit fixed-point 實作 + Groth16,在不洩漏權重/activation 的前提下提供「監控邏輯正確執行」的證明

    5. 與現有評估/監控系統的整合

    • LatentAudit 不是 用來取代離線評估(BLEU, Rouge, factuality benchmark),而是:
    • 補上一層 以模型「內在狀態」為基準的實時 guardrail
    • 建議實務策略:
    • 離線:用 benchmark / 人工評估確認 RAG pipeline 基本可靠
    • 線上:啟用 LatentAudit,只作「低分拋錯/告警」,不要一開始就用來做 aggressive block
    • 每隔一段時間(例如每週)抽樣「被 block / warn 的案例」做人工 review,調整 threshold / 校準

    對你的專案的實際好處
    – 在不引入第二個 LLM 的前提下,把幻覺監控塞進現有 RAG 路徑,几乎不加延遲
    – 增加一個 可量化、可調整的真實度分數,方便 API / UI / workflow 做自動化 fallback
    – 線上問題不再只有「出事後看 log」,而是可以 即時標記高風險回答,甚至直接攔截,特別適合醫療、法律、金融、客服等高風險場景。


    🚀 你現在可以做的事

    • 在現有自託管 Llama / Qwen / Mistral 專案中,加上殘差層 hook 並輸出簡單的 faithfulness_score
    • 針對你的業務 domain 收集一批「忠於證據 / 幻覺 / 部分支持」標註樣本,用來擬合 WΣ^{-1} 與校準參數
    • 在 API 回傳中加入 faithfulness_score,並在前端或 Orchestrator 中實作最簡版本的 warn / block / escalate 策略
  • 用 W-RAC 讓你的 RAG 省錢又好查

    📌 本文重點

    • W-RAC 目標是在不犧牲 RAG 效果下大幅壓低 chunking 成本
    • 先把網頁拆成可定址的小單元,再用 LLM 只做「分組決策」
    • 保留結構化資訊有助於 debug、調優與控制向量庫容量

    一件事先講清楚:W-RAC 的目的,就是在不犧牲 RAG 效果的前提下,把「為了 chunking 花給 LLM 的錢」砍到最低。

    參考論文:Web Retrieval-Aware Chunking (W-RAC)


    為什麼你現在的 chunking 很可能在燒錢

    多數團隊做 RAG,會遇到幾個典型做法:

    • 固定長度切分(例如 500 tokens 一刀)
    • rule-based(照標題、段落、HTML tag 切)
    • 直接丟給 LLM「幫我分合理的 chunk」

    這幾種方法的共通問題:

    1. 重複內容被 embed 很多次
      尤其是網頁側邊欄、導覽列、footer,幾乎每個 chunk 都有一份。

    2. LLM 成本被當 tokenizer 用
      用 LLM 來重寫、分段、產生摘要,等於把整個網站內容吃一遍,token 直接爆掉。

    3. 不好 debug
      一個查詢跑出來一堆 chunk,很難追:

    4. 這個 chunk 為什麼被這樣切?
    5. 是哪個頁面、哪個段落?

    W-RAC 的核心想法:先把網頁拆成結構化「可標號的小單元」,LLM 只負責決定「哪些單元湊成一個 chunk」,完全不改寫原文。

    這樣可以:

    • LLM 只看「結構化 outline + 短內容片段」,token 使用大幅下降
    • chunk 是由原始小單元組合而成,可追蹤來源、可重建原文
    • 重複小單元只存一次,減少向量庫容量

    💡 關鍵: 先抽取可定址小單元,再用 LLM 只做分組規劃,可以在保留 RAG 效果的前提下,把 chunking 相關的 LLM token 成本壓到最低。


    核心功能:W-RAC 在做什麼?

    1. 把網頁拆成「可定址單元」

    具體做法:

    1. 用瀏覽器自動化抓頁面(例如 Playwright)
    2. 保留 DOM 結構,轉成一棵樹:
    3. 節點:標題、段落、表格列、列表項目等
    4. 每個節點給一個 ID(例如 page_123.h2_3.p_2
    5. 把每個節點變成一個「原子單元」,包含:
    6. id
    7. tag(h1/h2/p/li/td…)
    8. text(文字內容)
    9. path(在頁面中的位置)

    你可以實作的步驟:

    pip install playwright beautifulsoup4
    playwright install
    

    用 Playwright 拉 HTML,再用 BeautifulSoup 做 DOM 清洗、節點提取,最後存成 JSON:

    {
      "id": "page_123.h2_3.p_2",
      "tag": "p",
      "path": ["body", "main", "section[2]", "h2", "p[2]"],
      "text": "本方案適用於企業內部知識庫..."
    }
    

    行動:先做「乾淨的節點抽取」,還不要想 embedding 和 LLM,確保每個網頁能拆成穩定、可追蹤的小單元。


    2. 用 LLM 做「分組決策」,而不是改寫文本

    傳統 agent 會:把整頁文字丟進 LLM,請它「改寫 + 切 chunk」。

    W-RAC 則是:

    1. 給 LLM 的不是全文,而是「節點清單 + 結構資訊」:
    2. 節點 ID
    3. 簡短前幾個字(preview)
    4. tag / 標題層級
    5. 要 LLM 回傳的,只是ID 分組規劃,例如:
    [
      {"chunk_id": 1, "node_ids": ["...h2_1", "...h2_1.p_1", "...h2_1.ul_1"]},
      {"chunk_id": 2, "node_ids": ["...h2_2", "...h2_2.p_1"]}
    ]
    

    範例提示詞(可直接改用自己的模型):

    你是一個文件分組器。給你一個網頁節點清單,每個節點有:id、tag、text_preview、heading_level。
    
    目標:
    - 將相關的節點分成多個 chunk
    - 每個 chunk 內容長度約 300–800 字
    - 優先讓同一個小節(同一個 h2/h3 底下)的節點在同一個 chunk
    
    輸出格式:只回傳 JSON 陣列,每個元素包含:
    - chunk_id:整數
    - node_ids:字串陣列
    
    不要產生任何說明文字。
    

    接下來你在程式裡做:

    • 根據 node_ids 把原子單元的 text 串起來
    • 生成真正要 embed 的 chunk 文本

    行動:選一個便宜的小模型(例如本地 LLM 或雲端小模型),先在 1–2 個頁面上跑一輪「ID 分組」,確認輸出格式與 chunk 長度合理,再批次上線。


    3. 保留結構化資訊,提升可觀測性與調優效率

    因為每個 chunk 只是「小單元的組合」:

    • 每個 chunk 知道自己由哪些 node_id 組成
    • 每個 node_id 可以反查 DOM path → 原頁面位置

    你可以做到:

    • 查詢輸出時,在後台顯示:
    • chunk 來源頁面 URL
    • 對應的標題、段落位置
    • 線上觀察「常被命中的 chunk」長什麼樣,是否太長或太短

    簡單的監控策略:

    1. 在 RAG pipeline 中記錄:query / 命中 chunk_id / 來源 page_id
    2. 定期統計:
    3. 哪些頁面 chunk 命中率高但回答不精準 → 調整該頁 chunk 最大長度
    4. 某些 tag(例如 table)被切得太散 → 調整「表格應視為一組」的規則

    行動:把 node_idchunk_id 一起寫入向量庫的 metadata,之後才能在 dashboard 上做查詢與可視化。


    適合誰用:三個典型場景

    1. 公司知識庫 / 文件中心

    情境:

    • 你有 Confluence、Notion、GitBook 或自建 docs 站
    • 想做內部問答助手,但頁面一多,embedding 成本驚人

    W-RAC 的落地方式:

    1. 用 Playwright 把內部 docs 網站轉成 HTML
    2. 用 BeautifulSoup 抓出 h1–h3、段落、列表,做節點抽取
    3. 用小模型做 chunk 分組
    4. 把完成的 chunk 丟進現有向量庫(如 OpenSearch、PGVector、Weaviate)

    效果:

    • 導覽列、側邊欄只存一次,不會每個 chunk 重複
    • 每個問題能對應到具體章節,方便文件 owner 微調內容

    💡 關鍵: 對於大量公司文件,W-RAC 可以避免重複 embed 導覽與樣板內容,顯著降低向量儲存與 embedding 成本。

    2. 官網 FAQ / 產品說明頁

    情境:

    • 產品 FAQ 分散在多個頁面、Accordion、tab 裡
    • 用固定長度切,很容易一個 chunk 內混到不同問題

    W-RAC 做法:

    • 把每個 Q/A 區塊視為一個原子單元
    • LLM 分組時以「一問一答」為最小單位

    好處:

    • 用戶問「退款怎麼算?」時,命中的 chunk 幾乎就是整個退款 FAQ,不會混到完全不相干的條款

    3. 大量公開網頁做 RAG(爬站型應用)

    情境:

    • 你在做垂直搜尋 / 行業資料聚合
    • 動輒幾十萬頁 HTML,要控制成本

    W-RAC 的優點在這裡會放大:

    • LLM 只負責分組計畫,成本可比「全 LLM 分 chunk」少一個數量級(論文的主張)
    • 分組邏輯可重跑:
    • 想換 chunk 長度,只要重新跑 LLM 分組,不必重新爬網

    行動:挑一個實際場景(知識庫、FAQ、或爬站),先對 50–100 個頁面做 W-RAC pipeline,算出:LLM token vs 傳統做法的差異,作為是否全面導入的依據。


    怎麼開始:從技術棧到實作指引

    建議技術棧

    類別 推薦選項 備註
    抓網頁 Playwright / Puppeteer Playwright 對登入、動態頁面支援較好
    HTML 解析 BeautifulSoup / lxml 把 DOM 轉成節點樹、抽取文字與 tag
    分組 LLM 任一小模型(如本地 Qwen/LLama) 只做規劃決策,不改寫文本,成本壓得很低
    向量庫 PGVector / Qdrant / Weaviate 支援 metadata 查詢較重要,以便 debug
    嵌入模型 開源 embedding 或雲端 embedding 固定長度輸入即可,和 W-RAC 本身無強耦合

    行動:先決定你現有的向量庫與 embedding 方案,再把「抓網頁 + W-RAC 分組」當作前處理模組接進去。


    最快上手路徑(簡化版流程)

    1. 抓一頁 HTML
    2. 用 Playwright:

    “`python
    from playwright.sync_api import sync_playwright

    with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto(“https://your-site.com/faq”)
    html = page.content()
    browser.close()
    “`

    1. 用 BeautifulSoup 拆節點
    2. h1–h3pli、table row 都變成節點
    3. 幫每個節點生成 idpath

    4. 呼叫 LLM 做分組

    5. 使用前面提供的提示詞
    6. 控制每次輸入的節點數量(例如 100–200 個),避免 context 太大

    7. 依照 node_id 組 chunk

    8. 按分組結果串 text,加入 metadata(node_idspage_url

    9. 寫入向量庫 + 接到現有 RAG

    10. 查詢時流程不變,只是每個 chunk 背後多了完整來源資訊

    線上觀察 chunk 品質與調優策略

    觀察重點:

    1. 回答不準時,回頭看 chunk
    2. 是否同一個 chunk 裡混了太多主題?
    3. 是否重要上下文被切開?
    4. 調整策略
    5. 提示詞裡明確告訴 LLM:
      • 表格應盡量保持在同一 chunk
      • 同一個 h2 底下不要分太多 chunk
    6. 調整每個 chunk 的目標字數(例如從 800 改成 500)

    行動:在你的 RAG 後台加一個「檢視來源 chunk」按鈕,點下去就顯示該 chunk 的 node 列表與原頁面位置,方便你和 PM / 內容 owner 一起 review。


    小結:把 LLM 用在刀口上

    W-RAC 的重點不是多厲害,而是很務實:

    • LLM 只做「分組規劃」這種高價值決策
    • 文本本身盡量保持原樣,避免幻覺與重寫成本
    • 一旦你有了「結構化可定址單元」,後面調優都變簡單

    如果你正在為 RAG 成本與效果卡關,先不要換模型,先把 chunking 換成類似 W-RAC 的流程,很可能就能省下一大筆 embedding/LLM 費用,還順便讓系統更好 debug。

    🚀 你現在可以做的事

    • 選一個實際頁面,用 Playwright + BeautifulSoup 做出「乾淨節點抽取」JSON
    • 用一個便宜的小模型,照文中提示詞跑一輪「ID 分組」,實際組出 chunk 並寫入向量庫
    • 在你的 RAG 後台加上 chunk_id / node_id 的 metadata 顯示與檢視來源 chunk 按鈕,開始觀察與調整 chunk 策略
  • Compiled AI:把提示變成可審計工作流

    📌 本文重點

    • 用 LLM 在編譯階段產生狹義程式碼,執行期不再依賴 LLM
    • 業務邏輯可測試、可審計,安全面積與成本大幅下降
    • 特別適合高要求、高流量且規則穩定的企業級工作流

    在多數專案裡,我們會每個請求都叫一次模型,把非結構化的 prompt 丟給 LLM,期待它「大致照規則」行事。問題是:結果不穩、難回溯、成本高,還容易被 prompt injection 玩壞。Compiled AI 要解的是這個痛點:

    把原本寫在 prompt 里的業務邏輯,在編譯階段用 LLM 產生狹義程式碼,透過型別檢查、靜態分析與測試驗收,一旦通過就當成普通程式部署,執行期不再依賴 LLM

    對開發者的直接好處:

    • 結果可預測且可審計:輸出由 deterministic code 決定,不是每次抽樣
    • 安全面縮小:執行期不再接受任意自然語言指令
    • 成本與延遲大幅下降:大量交易共用同一份已編譯邏輯,token 成本被攤薄

    💡 關鍵: Compiled AI 把「每次都叫 LLM」改成「先編譯一次,再重複執行」,大幅提升穩定性並攤平成本。


    重點說明

    1. 架構:LLM 只在「編譯階段」出現

    典型 Compiled AI 架構可以拆成三層:

    1. 模板/SDK 層(受控框架)
    2. 你先定義好已驗證的 workflow 模板與 SDK,例如:HTTP 呼叫、DB 查詢、RAG 檢索、權限檢查等
    3. LLM 只能在模板內部空洞生成狹義業務邏輯函式,例如 select_customer_segment()build_rag_query()

    4. 編譯管線(有 LLM)

    5. Step 1 – Prompt 設計:描述任務、提供 API 規格 & 範例,要求輸出符合特定語言/框架(如 TypeScript + 自家 SDK)
    6. Step 2 – 產生 code artifact:LLM 產生一份或多份候選程式碼
    7. Step 3 – 謝與測試:型別檢查、靜態分析、單元測試/合約測試,不過關就自動 loop 回 LLM 要求修正
    8. Step 4 – 人工審核 + 簽章(視風險):例如醫療或金流流程

    9. 執行期(無 LLM)

    10. 線上請求只執行已編譯出的 code artifact,全程 deterministic,可以完整 log & replay

    核心概念:限制 LLM 的自由度,換取可測試、可版本控管的業務邏輯程式碼


    2. 工作流設計:把一個傳統 RAG / Agent 重構成 Compiled AI

    以一個典型 RAG QA 流程為例:

    使用者問問題 → LLM 根據 prompt 決定如何搜尋 → 呼叫向量庫 → LLM 基於檢索結果生成答案

    在傳統設計中,LLM 負責檢索策略 + 答案生成,兩段都高度隨機。重構成 Compiled AI,可以這樣拆:

    1. 編譯階段
    2. 用 LLM 生成一個狹義函式:build_search_plan(question: string) => SearchPlan,被嵌在已驗證的 RAG 模板中
    3. SearchPlan 僅包含:要查哪個 index、使用哪些 filter、topK、是否需要 fallback 等
    4. 再用 LLM 生成:synthesize_answer(question, contexts) => string,但這個函式需遵守強約束(例如:不可編造、必須引用 context id)

    5. 執行階段

    6. 每次 QA 時:
      • 用 deterministic code 呼叫 build_search_plan() → 打 DB / 向量庫
      • 把檢索到的 contexts 丟給 synthesize_answer()(也是普通函式)
    7. 整個過程再也不直接丟自然語言給 LLM,所有 decision path 都是可測試、可覆盤的程式碼

    8. 版本控管與灰度發布

    9. 每次重新編譯:產出新版本如 rag_workflow_v3.ts
    10. 用 Git tag & CI pipeline 把版本與測試報告綁在一起
    11. 線上:用 routing 或 feature flag 灰度流量,對比 v2 / v3 的成功率、平均延遲、查詢成本

    3. 工程實務:與「每請求叫一次模型」的差異

    基於現有研究與業界實測,Compiled AI 在幾個維度的典型差異:

    • 可靠性(確定性 vs 隨機)
    • 傳統:每次請求都用 sampling(temperature > 0),同一輸入結果可能不同
    • Compiled AI:執行期只跑 deterministic code + DB/RAG,相同輸入必然同樣輸出

    • 安全

    • 傳統:使用者輸入直接進 prompt,prompt injection 面積很大
    • Compiled AI:執行期輸入只餵進已定義的函式參數(string / enum / id 等),無法直接改變控制流

    • 成本與延遲

    • 編譯階段比較貴,但只做一次,之後可在大量請求上攤平
    • 實務上常見:十幾次交易後就開始比傳統架構便宜,長期 token 使用量可降數十倍

    💡 關鍵: 只要請求次數夠多,執行期省下的 token 成本與延遲,會很快抵消一次性的編譯開銷。


    實作範例

    以下用 TypeScript + 假想 SDK 示範一個簡化版 pipeline。

    1. 已驗證模板/SDK

    // sdk.ts - 由你維護的安全 SDK
    
    export type SearchPlan = {
      index: 'faq' | 'policy' | 'logs';
      topK: number;
      filters?: Record<string, string>;
    };
    
    export async function runRagWorkflow(
      question: string,
      buildSearchPlan: (q: string) => SearchPlan,
      synthesizeAnswer: (q: string, ctxs: string[]) => string
    ): Promise<string> {
      const plan = buildSearchPlan(question);
      const contexts = await vectorSearch(plan.index, question, plan.topK, plan.filters);
      return synthesizeAnswer(question, contexts);
    }
    
    async function vectorSearch(
      index: string,
      query: string,
      topK: number,
      filters?: Record<string, string>
    ): Promise<string[]> {
      // 已驗證的檢索實作
      /* ... */
      return [];
    }
    

    2. LLM 產生的狹義業務邏輯(編譯產物)

    在編譯階段,你用一個 prompt 要求模型只實作兩個函式:

    // generated_v3.ts - 由 LLM 產生,但要通過型別檢查與測試
    
    import { SearchPlan } from './sdk';
    
    export function buildSearchPlan(question: string): SearchPlan {
      const q = question.toLowerCase();
    
      if (q.includes('退款') || q.includes('billing') || q.includes('invoice')) {
        return { index: 'policy', topK: 5, filters: { category: 'refund' } };
      }
    
      if (q.includes('錯誤') || q.includes('error code')) {
        return { index: 'logs', topK: 10 };
      }
    
      return { index: 'faq', topK: 8 };
    }
    
    export function synthesizeAnswer(question: string, contexts: string[]): string {
      // 嚴格規定:
      // 1. 不得回答與 contexts 無關內容
      // 2. 必須在文末列出引用的 context 索引
      const summary = summarizeWithRules(question, contexts); // 你事先實作好的工具
      const citations = contexts
        .map((_, i) => `[#${i + 1}]`)
        .join(' ');
    
      return `${summary}\n\n引用來源:${citations}`;
    }
    

    3. 編譯 pipeline(CI 裡跑)

    // compile.ts - 只在 CI / 開發環境執行
    
    import { z } from 'zod';
    import { callLLM } from './llm_client';
    import { execSync } from 'child_process';
    
    const schema = z.object({
      code: z.string(),
    });
    
    async function generateCode() {
      const prompt = `
    你是一個 TypeScript AI,請只輸出一個檔案內容,實作:
    - export function buildSearchPlan(question: string): SearchPlan
    - export function synthesizeAnswer(question: string, contexts: string[]): string
    
    必須符合已存在的型別定義:
    - SearchPlan { index: 'faq' | 'policy' | 'logs'; topK: number; filters?: Record<string, string> }
    
    禁止:
    - 呼叫任何未在註解中允許的函式
    - 使用 eval / new Function
    - 動態匯入
      `;
    
      const raw = await callLLM({
        model: '**gpt-4.1**',
        temperature: 0,
        response_format: { type: 'json_schema', schema },
        messages: [{ role: 'user', content: prompt }],
      });
    
      const { code } = schema.parse(JSON.parse(raw));
      return code;
    }
    
    async function main() {
      const code = await generateCode();
      require('fs').writeFileSync('generated_v3.ts', code, 'utf8');
    
      // 1) 型別檢查
      execSync('npx tsc --noEmit', { stdio: 'inherit' });
    
      // 2) 靜態分析
      execSync('npx eslint generated_v3.ts', { stdio: 'inherit' });
    
      // 3) 測試
      execSync('npm test -- generated_v3.test.ts', { stdio: 'inherit' });
    }
    
    main().catch((err) => {
      console.error(err);
      process.exit(1);
    });
    

    搭配 CI/CD:

    • CI:觸發 compile.ts → 產出 generated_v3.ts → 跑測試 → 產出報表
    • CD:若通過,打 tag rag_workflow_v3,並更新配置讓 5% 流量導到 v3;監控成功率、latency、成本指標再逐步擴大

    💡 關鍵: 把 LLM 產物納入 CI/CD(型別檢查、靜態分析、測試與灰度發佈),就能像管理普通程式碼一樣管理 AI 邏輯。


    建議與注意事項

    1. 業務規則變更頻率

    Compiled AI 適合:

    • 規則相對穩定、但正確性要求高的流程(客服 QA、金融函數呼叫、醫療文件處理)

    不適合:

    • 每天都在改規則、或依賴即時實驗的場景,因為每次改都要走「重新編譯 + 測試」流程
    • 高度探索型、open-ended 任務(創作、策略 brainstorm、UX 研究等)

    實務建議:

    • 把流程拆成兩層:核心決策邏輯用 Compiled AI,外層的探索與創意仍然用即時 LLM

    2. 測試覆蓋不足 = 把錯誤「編進系統」

    Compiled AI 的風險是:一旦編譯出的邏輯有 bug,它會一直穩定地錯

    必做:

    • 為生成函式設計合約測試:同一輸入 → 必須產出指定的 SearchPlan / 函式呼叫序列
    • 對關鍵場景建立 golden QA 測試集,每次編譯都跑完整 regression
    • 對模型產物加上防呆檢查(如:topK 不可大於 50,index 只能是白名單)

    3. 安全與最小權限

    • 模板 / SDK 層要實施 最小權限
    • 不給生成函式直接打 DB 連線,只能呼叫封裝好的 queryCustomerById(id) 等高階 API
    • 不允許檔案寫入、外網 request 等敏感操作
    • 透過靜態分析檢查:是否有 eval、動態 import、直接執行 shell 等 pattern

    4. 成本模型與「何時值得編譯」

    可以用簡單估算:

    • 編譯一次成本:C_compile(幾萬 token)
    • 傳統架構每次請求成本:C_online
    • Compiled AI 每次請求成本:C_compiled(通常 ≪ C_online

    只要請求數 N 滿足:

    C_compile + N * C_compiled < N * C_online

    就值得改成 Compiled AI。研究與實務常見:十幾到幾十次請求後就開始回本,高流量業務會很划算。

    5. 與現有專案整合的落地步驟

    1. 先挑一個穩定且高流量的子流程(例如:FAQ RAG 檢索策略、金融 function calling 的參數整理)
    2. 為它抽象出一個窄介面函式(例如 buildSearchPlanprepareFunctionCallParams
    3. 建立 minimal 的編譯 pipeline(LLM → 生成 code → tsc + 測試)
    4. 先 offline 對比:新老流程在測試集上的正確率 / 成本
    5. 小流量灰度上線,配合 metrics 監控,逐步拓展到更多流程

    結論:Compiled AI 的核心不是「用 LLM 寫程式」,而是把 prompt 中模糊的規則,轉成可測試、可簽章、可審計的程式碼工件。對需要穩定性、安全與成本控制的企業工作流,特別是 RAG、function calling、金融與醫療場景,是非常值得實驗的架構升級方向。

    🚀 你現在可以做的事

    • 在現有系統中挑一段高流量、規則穩定的 RAG 或 function calling 流程,先抽象出一個窄介面函式如 buildSearchPlan
    • 建一個最小可行的編譯 pipeline:用 LLM 產生 TypeScript 函式 → 跑 tsc + 單元/合約測試 → 輸出 generated_v1.ts
    • 用 feature flag 灰度導入新流程,監控正確率、延遲與 token 成本,評估轉為 Compiled AI 的回本點
  • AI Agent 正在變成各行各業的「專職角色」:從雲端故障指揮官到教育出題機的三個實戰案例

    如果哪天你打開 Slack,發現新加入的同事叫「ActionNex」,職稱寫著 Oncall Outage Manager(雲端故障值班經理),你大概不會意外——但真正驚訝的,是這位「同事」其實是個 AI Agent。

    這不是科幻,也是現在進行式。

    這一波 Agent 熱潮,真正有趣的變化不是「模型又變多強」,而是它開始在各個領域變成一個具體的專職角色

    • 在微軟 Azure,它是負責雲端停機調度的虛擬值班經理(ActionNex)
    • 在科研實驗室,它幫科學代理整理、鍛造會自己長大的技能庫(SkillFoundry)
    • 在程式課教室,它是老師身邊的出題助教(CODE-GEN)

    這篇文想聊的不是「又有幾篇新論文」,而是:

    Agent 落地時,真正重要的設計點,其實不是「模型多大、多強」,而是:
    1. 怎麼設計技能庫
    2. 怎麼設計工作流
    3. 怎麼設計人類在回圈中的協作

    我們會拆三個案例,順便帶到兩個很關鍵的底層技術:Profile-Then-Reason(PTR)Combee,來看 Agent 要怎麼變得更穩、更會學。


    一個共通現象:Agent 在團隊裡,開始有「職稱」了

    先抓一個大方向:

    以前我們講 LLM,多半把它當「加強版 ChatGPT」——一個很聰明的通用助手。

    但這幾個系統有個共同點:

    • 它們不是「萬事通」,而是清楚限定職責的角色
    • 它們都有專用的工具與技能庫
    • 它們都有固定的工作流程(workflow)
    • 它們都有穩定運作的記憶系統
    • 而且都強調 human-in-the-loop(人類在回圈中)

    換句話說,真正落地的 Agent,比較像是:

    「你團隊裡多了幾位非常認真、永遠 oncall、不會累的專職同事。」

    接下來就來看這三位「新同事」各自長什麼樣子。


    案例一:ActionNex —— 微軟 Azure 的雲端故障「虛擬指揮官」

    情境想像一下:

    凌晨三點,某區域的 Azure 服務掛了。平常流程:

    1. 值班工程師被叫醒
    2. 開會、看 dashboard、翻 playbook
    3. 瘋狂在 Teams 上 ping 各團隊
    4. 邊排查邊對外更新狀態

    這種跨團隊、資訊不完整、高壓的情境,過去完全靠人撐著。

    微軟在 ActionNex 論文 裡做的事情是:

    把這整個「停機事件管理」流程,交給一個 專職 Agent 當指揮官

    ActionNex 怎麼工作?

    它接收的資訊其實非常雜:

    • 停機事件內容(Ticket、公告)
    • 遙測資料(各種監控指標)
    • 人類在 Teams / Email 裡的對話

    第一步,它會做一件很重要的事:

    把一堆雜訊壓縮成一串「關鍵事件」(critical events)

    有點像是:

    • 從「聊天紀錄 + log + 報表」
    • 自動剪輯成一條事件時間線:「01:32 服務 A 延遲飆升 → 01:37 DB 重啟失敗 → 01:40 客戶大量 Time-out」

    接著它會用一套分層記憶系統來推理下一步該做什麼。

    三層記憶:讓 Agent 像資深值班工程師一樣「有歷史感」

    ActionNex 把記憶分成三種:

    1. KCA 知識庫(Key-Condition-Action)
      從歷史 playbook 萃取:
    2. 關鍵條件(Condition):例如「延遲 > 200ms 且錯誤率 > 5%」
    3. 對應動作(Action):例如「先 rollback 上一版」「切到備援區域」
      這有點像整個團隊的「作戰 SOP」被結構化塞進 Agent 裡。
    4. 情境記憶(Past outage memories)
      過去每一次停機的「故事版」:發生什麼、怎麼處理、結果如何。
    5. 工作記憶(Working memory)
      這次事件當下的進度:已做哪些操作、各團隊目前狀態。

    推理代理會把當前的關鍵事件,拿去跟這些記憶對照:

    • 找出「長得很像的歷史事件」
    • 套用對應的 KCA 規則
    • 給出「下一步該做什麼」的建議

    最重要的:人機協作,而不是全自動

    ActionNex 不是來「接管」值班,而是變成:

    • 為每個角色(不同團隊)
    • 在不同階段(初始 triage、調查、修復、收尾)
    • 給出角色與階段條件化(role- and stage-conditioned) 的建議

    而且每一次人類的接受 / 拒絕 / 更改行動,

    都會回寫成新的資料,讓系統持續「學會更像這個組織真正的作法」。

    簡單講,它就是個永遠在場、會記住每一次事故教訓的「虛擬 oncall 指揮官」。

    實測成效:不只是 demo,是真的上線用

    這篇論文最關鍵的一段是:

    • 8 次真實 Azure 停機案例 中測試
    • 下一步行動建議的:
    • 精確率約 71.4%
    • 召回率約 53–55%

    換句話說:

    • 它給的「可用建議」不少,而且品質不差
    • 又因為有值班工程師在回圈裡,不會傻傻地完全照做

    對營運團隊來說,這不是「AI 會不會取代我」的題目,而是:

    「我多了一個懂歷史、熟 SOP、24 小時在線的值班副手。」


    案例二:SkillFoundry —— 幫科研 Agent 打造會自己長大的技能庫

    第二個案例走進研究室。

    現在很多實驗室都在做「科學代理」:

    • 幫忙寫分析程式
    • 跑生物資訊 pipeline
    • 讀 paper、查資料

    但現實問題是——科研世界的「知識」非常碎:

    • GitHub repo 裡的腳本
    • API 文件
    • Lab wiki、Notebook
    • Database 查詢
    • 方法論寫在論文裡

    對 Agent 來說,這些都像一堆散落各地的「技能零件」,

    會寫 Python ≠ 會跑你實驗室那套 pipeline。

    SkillFoundry 做的事情,就是:

    把這些 heterogeneous 資源,鍛造成「可以直接拿來用的技能包」,而且會自我演進。

    什麼是「技能包」?

    在 SkillFoundry 裡,每個 skill 不是一句 prompt,而是一個完整的「模組」:

    包含:

    • 任務範圍(這技能用來幹嘛)
    • 輸入/輸出格式
    • 執行步驟(step-by-step 程序)
    • 環境假設(需要哪些環境 / 資料)
    • 來源(來自哪個 repo / 文件 / 論文)
    • 測試(怎樣算成功)

    很像你在寫一個「可重用的工具」,不是臨時寫一段 code 貼上就算。

    SkillFoundry 的核心流程:

    可以想像成四步:

    1. 建立領域知識樹(Domain Knowledge Tree)
    2. 把目標領域(例如基因組學)拆成一棵樹:
    3. 節點可能是:資料前處理 → 比對 → 變異檢測 → 下游分析
    4. 從高價值分支挖資源
    5. 從 repo / API / 文件 / 論文中抓出相關程式與描述
    6. 用 LLM 幫忙抽取出「這個操作到底在做什麼」
    7. 轉成技能包 + 測試
    8. 把操作流程寫成結構化 skill
    9. 自動或半自動生成測試案例
    10. 閉環驗證 + 自我演進
    11. 讓代理實際用這些 skill 去解 benchmark / 真實任務
    12. 觀察:
      • 哪些技能常用?
      • 哪些技能常出錯?
    13. 依狀況進行:擴展/修復/合併/刪減

    這個「挖 → 寫成 skill → 用 → 回饋 → 精煉」的迴圈,就是它的「自我演進」。

    結果:不是在堆技能,而是真的變強

    幾個有意思的數字:

    • SkillFoundry 產生的技能庫,跟現有的 SkillHub / SkillSMP 比,
    • 70% 以上的技能是新的(不是抄舊東西)
    • 把這些技能接上現有 coding agent:
    • 在多個科學基準上表現有明顯提升
    • 對像基因組學這種比較硬的任務,提升特別明顯

    更關鍵的是:

    你可以針對某個具體任務,按需設計一批技能,而不是丟給模型自己猜要怎麼做。

    從產品角度來看,這個訊號非常清楚:

    • 真正厲害的科學 Agent,不只是「模型懂很多生物學」
    • 而是它有一套針對領域打造的技能庫 + 驗證機制

    如果你在做 B2B / 垂直領域產品,這其實就是:

    「先把你的 domain SOP 結構化成一個會自己長大的技能庫。」


    案例三:CODE-GEN —— 程式課老師的 AI 出題助教

    第三個案例走進教室。

    程式課老師大概都懂這個痛點:

    • 要為不同程度的學生出足夠多、夠有品質的題目
    • 題目要對齊課程目標(不是隨便考)
    • 還要兼顧:清晰度、合理難度、沒有語病、程式碼要能跑…

    CODE-GEN 做的是:

    用一個 Human-in-the-loop 的 RAG Agent 系統,當老師的「出題助教」。

    兩個 Agent:出題者 + 驗題者

    整個系統拆成兩個角色:

    1. Generator(出題代理)
    2. 讀課程內容、學習目標(透過 RAG 把相關教材餵給模型)
    3. 產生多選題:題幹、選項、正解、解析
    4. Validator(驗證代理)
    5. 獨立地、用另一套流程檢查題目
    6. 檢查七個教學維度,例如:
      • 題目是否清晰
      • 程式碼是否可執行、沒有 bug
      • 概念是否對齊課程目標
      • 正確答案是否合理

    兩個 Agent 都配了一些專用工具

    • 用來實際跑程式碼
    • 驗證輸出
    • 做精確計算

    所以這不是「LLM 靠感覺出題」,而是:

    LLM + 工具 + 另一個 LLM 當審稿編輯。

    人類在回圈:老師還是最後的權威

    CODE-GEN 強調的是 Human-in-the-loop

    • 研究找了 6 位領域專家(程式教師)
    • 對 288 題 AI 生成題目做評估
    • 得到 2016 組人機共同評分數據

    在可被人類直接檢查的維度(清晰度、程式碼有效性、概念對齊、答案合理性)上:

    • 成功率在 79.9% – 98.6% 之間

    但研究也坦白說:

    • 有一些「比較微妙」的教學品質問題
    • 例如題目的「教育價值」「是否真的能引導學生思考」
    • 還是需要人類專業來判斷

    我覺得這是很健康的設計哲學:

    AI 幫你「大量產出高水準草稿」,
    老師主導「最後把關與精修」。

    對任何內容產品團隊也一樣:

    • 不要期待 Agent「全自動產出完美內容」
    • 要把它當成高效率內容工廠 + 嚴謹的 QA 流程

    底層技術:要讓 Agent 穩、快、會學,靠什麼?

    看完三個落地案例,你會發現一個 pattern:

    • 都是多步驟流程
    • 都要跟工具互動
    • 都要反覆執行很多次

    這種情境下,兩個瓶頸很常見:

    1. Agent 推理流程太長 → 延遲爆炸、錯誤累積
    2. 想讓 Agent 自我提升 → 學得太慢或學壞

    這時候,兩篇研究上場:Profile-Then-Reason(PTR)Combee

    Profile-Then-Reason(PTR):先寫流程,再執行

    一般常見的 Agent 模式(像 ReAct)是:

    想一步,call 一次工具;看結果,再想下一步。

    問題是:

    • 工具多 → LLM 每一小步都要重新推理
    • 跑久了延遲很高,而且很容易一錯再錯、錯誤累積

    PTR 論文 提出一種不一樣的做法:

    Profile-Then-Reason:先用模型「把整個工作流程寫出來」,再用比較穩的運算子去執行這個流程。

    大致流程:

    1. Profile(定義流程)
    2. LLM 看任務與可用工具
    3. 一口氣設計出一個 explicit workflow(像寫一個簡化版 pipeline)
    4. Execution(執行)
    5. 由 deterministic 或 guarded operator 來跑這個 workflow
    6. 這一步不再狂 call LLM,而是照規劃一步步執行
    7. Verification(驗證)
    8. 有一個 verifier 來檢查整個 trace 合不合理
    9. Repair / Re-Reason(修正)(只有必要才做)
    10. 若 verifier 發現流程不可靠,才再叫 LLM 來調整流程

    核心 idea 是:

    「盡量把『思考成本』集中在一兩次,再用穩定的程式化執行接手。」

    實驗結果:

    • 在 6 個 benchmark、4 個不同模型上測試
    • PTR 的精確匹配率普遍優於 ReAct
    • 模型呼叫次數也被嚴格限制在 2–3 次 左右

    尤其在:

    • 以檢索為主(RAG-heavy)
    • 任務拆解很多階段

    這種情境,PTR 特別吃香。

    對產品設計來說,這個訊息很直接:

    真正複雜的工作流,不要用「一直問模型下一步要幹嘛」來跑,而是讓模型先設計流程,再讓系統執行

    Combee:讓一大群 Agent 的經驗變成可用的「系統提示升級」

    第二個問題是:

    「我們收了一堆 Agent 執行軌跡,怎麼讓它們真的變成 Agent 變強的養分?」

    過去像 ACE、GEPA 這類 prompt learning 方法,可以從歷史任務中學出更好的 system prompt,但多半:

    • 針對單一 Agent 或小量並行
    • 當你想一次學很多 trace,就會:
    • 要嘛變超慢
    • 要嘛品質崩掉

    Combee 的出發點是:

    我們需要一個可以「高並行學 prompt」的框架,才配得上現在一堆大規模 Agent 執行軌跡。

    它的做法可以簡化理解為三個關鍵機制:

    1. 平行掃描(Parallel scan)
    2. 把大量軌跡拆開,在多個 worker 上同時做提示學習
    3. 增強隨機重排(Enhanced random reshuffling)
    4. 避免某些偏差樣本一直堆疊導致 prompt 學壞
    5. 動態批次控制(Dynamic batch size)
    6. 根據學習狀況調整 batch,兼顧穩定與速度

    實驗上,在 AppWorld、Terminal-Bench、Formula、FiNER 等任務上:

    • 相比之前方法,學習速度最高快 17 倍
    • 準確度大致持平或更好
    • 成本維持相近

    這帶來一件很實際的想像:

    未來你的產品如果有 10,000 個 Agent 在跑任務,它們的「軌跡」真的可以變成一種集體學習機制,而不是只拿來算 dashboard。


    三個案例的一致設計:記憶、技能、驗證、人類在回圈

    把 ActionNex、SkillFoundry、CODE-GEN 放在一起,你會看到一張很像的架構圖:

    1. 記憶系統(Memory)
    2. ActionNex:KCA + 過往事故 + 當前工作記憶
    3. SkillFoundry:領域知識樹 + 已驗證技能歷史
    4. CODE-GEN:課程內容、過往題目與評分結果
    5. 技能庫(Tools / Skills)
    6. ActionNex:操作手冊轉成 KCA;各種維運工具
    7. SkillFoundry:每個帶測試的 skill module
    8. CODE-GEN:程式執行、驗證工具 + RAG 工具
    9. 工作流程(Workflow / Orchestration)
    10. 有明確的階段:感知 → 推理 → 行動 → 回饋
    11. PTR 類的技術則用來把這工作流更結構化、穩定化
    12. 驗證與自我修正(Verification & Self-Improvement)
    13. ActionNex:人類值班人員的使用/拒絕行為
    14. SkillFoundry:用 benchmark 與測試來修技能
    15. CODE-GEN:Validator Agent + 老師評分
    16. Combee 類技術:把這些軌跡學成更好的 prompt
    17. Human-in-the-loop(人類在回圈中)
    18. 不只是「可選的審核」,而是:
      • ActionNex:值班工程師 + 跨團隊溝通
      • SkillFoundry:領域專家指導知識樹、審關鍵技能
      • CODE-GEN:老師最後裁決題目品質

    這裡面有一個很重要的觀點:

    真正落地的 Agent 系統,設計重心往往不在「選哪個模型」,而在:

    • 你怎麼整理你組織的知識(記憶)
    • 你怎麼把流程拆成可重用的技能
    • 你怎麼安排工作流與驗證點
    • 你怎麼讓人類有自然的介面可以介入、修正、教它

    如果你想在自家產品導入 Agent,應該先思考什麼?

    把研究拉回產品實務,我會建議你先從這三個問題開始,而不是先問「要不要上 GPT-4.1 還是別的?」

    1. 你想讓 Agent 當什麼「專職角色」?

    不要一開始就說:「我要一個 AI 助手。」

    改問:

    • 在你的業務裡,有沒有:
    • 雜事多、流程固定
    • 但又需要一定專業判斷的角色?

    例如:

    • 客服團隊裡的「初步 triage 專員」
    • SRE 團隊裡的「值班副手」(像 ActionNex)
    • 研究團隊裡的「腳本整理小幫手」(像 SkillFoundry)
    • 教育團隊裡的「出題助教」(像 CODE-GEN)

    給它一個清楚的職稱和職責範圍,

    你比較有機會設計出真的能上線用的 Agent,而不是玩具 demo。

    2. 你的「技能庫」要怎麼長出來?

    機器不懂你公司到底怎麼做事。

    你需要回答:

    • 你們現在的 SOP 放在哪?(文件、Notion、Wiki、內部工具?)
    • 哪些操作可以拆成「技能」?
    • 每個技能:輸入是什麼、輸出是什麼、怎樣算成功?
    • 有沒有測試機制可以驗證技能沒壞?

    可以借鏡 SkillFoundry 的心法:

    • 先畫一棵「業務知識樹」
    • 選幾個高價值分支去做 POC
    • 用半自動方式把 SOP 轉成技能,儘量帶上測試與環境假設

    3. 你要怎麼把人類放進回圈?

    這點在三個案例裡都被反覆強調:

    • 沒有人類在回圈的 Agent,很難安全地上產線

    你可以設計:

    • 哪些階段一定要人類確認?
    • 例如:
      • 發布外部公告前
      • 修改關鍵設定前
      • 上線前最後一版題目
    • 人類的操作會不會被記錄、回饋?
    • 接受 / 拒絕 / 修改 Agent 建議
    • 能不能作為未來 prompt / 技能優化的資料

    這裡就呼應 Combee 的價值:

    如果你能把大量的「人類如何修正 Agent」軌跡存下來,未來可以用高並行的 prompt learning 框架,把整體系統悄悄調得越來越好。


    結語:先設計角色與流程,再談模型

    ActionNex、SkillFoundry、CODE-GEN、PTR、Combee 這幾篇研究,對我來說共同在傳遞一件事:

    Agent 不再只是「一個更聰明的大模型」,而是「被放進組織裡,負責特定工作的專職角色」。

    而當它變成「同事」之後,你最需要思考的其實是那些很「工程」也很「管理」的問題:

    • 你要給它什麼職稱和職責?
    • 它的技能從哪裡來,怎麼維護?
    • 它的工作流長什麼樣?
    • 它怎麼跟人類同事協作、被教會?

    模型當然重要,但更像是:

    一個很會學習、很會表達、很會寫 code 的「大腦」,
    真正決定它能不能上線成為團隊一員的,是你給它的 記憶、技能、流程與人際關係(human-in-the-loop)設計

    如果你正準備在產品裡導入 Agent,可以試著先畫一張圖:

    1. 中間寫上那個你想要的「AI 職稱」
    2. 左邊列出它需要什麼技能(對應到工具 / API / SOP)
    3. 右邊畫出它每天的工作流程(哪裡要人類確認)
    4. 下方想想:它今天做錯了,你要怎麼讓它明天變得更好?

    當這張圖足夠清楚,選用哪個模型,反而是一個比較好解的工程問題了。


    延伸閱讀

    • ActionNex: A Virtual Outage Manager for Cloud
      https://arxiv.org/abs/2604.03512
    • SkillFoundry: Building Self-Evolving Agent Skill Libraries from Heterogeneous Scientific Resources
      https://arxiv.org/abs/2604.03964
    • CODE-GEN: A Human-in-the-Loop RAG-Based Agentic AI System for Multiple-Choice Question Generation
      https://arxiv.org/abs/2604.03926
    • Profile-Then-Reason (PTR): Bounded Semantic Complexity for Tool-Augmented Language Agents
      https://arxiv.org/abs/2604.04131
    • Combee: Scaling Prompt Learning for Self-Improving Language Model Agents
      https://arxiv.org/abs/2604.04247
  • 從「結果對不對」到「過程可追溯」:新一代 AI 評估與合規工具長什麼樣?

    從「結果對不對」到「過程可追溯」:新一代 AI 評估與合規工具長什麼樣?

    你有沒有發現,現在大家在講「AI 評估」時,還是很習慣問一個問題:

    這個模型準不準?

    比如:考試幾分、Pass@1 多高、Bleu/Rouge 幾分、Win Rate 打贏 GPT-4 幾%。

    但當 AI 真的進到工作流程、產品線、甚至走進法規監管的世界,這個問題其實遠遠不夠。

    更關鍵的反而是:

    它是怎麼得到這個結果的?這個過程,能不能攤在陽光下?

    這篇文想聊的是:
    – 為什麼「看結果」已經不夠
    – 六條正在匯流的研究線索:
    FactReview:把論文審稿變成「有證據、可重現」的流程
    Compliance-by-Construction:用 argument graph + RAG 做安全認證級合規
    Beyond Fluency:在 Agentic IR 裡,每一步都要設 verification gate
    OpenEval:為什麼 AI 評估需要「item-level benchmark」
    QualAnalyzer:把質性分析切成可審計的 atom
    Context Engineering:靠結構化上下文提高「第一次就做對」的機率
    – 最後收斂成一組實用 checklist:未來你在公司導入 AI 工具時,應該要求哪些「可追溯」與「流程級評估」能力


    一句話先破題:

    過去是「對或錯」,未來會是「為什麼是這樣、證據在哪?」

    如果你只看模型最後吐出的答案,其實有點像:只看考試最後幾分,不看每一題的作答方式,也不知道監考老師有沒有睡著。

    在低風險情境,這樣用 AI 還撐得過去;但在四種場景,很快就會不夠用:

    1. 學術審稿:你敢讓一個黑箱 AI 決定論文收不收?
    2. 安全/法規合規:出事時,誰做的決策、依據是什麼,說得清嗎?
    3. 研究工作(尤其是質性研究):審查委員問你「這個結論怎麼來的」,你不能回答「AI 覺得」。
    4. 一般知識工作(PM、法務、顧問、分析師):一年後回頭看決策,你有沒有辦法復原當時的脈絡?

    下面我們用這四種場景,把六篇研究串一串,看新一代「可追溯 AI」大概會長什麼樣。


    場景一:論文審稿 —— FactReview 把「主觀審」變成「有證據的審」

    傳統審稿有幾個痛點:
    – 審稿人時間不夠,只能「掃一掃」
    – 很吃「論文寫得好不好看」,文筆好可能加分不少
    – 主張對不對,常常要靠 reviewer 印象或手動翻文獻
    – 更別說「真的去跑作者的 code」這件事,現實是多數人做不到

    FactReview 的核心想法是:

    不要只看投稿的故事,而是把「主張→證據→重現」變成一條可以機器協助的鏈。

    它做了幾件事:

    1. 主張萃取(claim extraction)
    2. 把論文拆成一條條主張:

      • 提出什麼方法?
      • 相較於哪些 baseline?
      • 哪些任務上「顯著更好」?
    3. 文獻定位(literature positioning)

    4. 自動去檢索相關工作,幫你看:

      • 這篇真的比「最接近」的工作好嗎?
      • 有沒有漏引、或者「重新包裝舊方法」?
    5. 執行式驗證(execution-based claim verification)

    6. 有開源 code 的情況下,直接跑 repo,在有限資源下重現關鍵實驗。
    7. 然後對每個主張打標:

      • 支持 / 部分支持 / 衝突 / 無法驗證
    8. 生成審稿與證據報告

    9. LLM 幫你把上面這些整理成一份「有段落、有引用、有重現結果」的 review。

    作者在 CompGCN 案例裡,真的跑出一個有趣的狀況:
    – 某些任務真的重現了作者結果 → 支持
    – 但在圖分類任務,整體性能主張只被「部分支持」

    這就從「我覺得作者誇大了」變成「我實際跑過、結果在這」,整個審稿過程突然有一種「工程化」的味道。

    重點不是 AI 幫你寫 review,而是:AI 幫你把 review 變成一條「證據鏈」。


    場景二:合規/安全認證 —— Compliance-by-Construction:從黑箱到「每個 claim 都要有證據」

    在高風險系統裡(醫療、航空、金融風控、關鍵基礎設施),有一個關鍵問題:

    你怎麼證明「這個系統是安全、合規」的?

    傳統做法是寫一堆文件、報告,手動整理「設計→實作→測試→審查」的證據。這種東西一來超花人力,二來其實很容易斷鏈(文件沒更新、測試沒對齊實作等等)。

    Compliance-by-Construction 想做的是一個蠻激進的改變:

    把整個合規流程,變成一張形式化的 argument graph,每一個節點都是「可以被檢查的 claim」。

    再加上 LLM + RAG,去幫你建構和維護這張圖。

    核心組件有四個:

    1. Argument Graph(論證圖)
    2. 把合規聲明拆成很多層級的 claim:
      • 系統是安全的
      • 因為控制 A、B、C 存在
      • 控制 A 的證據是測試 X、設計文檔 Y
    3. 每個 claim 必須被「下層 claim + 證據」支持。

    4. RAG(檢索增強生成)

    5. LLM 不再亂掰,而是:

      • 對每個 claim,去現有文件、測試報告、log 裡找證據
      • 找不到,就標記缺口,而不是硬生生成一段看起來合理的說法。
    6. 推理驗證核心(reasoning core)

    7. 限制 LLM 的推理邏輯,讓它不能「跳步」或做出不合理的推論。
    8. 例如:嚴格要求每個 claim 都要有明確證據指向,不能只有語義上好像合理。

    9. 溯源日誌(provenance logging)

    10. 每個 claim 是怎麼被建立、修改、接受的,都有 log。
    11. 日後 audit,能把整張 graph 走一遍。

    這種設計有一個很重要的精神:

    AI 不是「幫你寫一份漂亮的合規報告」,而是「幫你組裝一張可以被驗證的 argument graph」。

    對公司端的影響很直接:
    – 你可以具體回答「某個合規聲明是基於哪些測試、哪些文件」
    – 出事時能回溯是「哪個 claim、哪段證據」有問題
    – 監管機關要看時,不會只看到一份 narrative,而是能看到全圖


    場景三:Agentic IR —— Beyond Fluency:語言再順,也不能蓋掉「路線走錯」

    很多人現在在玩「AI Agent」:
    – 會自己規劃任務
    – 自己去搜尋資料、調用工具
    – 自己迭代思考,最後給你結果

    聽起來很酷,但現實是:

    只要前面某一步稍微偏軌,後面就會一路放大錯誤,最後看起來超流暢,但整條路徹底走錯。

    Beyond Fluency: Toward Reliable Trajectories in Agentic IR 把這個問題講得很白:

    • Agentic IR(代理式資訊檢索)其實是一個 Reason → Act → Observe 的長鏈
    • 錯誤可能發生在:
    • 規劃(plan 錯了題目)
    • 檢索(查錯資料)
    • 推理(解讀錯資訊)
    • 執行(tool 用錯)
    • 最可怕的是:
    • 語言流暢度完全不會反映錯誤程度
    • 它可以非常有自信地,優雅地,講一段完全錯的故事

    作者主張:

    不要只看「最後答得對不對」,要開始看「整條 trajectory 有沒有 integrity」。

    具體做法:Verification Gates

    在每一個「互動單元」加上 verification gate:
    – 規劃完 → 有沒有檢查「這個 plan 是否覆蓋了問題關鍵」?
    – 檢索結果 → 有沒有檢查「這些文件真的跟 query 有關」?
    – 推理步驟 → 有沒有 cross-check「結論有沒有被文本支持」?
    – 執行工具 → 有沒有檢查 API 回傳是不是符合預期格式?

    甚至在高不確定性時,要勇於選擇「不執行」或「適度退出」,而不是硬把任務完成。

    這其實就是把 agent 從:「一次跑到底,看結果」
    變成:「每一步都過關,整條路才算數」。

    換成產品語言:

    未來你在導入 Agentic 系統時,不該只問「它完成任務的成功率」,還要問:「它有沒有內建 step-wise verification?」


    場景四:AI 評估本身 —— OpenEval:沒有 item-level,就談不上嚴肅的評估科學

    AI 評估現在也有一個很大的盲點:

    • 許多 benchmark 只公布「總分」或「平均 accuracy」
    • 研究者微調 prompt、換模型,看 leaderboard 排名
    • 但我們其實不知道:
    • 哪些題目是模型的「死穴」?
    • 是不是某個子類型題目完全失效?
    • 量表本身設計有沒有偏誤?

    Position: Science of AI Evaluation Requires Item-level Benchmark Data 直接開炮:

    要建立嚴肅的「AI 評估科學」,item-level data 是必要條件

    所謂 item-level,很簡單:
    – 不只要有「一個 benchmark 的總分」
    – 還要能看到:
    – 每一個題目(item)模型怎麼答
    – 每一題的 metadata(難度、題型、能力構面)
    – 標記者的分歧在哪裡

    這樣才有機會:
    – 做細粒度診斷:
    – 模型是否特別擅長某個子類型?
    – 評估本身是不是只測到某種偏狹的能力?
    – 檢驗 benchmark 的有效度(validity):
    – 我們以為在測「推理能力」,結果題目其實都在考「常識填空」。

    作者也推出了 OpenEval 倉庫,牽頭推這套做法。

    實務上,這件事對企業也非常 relevant:

    當你宣稱「我們用 X 個 benchmark 評估這個模型」,在高風險場景下,監管機關很可能會追問:
    – 這些 benchmark 的 item-level 表現長怎樣?
    – 你怎麼知道它沒在某個角度完全失明?


    質性研究:QualAnalyzer 把「一整份訪談」拆成一顆顆可審計的 atom

    質性研究一直很依賴人類的「閱讀 → 詮釋 → 編碼」。
    引入 LLM 之後,很快出現兩種極端:
    – 一種是:完全信 AI,丟整份訪談給它,讓它幫忙找主題
    – 另一種是:完全不信,因為「看不懂它怎麼得出這個結論」

    QualAnalyzer 提出一個蠻優雅的折衷:

    把 LLM 的分析流程切到「非常細粒度(atomistic)」:
    – 每一小段資料(比如一個段落、一個回合)獨立處理
    – 每一顆「分析 atom」都留存完整的:prompt、input、output

    他們做了一個 Chrome extension,嵌在 Google Workspace 裡,實際演示兩個案例:
    – 論文整體性評分
    – 訪談稿的演繹主題編碼

    關鍵不是工具本身,而是方法論

    • 分析不是一次「黑箱處理」,而是由很多小決策組成
    • 每個小決策都可以被審計:
    • 這段訪談為什麼會被編碼成這個主題?
    • AI 當時看到的上下文是什麼?
    • 如果人類不同意,可以精確指出哪個 atom 有問題

    對質性研究而言,這是大事:
    – 審查委員要的是「方法透明」
    – 有了這種 atom-level audit trail,
    – 你可以說:「這不是我瞎用 AI,而是一套可被審查的流程。」

    這概念其實可以平移到很多知識工作場景:
    – 客服 QA 標註
    – 內部文件分類
    – 品牌聲量質性分析

    只要你的任務是「看一堆文字 → 做判斷」,都應該問:
    我能不能把這個過程拆成很多小決策,每一個小決策都有 log?


    把錯一次做對:Context Engineering 用「結構化上下文」提升成功率

    前面幾個工作都在講「怎麼 audit 過程」,
    Context Engineering 則比較像是:

    在事情發生之前,先把「上下文」工程化,降低出錯機率。

    作者的觀察是:

    • 大家很愛聊「prompt 技巧」,但實務上更關鍵的是:
    • 你給模型的「上下文」是不是完整而結構化?

    於是他們提出:

    五種上下文角色(AEC-RM):

    1. Authority:權威來源
    2. 告訴模型「應該以誰的聲音說話、遵循哪個權威標準」

    3. Exemplar:範例

    4. 給幾個好的輸入→輸出樣本,讓模型對齊風格與格式

    5. Constraint:限制

    6. 明確哪些不能做、不能編造、不能超出範圍

    7. Rubric:評分規範

    8. 告訴模型「什麼叫好的輸出」,有點像給它一份自我評分表

    9. Metadata:元資料

    10. 任務背景、使用者角色、目標受眾等

    再加上四階段 pipeline:Reviewer → Designer → Builder → Auditor
    – 不是一個人憑直覺寫 prompt,而是有明確角色分工

    實驗結果蠻直白:
    – 沒有好上下文的情況下:
    – 72% 的互動需要來回多次
    – 平均 3.8 次互動才搞定一件事
    – 「第一次就做對」只有 32%
    – 用結構化上下文之後:
    – 平均互動次數降到 2.0
    – 首次通過率升到 55%
    – 若允許多次迭代,最終成功率達 91.5%

    這件事跟「過程可追溯」也完全連在一起:

    當上下文是結構化、可版本控制的,你才能在事後說:
    「這次模型做錯,是因為 Exemplar 給得不好,還是 Constraint 定義不清?」


    收斂:未來導入 AI 工具,應該檢查的「可追溯 & 流程級評估」清單

    把上面幾條線索拉在一起,我會把未來的 AI 工具能力拆成兩大塊:

    1. 過程可追溯(Process Traceability)
    2. 流程級評估(Process-level Evaluation)

    以下是一份給「公司導入 AI 工具」用的實務 checklist,
    你可以直接拿去問 vendor、內部 AI 團隊,甚至拿來檢視自己做的系統。

    A. 過程可追溯:這個工具的「路線圖」,你看得到嗎?

    1. 步驟級 log
    2. 模型是不是把任務拆成多步?
    3. 每一步的輸入、輸出、使用的工具(API / 檢索)是不是都有記錄?

    4. 主張(claim)與證據的對齊

    5. 對於關鍵結論,能不能追溯到:
      • 是哪幾段文本、哪幾筆數據支持?
    6. 有沒有類似 FactReview 或 argument graph 的機制,
      把「主張 → 證據 →狀態(支持/部分支持/衝突)」串起來?

    7. 上下文版本控制

    8. Prompt / context 是否可版本化管理?
    9. 每次輸出,可以回到當時的 Authority / Exemplar / Constraint / Rubric / Metadata?

    10. 細粒度單元(atoms/items)

    11. 對於「長文件處理/大量樣本分析」,
      有沒有像 QualAnalyzer & OpenEval 那樣的:

      • atom-level / item-level log?
      • 可以一題一題、一段一段檢查與抽樣?
    12. 溯源日誌(provenance)

    13. 能不能回答:
      • 這個結果在哪個時間、由哪個模型版本、在什麼上下文下產生?

    B. 流程級評估:不是只看「準不準」,而是「整條流程穩不穩」

    1. Step-wise evaluation
    2. 有沒有對每個步驟的品質做評估?
    3. Agent 的 plan / retrieve / reason / execute,有沒有各自的 metrics?

    4. Verification gates

    5. 關鍵步驟前後,有沒有自動或半自動的檢查?
    6. 高風險場景:

      • 模型是否在信心不足時「選擇不執行」?
      • 是否會 escalate 給人類?
    7. Item-level benchmark data

    8. 對於內部評估集:

      • 是否保留每一題的模型輸出?
      • 是否可以做子群體分析(某類問題表現特別差)?
    9. 人類在迴路中的角色(Human-in-the-loop)

    10. 人類 reviewer / auditor 能不能有效介入:

      • 看每一個 atom/item 的決策
      • 覆寫錯誤
      • 把這些 feedback 餵回系統?
    11. 合規/責任追蹤(Accountability)

    12. 當模型建議被採用變成決策時:

      • 系統能不能記錄「誰看過、誰按下批准」?
      • 日後 audit 能不能還原「這個決策背後的 argument graph」?
    13. Context Engineering 能力

    14. 工具有沒有把上下文顯式結構化?
    15. 有沒有方法去評估「上下文品質」對結果的影響,
      而不是只調模型參數或 prompt 關鍵字?

    結尾:AI 工具的新標準——「我不只要答案,還要你給我故事的全紀錄」

    如果要用一句話總結這篇:

    未來真正成熟的 AI 系統,
    不會只跟你說「答案是什麼」,而是會把「我是怎麼走到這個答案」完整攤開。

    • FactReview 告訴我們:審稿不該只看故事,要看主張 + 文獻 + 重現
    • Compliance-by-Construction 告訴我們:合規不該只是文件,而是一張可驗證的 argument graph
    • Beyond Fluency 提醒我們:Agent 不該只看最後結果,而要有每一步的 verification gate
    • OpenEval 在推:沒有 item-level data,談不上嚴肅的 AI 評估科學
    • QualAnalyzer 展示:即便是質性研究,也可以做到 atom-level audit trail
    • Context Engineering 則說:把上下文工程化,是讓 AI 第一次就做對 的關鍵

    如果你在公司裡負責導入 AI 工具,接下來可以慢慢把標準從:

    • 「這個模型分數比別人高嗎?」

    升級到:

    • 「這個系統能不能讓我:
    • 看懂它的推理過程?
    • 驗證它的證據?
    • 追溯每個決策的上下文與責任?」

    當我們開始用這套標準選 AI,整個生態會慢慢被推向一個更健康的方向:
    – 少一點漂亮的 demo
    – 多一點「可以挺過 audit」的實戰系統

    如果你現在就在設計 AI 產品,也可以試著問自己:

    「我能不能讓使用者,不只得到答案,還能獲得一條清楚的『推理與證據路線圖』?」

    這,可能會是下一代 AI 工具真正的競爭力所在。


    延伸閱讀