iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
佛心分享-IT 人自學之術

學習 LLM系列 第 19

Day19 把檢索結果套進 LLM 做回答

  • 分享至 

  • xImage
  •  

流程 :

  1. 使用者輸入 query
  2. 用 embedding model 檢索向量庫 → 取得 top-k(id, question, answer, score)
  3. 把 top-k 格式化成「參考資料」context,拼入 prompt template(明確告訴模型只可使用這些資料)
  4. 呼叫 LLM 生成回答(控制 temperature=0 以降低胡扯)
  5. 回傳 answer 並註明來源 id

注意重點 :

  • 務必在 prompt 明確告訴模型:「只能使用檢索到的參考資料來回答;若資料不足請回答『查無資料』」(以降低 hallucination)
  • token 長度限制:把 top-k 拼進 prompt 時可能超出模型 context,需用 tokenizer 檢查並做 truncation(只放最重要的 chunk)
  • 一致性:query 用跟 index 同一個 embedder encode
  • 生成設定:事實性回答用 temperature=0、do_sample=False
  • 來源標註:回答最後標示 [來源: q1,q3](或用 metadata 裡的來源字串)

實作 :

# 直接載入 Chroma,使用既有的索引
import chromadb
from sentence_transformers import SentenceTransformer


# 初始化 embedding 模型 & chroma client
embedder = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
client = chromadb.PersistentClient(path="./chroma_db")


# 直接 get 已存在的 collection(faq_collection)
collection = client.get_collection("faq_collection")


# 定義 retrieve_chroma()
def retrieve_chroma(query: str, k: int = 3):
    q_emb = embedder.encode([query], convert_to_numpy=True).tolist()
    res = collection.query(
        query_embeddings=q_emb,
        n_results=k,
        include=["documents", "metadatas", "distances"]
    )
    results = []
    for doc, meta, dist in zip(res["documents"][0], res["metadatas"][0], res["distances"][0]):
        results.append({
            "question": meta["question"],
            "answer": meta["answer"],
            "distance": dist
        })
    return results


# 定義 RAG 流程
def rag_answer(query: str, retriever="chroma", k=3):
    docs = retrieve_chroma(query, k=k)
    context_text = "\n".join([f"Q: {d['question']}\nA: {d['answer']}" for d in docs])
    prompt = f"""你是一個客服助理,根據以下的 FAQ 回答使用者的問題:
---------------------
{context_text}
---------------------
使用者的問題:{query}
請給一個簡潔且有幫助的回答:
"""
    answer = docs[0]["answer"] if docs else "抱歉,目前沒有相關資訊。"
    return {
        "query": query,
        "retrieved": docs,
        "prompt": prompt,
        "answer": answer
    }


# 測試
query = "如何退貨?"
result = rag_answer(query)
print("==== Answer ====")
print(result["answer"])

結果 :
https://ithelp.ithome.com.tw/upload/images/20251003/20169173S1wRhkhOMC.png


上一篇
Day18 把 embeddings 存入向量資料庫,實作簡單檢索
下一篇
Day20 做成 CLI 版本
系列文
學習 LLM20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言